<template> <div> <div class="content"> <!-- 面包屑 --> <div class="breadcrumbs"> <span> <span @click="goGoodsList">数字商品管理</span> <span class="active-span" >/ 新建数字商品</span ></span > </div> <!-- 新建数字商品 --> <div class="creatbox"> <div class="title">新建数字商品</div> <n-form ref="formRef" label-placement="left" label-width="auto" :model="model" :rules="rules" require-mark-placement="left" > <div class="disflex"> <div class="disflex-left"> <n-form-item label="上传封面" path="cover"> <div> <div v-show="model.cover === ''"> <div class="inputbox" @click="coverfileChange"> <n-icon size="40"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" > <path d="M368.5 240H272v-96.5c0-8.8-7.2-16-16-16s-16 7.2-16 16V240h-96.5c-8.8 0-16 7.2-16 16 0 4.4 1.8 8.4 4.7 11.3 2.9 2.9 6.9 4.7 11.3 4.7H240v96.5c0 4.4 1.8 8.4 4.7 11.3 2.9 2.9 6.9 4.7 11.3 4.7 8.8 0 16-7.2 16-16V272h96.5c8.8 0 16-7.2 16-16s-7.2-16-16-16z" /> </svg> </n-icon ></div> <input id="uploadInput" ref="uploadInput" type="file" class="input-file" @change="fileChange_cover" /> </div> <div v-show="model.cover !== ''" class="disflexupload"> <div class="cover_img"> <img :src="haveCoverurl" alt="" /> </div> <div class="uploadnew"> <span @click="againUpload('cover')">重新上传</span ><span class="delspan" @click="deleteUpload('cover')" >删除</span > </div> </div> <div class="tiptext">支持jpg/jpeg/png格式 5M以内</div> </div> </n-form-item> <n-form-item label="商品名称" path="name"> <n-input v-model:value="model.name" :clearable="true" maxlength="200" :style="{ width: '384px' }" placeholder="请输入" /> </n-form-item> <n-form-item label="图文说明书"> <div> <div v-show="model.pic === ''"> <div class="inputbox-video-book" @click="picfileChange"> <n-icon size="40"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" > <path d="M368.5 240H272v-96.5c0-8.8-7.2-16-16-16s-16 7.2-16 16V240h-96.5c-8.8 0-16 7.2-16 16 0 4.4 1.8 8.4 4.7 11.3 2.9 2.9 6.9 4.7 11.3 4.7H240v96.5c0 4.4 1.8 8.4 4.7 11.3 2.9 2.9 6.9 4.7 11.3 4.7 8.8 0 16-7.2 16-16V272h96.5c8.8 0 16-7.2 16-16s-7.2-16-16-16z" /> </svg> </n-icon ></div> <input id="uploadInputbook" ref="uploadInputbook" type="file" class="input-file" @change="fileChange_pic" /> </div> <div v-show="model.pic !== ''" class="disflexupload"> <div class="pic_img"> <img :src="havePicurl" alt="" /> </div> <div class="uploadnew"> <span @click="againUpload('pic')">重新上传</span> <span class="delspan" @click="deleteUpload('pic')" >删除</span > </div> </div> <div class="tiptext">支持jpg/jpeg/png格式 5M以内</div> </div> </n-form-item> <n-form-item label="视频说明书"> <div> <div v-show="model.video === ''"> <div class="inputbox-video-book" @click="videofileChange"> <n-icon size="40"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" > <path d="M368.5 240H272v-96.5c0-8.8-7.2-16-16-16s-16 7.2-16 16V240h-96.5c-8.8 0-16 7.2-16 16 0 4.4 1.8 8.4 4.7 11.3 2.9 2.9 6.9 4.7 11.3 4.7H240v96.5c0 4.4 1.8 8.4 4.7 11.3 2.9 2.9 6.9 4.7 11.3 4.7 8.8 0 16-7.2 16-16V272h96.5c8.8 0 16-7.2 16-16s-7.2-16-16-16z" /> </svg> </n-icon ></div> <input id="uploadInputvideo" ref="uploadInputvideo" type="file" class="input-file" @change="fileChange_video" /> </div> <div v-show="model.video !== ''" class="disflexupload"> <div class="pic_img"> <video ref="video" controls :src="haveVideourl" controlsList="nodownload" /> </div> <div class="uploadnew"> <span @click="againUpload('video')">重新上传</span> <span class="delspan" @click="deleteUpload('video')" >删除</span > </div> </div> <div class="videotiptext">支持MP4格式 100M以内</div> </div> </n-form-item> </div> <div class="disflex-right"> <n-form-item label="商品品类" path="product_type1"> <n-select v-model:value="model.product_type1" :style="{ width: '200px' }" :options="goodsOptions_one" :on-update:value="changeOne" /> <n-select v-model:value="model.product_type2" :style="{ width: '200px', 'margin-left': '16px' }" :options="goodsOptions_two" :on-update:value="changeTwo" /> </n-form-item> <n-form-item label="商品外链"> <n-input v-model:value="model.url" :clearable="true" maxlength="200" :style="{ width: '384px' }" placeholder="请输入" /> </n-form-item> <!-- 模型上传 --> <div> <input id="uploadInputmodel" ref="uploadInputmodel" type="file" class="input-file" @change="fileChange_fbx" /> </div> <!-- 规格上传 --> <div> <input id="specuploadInput" ref="specuploadInput" type="file" class="input-file" @change="spec_fileChange_cover" /> </div> <n-scrollbar trigger="none" :style="{ 'max-height': '430px' }" y-scrollable > <div class="specinfo"> <div v-for="(item, index) in specificationList" :key="index" class="spec" > <div class="specbox" :class=" submitClick === true && (item.specifications_name === '' || item.obj_url === '' || item.specifications_pic === '') ? 'activeSpecbox' : '' " > <div class="topbox"> <div v-if="index === 0" class="text" ><span>*</span>规格一</div > <div v-if="index === 1" class="text" ><span>*</span>规格二</div > <div v-if="index === 2" class="text" ><span>*</span>规格三</div > <div v-if="index === 3" class="text" ><span>*</span>规格四</div > <div v-if="index === 4" class="text" ><span>*</span>规格五</div > <div v-if="index === 5" class="text" ><span>*</span>规格六</div > <div v-if="index === 6" class="text" ><span>*</span>规格七</div > <div v-if="index === 7" class="text" ><span>*</span>规格八</div > <div v-if="index === 8" class="text" ><span>*</span>规格九</div > <div v-if="index === 9" class="text" ><span>*</span>规格十</div > <n-dialog-provider> <div @click="deletespec(index)" ><img src="@/assets/images/shop/deleteradius.png" alt="" /></div> </n-dialog-provider> </div> <div class="selectbox"> <div class="disBox"> <span>*</span> <n-form-item label="规格名称"> <n-input v-model:value="item.specifications_name" :clearable="true" maxlength="200" :style="{ width: '384px' }" placeholder="请输入" /> </n-form-item> </div> <div class="disBox"> <span>*</span> <n-form-item label="规格图上传" style="margin-left: 14px" > <div> <div v-show="item.specifications_pic === ''"> <div class="spec-inputbox" @click="speccoverfileChange(index)" > <n-icon size="40"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" > <path d="M368.5 240H272v-96.5c0-8.8-7.2-16-16-16s-16 7.2-16 16V240h-96.5c-8.8 0-16 7.2-16 16 0 4.4 1.8 8.4 4.7 11.3 2.9 2.9 6.9 4.7 11.3 4.7H240v96.5c0 4.4 1.8 8.4 4.7 11.3 2.9 2.9 6.9 4.7 11.3 4.7 8.8 0 16-7.2 16-16V272h96.5c8.8 0 16-7.2 16-16s-7.2-16-16-16z" /> </svg> </n-icon ></div> </div> <div v-show="item.specifications_pic !== ''" class="disflexupload" > <div class="spec-cover_img"> <img :src="item.specifications_pic" alt="" /> </div> <div class="spec-uploadnew"> <span @click="specagainUpload(index)" >重新上传</span ><span class="delspan" @click="specdeleteUpload(index)" >删除</span > </div> </div> <div class="spec-tiptext" >支持jpg/jpeg/png格式 5M以内</div > </div> </n-form-item> </div> <div class="disBox" style="height: 80px"> <span>*</span> <n-form-item label="模型上传"> <div v-show="item.uploadfbxState" class="disflexupload" > <div> <div class="inputbox-model" @click="specfbxfileChange(index)" > 上传模型 </div> </div> <div class="model-tiptext"> 支持扩展名:.fbx </div> </div> <div v-show="!item.uploadfbxState" class="progressbox" > <div v-if="item.percentageNum !== 100"> <div class="modelnamebox"> <div> {{ item.obj_name }}</div> </div> <n-progress type="line" :style="{ width: '256px' }" :percentage="item.percentageNum" processing > </n-progress> </div> <div v-else class="fbxbox"> {{ item.obj_name }} <img src="@/assets/images/shop/success.png" alt="" /> <span @click="specfbxagainUpload(index)" >重新上传</span ></div > </div> </n-form-item> </div> </div> </div> <div v-if=" submitClick === true && (item.specifications_name === '' || item.obj_url === '' || item.specifications_pic === '') " class="warningtext" > 此规格有数据为空 </div> </div> </div> </n-scrollbar> <div v-if="specificationList.length > 9" class="addspecbox puplic-btn-disable" >新增规格</div > <div v-else class="addspecbox" @click="addspec">新增规格</div> </div> </div> </n-form> </div> <div class="footerbtn"> <n-spin :show="showspin" size="small"> <div class="btn submit-btn" @click="handleValidateClick">提交</div> </n-spin> <div class="btn cancle-btn" @click="goGoodsList">取消</div> </div> </div> <Dialog v-model:show="showDelAll" @enter="handleDelAll"></Dialog> </div> </template> <script lang="ts" setup> import { onMounted, ref, computed } from 'vue'; import { useRouter } from 'vue-router'; import { FormInst, useMessage, useDialog, FormItemRule } from 'naive-ui'; import { useUpload } from '@/hooks/useAxios'; import Dialog from '@/components/Dialog.vue'; import { usePost } from '@/hooks/useAxios'; import { HttpAdminGoodsGetCategoryListParameter, HttpAdminGoodsGetCategoryListParameterInitial, HttpAdminGoodsGetCategoryListRsult, imgUploadResult, videoUploadResult, modelUploadResult, specification, goodsStore, goodsInfo, } from '@/types/httpGoods'; const haveCoverurl = ref(); const havePicurl = ref(); const haveVideourl = ref(); const message = useMessage(); const router = useRouter(); const formRef = ref<FormInst | null>(null); const uploadInput = ref<HTMLElement | null>(null); const specuploadInput = ref<HTMLElement | null>(null); const uploadInputvideo = ref<HTMLElement | null>(null); const uploadInputbook = ref<HTMLElement | null>(null); const uploadInputmodel = ref<HTMLElement | null>(null); const allspecOptions = ref(); const goodsOptions_one = ref(); const goodsOptions_two = ref(); const uploadfbxState = ref(true); const showDelAll = ref(false); const submitClick = ref(false); const delNum = ref(); const percentageNum = ref(0); const clickState = ref(false); const showspin = ref(false); const dialog = useDialog(); const initState = ref(true); const saveIndexnum = ref(); //循环上传存的索引值 const specificationList = ref([ { specifications_name: '', obj_name: '', obj_url: '', obj_url_nodomainname: '', uploadfbxState: true, percentageNum: 0, specifications_pic: '', }, ]); const queryInfo = router.currentRoute.value.query; const model = ref({ cover: '', //商品封面图 name: '', //商品封面图, //商品名称 pic: '', //商品封面图, //商品名称 video: '', product_type1: null, //一级分类 product_type2: null, //二级分类 url: '', //商品外链 // obj: '', //模型文件地址 // obj_name: '', specifications: '', //规格 }); const submitState = ref(false); const rules = { cover: { required: true, trigger: ['change'], message: '请上传封面', }, name: { required: true, trigger: ['blur', 'input'], message: '请填写商品名称', }, obj: { required: true, trigger: ['change'], message: '请上传模型', }, product_type1: { required: true, validator(rule: FormItemRule, value: string) { if ( submitState.value && (!model.value.product_type2 || !model.value.product_type1) ) { return new Error('请选择商品品类'); } return true; }, trigger: ['blur', 'change'], }, }; const parameterGoodsGetCategoryList = ref<HttpAdminGoodsGetCategoryListParameter>( HttpAdminGoodsGetCategoryListParameterInitial(), ); parameterGoodsGetCategoryList.value.pid = 0; const { data: dataGoodsGetCategoryList, // isLoading: isLoadingGoodsGetCategoryList, execute: executeGoodsGetCategoryList, onResult: onResultGoodsGetCategoryList, } = usePost<HttpAdminGoodsGetCategoryListRsult[]>( '/admin/goods/getCategoryList', parameterGoodsGetCategoryList, false, ); onResultGoodsGetCategoryList((result) => { const options: { label: string; value: number }[] = []; if (result.value === undefined) { } else { result.value.forEach((item) => { options.push({ label: item.name, value: item.id, }); }); } if (parameterGoodsGetCategoryList.value.pid === 0) { goodsOptions_one.value = options; } else { goodsOptions_two.value = options; } // console.log(goodsOptions_one.value); }); // 上传模型 // const { // fileData: fileDataUploadFbx, // // progress: percentageNum, // execute: executeUploadFbx, // // controller: controllerUploadFbx, // onResult: onmodelUploadResult, // } = useUpload<modelUploadResult[]>('/admin/goods/uploadFbx'); // onmodelUploadResult((result) => { // let uploadinfo = JSON.parse(JSON.stringify(result.value)); // specificationList.value[saveIndexnum.value].obj_url = uploadinfo.url; // specificationList.value[saveIndexnum.value].percentageNum = 100; // message.success('上传成功'); // }); function cancelUpload() { percentageNum.value = 0; uploadfbxState.value = true; // model.value.obj = ''; // controllerUploadFbx.value.abort(); } function changeTwo(value: null) { submitState.value = false; model.value.product_type2 = value; } function changeOne(value: null) { submitState.value = false; model.value.product_type1 = value; model.value.product_type2 = null; parameterGoodsGetCategoryList.value.pid = Number(value); executeGoodsGetCategoryList(); } function goGoodsList() { router.push({ path: '/goods', }); } function handleValidateClick(e: MouseEvent) { if (initState.value === true) { return; } submitState.value = true; let jsonSpec = JSON.parse(JSON.stringify(specificationList.value)); console.log(jsonSpec); // let obj_nameArray: string[] = []; let jsonSpecState = false; jsonSpec.forEach( (item: { obj_url: string; specifications_pic: string; specifications_name: string; }) => { if ( item.obj_url === '' || item.specifications_pic === '' || item.specifications_name === '' ) { jsonSpecState = true; } }, ); submitClick.value = true; // let obj_nameString = obj_nameArray.join(','); e.preventDefault(); if (formRef.value === null) { } else { formRef.value.validate((errors: unknown) => { if (!errors) { // if (obj_nameArray.length === 0) { // message.warning('每个商品至少一个规格有值'); // return; // } if (jsonSpecState === true) { return; } showspin.value = true; if (queryInfo.type === 'edit') { const params = { name: model.value.name, cover: model.value.cover, pic: model.value.pic, video: model.value.video, url: model.value.url, product_type1: model.value.product_type1, product_type2: model.value.product_type2, obj: specificationList.value[0].obj_url_nodomainname, // obj: model.value.obj, // obj_name: model.value.obj_name, // specifications: obj_nameString, specifications: specificationList.value, id: queryInfo.id, }; const { onResult: ongoodsStore, one rror: one rror } = usePost< goodsStore[] >('/admin/goods/update', params); ongoodsStore(() => { message.success('编辑成功'); showspin.value = false; goGoodsList(); }); one rror(() => { showspin.value = false; }); } else { const params = { name: model.value.name, cover: model.value.cover, pic: model.value.pic, video: model.value.video, url: model.value.url, product_type1: model.value.product_type1, product_type2: model.value.product_type2, obj: specificationList.value[0].obj_url_nodomainname, // obj_name: model.value.obj_name, specifications: specificationList.value, }; const { onResult: ongoodsStore, one rror: one rror } = usePost< goodsStore[] >('/admin/goods/store', params); ongoodsStore(() => { message.success('新建成功'); showspin.value = false; goGoodsList(); }); one rror(() => { showspin.value = false; }); } } else { clickState.value = true; } }); } } function formRefrules() { // console.log(clickState.value); if (clickState.value === false) { return; } if (formRef.value === null) { } else { formRef.value.validate((errors: unknown) => { if (!errors) { } else { // message.error('Invalid'); } }); } } function coverfileChange() { let oBtn = uploadInput.value as HTMLInputElement; oBtn.click(); } function videofileChange() { let oBtn = uploadInputvideo.value as HTMLInputElement; oBtn.click(); } function picfileChange() { let oBtn = uploadInputbook.value as HTMLInputElement; oBtn.click(); } function specfbxfileChange(index: any) { saveIndexnum.value = index; let oBtn = uploadInputmodel.value as HTMLInputElement; oBtn.click(); } // function speccoverfileChange(index: any) { saveIndexnum.value = index; let oBtn = specuploadInput.value as HTMLInputElement; oBtn.click(); } function againUpload(item: string) { if (item === 'cover') { coverfileChange(); return; } if (item === 'pic') { picfileChange(); return; } if (item === 'video') { videofileChange(); return; } // if (item === 'fbx') { // // fbxfileChange(); // return; // } } function deleteUpload(item: string) { if (item === 'cover') { haveCoverurl.value = ''; model.value.cover = ''; return; } if (item === 'pic') { havePicurl.value = ''; model.value.pic = ''; return; } if (item === 'video') { haveVideourl.value = ''; model.value.video = ''; return; } } function uploadfileimg(e: any, files: any, typename: string) { if ( files[0].type !== 'image/png' && files[0].type !== 'image/jpg' && files[0].type !== 'image/jpeg' ) { message.warning('文件格式错误'); e.target.value = ''; return; } if (files[0].size > 5 * 1024 * 1024) { message.warning('图片大小不能超过5M'); e.target.value = ''; return; } const fileData = ref<FormData>(new FormData()); fileData.value.append('file', files[0]); const { onResult: onimgUploadResult } = usePost<imgUploadResult[]>( '/admin/goods/uploadPic', fileData, ); onimgUploadResult((result) => { let uploadinfo = JSON.parse(JSON.stringify(result.value)); if (typename === 'cover') { model.value.cover = uploadinfo.url; haveCoverurl.value = `${process.env.VUE_APP_BASE_URL}${uploadinfo.url}`; formRefrules(); } else { model.value.pic = uploadinfo.url; havePicurl.value = `${process.env.VUE_APP_BASE_URL}${uploadinfo.url}`; } message.success('上传成功'); }); e.target.value = ''; } function fileChange_cover(e: any) { const input = e.target as HTMLInputElement; let files = input.files; if (files) { uploadfileimg(e, files, 'cover'); } } function spec_fileChange_cover(e: any) { const input = e.target as HTMLInputElement; let files = input.files; if (files) { if ( files[0].type !== 'image/png' && files[0].type !== 'image/jpg' && files[0].type !== 'image/jpeg' ) { message.warning('文件格式错误'); e.target.value = ''; return; } if (files[0].size > 5 * 1024 * 1024) { message.warning('图片大小不能超过5M'); e.target.value = ''; return; } const fileData = ref<FormData>(new FormData()); fileData.value.append('file', files[0]); const { onResult: onimgUploadResult } = usePost<imgUploadResult[]>( '/admin/goods/uploadPic', fileData, ); onimgUploadResult((result) => { let uploadinfo = JSON.parse(JSON.stringify(result.value)); specificationList.value[ saveIndexnum.value ].specifications_pic = `${process.env.VUE_APP_BASE_URL}${uploadinfo.url}`; message.success('上传成功'); }); e.target.value = ''; } } function specagainUpload(index: any) { speccoverfileChange(index); } function specfbxagainUpload(index: any) { specfbxfileChange(index); } function fileChange_video(e: any) { const input = e.target as HTMLInputElement; let files = input.files; if (files) { // console.log(files[0].type); if (files[0].type !== 'video/mp4') { message.warning('文件格式错误'); e.target.value = ''; return; } if (files[0].size > 100 * 1024 * 1024) { message.warning('视频大小不能超过100M'); e.target.value = ''; return; } const fileData = ref<FormData>(new FormData()); fileData.value.append('file', files[0]); const { onResult: onvideoUploadResult } = usePost<videoUploadResult[]>( '/admin/goods/uploadVideo', fileData, ); onvideoUploadResult((result) => { let uploadinfo = JSON.parse(JSON.stringify(result.value)); model.value.video = uploadinfo.url; haveVideourl.value = `${process.env.VUE_APP_BASE_URL}${uploadinfo.url}`; message.success('上传成功'); }); e.target.value = ''; } } function specdeleteUpload(index: any) { specificationList.value[index].specifications_pic = ''; } function fileChange_pic(e: Event) { const input = e.target as HTMLInputElement; let files = input.files; if (files) { uploadfileimg(e, files, 'pic'); } } function fileChange_fbx(e: any) { const input = e.target as HTMLInputElement; let files = input.files; if (files) { // model.value.obj_name = files[0].name; var index = files[0].name.lastIndexOf('.'); //获取后缀 var ext = files[0].name.substr(index + 1); if (ext !== 'fbx' && ext !== 'FBX') { message.warning('文件格式错误'); e.target.value = ''; return; } const fileData = ref<FormData>(new FormData()); fileData.value.append('file', files[0]); // executeUploadFbx(); specificationList.value[saveIndexnum.value].uploadfbxState = false; specificationList.value[saveIndexnum.value].obj_name = files[0].name; percentageNum.value = 0; // uploadfbxState.value = false; let timer = setInterval(function () { percentageNum.value++; Number(percentageNum.value) > 98 ? (percentageNum.value = 99) : percentageNum.value; console.log(percentageNum.value); specificationList.value[saveIndexnum.value].percentageNum = percentageNum.value; }, 1000); const { onResult: onmodelUploadResult, one rror: onmodelUploadResultError, } = usePost<modelUploadResult[]>('/admin/goods/uploadFbx', fileData); onmodelUploadResult((result) => { let uploadinfo = JSON.parse(JSON.stringify(result.value)); specificationList.value[ saveIndexnum.value ].obj_url_nodomainname = `${uploadinfo.url}`; specificationList.value[ saveIndexnum.value ].obj_url = `${process.env.VUE_APP_BASE_URL}${uploadinfo.url}`; specificationList.value[saveIndexnum.value].percentageNum = 100; clearInterval(timer); message.success('上传成功'); }); onmodelUploadResultError((result) => { clearInterval(timer); specificationList.value[saveIndexnum.value].percentageNum = 0; specificationList.value[saveIndexnum.value].uploadfbxState = true; // if (result !== 'Network Error') { // message.error('模型上传失败请重新上传'); // } }); e.target.value = ''; } } function addspec() { specificationList.value.push({ specifications_name: '', obj_name: '', obj_url: '', obj_url_nodomainname: '', uploadfbxState: true, percentageNum: 0, specifications_pic: '', }); } // 规格列表 function getspecificationList() { const params = {}; const { onResult: onspecification } = usePost<specification[]>( '/admin/goods/getSpecificationList', params, ); onspecification((result) => { const options: { label: string; value: string }[] = []; if (result.value === undefined) { } else { result.value.forEach((item) => { options.push({ label: item.name, value: String(item.id), }); }); } allspecOptions.value = options; }); } // 商品详情 function getgoodsInfo() { const params = { id: queryInfo.id, }; const { onResult: ongoodsInfo } = usePost<goodsInfo[]>( '/admin/goods/getInfo', params, ); ongoodsInfo((result) => { let goodsinfo = JSON.parse(JSON.stringify(result.value)); // console.log(goodsinfo); model.value = { cover: goodsinfo.cover, //商品封面图 name: goodsinfo.name, //商品封面图, //商品名称 pic: goodsinfo.pic, //商品封面图, //商品名称 video: goodsinfo.video, product_type1: goodsinfo.product_type1, //一级分类 product_type2: goodsinfo.product_type2, //二级分类 url: goodsinfo.url, //商品外链 // obj: goodsinfo.obj, //模型文件地址 // obj_name: goodsinfo.obj_name, //模型文件地址 specifications: goodsinfo.specifications, //规格 }; specificationList.value = goodsinfo.specifications; parameterGoodsGetCategoryList.value.pid = Number(goodsinfo.product_type1); executeGoodsGetCategoryList(); haveCoverurl.value = goodsinfo.cover_url; havePicurl.value = goodsinfo.pic_url; haveVideourl.value = goodsinfo.video_url; initState.value = false; }); } function handleDelAll() { specificationList.value.splice(delNum.value, 1); } function deletespec(index: number) { if (specificationList.value.length === 1) { message.warning('每个商品至少一个规格'); return; } showDelAll.value = true; delNum.value = index; // dialog.warning({ // title: '提示', // content: '确定删除此规格吗', // positiveText: '确定', // negativeText: '取消', // maskClosable: false, // closeOnEsc: false, // onPositiveClick: () => { // specificationList.value.splice(index, 1); // }, // onNegativeClick: () => { // // message.error('取消'); // }, // }); } onMounted(() => { // console.log(queryInfo); executeGoodsGetCategoryList(); // getspecificationList(); if (queryInfo.type === 'edit') { setTimeout(function () { getgoodsInfo(); }, 100); } else { initState.value = false; } }); </script> <style scoped lang="scss"> .breadcrumbs { span { color: #939eaf; } .active-span { color: #334767; } } .tiptext { font-size: 12px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #606266; margin-top: 15px; margin-left: 15px; } .videotiptext { font-size: 12px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #606266; margin-top: 15px; margin-left: 32px; } // .uploadbox { // } .disflexupload { display: flex; align-items: flex-end; } .cover_img { width: 199px; height: 199px; border-radius: 4px; border: 1px solid #dcdfe6; display: flex; overflow: hidden; align-items: center; justify-content: center; img { max-width: 199px; max-height: 199px; } } .pic_img { width: 199px; height: 101px; background: #f2f6fc; border-radius: 4px; border: 1px solid #dcdfe6; display: flex; overflow: hidden; justify-content: center; align-items: center; img { max-width: 199px; max-height: 101px; } video { max-width: 199px; max-height: 101px; } } .uploadnew { cursor: pointer; margin-left: 19px; font-size: 14px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #2f88eb; .delspan { color: #e0798a; margin-left: 15px; } } .inputbox { width: 199px; height: 199px; background: #f2f6fc; border-radius: 4px; border: 1px dashed #dcdfe6; display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: 14px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #606266; cursor: pointer; } .spec-inputbox { width: 120px; height: 120px; background: #f2f6fc; border-radius: 4px; border: 1px dashed #dcdfe6; display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: 14px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #606266; cursor: pointer; } .spec-cover_img { width: 120px; height: 120px; border-radius: 4px; border: 1px solid #dcdfe6; display: flex; overflow: hidden; align-items: center; justify-content: center; img { max-width: 120px; max-height: 120px; } } .spec-tiptext { font-size: 12px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #606266; margin-top: 15px; margin-left: -24px; } .spec-uploadnew { width: 200px; cursor: pointer; font-size: 14px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; margin-left: 19px; span { color: #2f88eb !important; margin-right: 0px !important; margin-left: 0px !important; } .delspan { color: #e0798a !important; margin-left: 15px !important; } } .inputbox-video-book { width: 199px; height: 101px; background: #f2f6fc; border-radius: 4px; border: 1px dashed #dcdfe6; display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: 14px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #606266; cursor: pointer; } .inputbox-model { width: 198px; height: 37px; border-radius: 3px; border: 1px solid #2c84ea; font-size: 18px; font-family: AlibabaPuHuiTiR; color: #2881ea; line-height: 37px; text-align: center; cursor: pointer; } .inputbox-model:hover { background: linear-gradient(180deg, #227ae9 0%, #3d97ee 100%); color: #ffffff; } .model-tiptext { font-size: 14px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #606266; margin-left: 14px; } .progressbox { position: relative; .modelnamebox { position: absolute; top: -8px; left: 0; font-size: 14px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #000000; display: flex; align-items: center; justify-content: space-between; width: 228px; .uploadcancle { font-size: 12px; color: RGBA(185, 185, 185, 1); cursor: pointer; } } .fbxbox { font-size: 14px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #606266; display: flex; flex-direction: row; align-items: center; img { width: 14px; height: 14px; margin-left: 6px; } span { font-size: 14px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: #1965ff; margin-left: 20px; cursor: pointer; } } } .creatbox { margin-top: 24px; width: 1230px; height: 735px; background: #ffffff; box-shadow: 0px 2px 3px 0px #e9ebf2; .title { font-size: 16px; font-family: AlibabaPuHuiTiM; color: #000000; padding: 33px 0 9px 47px; } .disflex { display: flex; margin-left: 72px; margin-right: 94px; .disflex-left { margin-right: 104px; width: 572px; } .disflex-right { width: 495px; .specinfo { width: 495px; } // .specinfo::-webkit-scrollbar { // display: none; /* Chrome Safari */ // } .addspecbox { user-select: none; width: 120px; height: 37px; border-radius: 8px; border: 1px solid #318aec; text-align: center; font-size: 18px; font-family: AlibabaPuHuiTiR; color: #348eec; line-height: 37px; margin-top: 30px; cursor: pointer; } .spec { margin-bottom: 30px; } // .spec:last-child { // // margin-bottom: 0; // } .specbox { width: 483px; border: 1px solid #e4e5e7; .topbox { height: 40px; background: #f6f9fc; display: flex; align-items: center; justify-content: space-between; .text { font-size: 14px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: rgba(96, 98, 102, 1); margin-left: 14px; span { color: rgb(239, 68, 68); margin-right: 3px; } } img { width: 22px; height: 22px; margin-right: 14px; cursor: pointer; } } .selectbox { margin-top: 32px; align-items: baseline; } } .activeSpecbox { border: 1px solid #de576d; } .spec:last-child { margin-bottom: 0px; } } } } .disBox { display: flex; align-items: baseline; span { color: rgb(239, 68, 68); margin-right: -10px; margin-left: 18px; } } .warningtext { color: rgb(239, 68, 68); margin-left: 1px; } :deep(.n-progress.n-progress--line .n-progress-icon.n-progress-icon--as-text) { color: var(--n-text-color-line-outer); text-align: center; width: 40px; font-size: var(--n-font-size); padding-left: 15px; transition: color 0.3s var(--n-bezier); } :deep(.n-progress .n-progress-graph .n-progress-graph-line .n-progress-graph-line-rail) { position: relative; overflow: hidden; height: var(--n-rail-height); border-radius: 5px; background-color: RGBA(213, 231, 251, 1); transition: background-color 0.3s var(--n-bezier); height: 4px; } :deep(.n-progress.n-progress--line .n-progress-content) { display: flex; align-items: center; margin-top: 10px; } .puplic-btn-disable { cursor: default !important; } </style>
标签:files,obj,记录,value,vue3,const,model,font From: https://www.cnblogs.com/ylblogs/p/16595633.html