为什么都没了

This commit is contained in:
路 范
2021-09-24 12:59:34 +08:00
parent a975b3bdee
commit a66921f0f4
962 changed files with 252792 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
/* 使用关键字await */
async function doc() {
const res1 = await this.$api.apiName1(params1)
const res2 = await this.$api.apiName2(params2)
}
/* 使用$queue */
this.$api
.$queue([
this.$api.apiName1Await(params1),
this.$api.apiName2Await(params2),
])
.then(([_res1, _res2]) => {
/* ... */
})

View File

@@ -0,0 +1,14 @@
export default {
/* 自定义的接口名称 */
apiName: [
/* 接口地址 */
url,
/* 请求类型 [get | post] */
'get',
/* axios所需的设置参数 */
options,
],
/* 默认为post的接口 */
apiPostName: postUrl
}

View File

@@ -0,0 +1,11 @@
this.$api
.apiName(params)
.then((res) => {
/* ... */
})
.catch((error) => {
/* catch */
})
.finally(() => {
/* finally */
})

View File

@@ -0,0 +1,14 @@
<template>
<section>
<!-- 简单的权限标识 -->
<Auth auth="sysApp:page">
<a-button>按钮1</a-button>
</Auth>
<!-- 多个并且关系的权限标识 -->
<Auth :auth="['sysApp:page', 'sysApp:add']"></Auth>
<!-- 多个或者关系的权限标识 -->
<Auth :auth="[['sysApp:page'], ['sysApp:add']]"></Auth>
<!-- 前缀简化 -->
<Auth :auth="{ sysApp: ['page', 'add'] }"></Auth>
</section>
</template>

View File

@@ -0,0 +1,109 @@
<template>
<!--
整页表单的外框架
v 1.2
2021-06-03
Lufthafen
-->
<div class="yo-form-page">
<!-- 表单主体 -->
<!-- 如果不想使用锚点,删除a-row->a-col,只留内部的a-card层即可 -->
<container>
<a-row :gutter="16" type="flex">
<a-col flex="1">
<br />
<a-card class="yo-form-page--body">
<template v-for="(part, index) in parts">
<section :id="`form-${index}-${id}`" :key="index">
<h5 v-if="part.title">{{part.title}}</h5>
<component
:is="part.component"
:key="index"
:param="param"
ref="forms"
v-if="part.component"
/>
</section>
<a-divider :key="`divider-${index}`" v-if="index < parts.length - 1" />
</template>
</a-card>
</a-col>
<a-col flex="240px">
<a-anchor
:get-container="()=> $el.parentNode"
:offset-top="24"
:wrapper-style="{ backgroundColor: 'transparent' }"
@click.prevent
>
<a-anchor-link
:href="`#form-${index}-${id}`"
:key="index"
:title="part.title"
v-for="(part, index) in parts"
/>
</a-anchor>
</a-col>
</a-row>
</container>
<!-- 底部工具栏 -->
<div class="yo-form-page--bar">
<container>
<div class="yo-form-page--bar-inner">
<span>
<!-- 可以在工具栏中增加其他控件(只能在一行内) -->
<!-- ... -->
</span>
<span>
<a-button @click="closeContentWindow()">取消</a-button>
<a-button :loading="saving" @click="onSubmit" type="primary">保存</a-button>
</span>
</div>
</container>
</div>
</div>
</template>
<script>
export default {
props: ['id', 'param'],
data() {
return {
saving: false,
parts: [
/**
{
title: '标题',
component: () => import('...'),
}
*/
],
};
},
methods: {
async onSubmit() {
let formData = {};
for (let i = 0; i < this.$refs.forms.length; i++) {
const form = this.$refs.forms[i];
try {
const data = await form.onGetData();
formData = {
...formData,
...data,
};
} catch (e) {
return;
}
}
this.saving = true;
/**
* 对表单提交进行处理
*/
this.saving = false;
},
},
};
</script>

View File

@@ -0,0 +1,123 @@
<template>
<!--
整页表单的分片表单
v 1.2
2021-06-03
Lufthafen
-->
<a-form-model
:label-col="labelCol"
:model="form"
:rules="rules"
:wrapper-col="wrapperCol"
ref="form"
>
<a-spin :spinning="loading">
<a-icon slot="indicator" spin type="loading" />
<!-- 表单控件 -->
<!-- ... -->
</a-spin>
</a-form-model>
</template>
<script>
/* 表单内容默认值 */
const defaultForm = {
/* ... */
};
export default {
props: ['param', 'frame'],
data() {
return {
labelCol: { flex: '150px' },
wrapperCol: { flex: '1' },
/** 表单数据 */
form: {
...defaultForm,
},
/** 验证格式 */
rules: {
/* ... */
},
/** 加载异步数据状态 */
loading: false,
/** 其他成员属性 */
/* ... */
};
},
created() {
this.onFillData();
},
methods: {
/**
* 必要的方法
* 在打开编辑页时允许填充数据
*/
async onFillData() {
this.loading = true;
{
const record = this.param && this.param.record;
const form = this.$_.cloneDeep(defaultForm);
if (record) {
this.$_.giveDeep(form, record);
}
this.form = form;
}
this.loading = false;
},
/**
* 必要方法
* 验证表单并获取表单数据
*/
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);
},
/** 当前组件的其他方法 */
/* ... */
},
};
</script>

View File

@@ -0,0 +1,147 @@
<template>
<!--
整页表单的页签外框架
v 1.2
2021-06-03
Lufthafen
-->
<div class="yo-form-page">
<a-spin :spinning="loading" class="w-100-p h-100-p" tip="表单加载中..." v-if="loading">
<a-icon slot="indicator" spin type="loading" />
<div title="用于撑高spin"></div>
</a-spin>
<div class="yo-form-page-layout" v-else>
<!-- 底部工具栏(需放在前面) -->
<div class="yo-form-page--bar yo-form-page--bar--with-tab">
<container>
<div class="yo-form-page--bar-inner">
<span>
<!-- 可以在工具栏中增加其他控件(只能在一行内) -->
<!-- ... -->
</span>
<span>
<a-button @click="closeContentWindow()">取消</a-button>
<a-button :loading="saving" @click="onSubmit" type="primary">保存</a-button>
</span>
</div>
</container>
</div>
<!-- 头部,默认不使用 -->
<!-- <div :style="{ paddingBottom: 0 }" class="yo-form-page--header">
<container>
</container>
</div>-->
<!-- 表单主体 -->
<!--
挂载了一个content到tab后面
如果直接使用antd-vue的tab,将会莫名其妙地做各种多余的渲染,导致卡顿
现在只使用其tab卡片,重写了一个tab内容
-->
<div class="yo-tab-external-mount">
<a-tabs @change="onTabChange" type="card">
<template v-for="(tab, index) in tabs">
<a-tab-pane :force-render="true" :key="index" :tab="tab.title"></a-tab-pane>
</template>
</a-tabs>
<div class="yo-tab-external-mount-content">
<template v-for="(tab, index) in tabs">
<div
:class="tab.active ? 'yo-tab-external-tabpane-active' : 'yo-tab-external-tabpane-inactive'"
:key="index"
class="yo-tab-external-tabpane"
>
<component
:frame="self"
:id="id"
:is="tab.component"
:param="param"
ref="forms"
v-if="tab.component"
/>
</div>
</template>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['id', 'param'],
data() {
return {
saving: false,
loading: true,
tabs: [
/**
{
title: '标题',
component: () => import('...'),
active: false,
}
*/
],
};
},
computed: {
self() {
return this;
},
},
created() {
this.loading = false;
},
methods: {
async onSubmit() {
let formData = {},
flag = true;
for (let i = 0; i < this.$refs.forms.length; i++) {
const form = this.$refs.forms[i];
try {
const data = await form.onGetData();
formData = {
...formData,
...data,
};
} catch (e) {
flag = false;
}
}
if (!flag) {
return;
}
this.saving = true;
/**
* 对表单提交进行处理
*/
this.saving = false;
},
onTabChange(key) {
this.tabs.forEach((p, i) => {
p.active = i === key;
});
},
/**
* 控制标签页的显隐性
*/
onTogglePane(show, name) {
const pane = this.tabs.find((p) => p.name === name);
if (pane) {
pane.show = show;
}
},
},
};
</script>

View File

@@ -0,0 +1,91 @@
<template>
<!--
整页表单的页签内框架,整合分片表单
v 1.2
2021-06-03
Lufthafen
-->
<container>
<!-- 如果不想使用锚点,删除a-row->a-col,只留内部的a-card层即可 -->
<a-row :gutter="16" type="flex">
<a-col flex="1">
<br />
<a-card class="yo-form-page--body">
<template v-for="(part, index) in parts">
<section :id="`form-${index}-${id}`" :key="index">
<h5 v-if="part.title">{{part.title}}</h5>
<component
:frame="frame"
:is="part.component"
:key="index"
:param="param"
ref="forms"
v-if="part.component"
/>
</section>
<a-divider :key="`divider-${index}`" v-if="index < parts.length - 1" />
</template>
</a-card>
</a-col>
<a-col flex="240px">
<a-anchor
:get-container="()=> $el.parentNode"
:offset-top="24"
:target-offset="48"
:wrapper-style="{ backgroundColor: 'transparent' }"
@click.prevent
>
<a-anchor-link
:href="`#form-${index}-${id}`"
:key="index"
:title="part.title"
v-for="(part, index) in parts"
/>
</a-anchor>
</a-col>
</a-row>
</container>
</template>
<script>
export default {
props: ['id', 'param', 'frame'],
data() {
return {
parts: [
/**
{
title: '标题',
component: () => import('...'),
}
*/
],
};
},
methods: {
/**
* 循环子组件中的onGetData
*/
onGetData() {
return new Promise(async (resolve, reject) => {
let formData = {};
for (let i = 0; i < this.$refs.forms.length; i++) {
const form = this.$refs.forms[i];
try {
const data = await form.onGetData();
formData = {
...formData,
...data,
};
} catch (e) {
reject(e);
return;
}
}
resolve(formData);
});
},
},
};
</script>

View File

@@ -0,0 +1,114 @@
<template>
<!--
普通编辑窗体
v 1.2
2021-04-30
Lufthafen
-->
<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>
/* 表单内容默认值 */
const defaultForm = {
/* ... */
};
export default {
data() {
return {
/** 表单数据 */
form: {},
/** 验证格式 */
rules: {
/* ... */
},
/** 加载异步数据状态 */
loading: false,
/** 其他成员属性 */
/* ... */
};
},
methods: {
/**
* 必要的方法
* 在打开编辑页时允许填充数据
*/
onFillData(params) {
/** 将默认数据覆盖到form */
this.form = this.$_.cloneDeep({
...defaultForm,
...params.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(params) {
this.loading = true;
/** 可以在这里await获取一些异步数据 */
/* ... */
this.loading = false;
},
/** 当前组件的其他方法 */
/* ... */
},
};
</script>

View File

@@ -0,0 +1,216 @@
<template>
<!--
普通查询表格
v 1.2
2021-04-30
Lufthafen
-->
<container>
<br />
<a-card :bordered="false">
<yo-table
:columns="columns"
:load-data="loadData"
@query="onQuery"
@resetQuery="onResetQuery"
ref="table"
>
<Auth auth="authCode:page" slot="query">
<!-- 此处添加查询表单控件 -->
<!-- ... -->
</Auth>
<Auth auth="authCode:add" slot="operator">
<a-button @click="onOpen('add-form')" icon="plus">新增...</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>
<!-- 新增表单 -->
<yo-modal-form :action="$api[api.add]" :title="'新增' + name" @ok="onReloadData" ref="add-form">
<form-body />
</yo-modal-form>
<!-- 编辑表单 -->
<yo-modal-form :action="$api[api.edit]" :title="'编辑' + name" @ok="onReloadData" ref="edit-form">
<form-body />
</yo-modal-form>
</container>
</template>
<script>
import FormBody from './form';
/* 在此管理整个页面需要的接口名称 */
const api = {
page: 'testPageApi...',
add: 'testAddApi',
edit: 'testEditApi',
delete: 'testDeleteApi...',
/* ... */
};
export default {
components: {
FormBody,
},
data() {
return {
api,
name: '...',
/* 查询条件 */
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[api.page]({
...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.sysDictTypeDropDownAwait({ code: 'code1' }),
this.$api.sysDictTypeDropDownAwait({ 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();
}
},
/**
* 必要方法
* 删除时调用
*/
onDelete(record) {
this.$refs.table.onLoading();
this.$api[api.delete](record)
.then(({ success }) => {
this.onResult(success, '删除成功');
})
.finally(() => {
this.$refs.table.onLoaded();
});
},
},
};
</script>

View File

@@ -0,0 +1,256 @@
<template>
<!--
普通树查询表格
v 1.2
2021-04-30
Lufthafen
-->
<yo-tree-layout
:load-data="loadTreeData"
@select="onSelect"
default-expanded-keys
ref="tree-layout"
>
<container>
<a-card :bordered="false">
<yo-table
:columns="columns"
:load-data="loadData"
@query="onQuery"
@resetQuery="onResetQuery"
ref="table"
>
<Auth auth="authCode:page" slot="query">
<!-- 此处添加查询表单控件 -->
<!-- ... -->
</Auth>
<Auth auth="authCode:add" slot="operator">
<a-button @click="onOpen('add-form')" icon="plus">新增机构</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>
</container>
<!-- 新增表单 -->
<yo-modal-form :action="$api[api.add]" :title="'新增' + name" @ok="onReloadData" ref="add-form">
<form-body />
</yo-modal-form>
<!-- 编辑表单 -->
<yo-modal-form :action="$api[api.edit]" :title="'编辑' + name" @ok="onReloadData" ref="edit-form">
<form-body />
</yo-modal-form>
</yo-tree-layout>
</template>
<script>
/* 需要引用YoTreeLayout组件 */
import YoTreeLayout from '@/components/yoTreeLayout';
import FormBody from './form';
/* 在此管理整个页面需要的接口名称 */
const api = {
tree: 'testTreeApi...',
page: 'testPageApi...',
add: 'testAddApi',
edit: 'testEditApi',
delete: 'testDeleteApi...',
/* ... */
};
export default {
components: {
YoTreeLayout,
FormBody,
},
data() {
return {
api,
name: '...',
/* 查询条件 */
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-layout以示意数据接口
*/
loadTreeData() {
return this.$api[api.tree]().then((res) => {
return res.data;
});
},
/**
* 树形选择界面必要的方法
* 选择树节点事件
*/
onSelect([id]) {
/** 在选择事件中可以对右侧表格添加父节点id的查询条件 */
this.query = {
pid: id,
};
this.onQuery();
},
/**
* 必要的方法
* 传给yo-table以示意数据接口及其参数和返回的数据结构
*/
loadData(params) {
return this.$api[api.page]({
...params,
...this.query,
}).then((res) => {
return res.data;
});
},
/**
* 有查询功能时的必要方法
* 加载数据时初始化分页信息
*/
onQuery() {
this.$refs.table.onReloadData(true);
},
/**
* 必要方法
* 重新列表数据
*/
onResetQuery() {
/* 与普通查询页不同的是,这里的父节点参数不应该在重置后被清空 */
Object.keys(this.query).forEach((p) => {
if (p !== 'pid') {
this.query[p] = undefined;
}
});
this.onQuery();
},
/**
* 必要方法
* 重新列表数据
*/
onReloadData() {
this.$refs.table.onReloadData();
this.$refs['tree-layout'].onReloadData();
},
/**
* 必要方法
* 加载字典数据
* 如果不需要获取相应的字典数据,此方法内容可空
*/
onLoadCodes() {
this.$api
.$queue([
this.$api.sysDictTypeDropDownAwait({ code: 'code1' }),
this.$api.sysDictTypeDropDownAwait({ 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,
pid: this.query.pid,
/* 按需添加其他参数 */
/* ... */
});
},
/**
* 必要方法
* 可以用做一系列操作的公共回调,此方法中会重新加载当前列表
*/
onResult(success, successMessage) {
if (success) {
this.$message.success(successMessage);
this.onReloadData();
}
},
/**
* 必要方法
* 删除时调用
*/
onDelete(record) {
this.$refs.table.onLoading();
this.$api[api.delete](record)
.then(({ success }) => {
this.onResult(success, '删除成功');
})
.finally(() => {
this.$refs.table.onLoaded();
});
},
},
};
</script>

View File

@@ -0,0 +1,9 @@
{
"seed-index.vue": {
"prefix": "seed.index",
"body": [
"<template>",
"</template>"
]
}
}