|
@@ -0,0 +1,325 @@
|
|
|
+<template>
|
|
|
+ <el-dialog
|
|
|
+ v-model="show"
|
|
|
+ class="upload-dialog"
|
|
|
+ title="上传图书"
|
|
|
+ width="663px"
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ >
|
|
|
+ <el-form ref="ruleFormRef" :model="form" :rules="rules" label-width="140px">
|
|
|
+ <el-form-item label="书名" prop="name">
|
|
|
+ <el-input
|
|
|
+ v-model="form.name"
|
|
|
+ clearable
|
|
|
+ class="w350"
|
|
|
+ placeholder="请填入内容,不超过20个字"
|
|
|
+ :maxlength="20"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="简介" prop="description">
|
|
|
+ <el-input
|
|
|
+ v-model="form.description"
|
|
|
+ type="textarea"
|
|
|
+ class="w350"
|
|
|
+ placeholder="请填入内容,不超过200个字"
|
|
|
+ :maxlength="200"
|
|
|
+ :autosize="{ minRows: 5 }"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="作者" prop="author">
|
|
|
+ <el-input
|
|
|
+ v-model="form.author"
|
|
|
+ clearable
|
|
|
+ class="w350"
|
|
|
+ placeholder="请填入内容,不超过20个字"
|
|
|
+ :maxlength="20"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="出版社" prop="press">
|
|
|
+ <el-input
|
|
|
+ v-model="form.press"
|
|
|
+ clearable
|
|
|
+ class="w350"
|
|
|
+ placeholder="请填入内容,不超过20个字"
|
|
|
+ :maxlength="20"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="出版年份" prop="year">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="form.year"
|
|
|
+ clearable
|
|
|
+ class="w350"
|
|
|
+ type="year"
|
|
|
+ placeholder="请选择年份"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="封面" prop="thumb">
|
|
|
+ <div>
|
|
|
+ <el-upload
|
|
|
+ class="upload-dialog__upload"
|
|
|
+ :http-request="handleUpload"
|
|
|
+ :show-file-list="false"
|
|
|
+ accept="image/jpeg,image/png,image/jpg"
|
|
|
+ :before-upload="onBeforeUploadImage"
|
|
|
+ >
|
|
|
+ <img v-if="imageUrl" :src="imageUrl" />
|
|
|
+ <div v-else>
|
|
|
+ <el-icon
|
|
|
+ :size="30"
|
|
|
+ color="var(--el-color-primary)"
|
|
|
+ class="avatar-uploader-icon"
|
|
|
+ ><Plus
|
|
|
+ /></el-icon>
|
|
|
+ </div>
|
|
|
+ </el-upload>
|
|
|
+ <p style="font-size: 12px; color: var(--text-color-placeholder)">
|
|
|
+ 格式要求:支持png、jpg图片格式;最大支持5M,最多1张
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="中图法分类" prop="storageId">
|
|
|
+ <el-cascader
|
|
|
+ v-model="form.storageId"
|
|
|
+ class="w350"
|
|
|
+ :loading="storageLoading"
|
|
|
+ :options="storageList"
|
|
|
+ placeholder="请选择"
|
|
|
+ :props="{ value: 'id', label: 'name', checkStrictly: true }"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="展示分类" prop="exhibitTypeId">
|
|
|
+ <el-select
|
|
|
+ v-model="form.exhibitTypeId"
|
|
|
+ :loading="exhibitLoading"
|
|
|
+ placeholder="请选择"
|
|
|
+ class="w350"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in exhibitList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.name"
|
|
|
+ :value="item.id"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="ISBN编号" prop="num">
|
|
|
+ <el-input
|
|
|
+ v-model="form.num"
|
|
|
+ class="w350"
|
|
|
+ clearable
|
|
|
+ placeholder="请填入内容,不超过20个字"
|
|
|
+ :maxlength="20"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="验证码" prop="randCode">
|
|
|
+ <div class="w350" style="display: flex; gap: 10px">
|
|
|
+ <el-input
|
|
|
+ v-model="form.randCode"
|
|
|
+ class="code"
|
|
|
+ type="number"
|
|
|
+ placeholder="请输入验证码"
|
|
|
+ />
|
|
|
+ <el-image
|
|
|
+ style="flex: 1; height: 50px; cursor: pointer"
|
|
|
+ :src="`${baseUrl}/api/wx/getRandCode?t=${timestamp}`"
|
|
|
+ @click="timestamp = new Date().getTime()"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button
|
|
|
+ class="upload-dialog__btn confirm"
|
|
|
+ type="primary"
|
|
|
+ @click="handleSubmit"
|
|
|
+ >提交</el-button
|
|
|
+ >
|
|
|
+ <el-button
|
|
|
+ class="upload-dialog__btn"
|
|
|
+ type="primary"
|
|
|
+ plain
|
|
|
+ @click="handleClose"
|
|
|
+ >取消</el-button
|
|
|
+ >
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </el-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { computed, ref, reactive, watch } from "vue";
|
|
|
+import { Plus } from "@element-plus/icons-vue";
|
|
|
+import {
|
|
|
+ uploadApi,
|
|
|
+ getStorageTreeApi,
|
|
|
+ getExhibitTypeListApi,
|
|
|
+ getBaseUrl,
|
|
|
+} from "@lsq/base";
|
|
|
+
|
|
|
+const DEFAULT_FORM = {
|
|
|
+ name: "",
|
|
|
+ description: "",
|
|
|
+ author: "",
|
|
|
+ author: "",
|
|
|
+ year: "",
|
|
|
+ thumb: "",
|
|
|
+ storageId: "",
|
|
|
+ exhibitTypeId: "",
|
|
|
+ num: "",
|
|
|
+ randCode: "",
|
|
|
+};
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ visible: {
|
|
|
+ type: Boolean,
|
|
|
+ required: true,
|
|
|
+ },
|
|
|
+});
|
|
|
+const emits = defineEmits(["update:visible"]);
|
|
|
+const ruleFormRef = ref();
|
|
|
+const baseUrl = getBaseUrl();
|
|
|
+const storageLoading = ref(false);
|
|
|
+const storageList = ref([]);
|
|
|
+const exhibitLoading = ref(false);
|
|
|
+const exhibitList = ref([]);
|
|
|
+const timestamp = ref(new Date().getTime());
|
|
|
+const form = reactive({ ...DEFAULT_FORM });
|
|
|
+const rules = reactive({
|
|
|
+ randCode: [{ required: true, message: "请输入验证码", trigger: "blur" }],
|
|
|
+ num: [{ required: true, message: "请输入编号", trigger: "blur" }],
|
|
|
+ name: [{ required: true, message: "请输入书名", trigger: "blur" }],
|
|
|
+ author: [{ required: true, message: "请输入作者", trigger: "blur" }],
|
|
|
+ press: [{ required: true, message: "请输入出版社", trigger: "blur" }],
|
|
|
+ year: [{ required: true, message: "请选择出版年份", trigger: "blur" }],
|
|
|
+ thumb: [{ required: true, message: "请上传封面", trigger: "blur" }],
|
|
|
+ storageId: [{ required: true, message: "请选择", trigger: "blur" }],
|
|
|
+ exhibitTypeId: [{ required: true, message: "请选择", trigger: "blur" }],
|
|
|
+});
|
|
|
+const imageUrl = ref("");
|
|
|
+
|
|
|
+const show = computed({
|
|
|
+ get() {
|
|
|
+ return props.visible;
|
|
|
+ },
|
|
|
+ set(v) {
|
|
|
+ emits("update:visible", v);
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+const onBeforeUploadImage = (file) => {
|
|
|
+ const isIMAGE = ["image/jpeg", "image/jpg", "image/png"].includes(file.type);
|
|
|
+ const isLt1M = file.size / 1024 / 1024 < 5;
|
|
|
+ if (!isIMAGE) {
|
|
|
+ ElMessage.error("上传文件只能是图片格式!");
|
|
|
+ }
|
|
|
+ if (!isLt1M) {
|
|
|
+ ElMessage.error("上传文件大小不能超过 5MB!");
|
|
|
+ }
|
|
|
+ return isIMAGE && isLt1M;
|
|
|
+};
|
|
|
+
|
|
|
+const handleUpload = async (params) => {
|
|
|
+ const formData = new FormData();
|
|
|
+ formData.append("file", params.file);
|
|
|
+ formData.append("type", "img");
|
|
|
+ try {
|
|
|
+ const data = await uploadApi(formData);
|
|
|
+ console.log(data);
|
|
|
+ params.onSuccess();
|
|
|
+ } catch (err) {
|
|
|
+ params.onError();
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const getStorageTree = async () => {
|
|
|
+ try {
|
|
|
+ storageLoading.value = true;
|
|
|
+ const data = await getStorageTreeApi();
|
|
|
+ storageList.value = data;
|
|
|
+ } finally {
|
|
|
+ storageLoading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const getExhibitTypeList = async () => {
|
|
|
+ try {
|
|
|
+ exhibitLoading.value = true;
|
|
|
+ const data = await getExhibitTypeListApi();
|
|
|
+ exhibitList.value = data;
|
|
|
+ } finally {
|
|
|
+ exhibitLoading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const handleSubmit = async () => {
|
|
|
+ await ruleFormRef.value.validate((valid) => {
|
|
|
+ if (valid) {
|
|
|
+ console.log("submit!");
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const handleClose = () => {
|
|
|
+ form.value = { ...DEFAULT_FORM };
|
|
|
+ show.value = false;
|
|
|
+ ruleFormRef.value.resetFields();
|
|
|
+};
|
|
|
+
|
|
|
+watch(show, (v) => {
|
|
|
+ if (v) {
|
|
|
+ !exhibitList.value.length && getExhibitTypeList();
|
|
|
+ !storageList.value.length && getStorageTree();
|
|
|
+ }
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+.upload-dialog {
|
|
|
+ &__btn {
|
|
|
+ width: 132px;
|
|
|
+ height: 55px;
|
|
|
+ border-radius: 0;
|
|
|
+ font-size: 16px;
|
|
|
+ background: white;
|
|
|
+
|
|
|
+ &.confirm {
|
|
|
+ border: 0;
|
|
|
+ background: url("@/assets/images/btn_02-min.png") no-repeat center right /
|
|
|
+ cover;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .el-dialog__header {
|
|
|
+ font-size: 24px;
|
|
|
+ font-family: "Source Han Serif CN-Bold";
|
|
|
+ }
|
|
|
+ .el-form {
|
|
|
+ --el-form-label-font-size: 18px;
|
|
|
+ }
|
|
|
+ .el-input {
|
|
|
+ --el-input-height: 50px;
|
|
|
+ }
|
|
|
+ .el-form-item__label {
|
|
|
+ height: 50px;
|
|
|
+ line-height: 50px;
|
|
|
+ }
|
|
|
+ .el-select__wrapper {
|
|
|
+ height: 50px;
|
|
|
+ }
|
|
|
+ .code {
|
|
|
+ width: 167px;
|
|
|
+ }
|
|
|
+ &__upload {
|
|
|
+ width: 85px;
|
|
|
+ height: 85px;
|
|
|
+ border-radius: 5px;
|
|
|
+ border: 1px dotted #d1bb9e;
|
|
|
+
|
|
|
+ div {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|