|
@@ -0,0 +1,389 @@
|
|
|
+<script setup lang="ts">
|
|
|
+import { FormRules, ElForm } from "element-plus";
|
|
|
+import { reactive, ref, unref } from "vue";
|
|
|
+import { httpUpdate, httpAdd, httpDetail } from "/@/api/parameter/good";
|
|
|
+import { responseHandle } from "/@/utils/responseHandle";
|
|
|
+import { useNav } from "/@/layout/hooks/useNav";
|
|
|
+import { GOOD_OPTIONS } from "/@/config/status";
|
|
|
+import { ImageUpload } from "/@/components/Upload";
|
|
|
+import { Unit } from "/@/components/RemoteSelect";
|
|
|
+import { ImageUploadList } from "/@/components/UploadList";
|
|
|
+import LadderModal from "./ladder-modal.vue";
|
|
|
+import LadderTable from "./ladder-table.vue";
|
|
|
+const ladderModalRef = ref<InstanceType<typeof LadderModal>>(null);
|
|
|
+enum FROM_TYPE {
|
|
|
+ create = "create",
|
|
|
+ edit = "edit",
|
|
|
+ view = "view"
|
|
|
+}
|
|
|
+const { logout } = useNav();
|
|
|
+const showModel = ref(false);
|
|
|
+const TYPE = ref<FROM_TYPE>(FROM_TYPE.create);
|
|
|
+const formRef = ref<InstanceType<typeof ElForm>>(null);
|
|
|
+const loading = ref(false);
|
|
|
+const titleType = ref("");
|
|
|
+const id = ref("");
|
|
|
+const emit = defineEmits(["reload"]);
|
|
|
+const initform = {
|
|
|
+ id: "",
|
|
|
+ good_name: "",
|
|
|
+ good_cover_img: "",
|
|
|
+ type: "",
|
|
|
+ unit_id: "",
|
|
|
+ moq: 1,
|
|
|
+ step: 1,
|
|
|
+ price: 0,
|
|
|
+ good_banner_img: [],
|
|
|
+ good_img: [],
|
|
|
+ good_param: [],
|
|
|
+ good_remark: ""
|
|
|
+};
|
|
|
+const ruleForm = ref({ ...initform });
|
|
|
+const rules = reactive<FormRules>({
|
|
|
+ good_name: [{ required: true, trigger: "bulr", message: "请输入商品名称" }],
|
|
|
+ good_cover_img: [
|
|
|
+ { required: true, trigger: "change", message: "请选择封面图" }
|
|
|
+ ],
|
|
|
+ type: [{ required: true, trigger: "change", message: "请选择商品类型" }],
|
|
|
+ unit_id: [{ required: true, trigger: "change", message: "请选择单位" }],
|
|
|
+ moq: [{ required: true, trigger: "bulr", message: "请选择起订量" }],
|
|
|
+ step: [{ required: true, trigger: "bulr", message: "请选择步长" }],
|
|
|
+ price: [{ required: true, trigger: "bulr", message: "请选择售价" }],
|
|
|
+ good_banner_img: [
|
|
|
+ {
|
|
|
+ type: "array",
|
|
|
+ required: true,
|
|
|
+ trigger: "change",
|
|
|
+ message: "请上传轮播图"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: "array",
|
|
|
+ min: 3,
|
|
|
+ max: 10,
|
|
|
+ trigger: "change",
|
|
|
+ message: "轮播图应为3~10张"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ good_img: [
|
|
|
+ {
|
|
|
+ type: "array",
|
|
|
+ required: true,
|
|
|
+ trigger: "change",
|
|
|
+ message: "请上传详情图"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: "array",
|
|
|
+ min: 1,
|
|
|
+ max: 20,
|
|
|
+ trigger: "change",
|
|
|
+ message: "详情图不得超过20张!"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ good_param: [
|
|
|
+ {
|
|
|
+ type: "array",
|
|
|
+ required: true,
|
|
|
+ trigger: "change",
|
|
|
+ message: "请填写商品参数!"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: "array",
|
|
|
+ min: 1,
|
|
|
+ max: 20,
|
|
|
+ trigger: "change",
|
|
|
+ message: "商品参数应为1~20条!"
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ good_remark: [{ required: true, trigger: "bulr", message: "请输入备注" }]
|
|
|
+});
|
|
|
+const initData = async () => {
|
|
|
+ const { code, data, message } = await httpDetail({ id: id.value });
|
|
|
+ responseHandle({
|
|
|
+ code,
|
|
|
+ message,
|
|
|
+ logout,
|
|
|
+ handler: () => {
|
|
|
+ console.log(data);
|
|
|
+ Object.keys(ruleForm.value).forEach(key => {
|
|
|
+ if (
|
|
|
+ key === "good_banner_img" ||
|
|
|
+ key === "good_img" ||
|
|
|
+ key === "good_param"
|
|
|
+ ) {
|
|
|
+ ruleForm.value[key] = data[key];
|
|
|
+ } else if (key === "moq" || key === "step" || key === "price") {
|
|
|
+ ruleForm.value[key] = Number(data[key]);
|
|
|
+ } else {
|
|
|
+ ruleForm.value[key] = data[key] + "";
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+async function show(node: any, did: string, isCreate: string) {
|
|
|
+ id.value = did;
|
|
|
+ Object.keys(ruleForm.value).forEach(key => {
|
|
|
+ if (
|
|
|
+ key === "good_banner_img" ||
|
|
|
+ key === "good_img" ||
|
|
|
+ key === "good_param"
|
|
|
+ ) {
|
|
|
+ ruleForm.value[key] = [];
|
|
|
+ } else if (key === "moq" || key === "step" || key === "price") {
|
|
|
+ ruleForm.value[key] = initform[key];
|
|
|
+ } else {
|
|
|
+ ruleForm.value[key] = initform[key] + "";
|
|
|
+ }
|
|
|
+ });
|
|
|
+ TYPE.value = isCreate;
|
|
|
+ switch (TYPE.value) {
|
|
|
+ case "create":
|
|
|
+ titleType.value = "新建商品";
|
|
|
+ break;
|
|
|
+ case "edit":
|
|
|
+ titleType.value = "编辑商品";
|
|
|
+ break;
|
|
|
+ case "view":
|
|
|
+ titleType.value = "商品详情";
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ titleType.value = "新建商品";
|
|
|
+ }
|
|
|
+ if (TYPE.value !== "create") {
|
|
|
+ await initData();
|
|
|
+ }
|
|
|
+ showModel.value = true;
|
|
|
+}
|
|
|
+async function handleLadderUpdate(_ladder, index) {
|
|
|
+ ruleForm.value.good_param[index] = _ladder;
|
|
|
+}
|
|
|
+async function handleLadderPush(_ladder) {
|
|
|
+ ruleForm.value.good_param.push(unref(_ladder));
|
|
|
+}
|
|
|
+function handleUpdate() {
|
|
|
+ const data = {
|
|
|
+ ...ruleForm.value
|
|
|
+ };
|
|
|
+
|
|
|
+ return {
|
|
|
+ data,
|
|
|
+ api: httpUpdate
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+function handleCreate() {
|
|
|
+ const data = {
|
|
|
+ ...ruleForm.value
|
|
|
+ };
|
|
|
+
|
|
|
+ return {
|
|
|
+ data,
|
|
|
+ api: httpAdd
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+function handleSave() {
|
|
|
+ formRef.value.validate(async vaild => {
|
|
|
+ if (vaild) {
|
|
|
+ if (loading.value) return;
|
|
|
+ const handler =
|
|
|
+ TYPE.value === FROM_TYPE.create ? handleCreate : handleUpdate;
|
|
|
+ loading.value = true;
|
|
|
+ const { api, data } = handler();
|
|
|
+ const { message, code } = await api(data);
|
|
|
+ loading.value = false;
|
|
|
+ responseHandle({
|
|
|
+ code,
|
|
|
+ message,
|
|
|
+ logout,
|
|
|
+ handler: () => {
|
|
|
+ showModel.value = false;
|
|
|
+
|
|
|
+ emit("reload");
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+defineExpose({
|
|
|
+ show
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <el-dialog
|
|
|
+ v-model="showModel"
|
|
|
+ :close-on-press-escape="false"
|
|
|
+ center
|
|
|
+ append-to-body
|
|
|
+ destroy-on-close
|
|
|
+ :width="'1040px'"
|
|
|
+ :title="titleType"
|
|
|
+ v-loading="loading"
|
|
|
+ >
|
|
|
+ <el-form
|
|
|
+ ref="formRef"
|
|
|
+ :model="ruleForm"
|
|
|
+ :rules="rules"
|
|
|
+ label-width="90px"
|
|
|
+ style="margin-top: -10px"
|
|
|
+ class="demo-ruleForm"
|
|
|
+ status-icon
|
|
|
+ >
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-form-item label="商品名称" prop="good_name">
|
|
|
+ <ElInput
|
|
|
+ placeholder="商品名称"
|
|
|
+ :disabled="TYPE === 'view'"
|
|
|
+ maxlength="50"
|
|
|
+ v-model="ruleForm.good_name"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="封面图" prop="good_cover_img">
|
|
|
+ <ImageUpload
|
|
|
+ v-model:url="ruleForm.good_cover_img"
|
|
|
+ :disabled="TYPE === 'view'"
|
|
|
+ :descs="['小于1Mb']"
|
|
|
+ :types="['png', 'jpg', 'jpeg']"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="商品类型" prop="type">
|
|
|
+ <el-select
|
|
|
+ v-model="ruleForm.type"
|
|
|
+ style="width: 100%"
|
|
|
+ :disabled="TYPE === 'view'"
|
|
|
+ placeholder="商品类型"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="(si, sii) in GOOD_OPTIONS"
|
|
|
+ :key="'type' + si.id + sii"
|
|
|
+ :label="si.label"
|
|
|
+ :value="si.id + ''"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="单位" prop="unit_id">
|
|
|
+ <Unit
|
|
|
+ v-model="ruleForm.unit_id"
|
|
|
+ :disabled="TYPE === 'view'"
|
|
|
+ placeholder="单位"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="起订量" prop="moq">
|
|
|
+ <el-input-number
|
|
|
+ style="width: 100%"
|
|
|
+ :disabled="TYPE === 'view'"
|
|
|
+ :precision="0"
|
|
|
+ :step="1"
|
|
|
+ controls-position="right"
|
|
|
+ v-model="ruleForm.moq"
|
|
|
+ :min="1"
|
|
|
+ placeholder="起订量"
|
|
|
+ :max="99999999"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="步长" prop="step">
|
|
|
+ <el-input-number
|
|
|
+ style="width: 100%"
|
|
|
+ :disabled="TYPE === 'view'"
|
|
|
+ :precision="0"
|
|
|
+ :step="1"
|
|
|
+ controls-position="right"
|
|
|
+ v-model="ruleForm.step"
|
|
|
+ :min="1"
|
|
|
+ placeholder="步长"
|
|
|
+ :max="99999999"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="售价" prop="price">
|
|
|
+ <el-input-number
|
|
|
+ style="width: 100%"
|
|
|
+ :disabled="TYPE === 'view'"
|
|
|
+ :precision="2"
|
|
|
+ :step="1"
|
|
|
+ controls-position="right"
|
|
|
+ v-model="ruleForm.price"
|
|
|
+ :min="0"
|
|
|
+ placeholder="售价"
|
|
|
+ :max="99999999"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-form-item label="轮播图" prop="good_banner_img">
|
|
|
+ <ImageUploadList
|
|
|
+ v-model:urls="ruleForm.good_banner_img"
|
|
|
+ :descs="['小于1Mb']"
|
|
|
+ :disabled="TYPE === 'view'"
|
|
|
+ :types="['png', 'jpg', 'jpeg']"
|
|
|
+ /> </el-form-item
|
|
|
+ ></el-col>
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-form-item label="详情图" prop="good_img">
|
|
|
+ <ImageUploadList
|
|
|
+ v-model:urls="ruleForm.good_img"
|
|
|
+ :descs="['小于1Mb']"
|
|
|
+ :disabled="TYPE === 'view'"
|
|
|
+ :types="['png', 'jpg', 'jpeg']"
|
|
|
+ /> </el-form-item
|
|
|
+ ></el-col>
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-form-item label="商品参数" prop="good_param">
|
|
|
+ <LadderTable
|
|
|
+ :readonly="TYPE === 'view'"
|
|
|
+ :ladder="ruleForm.good_param"
|
|
|
+ @choose="() => ladderModalRef.onDisplay()"
|
|
|
+ @update="
|
|
|
+ ({ data, index }) => ladderModalRef.onDisplay(data, index)
|
|
|
+ "
|
|
|
+ @delete="index => ruleForm.good_param.splice(index, 1)"
|
|
|
+ /> </el-form-item
|
|
|
+ ></el-col>
|
|
|
+ <el-col :span="24">
|
|
|
+ <el-form-item label="商品备注" prop="good_remark">
|
|
|
+ <ElInput
|
|
|
+ placeholder="商品备注"
|
|
|
+ :disabled="TYPE === 'view'"
|
|
|
+ type="textarea"
|
|
|
+ maxlength="600"
|
|
|
+ clearable
|
|
|
+ v-model="ruleForm.good_remark"
|
|
|
+ /> </el-form-item
|
|
|
+ ></el-col>
|
|
|
+ </el-row>
|
|
|
+ <div class="flex justify-end">
|
|
|
+ <el-button
|
|
|
+ v-if="TYPE !== 'view'"
|
|
|
+ :loading="loading"
|
|
|
+ :disabled="loading"
|
|
|
+ type="primary"
|
|
|
+ @click="handleSave"
|
|
|
+ >保存</el-button
|
|
|
+ >
|
|
|
+ <el-button @click="showModel = false">取消</el-button>
|
|
|
+ </div>
|
|
|
+ </el-form>
|
|
|
+ </el-dialog>
|
|
|
+ <LadderModal
|
|
|
+ ref="ladderModalRef"
|
|
|
+ @update="handleLadderUpdate"
|
|
|
+ @push="handleLadderPush"
|
|
|
+ />
|
|
|
+</template>
|