This commit is contained in:
@@ -4,6 +4,13 @@
|
||||
width: 660px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5 {
|
||||
color: darken(@white, 40%);
|
||||
}
|
||||
.yo-form-group {
|
||||
margin-bottom: @padding-md;
|
||||
}
|
||||
@@ -146,7 +153,11 @@
|
||||
padding: 0;
|
||||
}
|
||||
.yo-form {
|
||||
>h3 {
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5 {
|
||||
margin-top: @padding-sm;
|
||||
padding: 0 @padding-md;
|
||||
}
|
||||
@@ -162,3 +173,33 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
.yo-drawer-form {
|
||||
.ant-drawer-header {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 7;
|
||||
|
||||
width: 100%;
|
||||
}
|
||||
.ant-drawer-body {
|
||||
padding: @padding-lg + 56px @padding-lg;
|
||||
}
|
||||
.ant-drawer-footer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
z-index: 7;
|
||||
|
||||
width: 100%;
|
||||
padding: 10px @padding-md;
|
||||
|
||||
text-align: right;
|
||||
|
||||
border-top: @border-width-base @border-style-base @border-color-split;
|
||||
background: @white;
|
||||
button+button {
|
||||
margin-left: @padding-xs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
在此文件夹中添加控制主题颜色的less文件
|
||||
@@ -25,6 +25,8 @@ export default {
|
||||
return {
|
||||
loading: false,
|
||||
|
||||
type: '',
|
||||
|
||||
data: [],
|
||||
|
||||
pagination: {
|
||||
@@ -101,14 +103,23 @@ export default {
|
||||
pageSize: this.pagination.pageSize,
|
||||
...this.sorter
|
||||
}).then((res) => {
|
||||
this.data = res.rows
|
||||
this.pagination.total = res.totalRows
|
||||
if (res.rows) {
|
||||
// 普通表格
|
||||
this.type = 'table'
|
||||
this.data = res.rows
|
||||
this.pagination.total = res.totalRows
|
||||
} else if (res) {
|
||||
// 树形表格
|
||||
this.type = 'tree'
|
||||
this.data = this.onClearChildren(res)
|
||||
this.pagination = false
|
||||
}
|
||||
this.onLoaded()
|
||||
})
|
||||
},
|
||||
|
||||
onReloadData(refresh = false) {
|
||||
if (refresh && refresh.constructor === Boolean) {
|
||||
if (refresh && refresh.constructor === Boolean && this.pagination.constructor === Object) {
|
||||
this.pagination.current = this.pageNo
|
||||
this.pagination.pageSize = this.pageSize
|
||||
}
|
||||
@@ -119,7 +130,23 @@ export default {
|
||||
this.pagination = pagination
|
||||
this.sorter = sorter
|
||||
this.onLoadData()
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 清除没有子节点内容的子节点位置
|
||||
*/
|
||||
onClearChildren(data) {
|
||||
data.forEach(p => {
|
||||
if (p.children) {
|
||||
if (p.children.length) {
|
||||
p.children = this.onClearChildren(p.children)
|
||||
} else {
|
||||
delete p.children
|
||||
}
|
||||
}
|
||||
})
|
||||
return data
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
@@ -154,7 +181,9 @@ export default {
|
||||
<div class="yo-action-bar--actions">
|
||||
<a-button-group>
|
||||
<a-button onClick={this.onReloadData}>刷新</a-button>
|
||||
<ColumnSetting {...{ props: { columns: this.columns } }} />
|
||||
{
|
||||
this.type === 'table' && <ColumnSetting {...{ props: { columns: this.columns } }} />
|
||||
}
|
||||
</a-button-group>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
基本上所有列表页都可以通过拷贝此处的种子文件实现增删改查的功能
|
||||
所有带 ... 的注释是可以依据当前业务添加内容的地方
|
||||
其他所有尽量不要修改
|
||||
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:confirmLoading="confirmLoading"
|
||||
:visible="visible"
|
||||
@cancel="onCancel"
|
||||
@ok="onOk"
|
||||
class="yo-modal-form"
|
||||
title="新增XX"
|
||||
>
|
||||
<FormBody ref="form-body" />
|
||||
</a-modal>
|
||||
</template>
|
||||
<script>
|
||||
import FormBody from './form';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FormBody,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
confirmLoading: false,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
formBody() {
|
||||
return this.$refs['form-body'];
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* 必要的方法
|
||||
* 从外部调用打开本窗口
|
||||
*/
|
||||
async onOpen() {
|
||||
this.visible = true;
|
||||
this.$nextTick(() => {
|
||||
this.formBody.onInit();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要的方法
|
||||
* 点击保存时的操作
|
||||
*/
|
||||
onOk() {
|
||||
this.formBody.onGetData().then((data) => {
|
||||
this.confirmLoading = true;
|
||||
this.$api
|
||||
/** !!此处必须修改调用的接口方法 */
|
||||
.testAddApi(data)
|
||||
.then(({ success }) => {
|
||||
if (success) {
|
||||
this.$message.success('新增成功');
|
||||
this.onCancel();
|
||||
this.$emit('ok');
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.confirmLoading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要的方法
|
||||
* 关闭窗口时的操作
|
||||
*/
|
||||
onCancel() {
|
||||
this.formBody.onResetFields();
|
||||
this.visible = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<a-modal
|
||||
:confirmLoading="confirmLoading"
|
||||
:visible="visible"
|
||||
@close="onCancel"
|
||||
class="yo-modal-form"
|
||||
title="编辑XX"
|
||||
>
|
||||
<FormBody ref="form-body" />
|
||||
</a-modal>
|
||||
</template>
|
||||
<script>
|
||||
import FormBody from './form';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FormBody,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
confirmLoading: false,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
formBody() {
|
||||
return this.$refs['form-body'];
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* 必要的方法
|
||||
* 从外部调用打开本窗口,并填充外部传入的数据
|
||||
*/
|
||||
onOpen(record) {
|
||||
this.visible = true;
|
||||
this.$nextTick(async () => {
|
||||
await this.formBody.onInit();
|
||||
this.formBody.onFillData(record);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要的方法
|
||||
* 点击保存时的操作
|
||||
*/
|
||||
onOk() {
|
||||
this.formBody.onGetData().then((data) => {
|
||||
this.confirmLoading = true;
|
||||
this.$api
|
||||
/** !!此处必须修改调用的接口方法 */
|
||||
.testEditApi(data)
|
||||
.then(({ success }) => {
|
||||
if (success) {
|
||||
this.$message.success('编辑成功');
|
||||
this.onCancel();
|
||||
this.$emit('ok');
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.confirmLoading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要的方法
|
||||
* 关闭窗口时的操作
|
||||
*/
|
||||
onCancel() {
|
||||
this.formBody.onResetFields();
|
||||
this.visible = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<a-form-model :model="form" :rules="rules" class="yo-form" ref="form">
|
||||
<a-spin :spinning="loading">
|
||||
<a-icon slot="indicator" spin type="loading" />
|
||||
<div class="yo-form-group">
|
||||
<!-- 表单控件 -->
|
||||
</div>
|
||||
</a-spin>
|
||||
</a-form-model>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
/** 表单数据 */
|
||||
form: {},
|
||||
/** 验证格式 */
|
||||
rules: {},
|
||||
|
||||
/** 加载异步数据状态 */
|
||||
loading: false,
|
||||
|
||||
/** 其他成员属性 */
|
||||
/** ... */
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* 必要的方法
|
||||
* 在打开编辑页时允许填充数据
|
||||
*/
|
||||
onFillData(record) {
|
||||
/** 将默认数据覆盖到form */
|
||||
this.form = this.$_.cloneDeep({
|
||||
...record,
|
||||
/** 在此处添加默认数据转换 */
|
||||
/** ... */
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要方法
|
||||
* 验证表单并获取表单数据
|
||||
*/
|
||||
onGetData() {
|
||||
return new Promise((reslove, reject) => {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
const record = this.$_.cloneDeep(this.form);
|
||||
|
||||
/** 验证通过后可以对数据进行转换得到想要提交的格式 */
|
||||
/** ... */
|
||||
|
||||
reslove(record);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要的方法
|
||||
* 在外部窗口进行保存时调用表单验证
|
||||
*/
|
||||
onValidate(callback) {
|
||||
this.$refs.form.validate(callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要的方法
|
||||
* 在外部窗口关闭或重置时对表单验证进行初始化
|
||||
*/
|
||||
onResetFields() {
|
||||
setTimeout(() => {
|
||||
this.$refs.form.resetFields();
|
||||
|
||||
/** 在这里可以初始化当前组件中其他属性 */
|
||||
/** ... */
|
||||
}, 300);
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要方法
|
||||
* 加载当前表单中所需要的异步数据
|
||||
*/
|
||||
async onInit() {
|
||||
this.loading = true;
|
||||
/** 可以在这里await获取一些异步数据 */
|
||||
/** ...BEGIN */
|
||||
/** ...END */
|
||||
this.loading = false;
|
||||
},
|
||||
|
||||
/** 当前组件的其他方法 */
|
||||
/** ... */
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<container>
|
||||
<br />
|
||||
<a-card :bordered="false">
|
||||
<Auth auth="authCode:page">
|
||||
<div class="yo-query-bar">
|
||||
<a-form-model :model="query" layout="inline">
|
||||
<!-- 此处添加查询表单控件 -->
|
||||
<a-form-model-item>
|
||||
<a-button-group>
|
||||
<a-button @click="onQuery" type="primary">查询</a-button>
|
||||
<a-button @click="onResetQuery">重置</a-button>
|
||||
</a-button-group>
|
||||
</a-form-model-item>
|
||||
</a-form-model>
|
||||
</div>
|
||||
</Auth>
|
||||
|
||||
<yo-table :columns="columns" :load-data="loadData" ref="table">
|
||||
<Auth auth="authCode:add" slot="operator">
|
||||
<a-button @click="onOpen('add-form')" icon="plus">新增XX</a-button>
|
||||
</Auth>
|
||||
<!-- 格式化字段内容 -->
|
||||
<!-- 添加操作控件 -->
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<yo-table-actions>
|
||||
<Auth auth="authCode:edit">
|
||||
<a @click="onOpen('edit-form', record)">编辑</a>
|
||||
</Auth>
|
||||
<Auth auth="authCode:delete">
|
||||
<a-popconfirm @confirm="onDelete(record)" placement="topRight" title="是否确认删除">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</Auth>
|
||||
<!-- 可在此处添加其他操作控件 -->
|
||||
</yo-table-actions>
|
||||
</span>
|
||||
</yo-table>
|
||||
</a-card>
|
||||
<br />
|
||||
<add-form @ok="onReloadData" ref="add-form" />
|
||||
<edit-form @ok="onReloadData" ref="edit-form" />
|
||||
</container>
|
||||
</template>
|
||||
<script>
|
||||
import AddForm from './addForm';
|
||||
import EditForm from './editForm';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AddForm,
|
||||
EditForm,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
query: {},
|
||||
columns: [],
|
||||
codes: {
|
||||
code1: [],
|
||||
code2: [],
|
||||
},
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.onLoadCodes();
|
||||
|
||||
/** 根据权限添加操作列 */
|
||||
const flag = this.$auth(/** ... */);
|
||||
if (flag) {
|
||||
this.columns.push({
|
||||
title: '操作',
|
||||
width: '150px',
|
||||
dataIndex: 'action',
|
||||
scopedSlots: { customRender: 'action' },
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 必要的方法
|
||||
* 传给yo-table以示意数据接口及其参数和返回的数据结构
|
||||
*/
|
||||
loadData(params) {
|
||||
return (
|
||||
this.$api
|
||||
/** !!此处必须修改调用的接口方法 */
|
||||
.testGetApi({
|
||||
...params,
|
||||
...this.query,
|
||||
})
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* 有查询功能时的必要方法
|
||||
* 加载数据时初始化分页信息
|
||||
*/
|
||||
onQuery() {
|
||||
this.$refs.table.onReloadData(true);
|
||||
},
|
||||
|
||||
/**
|
||||
* 有查询功能时的必要方法
|
||||
* 重置查询条件
|
||||
*/
|
||||
onResetQuery() {
|
||||
/** 在这里重置查询条件时,可对特殊的字段做保留处理 */
|
||||
this.query = {};
|
||||
this.onQuery();
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要方法
|
||||
* 重新列表数据
|
||||
*/
|
||||
onReloadData() {
|
||||
this.$refs.table.onReloadData();
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要方法
|
||||
* 加载字典数据
|
||||
* 如果不需要获取相应的字典数据,此方法内容可空
|
||||
*/
|
||||
onLoadCodes() {
|
||||
this.$api
|
||||
.$queue([
|
||||
this.$api.sysDictTypeDropDownWait({ code: 'code1' }),
|
||||
this.$api.sysDictTypeDropDownWait({ code: 'code2' }),
|
||||
])
|
||||
.then(([code1, code2]) => {
|
||||
this.codes.code1 = code1.data;
|
||||
this.codes.code2 = code2.data;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要方法
|
||||
* 绑定数据字典值
|
||||
*/
|
||||
bindCodeValue(code, name) {
|
||||
const c = this.codes[name].find((p) => p.code == code);
|
||||
if (c) {
|
||||
return c.value;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要方法
|
||||
* 从列表页调用窗口的打开方法
|
||||
*/
|
||||
onOpen(formName, record) {
|
||||
this.$refs[formName].onOpen(record);
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要方法
|
||||
* 可以用做一系列操作的公共回调,此方法中会重新加载当前列表
|
||||
*/
|
||||
onResult(success, successMessage) {
|
||||
if (success) {
|
||||
this.$message.success(successMessage);
|
||||
this.onReloadData();
|
||||
}
|
||||
this.$refs.table.onLoaded();
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要方法
|
||||
* 删除时调用
|
||||
*/
|
||||
onDelete(record) {
|
||||
this.$refs.table.onLoading();
|
||||
this.$api
|
||||
/** !!此处必须修改调用的接口方法 */
|
||||
.testDeleteApi(record)
|
||||
.then(({ success }) => {
|
||||
this.onResult(success, '删除成功');
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
:confirmLoading="confirmLoading"
|
||||
:visible="visible"
|
||||
:width="800"
|
||||
@close="onClose"
|
||||
@ok="onOk"
|
||||
class="yo-drawer-form"
|
||||
title="新增菜单"
|
||||
>
|
||||
<FormBody ref="form-body" />
|
||||
<div class="ant-drawer-footer">
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button :loading="confirmLoading" @click="onOk" type="primary">确定</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
<script>
|
||||
import FormBody from './form';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FormBody,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
|
||||
confirmLoading: false,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
formBody() {
|
||||
return this.$refs['form-body'];
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* 必要的方法
|
||||
* 从外部调用打开本窗口
|
||||
*/
|
||||
async onOpen() {
|
||||
this.visible = true;
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.formBody.onInit();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要的方法
|
||||
* 点击保存时的操作
|
||||
*/
|
||||
onOk() {
|
||||
this.formBody.onGetData().then((data) => {
|
||||
this.confirmLoading = true;
|
||||
this.$api
|
||||
.sysMenuAdd(data)
|
||||
.then(({ success }) => {
|
||||
if (success) {
|
||||
this.$message.success('新增成功');
|
||||
this.onClose();
|
||||
this.$emit('ok');
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.confirmLoading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要的方法
|
||||
* 关闭窗口时的操作
|
||||
*/
|
||||
onClose() {
|
||||
this.formBody.onResetFields();
|
||||
this.visible = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,83 @@
|
||||
<template>
|
||||
<a-drawer
|
||||
:confirmLoading="confirmLoading"
|
||||
:visible="visible"
|
||||
:width="800"
|
||||
@close="onClose"
|
||||
class="yo-drawer-form"
|
||||
title="编辑应用"
|
||||
>
|
||||
<FormBody ref="form-body" />
|
||||
<div class="ant-drawer-footer">
|
||||
<a-button @click="onClose">取消</a-button>
|
||||
<a-button :loading="confirmLoading" @click="onOk" type="primary">确定</a-button>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</template>
|
||||
<script>
|
||||
import FormBody from './form';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FormBody,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
visible: false,
|
||||
|
||||
confirmLoading: false,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
formBody() {
|
||||
return this.$refs['form-body'];
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* 必要的方法
|
||||
* 从外部调用打开本窗口,并填充外部传入的数据
|
||||
*/
|
||||
onOpen(record) {
|
||||
this.visible = true;
|
||||
this.$nextTick(async () => {
|
||||
await this.formBody.onInit();
|
||||
this.formBody.onFillData(record);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要的方法
|
||||
* 点击保存时的操作
|
||||
*/
|
||||
onOk() {
|
||||
this.formBody.onGetData().then((data) => {
|
||||
this.confirmLoading = true;
|
||||
this.$api
|
||||
.sysMenuEdit(data)
|
||||
.then(({ success }) => {
|
||||
if (success) {
|
||||
this.$message.success('编辑成功');
|
||||
this.onClose();
|
||||
this.$emit('ok');
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
this.confirmLoading = false;
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要的方法
|
||||
* 关闭窗口时的操作
|
||||
*/
|
||||
onClose() {
|
||||
this.formBody.onResetFields();
|
||||
this.visible = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
297
Api/Ewide.Core/Ewide.Core.Web.Src/src/pages/system/menu/form.vue
Normal file
297
Api/Ewide.Core/Ewide.Core.Web.Src/src/pages/system/menu/form.vue
Normal file
@@ -0,0 +1,297 @@
|
||||
<template>
|
||||
<a-form-model :model="form" :rules="rules" class="yo-form" ref="form">
|
||||
<a-spin :spinning="loading">
|
||||
<a-icon slot="indicator" spin type="loading" />
|
||||
<a-alert type="warning">
|
||||
<template slot="message">当前没有写入字段[重定向]</template>
|
||||
</a-alert>
|
||||
<br />
|
||||
<div class="yo-form-group">
|
||||
<!-- 表单控件 -->
|
||||
<h3>基本信息</h3>
|
||||
<div class="yo-form-group">
|
||||
<a-form-model-item label="菜单类型" prop="type">
|
||||
<template slot="help">
|
||||
目录:默认添加在顶级
|
||||
<br />菜单:
|
||||
<br />按钮:
|
||||
</template>
|
||||
<a-radio-group @change="onTypeChange" v-model="form.type">
|
||||
<a-radio-button
|
||||
:key="type.code"
|
||||
:value="type.code"
|
||||
v-for="type in codes.menuType"
|
||||
>{{type.value}}</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="名称" prop="name">
|
||||
<a-input placeholder="请输入名称" v-model="form.name" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="唯一编码" prop="code">
|
||||
<a-input placeholder="请输入唯一编码" v-model="form.code" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="所属应用" prop="application">
|
||||
<a-select
|
||||
@change="onChangeApplication"
|
||||
placeholder="请选择所属应用"
|
||||
v-model="form.application"
|
||||
>
|
||||
<a-select-option
|
||||
:key="item.code"
|
||||
:value="item.code"
|
||||
v-for="item in appList"
|
||||
>{{item.name}}</a-select-option>
|
||||
</a-select>
|
||||
</a-form-model-item>
|
||||
<!-- 父级菜单只有[目录]不可用 -->
|
||||
<a-form-model-item label="父级菜单" prop="pid" v-if="form.type != 0">
|
||||
<a-tree-select
|
||||
:dropdown-style="{ maxHeight: '300px', overflow: 'auto' }"
|
||||
:tree-data="parentTreeData"
|
||||
placeholder="请选择父级菜单"
|
||||
v-model="form.pid"
|
||||
/>
|
||||
</a-form-model-item>
|
||||
</div>
|
||||
|
||||
<h3>扩展信息</h3>
|
||||
<div class="yo-form-group">
|
||||
<a-form-model-item label="打开方式" prop="openType" v-if="form.type == 1">
|
||||
<a-radio-group @change="onOpenTypeChange" v-model="form.openType">
|
||||
<a-radio-button
|
||||
:key="type.code"
|
||||
:value="type.code"
|
||||
v-for="type in codes.openType"
|
||||
>{{type.value}}</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
<!-- 前端组件只有[菜单]及[组件]可用 -->
|
||||
<a-form-model-item
|
||||
label="前端组件"
|
||||
prop="component"
|
||||
v-if="form.type == 1 && form.openType == 1"
|
||||
v-show="form.type == 1 && form.openType == 1"
|
||||
>
|
||||
<a-input placeholder="请输入前端组件" v-model="form.component" />
|
||||
</a-form-model-item>
|
||||
<!-- 内链地址只有[菜单]及[内链]可用 -->
|
||||
<a-form-model-item label="内链地址" prop="router" v-if="form.type == 1 && form.openType == 2">
|
||||
<a-input placeholder="请输入内链地址" v-model="form.router" />
|
||||
</a-form-model-item>
|
||||
<!-- 外链地址只有[菜单]及[外链]可用 -->
|
||||
<a-form-model-item label="内外链地址" prop="link" v-if="form.type == 1 && form.openType == 3">
|
||||
<a-input placeholder="请输入内外链地址" v-model="form.link" />
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="权重" prop="weight">
|
||||
<template slot="help">
|
||||
系统权重:菜单可分配给任何角色
|
||||
<br />业务权重:菜单对超级管理员不可见
|
||||
</template>
|
||||
<a-radio-group v-model="form.weight">
|
||||
<a-radio-button
|
||||
:key="type.code"
|
||||
:value="type.code"
|
||||
v-for="type in codes.menuWerght"
|
||||
>{{type.value}}</a-radio-button>
|
||||
</a-radio-group>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="可见性">
|
||||
<a-switch checked-children="可见" un-checked-children="隐藏" v-model="form.visible" />
|
||||
</a-form-model-item>
|
||||
<!-- 图标只有[按钮]不可用 -->
|
||||
<a-form-model-item label="图标" v-if="form.type != 2"></a-form-model-item>
|
||||
<a-form-model-item label="排序">
|
||||
<a-input-number
|
||||
:max="1000"
|
||||
:min="0"
|
||||
class="w-100-p"
|
||||
placeholder="请输入排序"
|
||||
v-model="form.sort"
|
||||
/>
|
||||
</a-form-model-item>
|
||||
<a-form-model-item label="备注信息">
|
||||
<a-textarea placeholder="请输入备注信息" v-model="form.remark" />
|
||||
</a-form-model-item>
|
||||
</div>
|
||||
</div>
|
||||
</a-spin>
|
||||
</a-form-model>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
/** 表单数据 */
|
||||
form: {
|
||||
type: '1',
|
||||
openType: '1',
|
||||
weight: '2',
|
||||
visible: true,
|
||||
sort: 100,
|
||||
},
|
||||
/** 验证格式 */
|
||||
rules: {
|
||||
type: [{ required: true, message: '请选择菜单类型' }],
|
||||
name: [{ required: true, message: '请输入名称' }],
|
||||
code: [{ required: true, message: '请输入唯一编码' }],
|
||||
application: [{ required: true, message: '请选择所属应用' }],
|
||||
pid: [{ required: true, message: '请选择父级' }],
|
||||
component: [{ required: true, message: '请输入前端组件' }],
|
||||
router: [{ required: true, message: '请输入内链地址' }],
|
||||
link: [{ required: true, message: '请输入外链地址' }],
|
||||
},
|
||||
|
||||
/** 加载异步数据状态 */
|
||||
loading: false,
|
||||
|
||||
/** 其他成员属性 */
|
||||
/** ... */
|
||||
appList: [],
|
||||
codes: {
|
||||
menuType: [],
|
||||
menuWerght: [],
|
||||
openType: [],
|
||||
},
|
||||
|
||||
parentTreeData: [],
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
/**
|
||||
* 必要的方法
|
||||
* 在打开编辑页时允许填充数据
|
||||
*/
|
||||
onFillData(record) {
|
||||
/** 将默认数据覆盖到form */
|
||||
this.form = this.$_.cloneDeep({
|
||||
...record,
|
||||
/** 在此处添加默认数据转换 */
|
||||
/** ... */
|
||||
visible: record.visible == 'Y',
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要方法
|
||||
* 验证表单并获取表单数据
|
||||
*/
|
||||
onGetData() {
|
||||
return new Promise((reslove, reject) => {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
const record = this.$_.cloneDeep(this.form);
|
||||
|
||||
/** 验证通过后可以对数据进行转换得到想要提交的格式 */
|
||||
/** ... */
|
||||
record.visible = record.visible ? 'Y' : 'N';
|
||||
|
||||
reslove(record);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要的方法
|
||||
* 在外部窗口进行保存时调用表单验证
|
||||
*/
|
||||
onValidate(callback) {
|
||||
this.$refs.form.validate(callback);
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要的方法
|
||||
* 在外部窗口关闭或重置时对表单验证进行初始化
|
||||
*/
|
||||
onResetFields() {
|
||||
setTimeout(() => {
|
||||
this.$refs.form.resetFields();
|
||||
|
||||
/** 在这里可以初始化当前组件中其他属性 */
|
||||
/** ... */
|
||||
this.parentTreeData = [];
|
||||
}, 300);
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要方法
|
||||
* 加载当前表单中所需要的异步数据
|
||||
*/
|
||||
async onInit() {
|
||||
this.loading = true;
|
||||
|
||||
/** 可以在这里await获取一些异步数据 */
|
||||
/** ...BEGIN */
|
||||
this.codes = await this.onLoadCodes();
|
||||
this.appList = await this.onLoadSysApplist();
|
||||
/** ...END */
|
||||
this.loading = false;
|
||||
},
|
||||
|
||||
/** 当前组件的其他方法 */
|
||||
/** ... */
|
||||
onLoadCodes() {
|
||||
return this.$api
|
||||
.$queue([
|
||||
this.$api.sysDictTypeDropDownWait({ code: 'menu_type' }),
|
||||
this.$api.sysDictTypeDropDownWait({ code: 'menu_weight' }),
|
||||
this.$api.sysDictTypeDropDownWait({ code: 'open_type' }),
|
||||
])
|
||||
.then(([menuType, menuWerght, openType]) => {
|
||||
return {
|
||||
menuType: menuType.data,
|
||||
menuWerght: menuWerght.data,
|
||||
openType: openType.data,
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
onLoadSysApplist() {
|
||||
return this.$api.getAppList().then(({ data }) => {
|
||||
return data;
|
||||
});
|
||||
},
|
||||
|
||||
onTypeChangeGroup() {
|
||||
const { type, openType } = this.form;
|
||||
if (type == 1 && openType == 2) {
|
||||
this.$set(this.form, 'component', 'iframe');
|
||||
} else {
|
||||
this.$set(this.form, 'component', '');
|
||||
}
|
||||
},
|
||||
|
||||
onTypeChange() {
|
||||
this.onTypeChangeGroup();
|
||||
|
||||
if (this.form.type == 0 || this.form.type == 2) {
|
||||
this.form.openType = '0';
|
||||
} else {
|
||||
this.form.openType = '1';
|
||||
}
|
||||
},
|
||||
|
||||
onOpenTypeChange() {
|
||||
this.onTypeChangeGroup();
|
||||
},
|
||||
|
||||
onChangeApplication(value) {
|
||||
this.$api.getMenuTree({ application: value }).then(({ data }) => {
|
||||
this.parentTreeData = [
|
||||
{
|
||||
id: -1,
|
||||
parentId: 0,
|
||||
title: '顶级',
|
||||
value: 0,
|
||||
pid: 0,
|
||||
children: data,
|
||||
},
|
||||
];
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,194 @@
|
||||
<template>
|
||||
<container>
|
||||
<br />
|
||||
<a-card :bordered="false">
|
||||
<yo-table :columns="columns" :load-data="loadData" ref="table">
|
||||
<Auth auth="sysMenu:add" slot="operator">
|
||||
<a-button @click="onOpen('add-form')" icon="plus">新增菜单</a-button>
|
||||
</Auth>
|
||||
<span slot="type" slot-scope="text">{{ bindCodeValue(text, 'menu_type') }}</span>
|
||||
<span slot="icon" slot-scope="text">
|
||||
<div v-if="text">
|
||||
<a-icon :type="text" />
|
||||
</div>
|
||||
</span>
|
||||
<span slot="action" slot-scope="text, record">
|
||||
<yo-table-actions>
|
||||
<Auth auth="sysMenu:edit">
|
||||
<a @click="onOpen('edit-form', record)">编辑</a>
|
||||
</Auth>
|
||||
<Auth auth="sysMenu:delete">
|
||||
<a-popconfirm @confirm="onDelete(record)" placement="topRight" title="是否确认删除">
|
||||
<a>删除</a>
|
||||
</a-popconfirm>
|
||||
</Auth>
|
||||
</yo-table-actions>
|
||||
</span>
|
||||
</yo-table>
|
||||
</a-card>
|
||||
<br />
|
||||
<add-form @ok="onReloadData" ref="add-form" />
|
||||
<edit-form @ok="onReloadData" ref="edit-form" />
|
||||
</container>
|
||||
</template>
|
||||
<script>
|
||||
import AddForm from './addForm';
|
||||
import EditForm from './editForm';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AddForm,
|
||||
EditForm,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
query: {},
|
||||
columns: [
|
||||
{
|
||||
title: '菜单名称',
|
||||
width: '220px',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: '菜单类型',
|
||||
width: '100px',
|
||||
dataIndex: 'type',
|
||||
scopedSlots: { customRender: 'type' },
|
||||
},
|
||||
{
|
||||
title: '图标',
|
||||
width: '100px',
|
||||
dataIndex: 'icon',
|
||||
scopedSlots: { customRender: 'icon' },
|
||||
},
|
||||
{
|
||||
title: '前端组件',
|
||||
width: '220px',
|
||||
dataIndex: 'component',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '权限标识',
|
||||
width: '220px',
|
||||
dataIndex: 'permission',
|
||||
ellipsis: true,
|
||||
},
|
||||
{
|
||||
title: '排序',
|
||||
width: '100px',
|
||||
dataIndex: 'sort',
|
||||
},
|
||||
],
|
||||
codes: [
|
||||
{
|
||||
code: 'menu_type',
|
||||
values: [],
|
||||
},
|
||||
{
|
||||
code: 'menu_weight',
|
||||
values: [],
|
||||
},
|
||||
{
|
||||
code: 'open_type',
|
||||
values: [],
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.onLoadCodes();
|
||||
|
||||
const flag = this.$auth({
|
||||
sysApp: [['edit'], ['delete']],
|
||||
});
|
||||
|
||||
if (flag) {
|
||||
this.columns.push({
|
||||
title: '操作',
|
||||
width: '150px',
|
||||
dataIndex: 'action',
|
||||
scopedSlots: { customRender: 'action' },
|
||||
});
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* 必要的方法
|
||||
* 传给yo-table以示意数据接口及其参数和返回的数据结构
|
||||
*/
|
||||
loadData(params) {
|
||||
return this.$api
|
||||
.getMenuList({
|
||||
...params,
|
||||
...this.query,
|
||||
})
|
||||
.then((res) => {
|
||||
return res.data;
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 有查询功能时的必要方法
|
||||
* 加载数据时初始化分页信息
|
||||
*/
|
||||
onQuery() {
|
||||
this.$refs.table.onReloadData(true);
|
||||
},
|
||||
|
||||
/**
|
||||
* 必要方法
|
||||
* 重新列表数据
|
||||
*/
|
||||
onReloadData() {
|
||||
this.$refs.table.onReloadData();
|
||||
},
|
||||
|
||||
/**
|
||||
* 加载字典数据时的必要方法
|
||||
*/
|
||||
onLoadCodes() {
|
||||
this.$api
|
||||
.$queue([
|
||||
this.$api.sysDictTypeDropDownWait({ code: 'menu_type' }),
|
||||
this.$api.sysDictTypeDropDownWait({ code: 'menu_weight' }),
|
||||
this.$api.sysDictTypeDropDownWait({ code: 'open_type' }),
|
||||
])
|
||||
.then(([menuType, menuWerght, openType]) => {
|
||||
this.codes.find((p) => p.code === 'menu_type').values = menuType.data;
|
||||
this.codes.find((p) => p.code === 'menu_weight').values = menuWerght.data;
|
||||
this.codes.find((p) => p.code === 'open_type').values = openType.data;
|
||||
});
|
||||
},
|
||||
bindCodeValue(code, name) {
|
||||
const c = this.codes.find((p) => p.code == name).values.find((p) => p.code == code);
|
||||
if (c) {
|
||||
return c.value;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* 有编辑新增功能的必要方法
|
||||
* 从列表页调用窗口的打开方法
|
||||
*/
|
||||
onOpen(formName, record) {
|
||||
this.$refs[formName].onOpen(record);
|
||||
},
|
||||
|
||||
onResult(success, successMessage) {
|
||||
if (success) {
|
||||
this.$message.success(successMessage);
|
||||
this.onReloadData();
|
||||
}
|
||||
this.$refs.table.onLoaded();
|
||||
},
|
||||
|
||||
onDelete(record) {
|
||||
this.$refs.table.onLoading();
|
||||
this.$api.sysMenuDelete(record).then(({ success }) => {
|
||||
this.onResult(success, '删除成功');
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
296
Api/Ewide.Core/Ewide.Core.Web.Src/src/views/error/404/index.css
Normal file
296
Api/Ewide.Core/Ewide.Core.Web.Src/src/views/error/404/index.css
Normal file
@@ -0,0 +1,296 @@
|
||||
@-webkit-keyframes noise-anim {
|
||||
0% {
|
||||
clip: rect(32px, 9999px, 16px, 0);
|
||||
}
|
||||
5% {
|
||||
clip: rect(5px, 9999px, 24px, 0);
|
||||
}
|
||||
10% {
|
||||
clip: rect(77px, 9999px, 87px, 0);
|
||||
}
|
||||
15% {
|
||||
clip: rect(91px, 9999px, 95px, 0);
|
||||
}
|
||||
20% {
|
||||
clip: rect(74px, 9999px, 9px, 0);
|
||||
}
|
||||
25% {
|
||||
clip: rect(37px, 9999px, 32px, 0);
|
||||
}
|
||||
30% {
|
||||
clip: rect(56px, 9999px, 27px, 0);
|
||||
}
|
||||
35% {
|
||||
clip: rect(35px, 9999px, 33px, 0);
|
||||
}
|
||||
40% {
|
||||
clip: rect(89px, 9999px, 6px, 0);
|
||||
}
|
||||
45% {
|
||||
clip: rect(81px, 9999px, 77px, 0);
|
||||
}
|
||||
50% {
|
||||
clip: rect(64px, 9999px, 69px, 0);
|
||||
}
|
||||
55% {
|
||||
clip: rect(12px, 9999px, 11px, 0);
|
||||
}
|
||||
60% {
|
||||
clip: rect(59px, 9999px, 11px, 0);
|
||||
}
|
||||
65% {
|
||||
clip: rect(69px, 9999px, 59px, 0);
|
||||
}
|
||||
70% {
|
||||
clip: rect(74px, 9999px, 65px, 0);
|
||||
}
|
||||
75% {
|
||||
clip: rect(56px, 9999px, 79px, 0);
|
||||
}
|
||||
80% {
|
||||
clip: rect(80px, 9999px, 64px, 0);
|
||||
}
|
||||
85% {
|
||||
clip: rect(87px, 9999px, 29px, 0);
|
||||
}
|
||||
90% {
|
||||
clip: rect(16px, 9999px, 21px, 0);
|
||||
}
|
||||
95% {
|
||||
clip: rect(69px, 9999px, 43px, 0);
|
||||
}
|
||||
100% {
|
||||
clip: rect(75px, 9999px, 63px, 0);
|
||||
}
|
||||
}
|
||||
@keyframes noise-anim {
|
||||
0% {
|
||||
clip: rect(32px, 9999px, 16px, 0);
|
||||
}
|
||||
5% {
|
||||
clip: rect(5px, 9999px, 24px, 0);
|
||||
}
|
||||
10% {
|
||||
clip: rect(77px, 9999px, 87px, 0);
|
||||
}
|
||||
15% {
|
||||
clip: rect(91px, 9999px, 95px, 0);
|
||||
}
|
||||
20% {
|
||||
clip: rect(74px, 9999px, 9px, 0);
|
||||
}
|
||||
25% {
|
||||
clip: rect(37px, 9999px, 32px, 0);
|
||||
}
|
||||
30% {
|
||||
clip: rect(56px, 9999px, 27px, 0);
|
||||
}
|
||||
35% {
|
||||
clip: rect(35px, 9999px, 33px, 0);
|
||||
}
|
||||
40% {
|
||||
clip: rect(89px, 9999px, 6px, 0);
|
||||
}
|
||||
45% {
|
||||
clip: rect(81px, 9999px, 77px, 0);
|
||||
}
|
||||
50% {
|
||||
clip: rect(64px, 9999px, 69px, 0);
|
||||
}
|
||||
55% {
|
||||
clip: rect(12px, 9999px, 11px, 0);
|
||||
}
|
||||
60% {
|
||||
clip: rect(59px, 9999px, 11px, 0);
|
||||
}
|
||||
65% {
|
||||
clip: rect(69px, 9999px, 59px, 0);
|
||||
}
|
||||
70% {
|
||||
clip: rect(74px, 9999px, 65px, 0);
|
||||
}
|
||||
75% {
|
||||
clip: rect(56px, 9999px, 79px, 0);
|
||||
}
|
||||
80% {
|
||||
clip: rect(80px, 9999px, 64px, 0);
|
||||
}
|
||||
85% {
|
||||
clip: rect(87px, 9999px, 29px, 0);
|
||||
}
|
||||
90% {
|
||||
clip: rect(16px, 9999px, 21px, 0);
|
||||
}
|
||||
95% {
|
||||
clip: rect(69px, 9999px, 43px, 0);
|
||||
}
|
||||
100% {
|
||||
clip: rect(75px, 9999px, 63px, 0);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes noise-anim-2 {
|
||||
0% {
|
||||
clip: rect(12px, 9999px, 52px, 0);
|
||||
}
|
||||
5% {
|
||||
clip: rect(42px, 9999px, 39px, 0);
|
||||
}
|
||||
10% {
|
||||
clip: rect(64px, 9999px, 36px, 0);
|
||||
}
|
||||
15% {
|
||||
clip: rect(52px, 9999px, 15px, 0);
|
||||
}
|
||||
20% {
|
||||
clip: rect(79px, 9999px, 7px, 0);
|
||||
}
|
||||
25% {
|
||||
clip: rect(17px, 9999px, 41px, 0);
|
||||
}
|
||||
30% {
|
||||
clip: rect(15px, 9999px, 20px, 0);
|
||||
}
|
||||
35% {
|
||||
clip: rect(62px, 9999px, 87px, 0);
|
||||
}
|
||||
40% {
|
||||
clip: rect(94px, 9999px, 11px, 0);
|
||||
}
|
||||
45% {
|
||||
clip: rect(49px, 9999px, 10px, 0);
|
||||
}
|
||||
50% {
|
||||
clip: rect(82px, 9999px, 4px, 0);
|
||||
}
|
||||
55% {
|
||||
clip: rect(70px, 9999px, 100px, 0);
|
||||
}
|
||||
60% {
|
||||
clip: rect(62px, 9999px, 23px, 0);
|
||||
}
|
||||
65% {
|
||||
clip: rect(51px, 9999px, 56px, 0);
|
||||
}
|
||||
70% {
|
||||
clip: rect(41px, 9999px, 24px, 0);
|
||||
}
|
||||
75% {
|
||||
clip: rect(6px, 9999px, 85px, 0);
|
||||
}
|
||||
80% {
|
||||
clip: rect(96px, 9999px, 58px, 0);
|
||||
}
|
||||
85% {
|
||||
clip: rect(16px, 9999px, 24px, 0);
|
||||
}
|
||||
90% {
|
||||
clip: rect(40px, 9999px, 31px, 0);
|
||||
}
|
||||
95% {
|
||||
clip: rect(91px, 9999px, 34px, 0);
|
||||
}
|
||||
100% {
|
||||
clip: rect(87px, 9999px, 26px, 0);
|
||||
}
|
||||
}
|
||||
@keyframes noise-anim-2 {
|
||||
0% {
|
||||
clip: rect(12px, 9999px, 52px, 0);
|
||||
}
|
||||
5% {
|
||||
clip: rect(42px, 9999px, 39px, 0);
|
||||
}
|
||||
10% {
|
||||
clip: rect(64px, 9999px, 36px, 0);
|
||||
}
|
||||
15% {
|
||||
clip: rect(52px, 9999px, 15px, 0);
|
||||
}
|
||||
20% {
|
||||
clip: rect(79px, 9999px, 7px, 0);
|
||||
}
|
||||
25% {
|
||||
clip: rect(17px, 9999px, 41px, 0);
|
||||
}
|
||||
30% {
|
||||
clip: rect(15px, 9999px, 20px, 0);
|
||||
}
|
||||
35% {
|
||||
clip: rect(62px, 9999px, 87px, 0);
|
||||
}
|
||||
40% {
|
||||
clip: rect(94px, 9999px, 11px, 0);
|
||||
}
|
||||
45% {
|
||||
clip: rect(49px, 9999px, 10px, 0);
|
||||
}
|
||||
50% {
|
||||
clip: rect(82px, 9999px, 4px, 0);
|
||||
}
|
||||
55% {
|
||||
clip: rect(70px, 9999px, 100px, 0);
|
||||
}
|
||||
60% {
|
||||
clip: rect(62px, 9999px, 23px, 0);
|
||||
}
|
||||
65% {
|
||||
clip: rect(51px, 9999px, 56px, 0);
|
||||
}
|
||||
70% {
|
||||
clip: rect(41px, 9999px, 24px, 0);
|
||||
}
|
||||
75% {
|
||||
clip: rect(6px, 9999px, 85px, 0);
|
||||
}
|
||||
80% {
|
||||
clip: rect(96px, 9999px, 58px, 0);
|
||||
}
|
||||
85% {
|
||||
clip: rect(16px, 9999px, 24px, 0);
|
||||
}
|
||||
90% {
|
||||
clip: rect(40px, 9999px, 31px, 0);
|
||||
}
|
||||
95% {
|
||||
clip: rect(91px, 9999px, 34px, 0);
|
||||
}
|
||||
100% {
|
||||
clip: rect(87px, 9999px, 26px, 0);
|
||||
}
|
||||
}
|
||||
.error-result {
|
||||
padding: 100px;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.error-result--text {
|
||||
font-size: 7rem;
|
||||
line-height: 1;
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 12.5rem;
|
||||
color: #5a5c69;
|
||||
}
|
||||
.error-result--text::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 2px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 900px, 0, 0);
|
||||
content: attr(data-text);
|
||||
animation: noise-anim 2s infinite linear alternate-reverse;
|
||||
color: #5a5c69;
|
||||
background: #f8f9fc;
|
||||
text-shadow: -1px 0 #e74a3b;
|
||||
}
|
||||
.error-result--text::before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -2px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 900px, 0, 0);
|
||||
content: attr(data-text);
|
||||
animation: noise-anim-2 3s infinite linear alternate-reverse;
|
||||
color: #5a5c69;
|
||||
background: #f8f9fc;
|
||||
text-shadow: 1px 0 #4e73df;
|
||||
}
|
||||
308
Api/Ewide.Core/Ewide.Core.Web.Src/src/views/error/404/index.less
Normal file
308
Api/Ewide.Core/Ewide.Core.Web.Src/src/views/error/404/index.less
Normal file
@@ -0,0 +1,308 @@
|
||||
@import (reference) '~ant-design-vue/dist/antd.less';
|
||||
@-webkit-keyframes noise-anim-after {
|
||||
0% {
|
||||
clip: rect(32px, 9999px, 16px, 0);
|
||||
}
|
||||
5% {
|
||||
clip: rect(5px, 9999px, 24px, 0);
|
||||
}
|
||||
10% {
|
||||
clip: rect(77px, 9999px, 87px, 0);
|
||||
}
|
||||
15% {
|
||||
clip: rect(91px, 9999px, 95px, 0);
|
||||
}
|
||||
20% {
|
||||
clip: rect(74px, 9999px, 9px, 0);
|
||||
}
|
||||
25% {
|
||||
clip: rect(37px, 9999px, 32px, 0);
|
||||
}
|
||||
30% {
|
||||
clip: rect(56px, 9999px, 27px, 0);
|
||||
}
|
||||
35% {
|
||||
clip: rect(35px, 9999px, 33px, 0);
|
||||
}
|
||||
40% {
|
||||
clip: rect(89px, 9999px, 6px, 0);
|
||||
}
|
||||
45% {
|
||||
clip: rect(81px, 9999px, 77px, 0);
|
||||
}
|
||||
50% {
|
||||
clip: rect(64px, 9999px, 69px, 0);
|
||||
}
|
||||
55% {
|
||||
clip: rect(12px, 9999px, 11px, 0);
|
||||
}
|
||||
60% {
|
||||
clip: rect(59px, 9999px, 11px, 0);
|
||||
}
|
||||
65% {
|
||||
clip: rect(69px, 9999px, 59px, 0);
|
||||
}
|
||||
70% {
|
||||
clip: rect(74px, 9999px, 65px, 0);
|
||||
}
|
||||
75% {
|
||||
clip: rect(56px, 9999px, 79px, 0);
|
||||
}
|
||||
80% {
|
||||
clip: rect(80px, 9999px, 64px, 0);
|
||||
}
|
||||
85% {
|
||||
clip: rect(87px, 9999px, 29px, 0);
|
||||
}
|
||||
90% {
|
||||
clip: rect(16px, 9999px, 21px, 0);
|
||||
}
|
||||
95% {
|
||||
clip: rect(69px, 9999px, 43px, 0);
|
||||
}
|
||||
100% {
|
||||
clip: rect(75px, 9999px, 63px, 0);
|
||||
}
|
||||
}
|
||||
@keyframes noise-anim-after {
|
||||
0% {
|
||||
clip: rect(32px, 9999px, 16px, 0);
|
||||
}
|
||||
5% {
|
||||
clip: rect(5px, 9999px, 24px, 0);
|
||||
}
|
||||
10% {
|
||||
clip: rect(77px, 9999px, 87px, 0);
|
||||
}
|
||||
15% {
|
||||
clip: rect(91px, 9999px, 95px, 0);
|
||||
}
|
||||
20% {
|
||||
clip: rect(74px, 9999px, 9px, 0);
|
||||
}
|
||||
25% {
|
||||
clip: rect(37px, 9999px, 32px, 0);
|
||||
}
|
||||
30% {
|
||||
clip: rect(56px, 9999px, 27px, 0);
|
||||
}
|
||||
35% {
|
||||
clip: rect(35px, 9999px, 33px, 0);
|
||||
}
|
||||
40% {
|
||||
clip: rect(89px, 9999px, 6px, 0);
|
||||
}
|
||||
45% {
|
||||
clip: rect(81px, 9999px, 77px, 0);
|
||||
}
|
||||
50% {
|
||||
clip: rect(64px, 9999px, 69px, 0);
|
||||
}
|
||||
55% {
|
||||
clip: rect(12px, 9999px, 11px, 0);
|
||||
}
|
||||
60% {
|
||||
clip: rect(59px, 9999px, 11px, 0);
|
||||
}
|
||||
65% {
|
||||
clip: rect(69px, 9999px, 59px, 0);
|
||||
}
|
||||
70% {
|
||||
clip: rect(74px, 9999px, 65px, 0);
|
||||
}
|
||||
75% {
|
||||
clip: rect(56px, 9999px, 79px, 0);
|
||||
}
|
||||
80% {
|
||||
clip: rect(80px, 9999px, 64px, 0);
|
||||
}
|
||||
85% {
|
||||
clip: rect(87px, 9999px, 29px, 0);
|
||||
}
|
||||
90% {
|
||||
clip: rect(16px, 9999px, 21px, 0);
|
||||
}
|
||||
95% {
|
||||
clip: rect(69px, 9999px, 43px, 0);
|
||||
}
|
||||
100% {
|
||||
clip: rect(75px, 9999px, 63px, 0);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes noise-anim-before {
|
||||
0% {
|
||||
clip: rect(12px, 9999px, 52px, 0);
|
||||
}
|
||||
5% {
|
||||
clip: rect(42px, 9999px, 39px, 0);
|
||||
}
|
||||
10% {
|
||||
clip: rect(64px, 9999px, 36px, 0);
|
||||
}
|
||||
15% {
|
||||
clip: rect(52px, 9999px, 15px, 0);
|
||||
}
|
||||
20% {
|
||||
clip: rect(79px, 9999px, 7px, 0);
|
||||
}
|
||||
25% {
|
||||
clip: rect(17px, 9999px, 41px, 0);
|
||||
}
|
||||
30% {
|
||||
clip: rect(15px, 9999px, 20px, 0);
|
||||
}
|
||||
35% {
|
||||
clip: rect(62px, 9999px, 87px, 0);
|
||||
}
|
||||
40% {
|
||||
clip: rect(94px, 9999px, 11px, 0);
|
||||
}
|
||||
45% {
|
||||
clip: rect(49px, 9999px, 10px, 0);
|
||||
}
|
||||
50% {
|
||||
clip: rect(82px, 9999px, 4px, 0);
|
||||
}
|
||||
55% {
|
||||
clip: rect(70px, 9999px, 100px, 0);
|
||||
}
|
||||
60% {
|
||||
clip: rect(62px, 9999px, 23px, 0);
|
||||
}
|
||||
65% {
|
||||
clip: rect(51px, 9999px, 56px, 0);
|
||||
}
|
||||
70% {
|
||||
clip: rect(41px, 9999px, 24px, 0);
|
||||
}
|
||||
75% {
|
||||
clip: rect(6px, 9999px, 85px, 0);
|
||||
}
|
||||
80% {
|
||||
clip: rect(96px, 9999px, 58px, 0);
|
||||
}
|
||||
85% {
|
||||
clip: rect(16px, 9999px, 24px, 0);
|
||||
}
|
||||
90% {
|
||||
clip: rect(40px, 9999px, 31px, 0);
|
||||
}
|
||||
95% {
|
||||
clip: rect(91px, 9999px, 34px, 0);
|
||||
}
|
||||
100% {
|
||||
clip: rect(87px, 9999px, 26px, 0);
|
||||
}
|
||||
}
|
||||
@keyframes noise-anim-before {
|
||||
0% {
|
||||
clip: rect(12px, 9999px, 52px, 0);
|
||||
}
|
||||
5% {
|
||||
clip: rect(42px, 9999px, 39px, 0);
|
||||
}
|
||||
10% {
|
||||
clip: rect(64px, 9999px, 36px, 0);
|
||||
}
|
||||
15% {
|
||||
clip: rect(52px, 9999px, 15px, 0);
|
||||
}
|
||||
20% {
|
||||
clip: rect(79px, 9999px, 7px, 0);
|
||||
}
|
||||
25% {
|
||||
clip: rect(17px, 9999px, 41px, 0);
|
||||
}
|
||||
30% {
|
||||
clip: rect(15px, 9999px, 20px, 0);
|
||||
}
|
||||
35% {
|
||||
clip: rect(62px, 9999px, 87px, 0);
|
||||
}
|
||||
40% {
|
||||
clip: rect(94px, 9999px, 11px, 0);
|
||||
}
|
||||
45% {
|
||||
clip: rect(49px, 9999px, 10px, 0);
|
||||
}
|
||||
50% {
|
||||
clip: rect(82px, 9999px, 4px, 0);
|
||||
}
|
||||
55% {
|
||||
clip: rect(70px, 9999px, 100px, 0);
|
||||
}
|
||||
60% {
|
||||
clip: rect(62px, 9999px, 23px, 0);
|
||||
}
|
||||
65% {
|
||||
clip: rect(51px, 9999px, 56px, 0);
|
||||
}
|
||||
70% {
|
||||
clip: rect(41px, 9999px, 24px, 0);
|
||||
}
|
||||
75% {
|
||||
clip: rect(6px, 9999px, 85px, 0);
|
||||
}
|
||||
80% {
|
||||
clip: rect(96px, 9999px, 58px, 0);
|
||||
}
|
||||
85% {
|
||||
clip: rect(16px, 9999px, 24px, 0);
|
||||
}
|
||||
90% {
|
||||
clip: rect(40px, 9999px, 31px, 0);
|
||||
}
|
||||
95% {
|
||||
clip: rect(91px, 9999px, 34px, 0);
|
||||
}
|
||||
100% {
|
||||
clip: rect(87px, 9999px, 26px, 0);
|
||||
}
|
||||
}
|
||||
.error-result {
|
||||
padding: 100px;
|
||||
|
||||
text-transform: uppercase;
|
||||
&--text {
|
||||
font-size: @font-size-base * 8;
|
||||
line-height: 1;
|
||||
|
||||
position: relative;
|
||||
|
||||
display: block;
|
||||
|
||||
width: 12.5rem;
|
||||
|
||||
color: #5a5c69;
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 2px;
|
||||
|
||||
overflow: hidden;
|
||||
clip: rect(0, 900px, 0, 0);
|
||||
|
||||
content: attr(data-text);
|
||||
animation: noise-anim-after 2s infinite linear alternate-reverse;
|
||||
|
||||
color: #5a5c69;
|
||||
background: @layout-body-background;
|
||||
text-shadow: -1px 0 #e74a3b;
|
||||
}
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -2px;
|
||||
|
||||
overflow: hidden;
|
||||
clip: rect(0, 900px, 0, 0);
|
||||
|
||||
content: attr(data-text);
|
||||
animation: noise-anim-before 3s infinite linear alternate-reverse;
|
||||
|
||||
color: #5a5c69;
|
||||
background: @layout-body-background;
|
||||
text-shadow: 1px 0 #4e73df;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<container>
|
||||
<div class="error-result">
|
||||
<div class="error-result--code">
|
||||
<span class="error-result--text" data-text="404">404</span>
|
||||
</div>
|
||||
<p>not found</p>
|
||||
</div>
|
||||
</container>
|
||||
</template>
|
||||
<style lang="less" scope>
|
||||
@import './index.less';
|
||||
|
||||
</style>
|
||||
@@ -74,7 +74,7 @@ export default {
|
||||
pane.loaded = true;
|
||||
NProgress.done();
|
||||
}).catch(() => {
|
||||
pane.component = () => import('@/views/404');
|
||||
pane.component = () => import('@/views/error/404');
|
||||
pane.loaded = true;
|
||||
NProgress.done();
|
||||
});
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
import Logo from '../logo';
|
||||
import Menu from './menu';
|
||||
|
||||
let swiper;
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Logo,
|
||||
@@ -65,16 +67,13 @@ export default {
|
||||
},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
swiper() {
|
||||
return this.$refs['sider-swiper'].$swiper;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
swiper = this.$refs['sider-swiper'].$swiper;
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
if (this.$root.global.settings.layout === 'left-menu' || this.$root.global.settings.layout === 'right-menu') {
|
||||
setTimeout(() => {
|
||||
this.swiper.update();
|
||||
swiper.update();
|
||||
}, 300);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user