|
|
@@ -0,0 +1,200 @@
|
|
|
+<script setup lang="ts">
|
|
|
+import {useRouter} from "vue-router";
|
|
|
+import {ref, computed} from "vue";
|
|
|
+import {createProduct} from "../../api/product.ts";
|
|
|
+import {uploadImage} from "../../api/image.ts";
|
|
|
+
|
|
|
+const router = useRouter();
|
|
|
+const storeId = router.currentRoute.value.params.storeId;
|
|
|
+const name = ref('')
|
|
|
+const category = ref('')
|
|
|
+const price = ref()
|
|
|
+const photoUrlList = ref([])
|
|
|
+
|
|
|
+const hasNameInput = computed(() => name.value != '')
|
|
|
+const hasCategoryInput = computed(() => category.value != '')
|
|
|
+const hasPriceInput = computed(() => price.value != '')
|
|
|
+const nameLegal = hasNameInput
|
|
|
+const categoryLegal = hasCategoryInput
|
|
|
+const priceLegal = hasPriceInput
|
|
|
+
|
|
|
+const isDragging = ref(false)
|
|
|
+const files = ref([])
|
|
|
+const fileInputRef = ref(null)
|
|
|
+
|
|
|
+function onChange() {
|
|
|
+ files.value = [...fileInputRef.value.files]
|
|
|
+}
|
|
|
+
|
|
|
+function dragover(e) {
|
|
|
+ e.preventDefault()
|
|
|
+ isDragging.value = true
|
|
|
+}
|
|
|
+
|
|
|
+function dragleave() {
|
|
|
+ isDragging.value = false
|
|
|
+}
|
|
|
+
|
|
|
+function drop(e) {
|
|
|
+ e.preventDefault()
|
|
|
+ fileInputRef.value.files = e.dataTransfer.files
|
|
|
+ onChange()
|
|
|
+ isDragging.value = false
|
|
|
+}
|
|
|
+
|
|
|
+function generateURL(file) {
|
|
|
+ let formData = new FormData();
|
|
|
+ formData.append('file', file);
|
|
|
+ uploadImage(formData).then(res => {
|
|
|
+ photoUrlList.value.push(res.result);
|
|
|
+ console.log(photoUrlList.value)
|
|
|
+ });
|
|
|
+
|
|
|
+ let fileSrc = URL.createObjectURL(file);
|
|
|
+ setTimeout(() => {
|
|
|
+ URL.revokeObjectURL(fileSrc);
|
|
|
+ }, 1000);
|
|
|
+
|
|
|
+ return fileSrc;
|
|
|
+}
|
|
|
+
|
|
|
+function remove(i) {
|
|
|
+ files.value.splice(i, 1);
|
|
|
+ console.log(photoUrlList.value)
|
|
|
+}
|
|
|
+
|
|
|
+const createDisabled = computed(() => {
|
|
|
+ return !(nameLegal.value && categoryLegal.value && priceLegal.value && files.value);
|
|
|
+})
|
|
|
+
|
|
|
+function handleCreateProduct() {
|
|
|
+ const payload = {
|
|
|
+ storeId: storeId,
|
|
|
+ name: name.value,
|
|
|
+ category: category.value,
|
|
|
+ price: price.value,
|
|
|
+ photoUrlList: photoUrlList.value
|
|
|
+ };
|
|
|
+ createProduct(payload).then(res => {
|
|
|
+ console.log(res);
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="flex flex-col items-center justify-center px-6 py-6 space-y-10">
|
|
|
+
|
|
|
+ <span class="flex items-center text-2xl font-semibold text-gray-900">
|
|
|
+ Blue Whale Shopping Online
|
|
|
+ </span>
|
|
|
+
|
|
|
+ <el-card class="w-full bg-white rounded-lg shadow-md md:mt-0 sm:max-w-md xl:p-0">
|
|
|
+
|
|
|
+ <div class="p-6 space-y-4 md:space-y-6 sm:p-8">
|
|
|
+
|
|
|
+ <h1 class="text-2xl font-bold leading-tight tracking-tight text-gray-900">
|
|
|
+ 添加商品
|
|
|
+ </h1>
|
|
|
+
|
|
|
+ <el-form class="space-y-4 md:space-y-6">
|
|
|
+
|
|
|
+ <el-form-item>
|
|
|
+ <label for="name" class="inline-block mb-2 text-sm font-medium text-gray-900">商品名</label>
|
|
|
+ <input id="name" v-model="name"
|
|
|
+ required
|
|
|
+ class="bg-gray-50 border border-gray-300 text-gray-900 focus:outline-primary-600 sm:text-sm rounded-lg block w-full p-2.5"
|
|
|
+ placeholder="请输入商品名">
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item class="mb-0">
|
|
|
+ <label for="category" class="block mb-2 text-sm font-medium text-gray-900">品类</label>
|
|
|
+ <select id="category"
|
|
|
+ v-model="category"
|
|
|
+ class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5">
|
|
|
+ <option disabled value="" selected>请选择品类</option>
|
|
|
+ <option value="FOOD">食品</option>
|
|
|
+ <option value="CLOTHES">服饰</option>
|
|
|
+ <option value="FURNITURE">家具</option>
|
|
|
+ <option value="ELECTRONICS">电子产品</option>
|
|
|
+ <option value="ENTERTAINMENT">娱乐</option>
|
|
|
+ <option value="SPORTS">体育产品</option>
|
|
|
+ <option value="LUXURY">奢侈品</option>
|
|
|
+ </select>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item>
|
|
|
+ <label for="location" class="inline-block mb-2 text-sm font-medium text-gray-900">商品单价</label>
|
|
|
+ <input id="location" v-model="price"
|
|
|
+ required
|
|
|
+ class="bg-gray-50 border border-gray-300 text-gray-900 focus:outline-primary-600 sm:text-sm rounded-lg block w-full p-2.5"
|
|
|
+ placeholder="请输入商品单价,单位(元)">
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item>
|
|
|
+ <label for="logoUrl" class="inline-block mb-2 text-sm font-medium text-gray-900">商品图片</label>
|
|
|
+ <div class="main">
|
|
|
+ <div
|
|
|
+ class="dropzone-container"
|
|
|
+ @dragover="dragover"
|
|
|
+ @dragleave="dragleave"
|
|
|
+ @drop="drop"
|
|
|
+ >
|
|
|
+ <input
|
|
|
+ type="file"
|
|
|
+ multiple
|
|
|
+ name="file"
|
|
|
+ id="fileInput"
|
|
|
+ class="hidden-input"
|
|
|
+ @change="onChange"
|
|
|
+ ref="fileInputRef"
|
|
|
+ accept=".pdf,.jpg,.jpeg,.png"
|
|
|
+ />
|
|
|
+
|
|
|
+ <label for="fileInput" class="file-label">
|
|
|
+ <div v-if="isDragging">释放以将文件放到此处。</div>
|
|
|
+ <div v-else>将文件拖到此处或单击此处上传。</div>
|
|
|
+ </label>
|
|
|
+
|
|
|
+ <div class="preview-container mt-4" v-if="files.length">
|
|
|
+ <div v-for="file in files" :key="file.name" class="preview-card">
|
|
|
+ <div>
|
|
|
+ <img class="preview-img" :src="generateURL(file)"/>
|
|
|
+ <p>
|
|
|
+ {{ file.name }}
|
|
|
+ </p>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <button
|
|
|
+ class="ml-2"
|
|
|
+ type="button"
|
|
|
+ @click="remove(files.indexOf(file))"
|
|
|
+ title="Remove file"
|
|
|
+ >
|
|
|
+ <b>×</b>
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-form-item>
|
|
|
+
|
|
|
+ <el-form-item>
|
|
|
+ <button @click.prevent="handleCreateProduct()"
|
|
|
+ :disabled="createDisabled"
|
|
|
+ class="block my-3 w-full text-white bg-primary-600 hover:bg-primary-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-3 text-center disabled:bg-primary-100">
|
|
|
+ 添加
|
|
|
+ </button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ </div>
|
|
|
+
|
|
|
+
|
|
|
+</template>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+
|
|
|
+</style>
|