Commit be864cde3640580beba69a3276bb7daed4c313a0

Authored by sqy
2 parents 81eba1ad 07d508e1

'解决冲突'

... ... @@ -7,26 +7,49 @@
7 7 width="500px"
8 8 @ok="handleSubmit"
9 9 >
10   - <BasicForm @register="registerForm" />
  10 + <BasicForm @register="registerForm">
  11 + <template #iconSelect>
  12 + <Upload
  13 + name="avatar"
  14 + list-type="picture-card"
  15 + class="avatar-uploader"
  16 + :show-upload-list="false"
  17 + :customRequest="customUpload"
  18 + :before-upload="beforeUpload"
  19 + >
  20 + <img v-if="devicePic" :src="devicePic" alt="avatar" />
  21 + <div v-else>
  22 + <loading-outlined v-if="loading" />
  23 + <plus-outlined v-else />
  24 + <div class="ant-upload-text">图片上传</div>
  25 + </div>
  26 + </Upload>
  27 + </template>
  28 + </BasicForm>
11 29 </BasicDrawer>
12 30 </template>
13 31 <script lang="ts">
14 32 import { defineComponent, ref, computed, unref } from 'vue';
15 33 import { BasicForm, useForm } from '/@/components/Form';
16   - import { formSchema } from './config.data';
  34 + import { formSchema } from './device.data';
17 35 import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  36 +
18 37 import { saveOrEditMessageConfig } from '/@/api/message/config';
19 38 import { useMessage } from '/@/hooks/web/useMessage';
  39 + import { upload } from '/@/api/oss/ossFileUploader';
  40 + import { message, Upload } from 'ant-design-vue';
  41 + import { FileItem } from '/@/components/Upload/src/typing';
20 42
21 43 export default defineComponent({
22   - name: 'ConfigDrawer',
23   - components: { BasicDrawer, BasicForm },
  44 + name: 'DeviceDrawer',
  45 + components: { BasicDrawer, BasicForm, Upload },
24 46 emits: ['success', 'register'],
25 47 setup(_, { emit }) {
26 48 const isUpdate = ref(true);
27 49
  50 + const devicePic = ref('');
28 51 const [registerForm, { validate, setFieldsValue, resetFields }] = useForm({
29   - labelWidth: 120,
  52 + labelWidth: 80,
30 53 schemas: formSchema,
31 54 showActionButtonGroup: false,
32 55 });
... ... @@ -46,7 +69,7 @@
46 69 }
47 70 });
48 71
49   - const getTitle = computed(() => (!unref(isUpdate) ? '新增消息配置' : '编辑消息配置'));
  72 + const getTitle = computed(() => (!unref(isUpdate) ? '新增设备' : '编辑设备'));
50 73
51 74 async function handleSubmit() {
52 75 try {
... ... @@ -78,13 +101,43 @@
78 101 setDrawerProps({ confirmLoading: false });
79 102 }
80 103 }
  104 + async function customUpload({ file }) {
  105 + if (beforeUpload(file)) {
  106 + const formData = new FormData();
  107 + formData.append('file', file);
  108 + const response = await upload(formData);
  109 + if (response.fileStaticUri) {
  110 + devicePic.value = response.fileStaticUri;
  111 + }
  112 + }
  113 + }
81 114
  115 + const beforeUpload = (file: FileItem) => {
  116 + const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
  117 + if (!isJpgOrPng) {
  118 + message.error('只能上传图片文件!');
  119 + }
  120 + const isLt2M = (file.size as number) / 1024 / 1024 < 2;
  121 + if (!isLt2M) {
  122 + message.error('图片大小不能超过2MB!');
  123 + }
  124 + return isJpgOrPng && isLt2M;
  125 + };
82 126 return {
83 127 registerDrawer,
84 128 registerForm,
85 129 getTitle,
86 130 handleSubmit,
  131 + beforeUpload,
  132 + customUpload,
  133 + devicePic,
87 134 };
88 135 },
89 136 });
90 137 </script>
  138 +<style>
  139 + .ant-upload-select-picture-card i {
  140 + font-size: 32px;
  141 + color: #999;
  142 + }
  143 +</style>
... ...
  1 +<template>
  2 + <BasicModal
  3 + v-bind="$attrs"
  4 + width="55rem"
  5 + @register="register"
  6 + :title=getTitle
  7 + @visible-change="handleVisibleChange"
  8 + >
  9 + <div class="step-form-form">
  10 + <a-steps :current="current">
  11 + <a-step title="填写设备信息" />
  12 + <a-step title="确认转账信息" />
  13 + <a-step title="完成" />
  14 + </a-steps>
  15 + </div>
  16 + <div class="mt-5">
  17 + <DeviceStep1 @next="handleStep1Next" v-show="current === 0" />
  18 + <DeviceStep2
  19 + @prev="handleStepPrev"
  20 + @next="handleStep2Next"
  21 + v-show="current === 1"
  22 + v-if="initStep2"
  23 + />
  24 + <DeviceStep3 v-show="current === 2" @redo="handleRedo" v-if="initStep3" />
  25 + </div>
  26 + </BasicModal>
  27 +</template>
  28 +<script lang="ts">
  29 +import {defineComponent, ref, nextTick, computed, unref, reactive, toRefs} from 'vue';
  30 + import { BasicModal, useModalInner } from '/@/components/Modal';
  31 + import { BasicForm, FormSchema, useForm } from '/@/components/Form';
  32 + import DeviceStep1 from "/@/views/device/step/DeviceStep1.vue";
  33 + import DeviceStep2 from "/@/views/device/step/DeviceStep2.vue";
  34 + import DeviceStep3 from "/@/views/device/step/DeviceStep3.vue";
  35 + import { Steps } from "ant-design-vue";
  36 + const schemas: FormSchema[] = [
  37 + {
  38 + field: 'field1',
  39 + component: 'Input',
  40 + label: '字段1',
  41 + colProps: {
  42 + span: 24,
  43 + },
  44 + defaultValue: '111',
  45 + },
  46 + {
  47 + field: 'field2',
  48 + component: 'Input',
  49 + label: '字段2',
  50 + colProps: {
  51 + span: 24,
  52 + },
  53 + },
  54 + ];
  55 + export default defineComponent({
  56 + name:'DeviceModal',
  57 + components: { BasicModal, BasicForm, DeviceStep1, DeviceStep2, DeviceStep3,
  58 + [Steps.name]: Steps,
  59 + [Steps.Step.name]: Steps.Step, },
  60 + props: {
  61 + userData: { type: Object },
  62 + },
  63 + setup(props) {
  64 + const state = reactive({
  65 + initStep2: false,
  66 + initStep3: false,
  67 + });
  68 + const current = ref(0);
  69 + const isUpdate = ref(true);
  70 + const modelRef = ref({});
  71 + const getTitle = computed(() => (!unref(isUpdate) ? '新增设备' : '编辑设备'));
  72 + const [
  73 + registerForm,
  74 + {
  75 + // setFieldsValue,
  76 + // setProps
  77 + },
  78 + ] = useForm({
  79 + labelWidth: 120,
  80 + schemas,
  81 + showActionButtonGroup: false,
  82 + actionColOptions: {
  83 + span: 24,
  84 + },
  85 + });
  86 +
  87 + const [register] = useModalInner((data) => {
  88 + isUpdate.value = !!data?.isUpdate;
  89 + data && onDataReceive(data);
  90 + });
  91 +
  92 + function handleStepPrev() {
  93 + current.value--;
  94 + }
  95 + function handleStep1Next(step1Values: any) {
  96 + current.value++;
  97 + state.initStep2 = true;
  98 + console.log(step1Values);
  99 + }
  100 + function handleStep2Next(step2Values: any) {
  101 + current.value++;
  102 + state.initStep3 = true;
  103 + console.log(step2Values);
  104 + }
  105 + function handleRedo() {
  106 + current.value = 0;
  107 + state.initSetp2 = false;
  108 + state.initSetp3 = false;
  109 + }
  110 +
  111 +
  112 + function onDataReceive(data) {
  113 + console.log('Data Received', data);
  114 + // 方式1;
  115 + // setFieldsValue({
  116 + // field2: data.data,
  117 + // field1: data.info,
  118 + // });
  119 +
  120 + // // 方式2
  121 + modelRef.value = { field2: data.data, field1: data.info };
  122 +
  123 + // setProps({
  124 + // model:{ field2: data.data, field1: data.info }
  125 + // })
  126 + }
  127 +
  128 + function handleVisibleChange(v) {
  129 + v && props.userData && nextTick(() => onDataReceive(props.userData));
  130 + }
  131 +
  132 + return { register, schemas, registerForm, model: modelRef, getTitle,handleVisibleChange,
  133 + current, ...toRefs(state), handleStepPrev, handleStep1Next, handleStep2Next, handleRedo};
  134 + },
  135 + });
  136 +</script>
... ...
  1 +import { BasicColumn } from '/@/components/Table';
  2 +import { FormSchema } from '/@/components/Table';
  3 +import {findDictItemByCode} from "/@/api/system/dict";
  4 +import {DeviceTypeEnum,DeviceState} from "/@/api/device/model/deviceModel";
  5 +export const columns: BasicColumn[] = [
  6 + {
  7 + title: '设备名称',
  8 + dataIndex: 'name',
  9 + width: 120,
  10 + },
  11 + {
  12 + title: '设备类型',
  13 + dataIndex: 'deviceType',
  14 + width: 100,
  15 + slots:{customRender:'deviceType'},
  16 + },
  17 + {
  18 + title: '设备配置',
  19 + dataIndex: 'deviceProfile.name',
  20 + width: 160,
  21 + slots: { customRender: 'deviceProfile' },
  22 + },
  23 +
  24 + {
  25 + title: '所属组织',
  26 + dataIndex: 'organizationId',
  27 + slots: { customRender: 'organizationId' },
  28 + },
  29 + {
  30 + title: '标签',
  31 + dataIndex: 'label',
  32 + width: 180
  33 + },
  34 + {
  35 + title: '状态',
  36 + dataIndex: 'deviceState',
  37 + width: 120,
  38 + slots: { customRender: 'deviceState' },
  39 + },
  40 +
  41 + {
  42 + title: '最后连接时间',
  43 + dataIndex: 'lastConnectTime',
  44 + width: 180,
  45 + },
  46 +];
  47 +
  48 +export const searchFormSchema: FormSchema[] = [
  49 + {
  50 + field: 'deviceType',
  51 + label: '设备类型',
  52 + component: 'Select',
  53 + componentProps: {
  54 + options: [
  55 + { label: '网关设备', value: DeviceTypeEnum.GATEWAY },
  56 + { label: '直连设备', value: DeviceTypeEnum.DIRECT_CONNECTION },
  57 + { label: '网关子设备', value: DeviceTypeEnum.SENSOR },
  58 + ],
  59 + },
  60 + colProps: { span: 4 },
  61 + },
  62 + {
  63 + field: 'deviceState',
  64 + label: '设备状态',
  65 + component: 'Select',
  66 + componentProps: {
  67 + options: [
  68 + { label: '待激活', value: DeviceState.INACTIVE },
  69 + { label: '在线', value: DeviceState.ONLINE },
  70 + { label: '离线', value: DeviceState.OFFLINE },
  71 + ],
  72 + },
  73 + colProps: { span: 4 },
  74 + },
  75 + {
  76 + field: 'name',
  77 + label: '设备名称',
  78 + component: 'Input',
  79 + colProps: { span: 8 },
  80 + },
  81 +];
  82 +
  83 +
  84 +export const formSchema: FormSchema[] = [
  85 + {
  86 + field: 'icon',
  87 + label: '设备图片: ',
  88 + slot: 'iconSelect',
  89 + component: 'Input',
  90 + },
  91 + {
  92 + field: 'name',
  93 + label: '设备名称',
  94 + required: true,
  95 + component:'Input',
  96 + componentProps:{
  97 + maxLength:30
  98 + }
  99 + },
  100 + {
  101 + field: 'deviceType',
  102 + label: '设备类型',
  103 + required: true,
  104 + component: 'ApiSelect',
  105 + componentProps: {
  106 + api:findDictItemByCode,
  107 + params:{
  108 + dictCode:"device_type"
  109 + },
  110 + labelField:'itemText',
  111 + valueField:'itemValue',
  112 + },
  113 + },
  114 + {
  115 + field: 'label',
  116 + label: '设备标签',
  117 + component:'Input',
  118 + componentProps:{
  119 + maxLength:255
  120 + }
  121 + },
  122 + {
  123 + label: '备注',
  124 + field: 'remark',
  125 + component: 'InputTextArea',
  126 + }
  127 +];
... ...
1 1 <template>
2   - <div>
3   - <BasicTable @register="registerTable">
  2 + <PageWrapper dense contentFullHeight fixedHeight contentClass="flex">
  3 + <OrganizationIdTree class="w-1/6 xl:w-1/5" @select="handleSelect" />
  4 + <BasicTable @register="registerTable" class="w-5/6 xl:w-4/5">
4 5 <template #toolbar>
5 6 <a-button type="primary" @click="handleCreate"> 新增设备 </a-button>
6 7 </template>
7   - <template #config="{ record }">
8   - <a-button type="link" class="ml-2" @click="showData(record)"> 查看配置 </a-button>
9   - </template>
  8 +
10 9 <template #deviceProfile="{ record }">
11 10 <a-button type="link" class="ml-2" @click="goDeviceProfile">
12 11 {{ record.deviceProfile.name }}
13 12 </a-button>
14 13 </template>
  14 + <template #organizationId="{ record }">
  15 + {{ record.organizationDTO.name }}
  16 + </template>
15 17 <template #deviceType="{ record }">
16 18 <Tag color="success" class="ml-2">
17 19 {{
... ... @@ -65,29 +67,45 @@
65 67 </template>
66 68 </BasicTable>
67 69 <ConfigDrawer @register="registerDrawer" @success="handleSuccess" />
68   - </div>
  70 + <DeviceModal @register="registerModal" @success="handleSuccess"></DeviceModal>
  71 + </PageWrapper>
69 72 </template>
70 73 <script lang="ts">
71   - import { defineComponent, h } from 'vue';
  74 + import { defineComponent, reactive } from 'vue';
72 75 import { DeviceState, DeviceTypeEnum } from '/@/api/device/model/deviceModel';
73 76 import { BasicTable, useTable, TableAction } from '/@/components/Table';
74 77 import { useDrawer } from '/@/components/Drawer';
75 78 import ConfigDrawer from './DeviceDrawer.vue';
76   - import { columns, searchFormSchema } from './config.data';
77   - import { Modal, Tag } from 'ant-design-vue';
78   - import { JsonPreview } from '/@/components/CodeEditor';
  79 + import { columns, searchFormSchema } from './device.data';
  80 + import { Tag } from 'ant-design-vue';
  81 + import { CodeEditor } from '/@/components/CodeEditor';
79 82 import { useMessage } from '/@/hooks/web/useMessage';
80 83 import { deleteDevice, devicePage } from '/@/api/device/deviceManager';
81 84 import { PageEnum } from '/@/enums/pageEnum';
82 85 import { useGo } from '/@/hooks/web/usePage';
  86 + import { PageWrapper } from '/@/components/Page';
  87 + import OrganizationIdTree from '/@/views/common/OrganizationIdTree.vue';
  88 + import { useModal } from '/@/components/Modal';
  89 + import DeviceModal from '/@/views/device/DeviceModal.vue';
83 90
84 91 export default defineComponent({
85 92 name: 'DeviceManagement',
86   - components: { BasicTable, ConfigDrawer, TableAction, Tag },
  93 + components: {
  94 + BasicTable,
  95 + ConfigDrawer,
  96 + PageWrapper,
  97 + TableAction,
  98 + OrganizationIdTree,
  99 + CodeEditor,
  100 + Tag,
  101 + DeviceModal,
  102 + },
87 103 setup() {
88   - const go = useGo();
89   - const { createMessage } = useMessage();
90 104 const [registerDrawer, { openDrawer }] = useDrawer();
  105 + const { createMessage } = useMessage();
  106 + const go = useGo();
  107 + const searchInfo = reactive<Recordable>({});
  108 + const [registerModal, { openModal }] = useModal();
91 109 const [registerTable, { reload }] = useTable({
92 110 title: '设备列表',
93 111 api: devicePage,
... ... @@ -100,6 +118,7 @@
100 118 showTableSetting: true,
101 119 bordered: true,
102 120 showIndexColumn: false,
  121 + searchInfo: searchInfo,
103 122 actionColumn: {
104 123 width: 180,
105 124 title: '操作',
... ... @@ -108,20 +127,23 @@
108 127 fixed: undefined,
109 128 },
110 129 });
111   - // 新增
  130 +
112 131 function handleCreate() {
113   - openDrawer(true, {
  132 + // openDrawer(true, {
  133 + // isUpdate: false,
  134 + // });
  135 + openModal(true, {
114 136 isUpdate: false,
115 137 });
116 138 }
117   - // 更新
  139 +
118 140 function handleEdit(record: Recordable) {
119 141 openDrawer(true, {
120 142 record,
121 143 isUpdate: true,
122 144 });
123 145 }
124   - // 删除
  146 +
125 147 function handleDelete(record: Recordable) {
126 148 let ids = [record.id];
127 149 deleteDevice(ids).then(() => {
... ... @@ -129,17 +151,13 @@
129 151 handleSuccess();
130 152 });
131 153 }
132   - // 刷新
  154 +
133 155 function handleSuccess() {
134 156 reload();
135 157 }
136   - // 查看某一个设备具体信息
137   - function showData(record: Recordable) {
138   - Modal.info({
139   - title: '当前配置',
140   - width: 480,
141   - content: h(JsonPreview, { data: JSON.parse(JSON.stringify(record.deviceInfo)) }),
142   - });
  158 + function handleSelect(organization) {
  159 + searchInfo.organizationId = organization;
  160 + handleSuccess();
143 161 }
144 162 function goDeviceProfile() {
145 163 go(PageEnum.DEVICE_PROFILE);
... ... @@ -147,7 +165,6 @@
147 165 return {
148 166 registerTable,
149 167 registerDrawer,
150   - showData,
151 168 handleCreate,
152 169 handleEdit,
153 170 handleDelete,
... ... @@ -155,6 +172,9 @@
155 172 goDeviceProfile,
156 173 DeviceTypeEnum,
157 174 DeviceState,
  175 + handleSelect,
  176 + searchInfo,
  177 + registerModal,
158 178 };
159 179 },
160 180 });
... ...
  1 +<template>
  2 + <div class="step1">
  3 + <div class="step1-form">
  4 + <BasicForm @register="register">
  5 + <template #iconSelect>
  6 + <Upload
  7 + name="avatar"
  8 + list-type="picture-card"
  9 + class="avatar-uploader"
  10 + :show-upload-list="false"
  11 + :customRequest="customUpload"
  12 + :before-upload="beforeUpload"
  13 + >
  14 + <img v-if="devicePic" :src="devicePic" alt="avatar"/>
  15 + <div v-else>
  16 + <loading-outlined v-if="loading"></loading-outlined>
  17 + <plus-outlined v-else></plus-outlined>
  18 + <div class="ant-upload-text">图片上传</div>
  19 + </div>
  20 + </Upload>
  21 + </template>
  22 + </BasicForm>
  23 + </div>
  24 + </div>
  25 +</template>
  26 +<script lang="ts">
  27 +import {defineComponent, ref} from 'vue';
  28 + import { BasicForm, useForm } from '/@/components/Form';
  29 + import { step1Schemas } from './data';
  30 + import {Select, Input, Divider, Upload, message} from 'ant-design-vue';
  31 + import {upload} from "/@/api/oss/ossFileUploader";
  32 + import {FileItem} from "/@/components/Upload/src/typing";
  33 + export default defineComponent({
  34 + components: {
  35 + BasicForm,
  36 + [Select.name]: Select,
  37 + ASelectOption: Select.Option,
  38 + [Input.name]: Input,
  39 + [Input.Group.name]: Input.Group,
  40 + [Divider.name]: Divider,
  41 + Upload
  42 + },
  43 + emits: ['next'],
  44 + setup(_, { emit }) {
  45 + const devicePic = ref("");
  46 + const [register, { validate }] = useForm({
  47 + labelWidth: 100,
  48 + schemas: step1Schemas,
  49 + actionColOptions: {
  50 + span: 14,
  51 + },
  52 + showResetButton: false,
  53 + submitButtonOptions: {
  54 + text: '下一步',
  55 + },
  56 + submitFunc: customSubmitFunc,
  57 + });
  58 +
  59 + async function customSubmitFunc() {
  60 + try {
  61 + const values = await validate();
  62 + emit('next', values);
  63 + } catch (error) {}
  64 + }
  65 + async function customUpload({file}) {
  66 + if (beforeUpload(file)) {
  67 + const formData = new FormData()
  68 + formData.append('file', file)
  69 + const response = await upload(formData);
  70 + if (response.fileStaticUri) {
  71 + devicePic.value = response.fileStaticUri;
  72 + }
  73 + }
  74 + }
  75 +
  76 + const beforeUpload = (file: FileItem) => {
  77 + const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
  78 + if (!isJpgOrPng) {
  79 + message.error('只能上传图片文件!');
  80 + }
  81 + const isLt2M = file.size as number / 1024 / 1024 < 2;
  82 + if (!isLt2M) {
  83 + message.error('图片大小不能超过2MB!');
  84 + }
  85 + return isJpgOrPng && isLt2M;
  86 + };
  87 +
  88 + return { register, beforeUpload, customUpload, devicePic };
  89 + },
  90 + });
  91 +</script>
  92 +<style lang="less" scoped>
  93 + .step1 {
  94 + &-form {
  95 + width: 450px;
  96 + margin: 0 auto;
  97 + }
  98 +
  99 + h3 {
  100 + margin: 0 0 12px;
  101 + font-size: 16px;
  102 + line-height: 32px;
  103 + color: @text-color;
  104 + }
  105 +
  106 + h4 {
  107 + margin: 0 0 4px;
  108 + font-size: 14px;
  109 + line-height: 22px;
  110 + color: @text-color;
  111 + }
  112 +
  113 + p {
  114 + color: @text-color;
  115 + }
  116 + }
  117 +
  118 + .pay-select {
  119 + width: 20%;
  120 + }
  121 +
  122 + .pay-input {
  123 + width: 70%;
  124 + }
  125 +</style>
... ...
  1 +<template>
  2 + <div class="step2">
  3 + <a-alert message="确认转账后,资金将直接打入对方账户,无法退回。" show-icon />
  4 + <a-descriptions :column="1" class="mt-5">
  5 + <a-descriptions-item label="付款账户"> ant-design@alipay.com </a-descriptions-item>
  6 + <a-descriptions-item label="收款账户"> test@example.com </a-descriptions-item>
  7 + <a-descriptions-item label="收款人姓名"> Vben </a-descriptions-item>
  8 + <a-descriptions-item label="转账金额"> 500元 </a-descriptions-item>
  9 + </a-descriptions>
  10 + <a-divider />
  11 + <BasicForm @register="register" />
  12 + </div>
  13 +</template>
  14 +<script lang="ts">
  15 + import { defineComponent } from 'vue';
  16 + import { BasicForm, useForm } from '/@/components/Form';
  17 + import { step2Schemas } from './data';
  18 + import { Alert, Divider, Descriptions } from 'ant-design-vue';
  19 +
  20 + export default defineComponent({
  21 + components: {
  22 + BasicForm,
  23 + [Alert.name]: Alert,
  24 + [Divider.name]: Divider,
  25 + [Descriptions.name]: Descriptions,
  26 + [Descriptions.Item.name]: Descriptions.Item,
  27 + },
  28 + emits: ['next', 'prev'],
  29 + setup(_, { emit }) {
  30 + const [register, { validate, setProps }] = useForm({
  31 + labelWidth: 80,
  32 + schemas: step2Schemas,
  33 + actionColOptions: {
  34 + span: 14,
  35 + },
  36 + resetButtonOptions: {
  37 + text: '上一步',
  38 + },
  39 + submitButtonOptions: {
  40 + text: '提交',
  41 + },
  42 + resetFunc: customResetFunc,
  43 + submitFunc: customSubmitFunc,
  44 + });
  45 +
  46 + async function customResetFunc() {
  47 + emit('prev');
  48 + }
  49 +
  50 + async function customSubmitFunc() {
  51 + try {
  52 + const values = await validate();
  53 + setProps({
  54 + submitButtonOptions: {
  55 + loading: true,
  56 + },
  57 + });
  58 + setTimeout(() => {
  59 + setProps({
  60 + submitButtonOptions: {
  61 + loading: false,
  62 + },
  63 + });
  64 + emit('next', values);
  65 + }, 1500);
  66 + } catch (error) {}
  67 + }
  68 +
  69 + return { register };
  70 + },
  71 + });
  72 +</script>
  73 +<style lang="less" scoped>
  74 + .step2 {
  75 + width: 450px;
  76 + margin: 0 auto;
  77 + }
  78 +</style>
... ...
  1 +<template>
  2 + <div class="step3">
  3 + <a-result status="success" title="操作成功" sub-title="预计两小时内到账">
  4 + <template #extra>
  5 + <a-button type="primary" @click="redo"> 再转一笔 </a-button>
  6 + <a-button> 查看账单 </a-button>
  7 + </template>
  8 + </a-result>
  9 + <div class="desc-wrap">
  10 + <a-descriptions :column="1" class="mt-5">
  11 + <a-descriptions-item label="付款账户"> ant-design@alipay.com </a-descriptions-item>
  12 + <a-descriptions-item label="收款账户"> test@example.com </a-descriptions-item>
  13 + <a-descriptions-item label="收款人姓名"> Vben </a-descriptions-item>
  14 + <a-descriptions-item label="转账金额"> 500元 </a-descriptions-item>
  15 + </a-descriptions>
  16 + </div>
  17 + </div>
  18 +</template>
  19 +<script lang="ts">
  20 + import { defineComponent } from 'vue';
  21 + import { Result, Descriptions } from 'ant-design-vue';
  22 + export default defineComponent({
  23 + components: {
  24 + [Result.name]: Result,
  25 + [Descriptions.name]: Descriptions,
  26 + [Descriptions.Item.name]: Descriptions.Item,
  27 + },
  28 + emits: ['redo'],
  29 + setup(_, { emit }) {
  30 + return {
  31 + redo: () => {
  32 + emit('redo');
  33 + },
  34 + };
  35 + },
  36 + });
  37 +</script>
  38 +<style lang="less" scoped>
  39 + .step3 {
  40 + width: 600px;
  41 + margin: 0 auto;
  42 + }
  43 +
  44 + .desc-wrap {
  45 + padding: 24px 40px;
  46 + margin-top: 24px;
  47 + background-color: @background-color-light;
  48 + }
  49 +</style>
... ...
  1 +<template>
  2 + <PageWrapper
  3 + title="分步表单"
  4 + contentBackground
  5 + content=" 将一个冗长或用户不熟悉的表单任务分成多个步骤,指导用户完成。"
  6 + contentClass="p-4"
  7 + >
  8 + <div class="step-form-form">
  9 + <a-steps :current="current">
  10 + <a-step title="填写转账信息" />
  11 + <a-step title="确认转账信息" />
  12 + <a-step title="完成" />
  13 + </a-steps>
  14 + </div>
  15 + <div class="mt-5">
  16 + <Step1 @next="handleStep1Next" v-show="current === 0" />
  17 + <Step2
  18 + @prev="handleStepPrev"
  19 + @next="handleStep2Next"
  20 + v-show="current === 1"
  21 + v-if="initSetp2"
  22 + />
  23 + <Step3 v-show="current === 2" @redo="handleRedo" v-if="initSetp3" />
  24 + </div>
  25 + </PageWrapper>
  26 +</template>
  27 +<script lang="ts">
  28 + import { defineComponent, ref, reactive, toRefs } from 'vue';
  29 + import Step1 from './DeviceStep1.vue';
  30 + import Step2 from './DeviceStep2.vue';
  31 + import Step3 from './DeviceStep3.vue';
  32 + import { PageWrapper } from '/@/components/Page';
  33 + import { Steps } from 'ant-design-vue';
  34 +
  35 + export default defineComponent({
  36 + name: 'FormStepPage',
  37 + components: {
  38 + Step1,
  39 + Step2,
  40 + Step3,
  41 + PageWrapper,
  42 + [Steps.name]: Steps,
  43 + [Steps.Step.name]: Steps.Step,
  44 + },
  45 + setup() {
  46 + const current = ref(0);
  47 +
  48 + const state = reactive({
  49 + initSetp2: false,
  50 + initSetp3: false,
  51 + });
  52 +
  53 + function handleStep1Next(step1Values: any) {
  54 + current.value++;
  55 + state.initSetp2 = true;
  56 + console.log(step1Values);
  57 + }
  58 +
  59 + function handleStepPrev() {
  60 + current.value--;
  61 + }
  62 +
  63 + function handleStep2Next(step2Values: any) {
  64 + current.value++;
  65 + state.initSetp3 = true;
  66 + console.log(step2Values);
  67 + }
  68 +
  69 + function handleRedo() {
  70 + current.value = 0;
  71 + state.initSetp2 = false;
  72 + state.initSetp3 = false;
  73 + }
  74 +
  75 + return {
  76 + current,
  77 + handleStep1Next,
  78 + handleStep2Next,
  79 + handleRedo,
  80 + handleStepPrev,
  81 + ...toRefs(state),
  82 + };
  83 + },
  84 + });
  85 +</script>
  86 +<style lang="less" scoped>
  87 + .step-form-content {
  88 + padding: 24px;
  89 + background-color: @component-background;
  90 + }
  91 +
  92 + .step-form-form {
  93 + width: 750px;
  94 + margin: 0 auto;
  95 + }
  96 +</style>
... ...
  1 +import { FormSchema } from '/@/components/Form';
  2 +import {findDictItemByCode} from "/@/api/system/dict";
  3 +
  4 +export const step1Schemas: FormSchema[] = [
  5 + {
  6 + field: 'icon',
  7 + label: '设备图片: ',
  8 + slot: 'iconSelect',
  9 + component: 'Input',
  10 + },
  11 + {
  12 + field: 'name',
  13 + label: '设备名称',
  14 + required: true,
  15 + component:'Input',
  16 + componentProps:{
  17 + maxLength:30
  18 + }
  19 + },
  20 + {
  21 + field: 'deviceType',
  22 + label: '设备类型',
  23 + required: true,
  24 + component: 'ApiSelect',
  25 + componentProps: {
  26 + api:findDictItemByCode,
  27 + params:{
  28 + dictCode:"device_type"
  29 + },
  30 + labelField:'itemText',
  31 + valueField:'itemValue',
  32 + },
  33 + },
  34 + {
  35 + field: 'label',
  36 + label: '设备标签',
  37 + component:'Input',
  38 + componentProps:{
  39 + maxLength:255
  40 + }
  41 + },
  42 + {
  43 + label: '备注',
  44 + field: 'remark',
  45 + component: 'InputTextArea',
  46 + }
  47 +];
  48 +
  49 +export const step2Schemas: FormSchema[] = [
  50 + {
  51 + field: 'pwd',
  52 + component: 'InputPassword',
  53 + label: '支付密码',
  54 + required: true,
  55 + defaultValue: '123456',
  56 + },
  57 +];
... ...