记录vue3

<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, onError: onError } = usePost<
              goodsStore[]
            >('/admin/goods/update', params);
            ongoodsStore(() => {
              message.success('编辑成功');
              showspin.value = false;
              goGoodsList();
            });
            onError(() => {
              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, onError: onError } = usePost<
              goodsStore[]
            >('/admin/goods/store', params);
            ongoodsStore(() => {
              message.success('新建成功');
              showspin.value = false;
              goGoodsList();
            });
            onError(() => {
              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,
        onError: 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>

  

posted @ 2022-08-17 16:15  小小小小小前端  阅读(94)  评论(0编辑  收藏  举报