228 lines
7.3 KiB
Vue
228 lines
7.3 KiB
Vue
<template>
|
|
<div class="manual-form">
|
|
<Form :label-col="labelCol" :wrapper-col="wrapperCol">
|
|
<Row>
|
|
<Col :span="12">
|
|
<FormItem label="手册名称" v-bind="validateInfos.name">
|
|
<Input v-model:value="modelRef.name" allow-clear placeholder="请输入手册名称" />
|
|
</FormItem>
|
|
<FormItem label="编著" v-bind="validateInfos.compile">
|
|
<Input v-model:value="modelRef.compile" allow-clear placeholder="请输入编著名称" />
|
|
</FormItem>
|
|
<FormItem label="出版" v-bind="validateInfos.publish">
|
|
<Input v-model:value="modelRef.publish" allow-clear placeholder="请输入出版信息" />
|
|
</FormItem>
|
|
<FormItem label="手册简介" v-bind="validateInfos.explain">
|
|
<Textarea v-model:value="modelRef.explain" :rows="4" allow-clear placeholder="请输入简介信息" />
|
|
</FormItem>
|
|
</Col>
|
|
<Col :span="12">
|
|
<FormItem label="手册分类" v-bind="validateInfos.classify">
|
|
<TreeSelect
|
|
v-model:value="modelRef.classify"
|
|
show-search
|
|
style="width: 100%"
|
|
:dropdown-style="{ maxHeight: '400px', overflow: 'auto' }"
|
|
placeholder="请选择分类"
|
|
allow-clear
|
|
:tree-data="treeData"
|
|
tree-node-filter-prop="label"
|
|
:fieldNames="{
|
|
label: 'name',
|
|
value: 'id',
|
|
}"
|
|
/>
|
|
</FormItem>
|
|
<FormItem label="手册分类" v-bind="validateInfos.cover">
|
|
<Upload
|
|
v-model:file-list="fileList"
|
|
accept="image/*"
|
|
name="file"
|
|
:headers="{ Authorization: token }"
|
|
list-type="picture-card"
|
|
:action="`${baseUrl}/resource/upload`"
|
|
:before-upload="beforeUpload"
|
|
@change="handleChange"
|
|
>
|
|
<div v-if="fileList.length < 1">
|
|
<LoadingOutlined v-if="loading" />
|
|
<PlusOutlined v-else />
|
|
<div class="ant-upload-text">上传</div>
|
|
</div>
|
|
</Upload>
|
|
</FormItem>
|
|
</Col>
|
|
</Row>
|
|
<FormItem :wrapper-col="{ span: 14, offset: 4 }" style="text-align: center;">
|
|
<Button type="primary" shape="round" @click.prevent="handleSubmit">保存</Button>
|
|
<Button type="primary" danger shape="round" style="margin-left: 10px" @click="handleResetForm">重置</Button>
|
|
<Button shape="round" style="margin-left: 10px" @click="handleGoBack">返回</Button>
|
|
</FormItem>
|
|
</Form>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, ref, reactive, toRaw, onMounted, watch, getCurrentInstance } from 'vue';
|
|
import { Form, FormItem, Row, Col, Input, Textarea, Button, TreeSelect, Upload, Checkbox, message } from 'ant-design-vue';
|
|
import type { TreeProps, UploadChangeParam, UploadProps } from 'ant-design-vue';
|
|
import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue';
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
import { listToTree } from '@/utils';
|
|
import { getManualClassifyListApi, addManualApi, editManualApi } from '@/apis/manual';
|
|
|
|
export default defineComponent({
|
|
name: 'manual-form',
|
|
components: { Form, FormItem, Row, Col, Input, Textarea, Button, TreeSelect, Upload, LoadingOutlined, PlusOutlined },
|
|
props: ['formData'],
|
|
emits: ['addDone'],
|
|
setup(props, { emit }) {
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
const instance = getCurrentInstance();
|
|
const token = instance?.appContext.config.globalProperties.$globalVariable.token;
|
|
const baseUrl = instance?.appContext.config.globalProperties.$globalVariable.baseUrl;
|
|
const resourceBaseUrl = instance?.appContext.config.globalProperties.$globalVariable.resourceBaseUrl;
|
|
const manualClassify = ref<string>();
|
|
const treeData = ref<any>([]);
|
|
const fileList = ref<any>([]);
|
|
const loading = ref<boolean>(false);
|
|
let modelRef = reactive({
|
|
id: undefined,
|
|
name: '',
|
|
compile: '',
|
|
publish: '',
|
|
explain: '',
|
|
classify: 0,
|
|
cover: '',
|
|
stick: false,
|
|
password: '',
|
|
canEditor: [1],
|
|
canView: [1],
|
|
});
|
|
const rulesRef = reactive({
|
|
name: [{ required: true, message: '请输入手册名称' }],
|
|
});
|
|
|
|
const { resetFields, validate, validateInfos } = Form.useForm(modelRef, rulesRef, {
|
|
onValidate: (...args) => console.log(...args),
|
|
});
|
|
|
|
onMounted(() => {
|
|
getManualClassifyList();
|
|
});
|
|
|
|
const resetForm = (data: any = {
|
|
id: undefined,
|
|
name: '',
|
|
compile: '',
|
|
publish: '',
|
|
explain: '',
|
|
classify: 0,
|
|
cover: '',
|
|
stick: false,
|
|
password: '',
|
|
canEditor: [1],
|
|
canView: [1],
|
|
}) => {
|
|
resetFields();
|
|
modelRef = Object.assign(modelRef, data);
|
|
if (modelRef.cover) {
|
|
fileList.value = [{ url: `${resourceBaseUrl}/${modelRef.cover}` }]
|
|
} else {
|
|
fileList.value = [];
|
|
}
|
|
};
|
|
|
|
watch(() => props.formData, resetForm, { immediate: true });
|
|
|
|
const getManualClassifyList = async () => {
|
|
const data = await getManualClassifyListApi();
|
|
let arr = [{ id: 0, name: '无分类', pid: 0 }];
|
|
arr = arr.concat(listToTree(data));
|
|
treeData.value = arr;
|
|
};
|
|
|
|
const handleChange = (info: UploadChangeParam) => {
|
|
if (info.file.status === 'uploading') {
|
|
loading.value = true;
|
|
return;
|
|
}
|
|
if (info.file.status === 'done') {
|
|
modelRef.cover = info.file.response.data.diskname;
|
|
loading.value = false;
|
|
}
|
|
if (info.file.status === 'error') {
|
|
loading.value = false;
|
|
message.error('upload error');
|
|
}
|
|
};
|
|
|
|
const beforeUpload = (file: any) => {
|
|
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
|
|
if (!isJpgOrPng) {
|
|
message.error('You can only upload JPG file!');
|
|
}
|
|
const isLt2M = file.size / 1024 / 1024 < 2;
|
|
if (!isLt2M) {
|
|
message.error('Image must smaller than 2MB!');
|
|
}
|
|
return isJpgOrPng && isLt2M;
|
|
};
|
|
|
|
const handleSubmit = () => {
|
|
validate()
|
|
.then(async () => {
|
|
const params = { ...modelRef }
|
|
if (!params.id) {
|
|
const data = await addManualApi(params);
|
|
message.success('手册创建成功');
|
|
router.push({
|
|
path: route.path,
|
|
query: { id: data.id, classify: data.classify }
|
|
});
|
|
} else {
|
|
await editManualApi(params.id, params);
|
|
message.success('手册修改成功');
|
|
}
|
|
})
|
|
.catch(err => {
|
|
console.log('error', err);
|
|
});
|
|
};
|
|
|
|
const handleResetForm = () => {
|
|
resetForm({
|
|
id: props.formData.id,
|
|
classify: props.formData.classify || 0
|
|
});
|
|
};
|
|
|
|
const handleGoBack = () => {
|
|
router.push('/manual');
|
|
};
|
|
|
|
return {
|
|
labelCol: { span: 2 },
|
|
wrapperCol: { span: 16 },
|
|
token,
|
|
baseUrl,
|
|
resourceBaseUrl,
|
|
manualClassify,
|
|
treeData,
|
|
fileList,
|
|
loading,
|
|
validateInfos,
|
|
handleResetForm,
|
|
modelRef,
|
|
handleChange,
|
|
beforeUpload,
|
|
handleSubmit,
|
|
handleGoBack,
|
|
};
|
|
}
|
|
});
|
|
</script>
|
|
<style lang="less" scoped>
|
|
</style>
|