mirror of
https://github.com/fumiama/paper-manager.git
synced 2026-06-29 23:30:43 +08:00
finish 试卷生成
This commit is contained in:
@@ -4,10 +4,16 @@ import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/FloatTech/ttl"
|
||||
"github.com/fumiama/go-docx"
|
||||
"github.com/fumiama/paper-manager/backend/global"
|
||||
)
|
||||
|
||||
var genfilecache = ttl.NewCache[int, *docx.Docx](time.Minute * 10)
|
||||
|
||||
func init() {
|
||||
apimap["/api/genFile"] = &apihandler{"POST", func(w http.ResponseWriter, r *http.Request) {
|
||||
user := usertokens.Get(r.Header.Get("Authorization"))
|
||||
@@ -27,6 +33,21 @@ func init() {
|
||||
writeresult(w, codeError, nil, err.Error(), typeError)
|
||||
return
|
||||
}
|
||||
genfilecache.Set(*user.ID, docf)
|
||||
writeresult(w, codeSuccess, "请在10分钟内下载, 且不要在下载完成前关闭页面, 云端不会保存", messageOk, typeSuccess)
|
||||
}}
|
||||
|
||||
apimap["/api/dlGen"] = &apihandler{"GET", func(w http.ResponseWriter, r *http.Request) {
|
||||
user := usertokens.Get(r.Header.Get("Authorization"))
|
||||
if user == nil {
|
||||
writeresult(w, codeError, nil, errInvalidToken.Error(), typeError)
|
||||
return
|
||||
}
|
||||
docf := genfilecache.Get(*user.ID)
|
||||
if docf == nil {
|
||||
writeresult(w, codeError, nil, os.ErrNotExist.Error(), typeError)
|
||||
return
|
||||
}
|
||||
_, _ = io.Copy(w, docf)
|
||||
}}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ func init() {
|
||||
panic(err)
|
||||
}
|
||||
err = FileDB.db.Create(FileTableQuestion, &Question{},
|
||||
"FOREIGN KEY(FileID) REFERENCES "+FileTableFile+"(ID)",
|
||||
"FOREIGN KEY(ListID) REFERENCES "+FileTableList+"(ID)",
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
||||
@@ -7,11 +7,13 @@ import (
|
||||
|
||||
sql "github.com/FloatTech/sqlite"
|
||||
"github.com/fumiama/go-docx"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidGenerateConfig = errors.New("invalid generate config")
|
||||
ErrMajorTooLarge = errors.New("major too large")
|
||||
ErrNoSuchMajor = errors.New("no such major")
|
||||
ErrNoEnoughQuestionToMatchRequire = errors.New("no enough question to match require")
|
||||
ErrRateLimitExceeded = errors.New("rate limit exceeded")
|
||||
)
|
||||
@@ -26,21 +28,31 @@ type GenerateConfig struct {
|
||||
}
|
||||
|
||||
// GenerateFile 用一些限定条件生成新试卷, 云端不保存
|
||||
func (f *FileDatabase) GenerateFile(config *GenerateConfig) (*docx.Docx, error) {
|
||||
func (f *FileDatabase) GenerateFile(config *GenerateConfig) (docf *docx.Docx, err error) {
|
||||
if config == nil || config.Distribution == nil || len(config.Distribution) == 0 {
|
||||
return nil, ErrInvalidGenerateConfig
|
||||
}
|
||||
if len(config.Distribution) > 10 {
|
||||
return nil, ErrMajorTooLarge
|
||||
}
|
||||
docf := docx.NewA4()
|
||||
mm := map[string]struct{}{}
|
||||
for _, m := range f.GetMajors() {
|
||||
mm[m] = struct{}{}
|
||||
}
|
||||
for n := range config.Distribution {
|
||||
if _, ok := mm[n]; !ok {
|
||||
return nil, ErrNoSuchMajor
|
||||
}
|
||||
}
|
||||
docf = docx.NewA4()
|
||||
f.mu.RLock()
|
||||
defer f.mu.RUnlock()
|
||||
i := 0
|
||||
for n, c := range config.Distribution {
|
||||
if c == 0 {
|
||||
if c <= 0 {
|
||||
continue
|
||||
}
|
||||
docf.AddParagraph().AddText(string([]rune("一二三四五六七八九十")[c]) + "、" + n).Size("44").Bold()
|
||||
docf.AddParagraph().AddText(string([]rune("一二三四五六七八九十")[i]) + "、" + n).Size("30").Bold()
|
||||
cond := " WHERE"
|
||||
hasfront := false
|
||||
if config.YearStart > 0 {
|
||||
@@ -51,20 +63,32 @@ func (f *FileDatabase) GenerateFile(config *GenerateConfig) (*docx.Docx, error)
|
||||
if hasfront {
|
||||
cond += " AND"
|
||||
}
|
||||
cond += " Year<=" + strconv.Itoa(int(config.YearStart))
|
||||
cond += " Year<=" + strconv.Itoa(int(config.YearEnd))
|
||||
hasfront = true
|
||||
}
|
||||
if config.TypeMask > 0 {
|
||||
if hasfront {
|
||||
cond += " AND"
|
||||
}
|
||||
cond += " (Type&" + strconv.Itoa(int(config.TypeMask)) + ")!=0"
|
||||
ques, err := sql.QueryAll[Question](&f.db,
|
||||
"SELECT * FROM "+FileTableQuestion+
|
||||
" WHERE FileID IN (SELECT FileID FROM "+
|
||||
FileTableFile+cond+
|
||||
") ORDER BY RANDOM() limit "+strconv.Itoa(int(c))+";",
|
||||
)
|
||||
typmsk := strconv.Itoa(int(config.TypeMask))
|
||||
cond += " (Type&" + typmsk + ")==" + typmsk
|
||||
hasfront = true
|
||||
}
|
||||
var ques []*Question
|
||||
q := ""
|
||||
if hasfront {
|
||||
q = "SELECT * FROM " + FileTableQuestion +
|
||||
" WHERE Major='" + n + "' AND ListID IN (SELECT DISTINCT ListID FROM " +
|
||||
FileTableFile + cond +
|
||||
") ORDER BY RANDOM() limit " + strconv.Itoa(int(c)) + ";"
|
||||
ques, err = sql.QueryAll[Question](&f.db, q)
|
||||
} else {
|
||||
q = "SELECT * FROM " + FileTableQuestion +
|
||||
" WHERE Major='" + n + "' ORDER BY RANDOM() limit " + strconv.Itoa(int(c)) + ";"
|
||||
ques, err = sql.QueryAll[Question](&f.db, q)
|
||||
}
|
||||
if err != nil {
|
||||
logrus.Warnln(err, q)
|
||||
return nil, err
|
||||
}
|
||||
if len(ques) != int(c) {
|
||||
@@ -79,7 +103,7 @@ func (f *FileDatabase) GenerateFile(config *GenerateConfig) (*docx.Docx, error)
|
||||
return nil, ErrRateLimitExceeded
|
||||
}
|
||||
for i, q := range ques {
|
||||
lst, err := sql.Find[List](&f.db, FileTableFile, "WHERE ID="+strconv.Itoa(q.ListID))
|
||||
lst, err := sql.Find[List](&f.db, FileTableList, "WHERE ID="+strconv.Itoa(q.ListID))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -98,6 +122,7 @@ func (f *FileDatabase) GenerateFile(config *GenerateConfig) (*docx.Docx, error)
|
||||
docf.AddParagraph().AddText(strconv.Itoa(i+1) + ". (" + lst.Desc + ")")
|
||||
docf.AppendFile(docq)
|
||||
}
|
||||
i++
|
||||
}
|
||||
return docf, nil
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
import { defHttp, paperHttp } from '/@/utils/http/axios'
|
||||
import { getFileListModel, AnalyzeFile, FileListGroupItem } from './model/fileListModel'
|
||||
import {
|
||||
getFileListModel,
|
||||
AnalyzeFile,
|
||||
FileListGroupItem,
|
||||
GenerateConfig,
|
||||
} from './model/fileListModel'
|
||||
import { DownloadFile, FileStatus } from './model/fileModel'
|
||||
|
||||
enum Api {
|
||||
@@ -11,6 +16,8 @@ enum Api {
|
||||
DlFile = '/dlFile',
|
||||
GetFileStatus = '/getFileStatus',
|
||||
GetMajors = '/getMajors',
|
||||
GenFile = '/genFile',
|
||||
DlGen = '/dlGen',
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,3 +88,20 @@ export const getFileStatus = (id: number) => {
|
||||
export const getMajors = () => {
|
||||
return defHttp.get<string[]>({ url: Api.GetMajors })
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Generate File
|
||||
*/
|
||||
export const generateFile = (config: GenerateConfig) => {
|
||||
return defHttp.post<string>({ url: Api.GenFile, params: config }, { errorMessageMode: 'none' })
|
||||
}
|
||||
|
||||
/**
|
||||
* @description: Download generated file
|
||||
*/
|
||||
export const dlGeneratedFile = () => {
|
||||
return paperHttp.get<any>(
|
||||
{ url: '/api' + Api.DlGen, responseType: 'blob' },
|
||||
{ errorMessageMode: 'none' },
|
||||
)
|
||||
}
|
||||
|
||||
@@ -18,3 +18,11 @@ export interface AnalyzeFile {
|
||||
code: number
|
||||
msg: string
|
||||
}
|
||||
|
||||
export interface GenerateConfig {
|
||||
Distribution: { [x: string]: any } // Distribution is map[majorname]subcount
|
||||
RateLimit: number // RateLimit 重复率上限
|
||||
YearStart: number // YearStart 起始年份(空则直到最旧)
|
||||
YearEnd: number // YearEnd 截止年份(空则直到最新)
|
||||
TypeMask: number // TypeMask & File.Type != 0 则匹配
|
||||
}
|
||||
|
||||
@@ -95,7 +95,12 @@
|
||||
async function customSubmitFunc() {
|
||||
try {
|
||||
const values = await validate()
|
||||
emit('next', values)
|
||||
const data = getDataSource()
|
||||
if (data.length == 0) {
|
||||
createMessage.error('必须指定至少一种题型!')
|
||||
return
|
||||
}
|
||||
emit('next', { values, data })
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,36 @@
|
||||
<template>
|
||||
<div class="step2">
|
||||
<a-alert message="确认转账后,资金将直接打入对方账户,无法退回。" show-icon />
|
||||
<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="收款人姓名"> Vben </a-descriptions-item>
|
||||
<a-descriptions-item label="转账金额"> 500元 </a-descriptions-item>
|
||||
<a-descriptions-item label="大题数">
|
||||
{{ state.step1Values.data.length }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="小题数">
|
||||
{{
|
||||
state.step1Values.data
|
||||
.map((record) => record.count || 0)
|
||||
.reduce((sum, count) => sum + count, 0)
|
||||
}}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="重复率上限">
|
||||
{{ state.step1Values.values.RateLimit[1] / 100 }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="起止年份" v-if="state.step1Values.values['[YearStart, YearEnd]']">
|
||||
{{ state.step1Values.values['[YearStart, YearEnd]'][0].$y }} -
|
||||
{{ state.step1Values.values['[YearStart, YearEnd]'][1].$y }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="试卷类别" v-if="state.step1Values.values.AB">
|
||||
{{ state.step1Values.values.AB }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="考试阶段" v-if="state.step1Values.values.MiddleFinal">
|
||||
{{ state.step1Values.values.MiddleFinal }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="考试学期" v-if="state.step1Values.values.FirstSecond">
|
||||
{{ state.step1Values.values.FirstSecond }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="考试类型" v-if="state.step1Values.values.OpenClose">
|
||||
{{ state.step1Values.values.OpenClose }}
|
||||
</a-descriptions-item>
|
||||
</a-descriptions>
|
||||
<a-divider />
|
||||
<BasicForm @register="register" />
|
||||
@@ -14,7 +39,9 @@
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { BasicForm, useForm } from '/@/components/Form'
|
||||
import { step2Schemas } from './data'
|
||||
import { state } from './data'
|
||||
import { generateFile } from '/@/api/page'
|
||||
import { useMessage } from '/@/hooks/web/useMessage'
|
||||
import { Alert, Divider, Descriptions } from 'ant-design-vue'
|
||||
|
||||
export default defineComponent({
|
||||
@@ -27,11 +54,10 @@
|
||||
},
|
||||
emits: ['next', 'prev'],
|
||||
setup(_, { emit }) {
|
||||
const [register, { validate, setProps }] = useForm({
|
||||
const [register, { setProps }] = useForm({
|
||||
labelWidth: 80,
|
||||
schemas: step2Schemas,
|
||||
actionColOptions: {
|
||||
span: 14,
|
||||
span: 16,
|
||||
},
|
||||
resetButtonOptions: {
|
||||
text: '上一步',
|
||||
@@ -43,30 +69,74 @@
|
||||
submitFunc: customSubmitFunc,
|
||||
})
|
||||
|
||||
const { createMessage } = useMessage()
|
||||
|
||||
async function customResetFunc() {
|
||||
emit('prev')
|
||||
}
|
||||
|
||||
async function customSubmitFunc() {
|
||||
try {
|
||||
const values = await validate()
|
||||
setProps({
|
||||
submitButtonOptions: {
|
||||
loading: true,
|
||||
},
|
||||
})
|
||||
setTimeout(() => {
|
||||
let ys = 0
|
||||
let ye = 0
|
||||
if (state.step1Values.values['[YearStart, YearEnd]']) {
|
||||
ys = state.step1Values.values['[YearStart, YearEnd]'][0].$y
|
||||
ye = state.step1Values.values['[YearStart, YearEnd]'][1].$y
|
||||
}
|
||||
let tm = 0
|
||||
if (state.step1Values.values.AB) {
|
||||
if (state.step1Values.values.AB == 'A') tm |= 1
|
||||
else if (state.step1Values.values.AB == 'B') tm |= 2
|
||||
}
|
||||
if (state.step1Values.values.MiddleFinal) {
|
||||
if (state.step1Values.values.MiddleFinal == '中') tm |= 1 << 4
|
||||
else if (state.step1Values.values.MiddleFinal == '末') tm |= 2 << 4
|
||||
}
|
||||
if (state.step1Values.values.FirstSecond) {
|
||||
if (state.step1Values.values.FirstSecond == '1') tm |= 1 << 8
|
||||
else if (state.step1Values.values.FirstSecond == '2') tm |= 2 << 8
|
||||
}
|
||||
if (state.step1Values.values.OpenClose) {
|
||||
if (state.step1Values.values.OpenClose == '开卷') tm |= 1 << 12
|
||||
else if (state.step1Values.values.OpenClose == '一页纸开卷') tm |= 2 << 12
|
||||
else if (state.step1Values.values.OpenClose == '闭卷') tm |= 4 << 12
|
||||
}
|
||||
const data = await generateFile({
|
||||
Distribution: state.step1Values.data.reduce((acc, { major, count }) => {
|
||||
console.log(major, count)
|
||||
acc[major] = count
|
||||
return acc
|
||||
}, {}),
|
||||
RateLimit: state.step1Values.values.RateLimit[1] / 100,
|
||||
YearStart: ys,
|
||||
YearEnd: ye,
|
||||
TypeMask: tm,
|
||||
})
|
||||
setProps({
|
||||
submitButtonOptions: {
|
||||
loading: false,
|
||||
},
|
||||
})
|
||||
emit('next', values)
|
||||
}, 1500)
|
||||
} catch (error) {}
|
||||
emit('next', data)
|
||||
} catch (error) {
|
||||
createMessage.error((error as unknown as Error).message)
|
||||
setProps({
|
||||
submitButtonOptions: {
|
||||
loading: false,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return { register }
|
||||
return {
|
||||
register,
|
||||
state,
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1,36 +1,87 @@
|
||||
<template>
|
||||
<div class="step3">
|
||||
<a-result status="success" title="操作成功" sub-title="预计两小时内到账">
|
||||
<a-result status="success" title="试卷生成成功" :sub-title="msg">
|
||||
<template #extra>
|
||||
<a-button type="primary" @click="redo"> 再转一笔 </a-button>
|
||||
<a-button> 查看账单 </a-button>
|
||||
<a-button type="primary" @click="redo"> 再次生成 </a-button>
|
||||
<a-button @click="downloadDocx"> 下载试卷 </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="收款人姓名"> Vben </a-descriptions-item>
|
||||
<a-descriptions-item label="转账金额"> 500元 </a-descriptions-item>
|
||||
</a-descriptions>
|
||||
<div class="docxWrap" :style="{ width }">
|
||||
<div ref="docxRef"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { defineComponent, ref } from 'vue'
|
||||
import { Result, Descriptions } from 'ant-design-vue'
|
||||
import { renderAsync } from 'docx-preview'
|
||||
import { state } from './data'
|
||||
import { dlGeneratedFile } from '/@/api/page'
|
||||
import { useMessage } from '/@/hooks/web/useMessage'
|
||||
import { downloadByData } from '/@/utils/file/download'
|
||||
|
||||
let docxRef = ref(null)
|
||||
|
||||
let docxNameRef = ref('paper.docx')
|
||||
let docxSizeRef = ref(0)
|
||||
|
||||
let docxBlob: Blob | null = null
|
||||
|
||||
function loadDocx(file: Blob) {
|
||||
docxBlob = file
|
||||
renderAsync(file, docxRef.value as unknown as HTMLElement, undefined, {
|
||||
className: 'docx', // 默认和文档样式类的类名/前缀
|
||||
inWrapper: false, // 启用围绕文档内容渲染包装器
|
||||
ignoreWidth: false, // 禁止页面渲染宽度
|
||||
ignoreHeight: false, // 禁止页面渲染高度
|
||||
ignoreFonts: false, // 禁止字体渲染
|
||||
breakPages: false, // 在分页符上启用分页
|
||||
ignoreLastRenderedPageBreak: true, //禁用lastRenderedPageBreak元素的分页
|
||||
experimental: true, // 启用实验性功能(制表符停止计算)
|
||||
trimXmlDeclaration: true, // 如果为真,xml声明将在解析之前从xml文档中删除
|
||||
debug: false, // 启用额外的日志记录
|
||||
})
|
||||
}
|
||||
|
||||
function downloadDocx() {
|
||||
downloadByData(docxBlob as BlobPart, docxNameRef.value)
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
[Result.name]: Result,
|
||||
[Descriptions.name]: Descriptions,
|
||||
[Descriptions.Item.name]: Descriptions.Item,
|
||||
},
|
||||
props: {
|
||||
width: {
|
||||
type: String as PropType<string>,
|
||||
default: '100%',
|
||||
},
|
||||
},
|
||||
emits: ['redo'],
|
||||
setup(_, { emit }) {
|
||||
const { createMessage } = useMessage()
|
||||
;(async () => {
|
||||
try {
|
||||
const data = await dlGeneratedFile()
|
||||
if (data) {
|
||||
loadDocx(data)
|
||||
return
|
||||
}
|
||||
} catch (error) {
|
||||
createMessage.error('加载docx错误: ' + (error as unknown as Error).message)
|
||||
}
|
||||
})()
|
||||
return {
|
||||
msg: state.step2Values,
|
||||
redo: () => {
|
||||
emit('redo')
|
||||
},
|
||||
docxRef,
|
||||
downloadDocx,
|
||||
docxNameRef,
|
||||
docxSizeRef,
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -41,9 +92,12 @@
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.desc-wrap {
|
||||
padding: 24px 40px;
|
||||
margin-top: 24px;
|
||||
background-color: @background-color-light;
|
||||
.docxWrap {
|
||||
padding-top: 0px;
|
||||
margin: 0 auto;
|
||||
overflow-x: auto;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,4 +1,12 @@
|
||||
import { FormSchema } from '/@/components/Form'
|
||||
import { reactive } from 'vue'
|
||||
|
||||
export const state = reactive({
|
||||
initSetp2: false,
|
||||
initSetp3: false,
|
||||
step1Values: { values: {} as any, data: [] as Recordable<any>[] },
|
||||
step2Values: {} as any,
|
||||
})
|
||||
|
||||
export const step1Schemas: FormSchema[] = [
|
||||
{
|
||||
@@ -119,16 +127,3 @@ export const step1Schemas: FormSchema[] = [
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
export const step2Schemas: FormSchema[] = [
|
||||
{
|
||||
field: 'pwd',
|
||||
component: 'InputPassword',
|
||||
label: '支付密码',
|
||||
required: true,
|
||||
defaultValue: '123456',
|
||||
colProps: {
|
||||
span: 24,
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<PageWrapper
|
||||
title="分步表单"
|
||||
:title="t('routes.genfile.name')"
|
||||
contentBackground
|
||||
content=" 将一个冗长或用户不熟悉的表单任务分成多个步骤,指导用户完成。"
|
||||
content="使用自定义限制条件生成试卷"
|
||||
contentClass="p-4"
|
||||
>
|
||||
<div class="step-form-form">
|
||||
<a-steps :current="current">
|
||||
<a-step title="填写转账信息" />
|
||||
<a-step title="确认转账信息" />
|
||||
<a-step title="完成" />
|
||||
<a-step title="填写信息" />
|
||||
<a-step title="确认生成" />
|
||||
<a-step title="下载" />
|
||||
</a-steps>
|
||||
</div>
|
||||
<div class="mt-5">
|
||||
@@ -25,12 +25,14 @@
|
||||
</PageWrapper>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, ref, reactive, toRefs } from 'vue'
|
||||
import { defineComponent, ref, toRefs } from 'vue'
|
||||
import { state } from './data'
|
||||
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'
|
||||
import { useI18n } from '/@/hooks/web/useI18n'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'FormStepPage',
|
||||
@@ -45,15 +47,12 @@
|
||||
setup() {
|
||||
const current = ref(0)
|
||||
|
||||
const state = reactive({
|
||||
initSetp2: false,
|
||||
initSetp3: false,
|
||||
})
|
||||
const { t } = useI18n()
|
||||
|
||||
function handleStep1Next(step1Values: any) {
|
||||
current.value++
|
||||
state.initSetp2 = true
|
||||
console.log(step1Values)
|
||||
state.step1Values = step1Values
|
||||
}
|
||||
|
||||
function handleStepPrev() {
|
||||
@@ -63,7 +62,7 @@
|
||||
function handleStep2Next(step2Values: any) {
|
||||
current.value++
|
||||
state.initSetp3 = true
|
||||
console.log(step2Values)
|
||||
state.step2Values = step2Values
|
||||
}
|
||||
|
||||
function handleRedo() {
|
||||
@@ -73,6 +72,7 @@
|
||||
}
|
||||
|
||||
return {
|
||||
t,
|
||||
current,
|
||||
handleStep1Next,
|
||||
handleStep2Next,
|
||||
|
||||
Reference in New Issue
Block a user