first commit

This commit is contained in:
ye1023
2026-04-09 15:09:34 +08:00
commit d8e3a63df1
2246 changed files with 352109 additions and 0 deletions
+119
View File
@@ -0,0 +1,119 @@
import { FormSchema } from '/@/components/Form';
export const schemas: FormSchema[] = [
{
field: 'title',
component: 'Input',
label: '标题',
componentProps: {
placeholder: '给目标起个名字',
},
required: true,
},
{
field: 'time',
component: 'RangePicker',
label: '起止日期',
required: true,
},
{
field: 'target',
component: 'InputTextArea',
label: '目标描述',
componentProps: {
placeholder: '请输入你的阶段性工作目标',
rows: 4,
},
required: true,
},
{
field: 'metrics',
component: 'InputTextArea',
label: '衡量标准',
componentProps: {
placeholder: '请输入衡量标准',
rows: 4,
},
required: true,
},
{
field: 'client',
component: 'Input',
label: '客户',
helpMessage: '目标的服务对象',
subLabel: '( 选填 )',
componentProps: {
placeholder: '请描述你服务的客户,内部客户直接 @姓名/工号',
},
},
{
field: 'inviteer',
component: 'Input',
label: '邀评人',
subLabel: '( 选填 )',
componentProps: {
placeholder: '请直接 @姓名/工号,最多可邀请 5 人',
},
},
{
field: 'weights',
component: 'InputNumber',
label: '权重',
subLabel: '( 选填 )',
componentProps: {
formatter: (value: string) => (value ? `${value}%` : ''),
parser: (value: string) => value.replace('%', ''),
placeholder: '请输入',
},
},
{
field: 'disclosure',
component: 'RadioGroup',
label: '目标公开',
itemProps: {
extra: '客户、邀评人默认被分享',
},
componentProps: {
options: [
{
label: '公开',
value: '1',
},
{
label: '部分公开',
value: '2',
},
{
label: '不公开',
value: '3',
},
],
},
},
{
field: 'disclosurer',
component: 'Select',
label: ' ',
show: ({ model }) => {
return model.disclosure === '2';
},
componentProps: {
placeholder: '公开给',
mode: 'multiple',
options: [
{
label: '同事1',
value: '1',
},
{
label: '同事2',
value: '2',
},
{
label: '同事3',
value: '3',
},
],
},
},
];
+64
View File
@@ -0,0 +1,64 @@
<template>
<PageWrapper title="基础表单" contentBackground content=" 表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。" contentClass="p-4">
<BasicForm @register="register" />
</PageWrapper>
</template>
<script lang="ts">
import { BasicForm, useForm } from '/@/components/Form';
import { defineComponent } from 'vue';
import { schemas } from './data';
import { useMessage } from '/@/hooks/web/useMessage';
import { PageWrapper } from '/@/components/Page';
export default defineComponent({
name: 'FormBasicPage',
components: { BasicForm, PageWrapper },
setup() {
const { createMessage } = useMessage();
const [register, { validate, setProps }] = useForm({
labelCol: {
span: 8,
},
wrapperCol: {
span: 10,
},
schemas: schemas,
actionColOptions: {
offset: 8,
span: 12,
},
submitButtonOptions: {
text: '提交',
},
submitFunc: customSubmitFunc,
});
async function customSubmitFunc() {
try {
await validate();
setProps({
submitButtonOptions: {
loading: true,
},
});
setTimeout(() => {
setProps({
submitButtonOptions: {
loading: false,
},
});
createMessage.success('提交成功!');
}, 2000);
} catch (error) {}
}
return { register };
},
});
</script>
<style lang="less" scoped>
.form-wrap {
padding: 24px;
background-color: @component-background;
}
</style>
@@ -0,0 +1,137 @@
<template>
<div>
<BasicTable @register="registerTable" @edit-change="handleEditChange">
<template #action="{ record, column }">
<TableAction :actions="createActions(record, column)" />
</template>
</BasicTable>
<a-button block class="mt-5" type="dashed" @click="handleAdd"> 新增成员 </a-button>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicTable, useTable, TableAction, BasicColumn, ActionItem, EditRecordRow } from '/@/components/Table';
const columns: BasicColumn[] = [
{
title: '成员姓名',
dataIndex: 'name',
editRow: true,
},
{
title: '工号',
dataIndex: 'no',
editRow: true,
},
{
title: '所属部门',
dataIndex: 'dept',
editRow: true,
},
];
const data: any[] = [
{
name: 'John Brown',
no: '00001',
dept: 'New York No. 1 Lake Park',
},
{
name: 'John Brown2',
no: '00002',
dept: 'New York No. 2 Lake Park',
},
{
name: 'John Brown3',
no: '00003',
dept: 'New York No. 3Lake Park',
},
];
export default defineComponent({
components: { BasicTable, TableAction },
setup() {
const [registerTable, { getDataSource }] = useTable({
columns: columns,
showIndexColumn: false,
dataSource: data,
actionColumn: {
width: 160,
title: '操作',
dataIndex: 'action',
slots: { customRender: 'action' },
},
pagination: false,
});
function handleEdit(record: EditRecordRow) {
record.onEdit?.(true);
}
function handleCancel(record: EditRecordRow) {
record.onEdit?.(false);
if (record.isNew) {
const data = getDataSource();
const index = data.findIndex((item) => item.key === record.key);
data.splice(index, 1);
}
}
function handleSave(record: EditRecordRow) {
record.onEdit?.(false, true);
}
function handleEditChange(data: Recordable) {
console.log(data);
}
function handleAdd() {
const data = getDataSource();
const addRow: EditRecordRow = {
name: '',
no: '',
dept: '',
editable: true,
isNew: true,
key: `${Date.now()}`,
};
data.push(addRow);
}
function createActions(record: EditRecordRow, column: BasicColumn): ActionItem[] {
if (!record.editable) {
return [
{
label: '编辑',
onClick: handleEdit.bind(null, record),
},
{
label: '删除',
},
];
}
return [
{
label: '保存',
onClick: handleSave.bind(null, record, column),
},
{
label: '取消',
popConfirm: {
title: '是否取消编辑',
confirm: handleCancel.bind(null, record, column),
},
},
];
}
return {
registerTable,
handleEdit,
createActions,
handleAdd,
getDataSource,
handleEditChange,
};
},
});
</script>
+149
View File
@@ -0,0 +1,149 @@
import { FormSchema } from '/@/components/Form';
const basicOptions: LabelValueOptions = [
{
label: '付晓晓',
value: '1',
},
{
label: '周毛毛',
value: '2',
},
];
const storeTypeOptions: LabelValueOptions = [
{
label: '私密',
value: '1',
},
{
label: '公开',
value: '2',
},
];
export const schemas: FormSchema[] = [
{
field: 'f1',
component: 'Input',
label: '仓库名',
required: true,
},
{
field: 'f2',
component: 'Input',
label: '仓库域名',
required: true,
componentProps: {
addonBefore: 'http://',
addonAfter: 'com',
},
colProps: {
offset: 2,
},
},
{
field: 'f3',
component: 'Select',
label: '仓库管理员',
componentProps: {
options: basicOptions,
},
required: true,
colProps: {
offset: 2,
},
},
{
field: 'f4',
component: 'Select',
label: '审批人',
componentProps: {
options: basicOptions,
},
required: true,
},
{
field: 'f5',
component: 'RangePicker',
label: '生效日期',
required: true,
colProps: {
offset: 2,
},
},
{
field: 'f6',
component: 'Select',
label: '仓库类型',
componentProps: {
options: storeTypeOptions,
},
required: true,
colProps: {
offset: 2,
},
},
];
export const taskSchemas: FormSchema[] = [
{
field: 't1',
component: 'Input',
label: '任务名',
required: true,
},
{
field: 't2',
component: 'Input',
label: '任务描述',
required: true,
colProps: {
offset: 2,
},
},
{
field: 't3',
component: 'Select',
label: '执行人',
componentProps: {
options: basicOptions,
},
required: true,
colProps: {
offset: 2,
},
},
{
field: 't4',
component: 'Select',
label: '责任人',
componentProps: {
options: basicOptions,
},
required: true,
},
{
field: 't5',
component: 'TimePicker',
label: '生效日期',
required: true,
componentProps: {
style: { width: '100%' },
},
colProps: {
offset: 2,
},
},
{
field: 't6',
component: 'Select',
label: '任务类型',
componentProps: {
options: storeTypeOptions,
},
required: true,
colProps: {
offset: 2,
},
},
];
+77
View File
@@ -0,0 +1,77 @@
<template>
<PageWrapper class="high-form" title="高级表单" content=" 高级表单常见于一次性输入和提交大批量数据的场景。">
<a-card title="仓库管理" :bordered="false">
<BasicForm @register="register" />
</a-card>
<a-card title="任务管理" :bordered="false" class="!mt-5">
<BasicForm @register="registerTask" />
</a-card>
<a-card title="成员管理" :bordered="false">
<PersonTable ref="tableRef" />
</a-card>
<template #rightFooter>
<a-button type="primary" @click="submitAll"> 提交 </a-button>
</template>
</PageWrapper>
</template>
<script lang="ts">
import { BasicForm, useForm } from '/@/components/Form';
import { defineComponent, ref } from 'vue';
import PersonTable from './PersonTable.vue';
import { PageWrapper } from '/@/components/Page';
import { schemas, taskSchemas } from './data';
import { Card } from 'ant-design-vue';
export default defineComponent({
name: 'FormHightPage',
components: { BasicForm, PersonTable, PageWrapper, [Card.name]: Card },
setup() {
const tableRef = ref<{ getDataSource: () => any } | null>(null);
const [register, { validate }] = useForm({
baseColProps: {
span: 6,
},
labelWidth: 200,
layout: 'vertical',
schemas: schemas,
showActionButtonGroup: false,
});
const [registerTask, { validate: validateTaskForm }] = useForm({
baseColProps: {
span: 6,
},
labelWidth: 200,
layout: 'vertical',
schemas: taskSchemas,
showActionButtonGroup: false,
});
async function submitAll() {
try {
if (tableRef.value) {
console.log('table data:', tableRef.value.getDataSource());
}
const [values, taskValues] = await Promise.all([validate(), validateTaskForm()]);
console.log('form data:', values, taskValues);
} catch (error) {}
}
return { register, registerTask, submitAll, tableRef };
},
});
</script>
<style lang="less" scoped>
.high-form {
padding-bottom: 48px;
}
/** update-begin-author:taoyan date:2022-5-16 for:/issues/63 下拉框z-index问题 */
:deep(.ant-select-dropdown) {
z-index: 98 !important;
}
/** update-end-author:taoyan date:2022-5-16 for:/issues/63 下拉框z-index问题 */
</style>
+103
View File
@@ -0,0 +1,103 @@
<template>
<div class="step1">
<div class="step1-form">
<BasicForm @register="register">
<template #fac="{ model, field }">
<a-input-group compact>
<a-select v-model:value="model['pay']" class="pay-select">
<a-select-option value="zfb"> 支付宝 </a-select-option>
<a-select-option value="yl"> 银联 </a-select-option>
</a-select>
<a-input class="pay-input" v-model:value="model[field]" />
</a-input-group>
</template>
</BasicForm>
</div>
<a-divider />
<h3>说明</h3>
<h4>转账到支付宝账户</h4>
<p>
如果需要这里可以放一些关于产品的常见问题说明如果需要这里可以放一些关于产品的常见问题说明如果需要这里可以放一些关于产品的常见问题说明
</p>
<h4>转账到银行卡</h4>
<p>
如果需要这里可以放一些关于产品的常见问题说明如果需要这里可以放一些关于产品的常见问题说明如果需要这里可以放一些关于产品的常见问题说明
</p>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicForm, useForm } from '/@/components/Form';
import { step1Schemas } from './data';
import { Select, Input, Divider } from 'ant-design-vue';
export default defineComponent({
components: {
BasicForm,
[Select.name]: Select,
ASelectOption: Select.Option,
[Input.name]: Input,
[Input.Group.name]: Input.Group,
[Divider.name]: Divider,
},
emits: ['next'],
setup(_, { emit }) {
const [register, { validate }] = useForm({
labelWidth: 200,
schemas: step1Schemas,
actionColOptions: {
span: 14,
},
showResetButton: false,
submitButtonOptions: {
text: '下一步',
},
submitFunc: customSubmitFunc,
});
async function customSubmitFunc() {
try {
const values = await validate();
emit('next', values);
} catch (error) {}
}
return { register };
},
});
</script>
<style lang="less" scoped>
.step1 {
&-form {
width: 550px;
margin: 0 auto;
}
h3 {
margin: 0 0 12px;
font-size: 16px;
line-height: 32px;
color: @text-color;
}
h4 {
margin: 0 0 4px;
font-size: 14px;
line-height: 22px;
color: @text-color;
}
p {
color: @text-color;
}
}
.pay-select {
width: 20%;
}
.pay-input {
width: 70%;
}
</style>
+78
View File
@@ -0,0 +1,78 @@
<template>
<div class="step2">
<a-alert message="确认转账后,资金将直接打入对方账户,无法退回。" show-icon />
<a-descriptions :column="1" class="mt-5">
<a-descriptions-item label="付款账户"> ant-design@alipay.com </a-descriptions-item>
<a-descriptions-item label="收款账户"> test@example.com </a-descriptions-item>
<a-descriptions-item label="收款人姓名"> Jeecg </a-descriptions-item>
<a-descriptions-item label="转账金额"> 500 </a-descriptions-item>
</a-descriptions>
<a-divider />
<BasicForm @register="register" />
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { BasicForm, useForm } from '/@/components/Form';
import { step2Schemas } from './data';
import { Alert, Divider, Descriptions } from 'ant-design-vue';
export default defineComponent({
components: {
BasicForm,
[Alert.name]: Alert,
[Divider.name]: Divider,
[Descriptions.name]: Descriptions,
[Descriptions.Item.name]: Descriptions.Item,
},
emits: ['next', 'prev'],
setup(_, { emit }) {
const [register, { validate, setProps }] = useForm({
labelWidth: 120,
schemas: step2Schemas,
actionColOptions: {
span: 14,
},
resetButtonOptions: {
text: '上一步',
},
submitButtonOptions: {
text: '提交',
},
resetFunc: customResetFunc,
submitFunc: customSubmitFunc,
});
async function customResetFunc() {
emit('prev');
}
async function customSubmitFunc() {
try {
const values = await validate();
setProps({
submitButtonOptions: {
loading: true,
},
});
setTimeout(() => {
setProps({
submitButtonOptions: {
loading: false,
},
});
emit('next', values);
}, 1500);
} catch (error) {}
}
return { register };
},
});
</script>
<style lang="less" scoped>
.step2 {
width: 550px;
margin: 0 auto;
}
</style>
+49
View File
@@ -0,0 +1,49 @@
<template>
<div class="step3">
<a-result status="success" title="操作成功" sub-title="预计两小时内到账">
<template #extra>
<a-button type="primary" @click="redo"> 再转一笔 </a-button>
<a-button> 查看账单 </a-button>
</template>
</a-result>
<div class="desc-wrap">
<a-descriptions :column="1" class="mt-5">
<a-descriptions-item label="付款账户"> ant-design@alipay.com </a-descriptions-item>
<a-descriptions-item label="收款账户"> test@example.com </a-descriptions-item>
<a-descriptions-item label="收款人姓名"> Jeecg </a-descriptions-item>
<a-descriptions-item label="转账金额"> 500 </a-descriptions-item>
</a-descriptions>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { Result, Descriptions } from 'ant-design-vue';
export default defineComponent({
components: {
[Result.name]: Result,
[Descriptions.name]: Descriptions,
[Descriptions.Item.name]: Descriptions.Item,
},
emits: ['redo'],
setup(_, { emit }) {
return {
redo: () => {
emit('redo');
},
};
},
});
</script>
<style lang="less" scoped>
.step3 {
width: 600px;
margin: 0 auto;
}
.desc-wrap {
padding: 24px 40px;
margin-top: 24px;
background-color: @background-color-light;
}
</style>
+63
View File
@@ -0,0 +1,63 @@
import { FormSchema } from '/@/components/Form';
export const step1Schemas: FormSchema[] = [
{
field: 'account',
component: 'Select',
label: '付款账户',
required: true,
defaultValue: '1',
componentProps: {
options: [
{
label: 'anncwb@126.com',
value: '1',
},
],
},
},
{
field: 'fac',
component: 'InputGroup',
label: '收款账户',
required: true,
defaultValue: 'test@example.com',
slot: 'fac',
},
{
field: 'pay',
component: 'Input',
label: '',
defaultValue: 'zfb',
show: false,
},
{
field: 'payeeName',
component: 'Input',
label: '收款人姓名',
defaultValue: 'Jeecg',
required: true,
},
{
field: 'money',
component: 'Input',
label: '转账金额',
defaultValue: '500',
required: true,
renderComponentContent: () => {
return {
prefix: () => '¥',
};
},
},
];
export const step2Schemas: FormSchema[] = [
{
field: 'pwd',
component: 'InputPassword',
label: '支付密码',
required: true,
defaultValue: '123456',
},
];
+86
View File
@@ -0,0 +1,86 @@
<template>
<PageWrapper title="分步表单" contentBackground content=" 将一个冗长或用户不熟悉的表单任务分成多个步骤,指导用户完成。" contentClass="p-4">
<div class="step-form-form">
<a-steps :current="current">
<a-step title="填写转账信息" />
<a-step title="确认转账信息" />
<a-step title="完成" />
</a-steps>
</div>
<div class="mt-5">
<Step1 @next="handleStep1Next" v-show="current === 0" />
<Step2 @prev="handleStepPrev" @next="handleStep2Next" v-show="current === 1" v-if="initSetp2" />
<Step3 v-show="current === 2" @redo="handleRedo" v-if="initSetp3" />
</div>
</PageWrapper>
</template>
<script lang="ts">
import { defineComponent, ref, reactive, toRefs } from 'vue';
import Step1 from './Step1.vue';
import Step2 from './Step2.vue';
import Step3 from './Step3.vue';
import { PageWrapper } from '/@/components/Page';
import { Steps } from 'ant-design-vue';
export default defineComponent({
name: 'FormStepPage',
components: {
Step1,
Step2,
Step3,
PageWrapper,
[Steps.name]: Steps,
[Steps.Step.name]: Steps.Step,
},
setup() {
const current = ref(0);
const state = reactive({
initSetp2: false,
initSetp3: false,
});
function handleStep1Next(step1Values: any) {
current.value++;
state.initSetp2 = true;
console.log(step1Values);
}
function handleStepPrev() {
current.value--;
}
function handleStep2Next(step2Values: any) {
current.value++;
state.initSetp3 = true;
console.log(step2Values);
}
function handleRedo() {
current.value = 0;
state.initSetp2 = false;
state.initSetp3 = false;
}
return {
current,
handleStep1Next,
handleStep2Next,
handleRedo,
handleStepPrev,
...toRefs(state),
};
},
});
</script>
<style lang="less" scoped>
.step-form-content {
padding: 24px;
background-color: @component-background;
}
.step-form-form {
width: 750px;
margin: 0 auto;
}
</style>