feat:优化页面代码及版本升级报错处理

main
朱群锋 2025-02-11 08:57:04 +08:00
parent 15a5b4804b
commit 969d9f5d7d
8 changed files with 1008 additions and 931 deletions

View File

@ -1,15 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import {reactive, toRefs, watch} from 'vue' import {reactive, toRefs, watch} from 'vue'
import common from '@/utils/common' import common from '@/utils/common'
import {Sort, Setting} from '@element-plus/icons-vue'
const prop = defineProps({ const prop = defineProps({
loading: { loading: {
type: Boolean, type: Boolean,
default: false default: false
}, },
page: { page: {
type: Object, type: Object,
default:{ default: {
current: 1, current: 1,
size: 10, size: 10,
total: 0, total: 0,
@ -32,67 +33,74 @@
}, },
headerCellStyle: { headerCellStyle: {
type: Object, type: Object,
default:{color:'#606266', fontWeight: 700} default: {color: '#606266', fontWeight: 700}
}, },
data: { data: {
type: Array, type: Array,
default: [] default: []
}, },
}) })
const emit = defineEmits([ const emit = defineEmits([
'onSizeChange','onCurrentChange','onSelectionChange','setCellColor', 'onSizeChange', 'onCurrentChange', 'onSelectionChange', 'setCellColor',
'onButtonClick','onSwitchChange', 'onButtonClick', 'onSwitchChange',
]) ])
const state = reactive({ const state = reactive({
maxHeight: window.innerHeight - 280, maxHeight: window.innerHeight - 280,
tableHeight: prop.tableHeight, tableHeight: prop.tableHeight,
headerCellStyle: prop.headerCellStyle, headerCellStyle: prop.headerCellStyle,
size: 'default', size: 'default',
columns: prop.column.map((item:any) => {return item.prop}), columns: prop.column.map((item: any) => {
return item.prop
}),
checkColAll: true, checkColAll: true,
isIndeterminate: true, isIndeterminate: true,
cellStyle: function(e:any){ cellStyle: function (e: any) {
let obj:any = {}; let obj: any = {};
emit('setCellColor', e, (color = {}) =>{ emit('setCellColor', e, (color = {}) => {
obj = color; obj = color;
}); });
return obj; return obj;
}, },
}) })
const { const {
maxHeight,tableHeight,headerCellStyle,cellStyle,size,columns,checkColAll,isIndeterminate maxHeight, tableHeight, headerCellStyle, cellStyle, size, columns, checkColAll, isIndeterminate
} = toRefs(state) } = toRefs(state)
const onSizeChange = (e:any) =>{ const onSizeChange = (e: any) => {
emit('onSizeChange', e) emit('onSizeChange', e)
} }
const onCurrentChange = (e:any) =>{ const onCurrentChange = (e: any) => {
emit('onCurrentChange', e) emit('onCurrentChange', e)
} }
function onFind(arr:any,val:any){ function onFind(arr: any, val: any) {
if(!arr) return 'info'; if (!arr) return 'info';
return arr.find((item:any)=>{ return item.value == val}).label; return arr.find((item: any) => {
} return item.value == val
}).label;
}
function onCheckColAll(val:boolean){ function onCheckColAll(val: boolean) {
const _columns = prop.column.map((item:any) => {return item.prop}) const _columns = prop.column.map((item: any) => {
return item.prop
})
state.columns = val ? _columns : [] state.columns = val ? _columns : []
state.isIndeterminate = false state.isIndeterminate = false
} }
function onCheckedCol(value: string[]){
function onCheckedCol(value: string[]) {
let checkedCount = value.length let checkedCount = value.length
state.checkColAll = checkedCount === prop.column.length state.checkColAll = checkedCount === prop.column.length
state.isIndeterminate = checkedCount > 0 && checkedCount < prop.column.length state.isIndeterminate = checkedCount > 0 && checkedCount < prop.column.length
} }
watch(columns, (newValue, oldValue) =>{ watch(columns, (newValue) => {
prop.column.filter((item:any) =>{ prop.column.filter((item: any) => {
item.isShow = newValue.indexOf(item.prop) == -1; item.isShow = newValue.indexOf(item.prop) == -1;
}) })
}) })
</script> </script>
<template> <template>
@ -107,43 +115,51 @@
<el-popover placement="bottom" :width="80" trigger="click"> <el-popover placement="bottom" :width="80" trigger="click">
<template #reference> <template #reference>
<el-button link> <el-button link>
<el-icon :size="20"><Sort /></el-icon> <el-icon :size="20">
<Sort/>
</el-icon>
</el-button> </el-button>
</template> </template>
<div> <div>
<el-radio-group v-model="size"> <el-radio-group v-model="size">
<el-radio label="small">紧凑</el-radio> <el-radio value="small">紧凑</el-radio>
<el-radio label="default">默认</el-radio> <el-radio value="default">默认</el-radio>
<el-radio label="large">中等</el-radio> <el-radio value="large">中等</el-radio>
</el-radio-group> </el-radio-group>
</div> </div>
</el-popover> </el-popover>
<el-popover placement="bottom" :width="120" trigger="click"> <el-popover placement="bottom" :width="120" trigger="click">
<template #reference> <template #reference>
<el-button link> <el-button link>
<el-icon :size="20"><Setting /></el-icon> <el-icon :size="20">
<Setting/>
</el-icon>
</el-button> </el-button>
</template> </template>
<div> <div>
<el-checkbox v-model="checkColAll" :indeterminate="isIndeterminate" @change="onCheckColAll">/</el-checkbox> <el-checkbox v-model="checkColAll" :indeterminate="isIndeterminate" @change="onCheckColAll">/
</el-checkbox>
<el-scrollbar height="400px"> <el-scrollbar height="400px">
<el-checkbox-group v-model="columns" @change="onCheckedCol" > <el-checkbox-group v-model="columns" @change="onCheckedCol">
<el-checkbox v-for="col in column" :key="col" :label="col.prop">{{col.label}}</el-checkbox> <el-checkbox v-for="col in column" :key="col" :label="col.label" :value="col.prop">{{ col.label }}
</el-checkbox>
</el-checkbox-group> </el-checkbox-group>
</el-scrollbar> </el-scrollbar>
</div> </div>
</el-popover> </el-popover>
</div> </div>
<el-table :data="data" border stripe :size="size" :height="tableHeight" :max-height="maxHeight" row-key="id" :tree-props="{children: 'children', hasChildren: 'hasChildren'}" <el-table :data="data" border stripe :size="size" :height="tableHeight" :max-height="maxHeight" row-key="id"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
v-loading="loading" :header-cell-style="headerCellStyle" :cell-style="cellStyle" v-loading="loading" :header-cell-style="headerCellStyle" :cell-style="cellStyle"
@selection-change="$emit('onSelectionChange')" style="width: 100%;"> @selection-change="$emit('onSelectionChange')" style="width: 100%;">
<template v-for="item in column" :key="item"> <template v-for="item in column" :key="item">
<el-table-column v-if="!item.prop && !item.label && !item.isShow" :fixed="item.fixed" type="selection" width="45"></el-table-column> <el-table-column v-if="!item.prop && !item.label && !item.isShow" :fixed="item.fixed" type="selection"
width="45"></el-table-column>
<!-- color值 --> <!-- color值 -->
<el-table-column v-else-if="item.type == 'color' && !item.isShow" <el-table-column v-else-if="item.type == 'color' && !item.isShow"
:label="item.label" :align="item.align != null ? item.align : 'center'" :width="item.width"> :label="item.label" :align="item.align != null ? item.align : 'center'" :width="item.width">
<template #default="scope"> <template #default="scope">
<span :style="{color: scope.row[item.prop]}">{{scope.row[item.prop]}}</span> <span :style="{color: scope.row[item.prop]}">{{ scope.row[item.prop] }}</span>
</template> </template>
</el-table-column> </el-table-column>
<!-- icon图标 --> <!-- icon图标 -->
@ -170,14 +186,15 @@
<el-table-column v-else-if="item.type == 'image' && !item.isShow" <el-table-column v-else-if="item.type == 'image' && !item.isShow"
:label="item.label" :align="item.align != null ? item.align : 'center'" :width="item.width"> :label="item.label" :align="item.align != null ? item.align : 'center'" :width="item.width">
<template #default="scope"> <template #default="scope">
<el-image :src="scope.row[item.prop]" :preview-src-list="[scope.row[item.prop]]" preview-teleported fit="cover" style="width: 50px; height: 50px"/> <el-image :src="scope.row[item.prop]" :preview-src-list="[scope.row[item.prop]]" preview-teleported
fit="cover" style="width: 50px; height: 50px"/>
</template> </template>
</el-table-column> </el-table-column>
<!-- el-rate --> <!-- el-rate -->
<el-table-column v-else-if="item.type == 'rate' && !item.isShow" <el-table-column v-else-if="item.type == 'rate' && !item.isShow"
:label="item.label" :align="item.align != null ? item.align : 'center'" :width="item.width"> :label="item.label" :align="item.align != null ? item.align : 'center'" :width="item.width">
<template #default="scope"> <template #default="scope">
<el-rate v-model="scope.row[item.prop]" disabled allow-half /> <el-rate v-model="scope.row[item.prop]" disabled allow-half/>
</template> </template>
</el-table-column> </el-table-column>
<!-- el-tag --> <!-- el-tag -->
@ -187,7 +204,7 @@
<el-tag :size="item.option.size" <el-tag :size="item.option.size"
:effect="item.option.effect" :effect="item.option.effect"
:type="onFind(item.option.typeList, scope.row[item.prop])"> :type="onFind(item.option.typeList, scope.row[item.prop])">
{{scope.row[item.alias==null?item.prop:item.alias]}} {{ scope.row[item.alias == null ? item.prop : item.alias] }}
</el-tag> </el-tag>
</template> </template>
</el-table-column> </el-table-column>
@ -195,8 +212,9 @@
<el-table-column v-else-if="item.type == 'button' && !item.isShow" show-overflow-tooltip <el-table-column v-else-if="item.type == 'button' && !item.isShow" show-overflow-tooltip
:label="item.label" :align="item.align != null ? item.align : 'center'" :width="item.width"> :label="item.label" :align="item.align != null ? item.align : 'center'" :width="item.width">
<template #default="scope"> <template #default="scope">
<el-button @click="$emit('onButtonClick',scope.row)" :type="item.option.type" link :size="item.option.size"> <el-button @click="$emit('onButtonClick',scope.row)" :type="item.option.type" link
{{scope.row[item.alias==null?item.prop:item.alias]}} :size="item.option.size">
{{ scope.row[item.alias == null ? item.prop : item.alias] }}
</el-button> </el-button>
</template> </template>
</el-table-column> </el-table-column>
@ -205,8 +223,10 @@
:label="item.label" :align="item.align != null ? item.align : 'center'" :width="item.width"> :label="item.label" :align="item.align != null ? item.align : 'center'" :width="item.width">
<template #default="scope"> <template #default="scope">
<el-switch @change="$emit('onSwitchChange',scope.row)" :inline-prompt="!item.option.inlinePrompt" <el-switch @change="$emit('onSwitchChange',scope.row)" :inline-prompt="!item.option.inlinePrompt"
:active-value="item.option.activeValue" :active-color="item.option.activeColor" :active-text="item.option.activeText" :active-value="item.option.activeValue" :active-color="item.option.activeColor"
:inactive-value="item.option.inactiveValue" :inactive-color="item.option.inactiveColor" :inactive-text="item.option.inactiveText" :active-text="item.option.activeText"
:inactive-value="item.option.inactiveValue" :inactive-color="item.option.inactiveColor"
:inactive-text="item.option.inactiveText"
:size="item.option.size" :size="item.option.size"
v-model="scope.row[item.prop]" v-model="scope.row[item.prop]"
></el-switch> ></el-switch>
@ -225,7 +245,7 @@
<el-table-column v-else-if="item.type == 'dict' && !item.isShow" <el-table-column v-else-if="item.type == 'dict' && !item.isShow"
:label="item.label" :align="item.align != null ? item.align : 'center'" :width="item.width"> :label="item.label" :align="item.align != null ? item.align : 'center'" :width="item.width">
<template #default="scope"> <template #default="scope">
<span>{{common.getDictLabel(item.dictType, scope.row[item.prop])}}</span> <span>{{ common.getDictLabel(item.dictType, scope.row[item.prop]) }}</span>
</template> </template>
</el-table-column> </el-table-column>
<!-- 其他数据列 --> <!-- 其他数据列 -->
@ -257,36 +277,41 @@
</div> </div>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.table-container{ .table-container {
.search-wrap{ .search-wrap {
// background: var(--bg1); // background: var(--bg1);
border: 1px solid var(--el-border-color); border: 1px solid var(--el-border-color);
border-radius: var(--el-border-radius-base); border-radius: var(--el-border-radius-base);
padding: 1rem; padding: 1rem;
} }
.table-wrap{
.table-wrap {
padding: 1rem 0; padding: 1rem 0;
.header{
.header {
float: right; float: right;
padding-bottom: 0.4rem; padding-bottom: 0.4rem;
} }
} }
.pagination-wrap{
.pagination-wrap {
padding-bottom: 0.2rem; padding-bottom: 0.2rem;
float: right; float: right;
} }
} }
.el-table__body-wrapper::-webkit-scrollbar { .el-table__body-wrapper::-webkit-scrollbar {
width: 5px; width: 5px;
height: 1px; height: 1px;
} }
.el-table__body-wrapper::-webkit-scrollbar-thumb {
.el-table__body-wrapper::-webkit-scrollbar-thumb {
background-color: #909399; background-color: #909399;
border-radius: 5px; border-radius: 5px;
} }
.el-table__body-wrapper::-webkit-scrollbar-track {
.el-table__body-wrapper::-webkit-scrollbar-track {
border-radius: 5px; border-radius: 5px;
background: #ededed; background: #ededed;
} }
</style> </style>

View File

@ -2,20 +2,20 @@
<div id="amisid" ref="boxRef"></div> <div id="amisid" ref="boxRef"></div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import {watch,ref} from "vue" import {watch, ref} from "vue"
import {ElMessage} from 'element-plus' import {ElMessage} from 'element-plus'
import 'amis/sdk/sdk.js' import 'amis/sdk/sdk.js'
import 'amis/lib/themes/default.css' import 'amis/lib/themes/default.css'
import 'amis/sdk/color-picker.js' import 'amis/sdk/color-picker.js'
import 'amis/sdk/rest.js' import 'amis/sdk/rest.js'
// import {InputCity} from 'amis/esm/renderers/Form/InputCity.js' import InputCity from 'amis/lib/renderers/Form/InputCity'
// import {InputColor} from 'amis/esm/renderers/Form/InputColor.js' import InputColor from 'amis/lib/renderers/Form/InputColor'
import axios from 'axios' import axios from 'axios'
import copy from 'copy-to-clipboard' import copy from 'copy-to-clipboard'
import {getToken} from '@/api/auth' import {getToken} from '@/api/auth'
const props = defineProps({ const props = defineProps({
formid: { formid: {
type: String, type: String,
default: () => { default: () => {
@ -28,26 +28,28 @@
return {} return {}
} }
} }
}) })
// @ts-ignore // @ts-ignore
const amis = amisRequire('amis/embed'); const amis = amisRequire('amis/embed');
const boxRef = ref(null) const boxRef = ref(null)
watch(()=> props.formjson, (data)=>{ watch(() => props.formjson, (data) => {
if (Object.keys(data).length !== 0) {
onRendering(data) onRendering(data)
}, }
{immediate: true,deep: true} }, {immediate: true, deep: true}
) )
function onRendering(data:any){ function onRendering(data: any) {
// let amisScoped = amis.embed('#amisid', data); // let amisScoped = amis.embed('#amisid', data);
let theme = 'cxd' let theme = 'cxd'
let amisScoped = amis.embed( let amisScoped = amis.embed(
'#amisid', '#amisid',
data, data,
{ {
updateLocation: (to, replace) => {}, updateLocation: (to, replace) => {
},
}, },
{ {
// //
@ -57,7 +59,7 @@
data, // data, //
responseType, responseType,
config, // config, //
headers ,// headers,//
updateLocation updateLocation
}) => { }) => {
config = config || {}; config = config || {};
@ -87,7 +89,7 @@
config.params = data; config.params = data;
} }
return (axios )[method](url, config); return (axios)[method](url, config);
} else if (data && data instanceof FormData) { } else if (data && data instanceof FormData) {
config.headers = config.headers || {}; config.headers = config.headers || {};
config.headers['Content-Type'] = 'multipart/form-data'; config.headers['Content-Type'] = 'multipart/form-data';
@ -97,9 +99,9 @@
config.headers['Content-Type'] = 'application/json'; config.headers['Content-Type'] = 'application/json';
} }
return (axios )[method](url, data, config); return (axios)[method](url, data, config);
}, },
isCancel: (value) => (axios ).isCancel(value), isCancel: (value) => (axios).isCancel(value),
copy: content => { copy: content => {
copy(content); copy(content);
ElMessage.success('内容已复制到粘贴板'); ElMessage.success('内容已复制到粘贴板');
@ -107,7 +109,7 @@
theme theme
} }
) )
} }
</script> </script>
<style scoped> <style scoped>
</style> </style>

View File

@ -85,21 +85,15 @@ function onCloseAllTab() {
</script> </script>
<template> <template>
<div class="tabs-menu"> <el-tabs type="card"
<el-tabs type="card" v-model="tabsMenuValue" @tab-click="onTabMenuClick" @tab-remove="onTabMenuRemove"> v-model="tabsMenuValue"
<el-tab-pane v-for="item in tabsMenuList" addable
:key="item.path" @tab-add="onTabMenuRemove"
:path="item.path" @tab-click="onTabMenuClick"
:label="item.title" @tab-remove="onTabMenuRemove">
:name="item.path" <template #add-icon>
:closable="item.close" <el-dropdown>
@node-contextmenu="onTabMenuRemove"> <el-icon><ArrowDown /></el-icon>
<template #label>
<el-icon v-if="item.icon" style="vertical-align: middle;">
<component :is="item.icon"></component>
</el-icon>
<el-dropdown :id="item.path" trigger="contextmenu">
<span style="vertical-align: middle">{{ item.title }}</span>
<template #dropdown> <template #dropdown>
<el-dropdown-menu> <el-dropdown-menu>
<el-dropdown-item icon="CircleCloseFilled" @click="onCloseCurrentTab"></el-dropdown-item> <el-dropdown-item icon="CircleCloseFilled" @click="onCloseCurrentTab"></el-dropdown-item>
@ -109,9 +103,15 @@ function onCloseAllTab() {
</template> </template>
</el-dropdown> </el-dropdown>
</template> </template>
<el-tab-pane v-for="item in tabsMenuList"
:key="item.path"
:path="item.path"
:label="item.title"
:name="item.path"
:closable="item.close"
@node-contextmenu="onTabMenuRemove">
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div>
</template> </template>
<style lang="scss"> <style lang="scss">
.tabs-menu { .tabs-menu {

View File

@ -34,7 +34,7 @@
<div class="home-container"> <div class="home-container">
<el-card shadow="never"> <el-card shadow="never">
<template #header> <template #header>
<span>公告</span> <span>简介</span>
</template> </template>
<div> <div>
<div> <div>
@ -42,10 +42,9 @@
</div> </div>
<div class="text"> <div class="text">
<el-space alignment="normal" direction="vertical"> <el-space alignment="normal" direction="vertical">
<el-text tag="p">基于 SpringBoot2 + magic-api + Vue3 + Element Plus + amis3.0 快速开发管理系统</el-text> <el-text tag="p">基于 SpringBoot2 + Vue3 + Element Plus + amis3.0 快速开发管理系统</el-text>
<el-text tag="p">Tansci-Boot 是一个前后端分离后台管理系统 前端集成 amis 低代码前端框架后端集成 magic-api 的接口快速开发框架包含基础权限安全认证以及常用的一些组件功能项目易上手技术更综合能力更全面</el-text> <el-text tag="p">SCFS-UI 是一个前后端分离后台管理系统 前端集成 amis 低代码前端框架包含基础权限安全认证以及常用的一些组件功能项目易上手技术更综合能力更全面</el-text>
<el-text tag="p">amis 是一个低代码前端框架它使用 JSON 配置来生成页面可以减少页面开发工作量极大提升效率</el-text> <el-text tag="p">amis 是一个低代码前端框架它使用 JSON 配置来生成页面可以减少页面开发工作量极大提升效率</el-text>
<el-text tag="p">magic-api 一个基于 Java 的接口快速开发框架通过 magic-api 提供的 UI 界面完成编写接口无需定义 ControllerServiceDaoMapperXMLVO Java 对象即可完成常见的 HTTP API 接口开发</el-text>
</el-space> </el-space>
</div> </div>
</div> </div>

View File

@ -1,17 +1,17 @@
<script setup> <script setup>
import {onMounted, reactive, getCurrentInstance, ref} from 'vue' import {onMounted, reactive, getCurrentInstance, ref} from 'vue'
import {ElMessage,ElMessageBox} from 'element-plus' import {ElMessage, ElMessageBox} from 'element-plus'
import {getToken} from '@/api/auth' import {getToken} from '@/api/auth'
import {page,save,update,bindMenu,del,batchDelete} from '@/api/lowcode/lcPages' import {page, save, update, bindMenu, del, batchDelete} from '@/api/lowcode/lcPages'
import {classifyList,classifySave,classifyUpdate,classifyDel} from '@/api/lowcode/lcPagesClassify' import {classifyList, classifySave, classifyUpdate, classifyDel} from '@/api/lowcode/lcPagesClassify'
import {list} from '@/api/system/menu' import {list} from '@/api/system/menu'
const { proxy } = getCurrentInstance() const {proxy} = getCurrentInstance()
const renameFormRef = ref() const renameFormRef = ref()
const menuFormRef = ref() const menuFormRef = ref()
const addFormRef = ref() const addFormRef = ref()
const classifyFormRef = ref() const classifyFormRef = ref()
const state = reactive({ const state = reactive({
loading: false, loading: false,
search: { search: {
parentId: null, parentId: null,
@ -44,63 +44,66 @@
pageschema: '{}', pageschema: '{}',
remarks: null remarks: null
}, },
classifyData:[], classifyData: [],
classifyOperate: 0, classifyOperate: 0,
classifyVisible: false, classifyVisible: false,
classifyForm:{ classifyForm: {
name: "", name: "",
parentId: null, parentId: null,
remarks: null remarks: null
} }
}) })
onMounted(()=>{ onMounted(() => {
onClassifyList() onClassifyList()
onLcPages() onLcPages()
}) })
function onLcPages(){ function onLcPages() {
state.loading = true state.loading = true
page(Object.assign(state.page,state.search)).then(res=>{ page(Object.assign(state.page, state.search)).then(res => {
state.loading = false; state.loading = false;
state.data = res.result.records; state.data = res.result.records;
state.page.current = res.result.current; state.page.current = res.result.current;
state.page.size = res.result.size; state.page.size = res.result.size;
state.page.total = res.result.total; state.page.total = res.result.total;
}) })
} }
function onSizeChange(e){ function onSizeChange(e) {
state.page.size = e; state.page.size = e;
onLcPages(); onLcPages();
} }
function onCurrentChange(e){
function onCurrentChange(e) {
state.page.current = e; state.page.current = e;
onLcPages(); onLcPages();
} }
function onSearch(){
function onSearch() {
onLcPages() onLcPages()
} }
function onRefresh(){
function onRefresh() {
state.search = { state.search = {
parentId: null, parentId: null,
title: null, title: null,
classify: null, classify: null,
} }
onLcPages(); onLcPages();
} }
function onPageClick(val){ function onPageClick(val) {
state.search.parentId = val.id state.search.parentId = val.id
onLcPages() onLcPages()
} }
function onPageDesign(val){ function onPageDesign(val) {
let id = window.btoa(val.id+","+getToken()) let id = window.btoa(val.id + "," + getToken())
window.open(proxy.$global.editorUrl + '/gh-pages/index.html#/edit/0g?id=' + id, '_blank') window.open(proxy.$global.editorUrl + '/gh-pages/index.html#/edit/0g?id=' + id, '_blank')
} }
function onRename(val){ function onRename(val) {
state.addForm = { state.addForm = {
id: val.id, id: val.id,
title: val.title, title: val.title,
@ -113,9 +116,9 @@
} }
state.operate = 1 state.operate = 1
state.addVisible = true; state.addVisible = true;
} }
function onDelete(val){ function onDelete(val) {
ElMessageBox.confirm('此操作会永久删除, 是否继续?', '提示', { ElMessageBox.confirm('此操作会永久删除, 是否继续?', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
@ -126,8 +129,9 @@
onLcPages() onLcPages()
}) })
}) })
} }
function onBatchDelete(){
function onBatchDelete() {
ElMessageBox.confirm('此操作会永久删除选中的所有数据, 是否继续?', '提示', { ElMessageBox.confirm('此操作会永久删除选中的所有数据, 是否继续?', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
@ -138,13 +142,13 @@
onLcPages() onLcPages()
}) })
}) })
} }
function onContextMenu(val){ function onContextMenu(val) {
list({isShow: 1}).then((res) => { list({isShow: 1}).then((res) => {
state.menuList = res.result; state.menuList = res.result;
let menuIds let menuIds
if(Object.prototype.toString.call(val.menuIds) === '[object Array]'){ if (Object.prototype.toString.call(val.menuIds) === '[object Array]') {
menuIds = val.menuIds menuIds = val.menuIds
} else { } else {
menuIds = val.menuIds ? [val.menuIds] : [] menuIds = val.menuIds ? [val.menuIds] : []
@ -155,13 +159,14 @@
} }
state.menuVisible = true state.menuVisible = true
}) })
} }
function onContextMenuSubmit(){
function onContextMenuSubmit() {
ElMessageBox.confirm('此操作会将已绑定的菜单覆盖, 是否继续?', '提示', { ElMessageBox.confirm('此操作会将已绑定的菜单覆盖, 是否继续?', '提示', {
confirmButtonText: '确定', confirmButtonText: '确定',
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(()=>{ }).then(() => {
menuFormRef.value.validate((valid) => { menuFormRef.value.validate((valid) => {
if (valid) { if (valid) {
bindMenu({ bindMenu({
@ -171,48 +176,49 @@
onLcPages() onLcPages()
state.menuForm = {} state.menuForm = {}
state.menuVisible = false state.menuVisible = false
}).catch( e => }).catch(e =>
ElMessage.error(e.msg) ElMessage.error(e.msg)
) )
} }
}) })
}) })
} }
function onSelecting(id){ function onSelecting(id) {
let selectIds = [] let selectIds = []
state.data.forEach(item=>{ state.data.forEach(item => {
let d = document.getElementById("page" + item.id); let d = document.getElementById("page" + item.id);
if(item.checked || item.checked === 1){ if (item.checked || item.checked === 1) {
d.style.border="1px solid #409EFF"; d.style.border = "1px solid #409EFF";
selectIds.push(item.id) selectIds.push(item.id)
} else { } else {
d.style.border="1px solid #e4e7ed"; d.style.border = "1px solid #e4e7ed";
} }
}) })
state.selectIds = selectIds state.selectIds = selectIds
} }
function onSelectAll(){
if(state.selectIds && state.selectIds.length === state.data.length){ function onSelectAll() {
state.data.forEach(item=>{ if (state.selectIds && state.selectIds.length === state.data.length) {
state.data.forEach(item => {
item.checked = 0 item.checked = 0
let d = document.getElementById("page" + item.id); let d = document.getElementById("page" + item.id);
d.style.border="1px solid #e4e7ed"; d.style.border = "1px solid #e4e7ed";
}) })
state.selectIds = [] state.selectIds = []
} else { } else {
let selectIds = [] let selectIds = []
state.data.forEach(item=>{ state.data.forEach(item => {
item.checked = 1 item.checked = 1
let d = document.getElementById("page" + item.id); let d = document.getElementById("page" + item.id);
d.style.border="1px solid #409EFF"; d.style.border = "1px solid #409EFF";
selectIds.push(item.id) selectIds.push(item.id)
}) })
state.selectIds = selectIds state.selectIds = selectIds
} }
} }
function onAdd(){ function onAdd() {
state.addForm = { state.addForm = {
title: '', title: '',
subtitle: '', subtitle: '',
@ -224,44 +230,44 @@
} }
state.operate = 0 state.operate = 0
state.addVisible = true; state.addVisible = true;
} }
function onAddSubmit(){ function onAddSubmit() {
addFormRef.value.validate((valid) => { addFormRef.value.validate((valid) => {
if (valid) { if (valid) {
if(state.operate === 0){ if (state.operate === 0) {
save(state.addForm).then((res) => { save(state.addForm).then((res) => {
onLcPages() onLcPages()
state.addVisible = false state.addVisible = false
}).catch( e => }).catch(e =>
ElMessage.error(e.msg) ElMessage.error(e.msg)
) )
} else { } else {
update(state.addForm).then((res) => { update(state.addForm).then((res) => {
onLcPages() onLcPages()
state.addVisible = false state.addVisible = false
}).catch( e => }).catch(e =>
ElMessage.error(e.msg) ElMessage.error(e.msg)
) )
} }
} }
}) })
} }
// ================================== // ==================================
function onClassifyList(){ function onClassifyList() {
classifyList().then(res=>{ classifyList().then(res => {
state.classifyData = res.result; state.classifyData = res.result;
}) })
} }
function onNodeClick(data){ function onNodeClick(data) {
state.search.classify = data.id; state.search.classify = data.id;
onSearch() onSearch()
} }
function onOperateChange(val,type){ function onOperateChange(val, type) {
if(type === 1){ if (type === 1) {
state.classifyForm = { state.classifyForm = {
id: '', id: '',
parentId: val.id, parentId: val.id,
@ -270,7 +276,7 @@
} }
state.classifyOperate = 0 state.classifyOperate = 0
state.classifyVisible = true; state.classifyVisible = true;
} else if(type === 2) { } else if (type === 2) {
state.classifyForm = { state.classifyForm = {
id: val.id, id: val.id,
parentId: val.parentId, parentId: val.parentId,
@ -286,8 +292,8 @@
cancelButtonText: '取消', cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
classifyDel(val.id).then(res=>{ classifyDel(val.id).then(res => {
if(res){ if (res) {
ElMessage.success("删除成功!"); ElMessage.success("删除成功!");
state.classifyForm = { state.classifyForm = {
id: '', id: '',
@ -298,40 +304,41 @@
onClassifyList() onClassifyList()
} }
}) })
}).catch(e=>{ }).catch(e => {
console.log(e) console.log(e)
}) })
} }
} }
function onClassifySubmit(){ function onClassifySubmit() {
classifyFormRef.value.validate((valid) => { classifyFormRef.value.validate((valid) => {
if (valid) { if (valid) {
if(state.classifyOperate === 0){ if (state.classifyOperate === 0) {
classifySave(state.classifyForm).then((res) => { classifySave(state.classifyForm).then((res) => {
onClassifyList() onClassifyList()
state.classifyVisible = false state.classifyVisible = false
}).catch( e => }).catch(e =>
ElMessage.error(e.msg) ElMessage.error(e.msg)
) )
} else { } else {
classifyUpdate(state.classifyForm).then((res) => { classifyUpdate(state.classifyForm).then((res) => {
onClassifyList() onClassifyList()
state.classifyVisible = false state.classifyVisible = false
}).catch( e => }).catch(e =>
ElMessage.error(e.msg) ElMessage.error(e.msg)
) )
} }
} }
}) })
} }
</script> </script>
<template> <template>
<div class="lc-pages"> <div class="lc-pages">
<div class="pages-classify"> <div class="pages-classify">
<el-scrollbar height="45rem"> <el-scrollbar height="45rem">
<el-tree :data="state.classifyData" :props="{children: 'children', label: 'name'}" highlight-current @node-click="onNodeClick" empty-text=""> <el-tree :data="state.classifyData" :props="{children: 'children', label: 'name'}" highlight-current
@node-click="onNodeClick" empty-text="暂无数据">
<template #default="{ node, data }"> <template #default="{ node, data }">
<el-tooltip placement="right-start" effect="light" popper-class="classify-tooltip"> <el-tooltip placement="right-start" effect="light" popper-class="classify-tooltip">
<span class="custom-tree-node"> <span class="custom-tree-node">
@ -352,13 +359,18 @@
</el-tree> </el-tree>
</el-scrollbar> </el-scrollbar>
<el-dialog v-model="state.classifyVisible" title="分类管理" :show-close="false" width="30%"> <el-dialog v-model="state.classifyVisible" title="分类管理" :show-close="false" width="30%">
<el-form :model="state.classifyForm" ref="classifyFormRef" :rules="rules" label-width="60px" status-icon> <el-form :model="state.classifyForm" ref="classifyFormRef" label-width="60px" status-icon>
<el-form-item v-show="state.classifyForm.parentId !== '0'" label="父级" prop="parentId" :rules="[{required: true, message: '请选择父级', trigger: 'blur'}]"> <el-form-item v-show="state.classifyForm.parentId !== '0'" label="父级" prop="parentId"
<el-tree-select v-model="state.classifyForm.parentId" :data="state.classifyData" :props="{children: 'children', label: 'name'}" node-key="id" :rules="[{required: true, message: '请选择父级', trigger: 'blur'}]">
check-strictly :render-after-expand="false" :default-checked-keys="[state.classifyForm.parentId]" :default-expanded-keys="[state.classifyForm.parentId]" placeholder="请选父级" style="width:100%"/> <el-tree-select v-model="state.classifyForm.parentId" :data="state.classifyData"
:props="{children: 'children', label: 'name'}" node-key="id"
check-strictly :render-after-expand="false"
:default-checked-keys="[state.classifyForm.parentId]"
:default-expanded-keys="[state.classifyForm.parentId]" placeholder="请选父级"
style="width:100%"/>
</el-form-item> </el-form-item>
<el-form-item label="名称" prop="name" :rules="[{required: true, message: '请输入名称', trigger: 'blur'}]"> <el-form-item label="名称" prop="name" :rules="[{required: true, message: '请输入名称', trigger: 'blur'}]">
<el-input v-model="state.classifyForm.name" placeholder="请输入名称" /> <el-input v-model="state.classifyForm.name" placeholder="请输入名称"/>
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
@ -380,55 +392,74 @@
<div class="main-operate"> <div class="main-operate">
<el-button @click="onSelectAll()"></el-button> <el-button @click="onSelectAll()"></el-button>
<el-button @click="onAdd()" type="primary">新增</el-button> <el-button @click="onAdd()" type="primary">新增</el-button>
<el-button @click="onBatchDelete()" :disabled="state.selectIds && state.selectIds.length === 0" type="danger">批量删除</el-button> <el-button @click="onBatchDelete()" :disabled="state.selectIds && state.selectIds.length === 0"
<el-button v-if="state.search.parentId && state.search.parentId !== '0'" @click="onRefresh()" type="primary" icon="Back" style="float: right;"></el-button> type="danger">批量删除
</el-button>
<el-button v-if="state.search.parentId && state.search.parentId !== '0'" @click="onRefresh()" type="primary"
icon="Back" style="float: right;">返回
</el-button>
</div> </div>
<div v-if="state.data" v-loading="state.loading" class="main-card"> <div v-if="state.data" v-loading="state.loading" class="main-card">
<el-card v-for="item in state.data" :key="item" shadow="hover" :body-style="{ padding: '0px' }" :id="'page'+item.id" style="margin: 0.4rem;"> <el-card v-for="item in state.data" :key="item" shadow="hover" :body-style="{ padding: '0px' }"
:id="'page'+item.id" style="margin: 0.4rem;">
<template #header> <template #header>
<div class="card-header"> <div class="card-header">
<el-text tag="b">{{item.title}}</el-text> <el-text tag="b">{{ item.title }}</el-text>
<el-checkbox @change="onSelecting()" v-model="item.checked" :true-label="1" :false-label="0"/> <el-checkbox @change="onSelecting()" v-model="item.checked" :true-value="1" :false-value="0"/>
</div> </div>
</template> </template>
<div @click="onPageClick(item)" class="card-content"> <div @click="onPageClick(item)" class="card-content">
<el-icon v-if="!item.menuIds || item.menuIds.length === 0" size="100" color="#E6A23C"><Setting /></el-icon> <el-icon v-if="!item.menuIds || item.menuIds.length === 0" size="100" color="#E6A23C">
<el-icon v-else size="100" color="#67C23A"><UploadFilled /></el-icon> <Setting/>
</el-icon>
<el-icon v-else size="100" color="#67C23A">
<UploadFilled/>
</el-icon>
<div class="content"> <div class="content">
<div class="content-item"> <div class="content-item">
<el-text truncated>{{item.subtitle}}</el-text> <el-text truncated>{{ item.subtitle }}</el-text>
<div> <div>
<el-tag v-if="item.status === 0" type="success" effect="light" round>已发布</el-tag> <el-tag v-if="item.status === 0" type="success" effect="light" round>已发布</el-tag>
<el-tag v-else type="warning" effect="light" round>未发布</el-tag> <el-tag v-else type="warning" effect="light" round>未发布</el-tag>
</div> </div>
</div> </div>
<div> <div>
<el-text truncated tag="sub" size="small" style="max-width:12rem;padding-top:0.4rem;font-size:12px;">{{item.remarks}}</el-text> <el-text truncated tag="sub" size="small"
style="max-width:12rem;padding-top:0.4rem;font-size:12px;">{{ item.remarks }}
</el-text>
</div> </div>
</div> </div>
</div> </div>
<div class="card-footer"> <div class="card-footer">
<el-button-group style="width:100%; display: flex;"> <el-button-group style="width:100%; display: flex;">
<el-button @click="onPageDesign(item)" icon="Edit" style="width:100%; border-left: none;">设计页面</el-button> <el-button @click="onPageDesign(item)" icon="Edit" style="width:100%; border-left: none;">设计页面
</el-button>
<el-button @click="onRename(item)" icon="EditPen" style="width:100%">修改</el-button> <el-button @click="onRename(item)" icon="EditPen" style="width:100%">修改</el-button>
<el-button @click="onDelete(item)" icon="Delete" style="width:100%">删除</el-button> <el-button @click="onDelete(item)" icon="Delete" style="width:100%">删除</el-button>
<el-button @click="onContextMenu(item)" icon="Connection" style="width:100%; border-right: none;">关联菜单</el-button> <el-button @click="onContextMenu(item)" icon="Connection" style="width:100%; border-right: none;">
关联菜单
</el-button>
</el-button-group> </el-button-group>
</div> </div>
</el-card> </el-card>
</div> </div>
<el-pagination v-if="state.data && state.data.length > 0" :current-page="state.page.current" :page-size="state.page.size" :total="state.page.total" <el-pagination v-if="state.data && state.data.length > 0" :current-page="state.page.current"
:page-size="state.page.size" :total="state.page.total"
layout="total, prev, pager, next, jumper" layout="total, prev, pager, next, jumper"
@size-change="onSizeChange" @size-change="onSizeChange"
@current-change="onCurrentChange" style="margin-top: 1.2rem;"/> @current-change="onCurrentChange" style="margin-top: 1.2rem;"/>
<div v-if="!state.data || state.data.length === 0"> <div v-if="!state.data || state.data.length === 0">
<el-empty description="暂无数据" /> <el-empty description="暂无数据"/>
</div> </div>
</el-card> </el-card>
<el-dialog v-model="state.menuVisible" title="关联菜单" :show-close="false" width="30%"> <el-dialog v-model="state.menuVisible" title="关联菜单" :show-close="false" width="30%">
<el-form :model="state.menuForm" ref="menuFormRef" :rules="rules" label-width="60px" status-icon> <el-form :model="state.menuForm" ref="menuFormRef" label-width="60px" status-icon>
<el-form-item label="菜单" prop="menuId" :rules="[{required: true, message: '请选择菜单', trigger: 'blur'}]"> <el-form-item label="菜单" prop="menuId"
<el-tree-select v-model="state.menuForm.menuId" :data="state.menuList" :props="{children: 'children', label: 'chineseName'}" node-key="id" multiple :render-after-expand="false" :default-checked-keys="state.menuForm.menuId" :default-expanded-keys="state.menuForm.menuId" style="width:100%;"/> :rules="[{required: true, message: '请选择菜单', trigger: 'blur'}]">
<el-tree-select v-model="state.menuForm.menuId" :data="state.menuList"
:props="{children: 'children', label: 'chineseName'}" node-key="id" multiple
:render-after-expand="false" :default-checked-keys="state.menuForm.menuId"
:default-expanded-keys="state.menuForm.menuId" style="width:100%;"/>
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
@ -439,19 +470,28 @@
</template> </template>
</el-dialog> </el-dialog>
<el-dialog v-model="state.addVisible" title="新增页面" :show-close="false" width="40%"> <el-dialog v-model="state.addVisible" title="新增页面" :show-close="false" width="40%">
<el-form :model="state.addForm" ref="addFormRef" :rules="rules" label-width="100px" status-icon> <el-form :model="state.addForm" ref="addFormRef" label-width="100px" status-icon>
<el-form-item label="页面名称" prop="title" :rules="[{required: true, message: '请输入名称', trigger: 'blur'}]"> <el-form-item label="页面名称" prop="title"
<el-input v-model="state.addForm.title" placeholder="请输入名称" /> :rules="[{required: true, message: '请输入名称', trigger: 'blur'}]">
<el-input v-model="state.addForm.title" placeholder="请输入名称"/>
</el-form-item> </el-form-item>
<el-form-item label="页面标题" prop="subtitle" :rules="[{required: true, message: '请输入标题', trigger: 'blur'}]"> <el-form-item label="页面标题" prop="subtitle"
:rules="[{required: true, message: '请输入标题', trigger: 'blur'}]">
<el-input v-model="state.addForm.subtitle" placeholder="请输入标题"/> <el-input v-model="state.addForm.subtitle" placeholder="请输入标题"/>
</el-form-item> </el-form-item>
<el-form-item label="页面状态" prop="status" :rules="[{required: true, message: '请选择状态', trigger: 'blur'}]"> <el-form-item label="页面状态" prop="status"
<el-switch v-model="state.addForm.status" inline-prompt active-text="" :active-value="0" inactive-text="" :inactive-value="1"/> :rules="[{required: true, message: '请选择状态', trigger: 'blur'}]">
<el-switch v-model="state.addForm.status" inline-prompt active-text="" :active-value="0"
inactive-text="否" :inactive-value="1"/>
</el-form-item> </el-form-item>
<el-form-item label="页面分类" prop="status" :rules="[{required: true, message: '请选择分类', trigger: 'blur'}]"> <el-form-item label="页面分类" prop="status"
<el-tree-select v-model="state.addForm.classify" :data="state.classifyData" :props="{children: 'children', label: 'name'}" node-key="id" :rules="[{required: true, message: '请选择分类', trigger: 'blur'}]">
check-strictly :render-after-expand="false" :default-checked-keys="[state.addForm.classify]" :default-expanded-keys="[state.addForm.classify]" placeholder="请选父级" style="width:100%"/> <el-tree-select v-model="state.addForm.classify" :data="state.classifyData"
:props="{children: 'children', label: 'name'}" node-key="id"
check-strictly :render-after-expand="false"
:default-checked-keys="[state.addForm.classify]"
:default-expanded-keys="[state.addForm.classify]" placeholder="请选父级"
style="width:100%"/>
</el-form-item> </el-form-item>
<el-form-item label="页面描述" prop="remarks"> <el-form-item label="页面描述" prop="remarks">
<el-input v-model="state.addForm.remarks" placeholder="请输入描述" type="textarea" :rows="2"/> <el-input v-model="state.addForm.remarks" placeholder="请输入描述" type="textarea" :rows="2"/>
@ -468,19 +508,22 @@
</div> </div>
</div> </div>
</template> </template>
<style lang="scss" > <style lang="scss">
.classify-tooltip.is-light { .classify-tooltip.is-light {
background: none !important; background: none !important;
border: none !important; border: none !important;
padding: 0 !important; padding: 0 !important;
} }
.lc-pages{
.lc-pages {
display: flex; display: flex;
.pages-classify{
.pages-classify {
border-right: 1px solid #e4e7ed; border-right: 1px solid #e4e7ed;
margin: 0 1rem 0 1rem; margin: 0 1rem 0 1rem;
min-width: 12rem; min-width: 12rem;
.el-tree-node:hover>.el-tree-node__content{
.el-tree-node:hover > .el-tree-node__content {
background-color: #fff !important; background-color: #fff !important;
color: var(--theme) !important; color: var(--theme) !important;
} }
@ -492,55 +535,68 @@
} }
.pages-list{
.pages-list {
width: 100%; width: 100%;
.pages-search{
.pages-search {
display: flex; display: flex;
} }
.pages-main{
.pages-main {
padding-top: 1rem; padding-top: 1rem;
.main-operate{
.main-operate {
padding-bottom: 1rem; padding-bottom: 1rem;
} }
.main-card{
.main-card {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: flex-start; justify-content: flex-start;
.el-card{
.el-card {
// flex: 0 0 24%; // flex: 0 0 24%;
:deep(.el-card__header){ :deep(.el-card__header) {
padding: 1rem; padding: 1rem;
border: none; border: none;
} }
.card-header { .card-header {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
} }
.card-content{
.card-content {
display: flex; display: flex;
align-items: center; align-items: center;
font-size: 12px; font-size: 12px;
color: #606266; color: #606266;
padding: 0 0.4rem 1rem 0.4rem; padding: 0 0.4rem 1rem 0.4rem;
cursor: pointer; cursor: pointer;
.content{
.content {
width: 100%; width: 100%;
padding-left: 1.2rem; padding-left: 1.2rem;
.content-item{
.content-item {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
} }
} }
} }
.card-footer{
.el-button{ .card-footer {
.el-button {
border-bottom: none; border-bottom: none;
} }
.el-button-group>.el-button:first-child{
.el-button-group > .el-button:first-child {
border-top-left-radius: 0; border-top-left-radius: 0;
} }
.el-button-group>.el-button:last-child {
.el-button-group > .el-button:last-child {
border-top-right-radius: 0; border-top-right-radius: 0;
} }
} }
@ -548,5 +604,5 @@
} }
} }
} }
} }
</style> </style>

View File

@ -144,7 +144,7 @@
<template> <template>
<div class="dict-container"> <div class="dict-container">
<Table :data="table.tableData" :column="table.tableTitle" :operation="table.operation" :page="false" :loading="table.loading"> <Table :data="table.tableData" :column="table.tableTitle" :operation="table.operation" :loading="table.loading">
<template #search> <template #search>
<div><el-button @click="onAdd(null)" v-permission="'dict:save'" type="primary"></el-button></div> <div><el-button @click="onAdd(null)" v-permission="'dict:save'" type="primary"></el-button></div>
</template> </template>
@ -155,7 +155,7 @@
</template> </template>
</Table> </Table>
<el-dialog title="字典信息" v-model="form.dictVisible" :show-close="false" width="40%"> <el-dialog title="字典信息" v-model="form.dictVisible" :show-close="false" width="40%">
<el-form :model="form.dictForm" ref="formRef" :rules="rules" label-width="80px" status-icon> <el-form :model="form.dictForm" ref="formRef" label-width="80px" status-icon>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="分组名称" prop="groupName" :rules="[{required: true,message:'请输入分组名称',trigger: 'blur'}]"> <el-form-item label="分组名称" prop="groupName" :rules="[{required: true,message:'请输入分组名称',trigger: 'blur'}]">
@ -165,8 +165,8 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item label="类型" prop="type" :rules="[{required: true,message:'请选择类型',trigger: 'blur'}]"> <el-form-item label="类型" prop="type" :rules="[{required: true,message:'请选择类型',trigger: 'blur'}]">
<el-radio-group v-model="form.dictForm.type"> <el-radio-group v-model="form.dictForm.type">
<el-radio :label="0">系统</el-radio> <el-radio :value="0">系统</el-radio>
<el-radio :label="1">业务</el-radio> <el-radio :value="1">业务</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>

View File

@ -14,8 +14,7 @@
tableTitle: [ tableTitle: [
{prop:'code',label:'组织编码',align:'left'}, {prop:'code',label:'组织编码',align:'left'},
{prop:'name',label:'组织名称'}, {prop:'name',label:'组织名称'},
{prop:'name',label:'组织名称'}, {prop:'sort',label:'组织级别'},
{prop:'sort',label:'排序'},
{prop:'createTime',label:'创建时间'}, {prop:'createTime',label:'创建时间'},
{prop:'remarks',label:'描述'} {prop:'remarks',label:'描述'}
], ],
@ -126,8 +125,8 @@
</script> </script>
<template> <template>
<div class="org-container"> <div>
<Table :data="table.tableData" :column="table.tableTitle" :operation="table.operation" :page="false" :loading="table.loading"> <Table :data="table.tableData" :column="table.tableTitle" :operation="table.operation" :loading="table.loading">
<template #search> <template #search>
<div><el-button @click="onAdd(null)" v-permission="'org:save'" type="primary"></el-button></div> <div><el-button @click="onAdd(null)" v-permission="'org:save'" type="primary"></el-button></div>
</template> </template>
@ -138,7 +137,7 @@
</template> </template>
</Table> </Table>
<el-dialog title="组织信息" v-model="form.orgVisible" :show-close="false" width="40%"> <el-dialog title="组织信息" v-model="form.orgVisible" :show-close="false" width="40%">
<el-form :model="form.orgForm" ref="formRef" :rules="rules" label-width="80px" status-icon> <el-form :model="form.orgForm" ref="formRef" label-width="80px" status-icon>
<el-form-item label="名称" prop="name" :rules="[{required: true,message:'请输入名称',trigger: 'blur'}]"> <el-form-item label="名称" prop="name" :rules="[{required: true,message:'请输入名称',trigger: 'blur'}]">
<el-input v-model="form.orgForm.name" placeholder="请输入名称" style="width: 100%"/> <el-input v-model="form.orgForm.name" placeholder="请输入名称" style="width: 100%"/>
</el-form-item> </el-form-item>
@ -158,8 +157,3 @@
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<style lang="scss" scoped>
.org-container{
}
</style>

View File

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import {onMounted, reactive, ref, unref} from 'vue' import {onMounted, reactive, ref} from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus' import {ElMessage, ElMessageBox} from 'element-plus'
import type {FormInstance} from 'element-plus' import type {FormInstance} from 'element-plus'
import Table from '@/components/Table.vue' import Table from '@/components/Table.vue'
@ -8,7 +8,6 @@
const searchForm = reactive({ const searchForm = reactive({
username: null username: null
}) })
const table = reactive({ const table = reactive({
loading: false, loading: false,
page: { page: {
@ -158,6 +157,8 @@
form.userForm = { form.userForm = {
id: val.column.row.id, id: val.column.row.id,
username: val.column.row.username, username: val.column.row.username,
password: '',
rePassword: '',
nickname: val.column.row.nickname, nickname: val.column.row.nickname,
type: val.column.row.type, type: val.column.row.type,
phone: val.column.row.phone, phone: val.column.row.phone,
@ -232,7 +233,7 @@
</template> </template>
</Table> </Table>
<el-dialog title="用户信息" v-model="form.userVisible" :show-close="false" width="50%"> <el-dialog title="用户信息" v-model="form.userVisible" :show-close="false" width="50%">
<el-form :model="form.userForm" ref="formRef" :rules="rules" label-width="80px" status-icon> <el-form :model="form.userForm" ref="formRef" label-width="80px" status-icon>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="名称" prop="username" :rules="[ <el-form-item label="名称" prop="username" :rules="[
@ -264,16 +265,16 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item label="类型" prop="type" :rules="[{required: true,message:'请选择类型',trigger: 'blur'}]"> <el-form-item label="类型" prop="type" :rules="[{required: true,message:'请选择类型',trigger: 'blur'}]">
<el-radio-group v-model="form.userForm.type"> <el-radio-group v-model="form.userForm.type">
<el-radio :label="1">管理员</el-radio> <el-radio :value="1">管理员</el-radio>
<el-radio :label="2">普通用户</el-radio> <el-radio :value="2">普通用户</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="性别" prop="gender"> <el-form-item label="性别" prop="gender">
<el-radio-group v-model="form.userForm.gender"> <el-radio-group v-model="form.userForm.gender">
<el-radio :label="0"></el-radio> <el-radio :value="0"></el-radio>
<el-radio :label="1"></el-radio> <el-radio :value="1"></el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
@ -306,7 +307,7 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item label="角色" prop="roleId" :rules="[{required: true,message:'请选择角色',trigger: 'change'}]"> <el-form-item label="角色" prop="roleId" :rules="[{required: true,message:'请选择角色',trigger: 'change'}]">
<el-select v-model="form.userForm.roleId" placeholder="请选角色" style="width: 100%"> <el-select v-model="form.userForm.roleId" placeholder="请选角色" style="width: 100%">
<el-option v-for="item in form.roleList" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in form.roleList" :key="item['id']" :label="item['name']" :value="item['id']" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>