瀏覽代碼

多图上传组件优化

puhui999 1 年之前
父節點
當前提交
f88b26e3c3

+ 2 - 0
src/api/crm/followup/index.ts

@@ -7,6 +7,8 @@ export interface FollowUpRecordVO {
   bizId: number // 数据编号
   bizId: number // 数据编号
   type: number // 跟进类型
   type: number // 跟进类型
   content: string // 跟进内容
   content: string // 跟进内容
+  picUrls: string[]
+  fileUrls: string[]
   nextTime: Date // 下次联系时间
   nextTime: Date // 下次联系时间
   businessIds: number[] // 关联的商机编号数组
   businessIds: number[] // 关联的商机编号数组
   contactIds: number[] // 关联的联系人编号数组
   contactIds: number[] // 关联的联系人编号数组

+ 43 - 25
src/components/UploadFile/src/UploadImgs.vue

@@ -28,7 +28,7 @@
             <Icon icon="ep:zoom-in" />
             <Icon icon="ep:zoom-in" />
             <span>查看</span>
             <span>查看</span>
           </div>
           </div>
-          <div class="handle-icon" @click="handleRemove(file)" v-if="!disabled">
+          <div v-if="!disabled" class="handle-icon" @click="handleRemove(file)">
             <Icon icon="ep:delete" />
             <Icon icon="ep:delete" />
             <span>删除</span>
             <span>删除</span>
           </div>
           </div>
@@ -46,7 +46,6 @@
   </div>
   </div>
 </template>
 </template>
 <script lang="ts" setup>
 <script lang="ts" setup>
-import { PropType } from 'vue'
 import type { UploadFile, UploadProps, UploadUserFile } from 'element-plus'
 import type { UploadFile, UploadProps, UploadUserFile } from 'element-plus'
 import { ElNotification } from 'element-plus'
 import { ElNotification } from 'element-plus'
 
 
@@ -70,10 +69,7 @@ type FileTypes =
   | 'image/x-icon'
   | 'image/x-icon'
 
 
 const props = defineProps({
 const props = defineProps({
-  modelValue: {
-    type: Array as PropType<UploadUserFile[]>,
-    required: true
-  },
+  modelValue: propTypes.oneOfType<string | string[]>([String, Array<String>]).isRequired,
   updateUrl: propTypes.string.def(import.meta.env.VITE_UPLOAD_URL),
   updateUrl: propTypes.string.def(import.meta.env.VITE_UPLOAD_URL),
   drag: propTypes.bool.def(true), // 是否支持拖拽上传 ==> 非必传(默认为 true)
   drag: propTypes.bool.def(true), // 是否支持拖拽上传 ==> 非必传(默认为 true)
   disabled: propTypes.bool.def(false), // 是否禁用上传组件 ==> 非必传(默认为 false)
   disabled: propTypes.bool.def(false), // 是否禁用上传组件 ==> 非必传(默认为 false)
@@ -91,18 +87,8 @@ const uploadHeaders = ref({
 })
 })
 
 
 const fileList = ref<UploadUserFile[]>([])
 const fileList = ref<UploadUserFile[]>([])
-// fix: 改为动态监听赋值解决图片回显问题
-watch(
-  () => props.modelValue,
-  (data) => {
-    if (!data) return
-    fileList.value = data
-  },
-  {
-    deep: true,
-    immediate: true
-  }
-)
+const uploadNumber = ref<number>(0)
+const uploadList = ref<UploadUserFile[]>([])
 /**
 /**
  * @description 文件上传之前判断
  * @description 文件上传之前判断
  * @param rawFile 上传的文件
  * @param rawFile 上传的文件
@@ -122,29 +108,61 @@ const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
       message: `上传图片大小不能超过 ${props.fileSize}M!`,
       message: `上传图片大小不能超过 ${props.fileSize}M!`,
       type: 'warning'
       type: 'warning'
     })
     })
+  uploadNumber.value++
   return imgType.includes(rawFile.type as FileTypes) && imgSize
   return imgType.includes(rawFile.type as FileTypes) && imgSize
 }
 }
 
 
 // 图片上传成功
 // 图片上传成功
 interface UploadEmits {
 interface UploadEmits {
-  (e: 'update:modelValue', value: UploadUserFile[]): void
+  (e: 'update:modelValue', value: string[]): void
 }
 }
 
 
 const emit = defineEmits<UploadEmits>()
 const emit = defineEmits<UploadEmits>()
-const uploadSuccess = (response, uploadFile: UploadFile) => {
-  if (!response) return
-  // TODO 多图上传组件成功后只是把保存成功后的url替换掉组件选图时的文件路径,所以返回的fileList包含的是一个包含文件信息的对象列表
-  uploadFile.url = response.data
-  emit('update:modelValue', fileList.value)
+const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => {
   message.success('上传成功')
   message.success('上传成功')
+  // 删除自身
+  debugger
+  const index = fileList.value.findIndex((item) => item.response?.data === res.data)
+  fileList.value.splice(index, 1)
+  uploadList.value.push({ name: res.data, url: res.data })
+  if (uploadList.value.length == uploadNumber.value) {
+    fileList.value.push(...uploadList.value)
+    uploadList.value = []
+    uploadNumber.value = 0
+    emitUpdateModelValue()
+  }
 }
 }
 
 
+// 监听模型绑定值变动
+watch(
+  () => props.modelValue,
+  (val: string | string[]) => {
+    if (!val) {
+      fileList.value = [] // fix:处理掉缓存,表单重置后上传组件的内容并没有重置
+      return
+    }
+
+    fileList.value = [] // 保障数据为空
+    fileList.value.push(
+      ...(val as string[]).map((url) => ({ name: url.substring(url.lastIndexOf('/') + 1), url }))
+    )
+  },
+  { immediate: true, deep: true }
+)
+// 发送图片链接列表更新
+const emitUpdateModelValue = () => {
+  let result: string[] = fileList.value.map((file) => file.url!)
+  emit('update:modelValue', result)
+}
 // 删除图片
 // 删除图片
 const handleRemove = (uploadFile: UploadFile) => {
 const handleRemove = (uploadFile: UploadFile) => {
   fileList.value = fileList.value.filter(
   fileList.value = fileList.value.filter(
     (item) => item.url !== uploadFile.url || item.name !== uploadFile.name
     (item) => item.url !== uploadFile.url || item.name !== uploadFile.name
   )
   )
-  emit('update:modelValue', fileList.value)
+  emit(
+    'update:modelValue',
+    fileList.value.map((file) => file.url!)
+  )
 }
 }
 
 
 // 图片上传错误提示
 // 图片上传错误提示

+ 21 - 32
src/views/crm/followup/FollowUpRecordForm.vue

@@ -34,49 +34,36 @@
         <!-- TODO @puhui999:不搞富文本哈;然后加个附件、图片两个 form-item 哈 -->
         <!-- TODO @puhui999:不搞富文本哈;然后加个附件、图片两个 form-item 哈 -->
         <el-col :span="24">
         <el-col :span="24">
           <el-form-item label="跟进内容" prop="content">
           <el-form-item label="跟进内容" prop="content">
-            <Editor v-model="formData.content" height="300px" />
+            <el-input v-model="formData.content" :rows="3" type="textarea" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="图片" prop="content">
+            <UploadImgs v-model="formData.picUrls" class="min-w-80px" />
+          </el-form-item>
+        </el-col>
+        <el-col :span="24">
+          <el-form-item label="附件" prop="content">
+            <UploadFile v-model="formData.fileUrls" class="min-w-80px" />
           </el-form-item>
           </el-form-item>
         </el-col>
         </el-col>
-        <!-- TODO @puhui999:因为不考虑编辑的情况,是不是关联要是个弹窗选择哈? -->
         <el-col :span="24">
         <el-col :span="24">
           <el-form-item label="关联联系人" prop="contactIds">
           <el-form-item label="关联联系人" prop="contactIds">
-            <el-select v-model="formData.contactIds" multiple placeholder="请选择">
-              <el-option
-                v-for="item in allContactList"
-                :key="item.id"
-                :label="item.name"
-                :value="item.id"
-              />
-            </el-select>
+            <el-button @click="handleAddContact">
+              <Icon class="mr-5px" icon="ep:plus" />
+              添加联系人
+            </el-button>
             <contact-list v-model:contactIds="formData.contactIds" />
             <contact-list v-model:contactIds="formData.contactIds" />
           </el-form-item>
           </el-form-item>
-          <!--          <el-form-item label="关联联系人" prop="contactIds">-->
-          <!--            <el-button @click="handleAddContact">-->
-          <!--              <Icon class="mr-5px" icon="ep:plus" />-->
-          <!--              选择添加联系人-->
-          <!--            </el-button>-->
-          <!--            <contact-list v-model:contactIds="formData.contactIds" />-->
-          <!--          </el-form-item>-->
         </el-col>
         </el-col>
         <el-col :span="24">
         <el-col :span="24">
           <el-form-item label="关联商机" prop="businessIds">
           <el-form-item label="关联商机" prop="businessIds">
-            <el-select v-model="formData.businessIds" multiple placeholder="请选择">
-              <el-option
-                v-for="item in allBusinessList"
-                :key="item.id"
-                :label="item.name"
-                :value="item.id"
-              />
-            </el-select>
+            <el-button @click="handleAddBusiness">
+              <Icon class="mr-5px" icon="ep:plus" />
+              添加商机
+            </el-button>
             <business-list v-model:businessIds="formData.businessIds" />
             <business-list v-model:businessIds="formData.businessIds" />
           </el-form-item>
           </el-form-item>
-          <!--          <el-form-item label="关联商机" prop="businessIds">-->
-          <!--            <el-button @click="handleAddBusiness">-->
-          <!--              <Icon class="mr-5px" icon="ep:plus" />-->
-          <!--              选择添加商机-->
-          <!--            </el-button>-->
-          <!--            <business-list v-model:businessIds="formData.businessIds" />-->
-          <!--          </el-form-item>-->
         </el-col>
         </el-col>
       </el-row>
       </el-row>
     </el-form>
     </el-form>
@@ -159,6 +146,8 @@ const submitForm = async () => {
   }
   }
 }
 }
 
 
+const handleAddContact = () => {}
+const handleAddBusiness = () => {}
 /** 重置表单 */
 /** 重置表单 */
 const resetForm = () => {
 const resetForm = () => {
   formRef.value?.resetFields()
   formRef.value?.resetFields()

+ 4 - 4
src/views/crm/message/tables/TodayCustomer.vue

@@ -15,9 +15,9 @@
         <el-select v-model="queryParams.contactStatus" class="!w-240px" placeholder="状态">
         <el-select v-model="queryParams.contactStatus" class="!w-240px" placeholder="状态">
           <el-option
           <el-option
             v-for="(option, index) in CONTACT_STATUS"
             v-for="(option, index) in CONTACT_STATUS"
+            :key="index"
             :label="option.label"
             :label="option.label"
             :value="option.value"
             :value="option.value"
-            :key="index"
           />
           />
         </el-select>
         </el-select>
       </el-form-item>
       </el-form-item>
@@ -25,9 +25,9 @@
         <el-select v-model="queryParams.sceneType" class="!w-240px" placeholder="归属">
         <el-select v-model="queryParams.sceneType" class="!w-240px" placeholder="归属">
           <el-option
           <el-option
             v-for="(option, index) in SCENE_TYPES"
             v-for="(option, index) in SCENE_TYPES"
+            :key="index"
             :label="option.label"
             :label="option.label"
             :value="option.value"
             :value="option.value"
-            :key="index"
           />
           />
         </el-select>
         </el-select>
       </el-form-item>
       </el-form-item>
@@ -84,7 +84,7 @@
           <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.dealStatus" />
           <dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.dealStatus" />
         </template>
         </template>
       </el-table-column>
       </el-table-column>
-      <!-- TODO @puhui999:距进入公海天数 -->
+      <el-table-column align="center" label="距进入公海天数" prop="poolDay" width="100px" />
       <el-table-column
       <el-table-column
         :formatter="dateFormatter"
         :formatter="dateFormatter"
         align="center"
         align="center"
@@ -120,7 +120,7 @@
   </ContentWrap>
   </ContentWrap>
 </template>
 </template>
 
 
-<script lang="ts" setup name="TodayCustomer">
+<script lang="ts" name="TodayCustomer" setup>
 import { DICT_TYPE } from '@/utils/dict'
 import { DICT_TYPE } from '@/utils/dict'
 import { dateFormatter } from '@/utils/formatTime'
 import { dateFormatter } from '@/utils/formatTime'
 import * as MessageApi from '@/api/crm/message'
 import * as MessageApi from '@/api/crm/message'

+ 9 - 14
src/views/mall/product/comment/CommentForm.vue

@@ -1,17 +1,17 @@
 <template>
 <template>
-  <Dialog title="添加虚拟评论" v-model="dialogVisible">
+  <Dialog v-model="dialogVisible" title="添加虚拟评论">
     <el-form
     <el-form
       ref="formRef"
       ref="formRef"
+      v-loading="formLoading"
       :model="formData"
       :model="formData"
       :rules="formRules"
       :rules="formRules"
       label-width="100px"
       label-width="100px"
-      v-loading="formLoading"
     >
     >
       <el-form-item label="商品" prop="spuId">
       <el-form-item label="商品" prop="spuId">
         <SpuShowcase v-model="formData.spuId" :limit="1" />
         <SpuShowcase v-model="formData.spuId" :limit="1" />
       </el-form-item>
       </el-form-item>
-      <el-form-item label="商品规格" prop="skuId" v-if="formData.spuId">
-        <div @click="handleSelectSku" class="h-60px w-60px">
+      <el-form-item v-if="formData.spuId" label="商品规格" prop="skuId">
+        <div class="h-60px w-60px" @click="handleSelectSku">
           <div v-if="skuData && skuData.picUrl">
           <div v-if="skuData && skuData.picUrl">
             <el-image :src="skuData.picUrl" />
             <el-image :src="skuData.picUrl" />
           </div>
           </div>
@@ -27,7 +27,7 @@
         <el-input v-model="formData.userNickname" placeholder="请输入用户名称" />
         <el-input v-model="formData.userNickname" placeholder="请输入用户名称" />
       </el-form-item>
       </el-form-item>
       <el-form-item label="评论内容" prop="content">
       <el-form-item label="评论内容" prop="content">
-        <el-input type="textarea" v-model="formData.content" />
+        <el-input v-model="formData.content" type="textarea" />
       </el-form-item>
       </el-form-item>
       <el-form-item label="描述星级" prop="descriptionScores">
       <el-form-item label="描述星级" prop="descriptionScores">
         <el-rate v-model="formData.descriptionScores" />
         <el-rate v-model="formData.descriptionScores" />
@@ -40,13 +40,13 @@
       </el-form-item>
       </el-form-item>
     </el-form>
     </el-form>
     <template #footer>
     <template #footer>
-      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
+      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
       <el-button @click="dialogVisible = false">取 消</el-button>
       <el-button @click="dialogVisible = false">取 消</el-button>
     </template>
     </template>
   </Dialog>
   </Dialog>
-  <SkuTableSelect ref="skuTableSelectRef" @change="handleSkuChange" :spu-id="formData.spuId" />
+  <SkuTableSelect ref="skuTableSelectRef" :spu-id="formData.spuId" @change="handleSkuChange" />
 </template>
 </template>
-<script setup lang="ts">
+<script lang="ts" setup>
 import * as CommentApi from '@/api/mall/product/comment'
 import * as CommentApi from '@/api/mall/product/comment'
 import SpuShowcase from '@/views/mall/product/spu/components/SpuShowcase.vue'
 import SpuShowcase from '@/views/mall/product/spu/components/SpuShowcase.vue'
 import * as ProductSpuApi from '@/api/mall/product/spu'
 import * as ProductSpuApi from '@/api/mall/product/spu'
@@ -115,13 +115,8 @@ const submitForm = async () => {
   // 提交请求
   // 提交请求
   formLoading.value = true
   formLoading.value = true
   try {
   try {
-    //处理评论图片
-    const picUrls = formData.value.picUrls.map((item) => {
-      return item?.url ? item.url : item
-    })
-    const data = { ...formData.value, picUrls }
     if (formType.value === 'create') {
     if (formType.value === 'create') {
-      await CommentApi.createComment(data)
+      await CommentApi.createComment(unref(formData.value) as any)
       message.success(t('common.createSuccess'))
       message.success(t('common.createSuccess'))
     }
     }
     dialogVisible.value = false
     dialogVisible.value = false

+ 15 - 19
src/views/mall/product/spu/form/InfoForm.vue

@@ -1,16 +1,16 @@
 <!-- 商品发布 - 基础设置 -->
 <!-- 商品发布 - 基础设置 -->
 <template>
 <template>
-  <el-form ref="formRef" :model="formData" :rules="rules" label-width="120px" :disabled="isDetail">
+  <el-form ref="formRef" :disabled="isDetail" :model="formData" :rules="rules" label-width="120px">
     <el-form-item label="商品名称" prop="name">
     <el-form-item label="商品名称" prop="name">
       <el-input
       <el-input
         v-model="formData.name"
         v-model="formData.name"
-        placeholder="请输入商品名称"
-        type="textarea"
         :autosize="{ minRows: 2, maxRows: 2 }"
         :autosize="{ minRows: 2, maxRows: 2 }"
-        maxlength="64"
-        :show-word-limit="true"
         :clearable="true"
         :clearable="true"
+        :show-word-limit="true"
         class="w-80!"
         class="w-80!"
+        maxlength="64"
+        placeholder="请输入商品名称"
+        type="textarea"
       />
       />
     </el-form-item>
     </el-form-item>
     <el-form-item label="商品分类" prop="categoryId">
     <el-form-item label="商品分类" prop="categoryId">
@@ -20,12 +20,12 @@
         :props="defaultProps"
         :props="defaultProps"
         class="w-80"
         class="w-80"
         clearable
         clearable
-        placeholder="请选择商品分类"
         filterable
         filterable
+        placeholder="请选择商品分类"
       />
       />
     </el-form-item>
     </el-form-item>
     <el-form-item label="商品品牌" prop="brandId">
     <el-form-item label="商品品牌" prop="brandId">
-      <el-select v-model="formData.brandId" placeholder="请选择商品品牌" class="w-80">
+      <el-select v-model="formData.brandId" class="w-80" placeholder="请选择商品品牌">
         <el-option
         <el-option
           v-for="item in brandList"
           v-for="item in brandList"
           :key="item.id"
           :key="item.id"
@@ -35,25 +35,25 @@
       </el-select>
       </el-select>
     </el-form-item>
     </el-form-item>
     <el-form-item label="商品关键字" prop="keyword">
     <el-form-item label="商品关键字" prop="keyword">
-      <el-input v-model="formData.keyword" placeholder="请输入商品关键字" class="w-80!" />
+      <el-input v-model="formData.keyword" class="w-80!" placeholder="请输入商品关键字" />
     </el-form-item>
     </el-form-item>
     <el-form-item label="商品简介" prop="introduction">
     <el-form-item label="商品简介" prop="introduction">
       <el-input
       <el-input
         v-model="formData.introduction"
         v-model="formData.introduction"
-        placeholder="请输入商品名称"
-        type="textarea"
         :autosize="{ minRows: 2, maxRows: 2 }"
         :autosize="{ minRows: 2, maxRows: 2 }"
-        maxlength="128"
-        :show-word-limit="true"
         :clearable="true"
         :clearable="true"
+        :show-word-limit="true"
         class="w-80!"
         class="w-80!"
+        maxlength="128"
+        placeholder="请输入商品名称"
+        type="textarea"
       />
       />
     </el-form-item>
     </el-form-item>
     <el-form-item label="商品封面图" prop="picUrl">
     <el-form-item label="商品封面图" prop="picUrl">
-      <UploadImg v-model="formData.picUrl" height="80px" :disabled="isDetail" />
+      <UploadImg v-model="formData.picUrl" :disabled="isDetail" height="80px" />
     </el-form-item>
     </el-form-item>
     <el-form-item label="商品轮播图" prop="sliderPicUrls">
     <el-form-item label="商品轮播图" prop="sliderPicUrls">
-      <UploadImgs v-model:modelValue="formData.sliderPicUrls" :disabled="isDetail" />
+      <UploadImgs v-model="formData.sliderPicUrls" :disabled="isDetail" />
     </el-form-item>
     </el-form-item>
   </el-form>
   </el-form>
 </template>
 </template>
@@ -64,9 +64,9 @@ import { propTypes } from '@/utils/propTypes'
 import { defaultProps, handleTree } from '@/utils/tree'
 import { defaultProps, handleTree } from '@/utils/tree'
 import type { Spu } from '@/api/mall/product/spu'
 import type { Spu } from '@/api/mall/product/spu'
 import * as ProductCategoryApi from '@/api/mall/product/category'
 import * as ProductCategoryApi from '@/api/mall/product/category'
+import { CategoryVO } from '@/api/mall/product/category'
 import * as ProductBrandApi from '@/api/mall/product/brand'
 import * as ProductBrandApi from '@/api/mall/product/brand'
 import { BrandVO } from '@/api/mall/product/brand'
 import { BrandVO } from '@/api/mall/product/brand'
-import { CategoryVO } from '@/api/mall/product/category'
 
 
 defineOptions({ name: 'ProductSpuInfoForm' })
 defineOptions({ name: 'ProductSpuInfoForm' })
 const props = defineProps({
 const props = defineProps({
@@ -107,10 +107,6 @@ watch(
       return
       return
     }
     }
     copyValueToTarget(formData, data)
     copyValueToTarget(formData, data)
-    // TODO @puhui999:优化多文件上传,看看有没可能搞成返回 v-model 图片列表这种
-    formData.sliderPicUrls = data['sliderPicUrls']?.map((item) => ({
-      url: item
-    }))
   },
   },
   {
   {
     immediate: true
     immediate: true

+ 6 - 16
src/views/mall/promotion/diy/page/DiyPageForm.vue

@@ -1,11 +1,11 @@
 <template>
 <template>
-  <Dialog :title="dialogTitle" v-model="dialogVisible">
+  <Dialog v-model="dialogVisible" :title="dialogTitle">
     <el-form
     <el-form
       ref="formRef"
       ref="formRef"
+      v-loading="formLoading"
       :model="formData"
       :model="formData"
       :rules="formRules"
       :rules="formRules"
       label-width="100px"
       label-width="100px"
-      v-loading="formLoading"
     >
     >
       <el-form-item label="页面名称" prop="name">
       <el-form-item label="页面名称" prop="name">
         <el-input v-model="formData.name" placeholder="请输入页面名称" />
         <el-input v-model="formData.name" placeholder="请输入页面名称" />
@@ -18,12 +18,12 @@
       </el-form-item>
       </el-form-item>
     </el-form>
     </el-form>
     <template #footer>
     <template #footer>
-      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
+      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
       <el-button @click="dialogVisible = false">取 消</el-button>
       <el-button @click="dialogVisible = false">取 消</el-button>
     </template>
     </template>
   </Dialog>
   </Dialog>
 </template>
 </template>
-<script setup lang="ts">
+<script lang="ts" setup>
 import * as DiyPageApi from '@/api/mall/promotion/diy/page'
 import * as DiyPageApi from '@/api/mall/promotion/diy/page'
 
 
 /** 装修页面表单 */
 /** 装修页面表单 */
@@ -57,13 +57,7 @@ const open = async (type: string, id?: number) => {
   if (id) {
   if (id) {
     formLoading.value = true
     formLoading.value = true
     try {
     try {
-      const diyPage = await DiyPageApi.getDiyPage(id) // 处理预览图
-      if (diyPage?.previewPicUrls?.length > 0) {
-        diyPage.previewPicUrls = diyPage.previewPicUrls.map((url: string) => {
-          return { url }
-        })
-      }
-      formData.value = diyPage
+      formData.value = await DiyPageApi.getDiyPage(id)
     } finally {
     } finally {
       formLoading.value = false
       formLoading.value = false
     }
     }
@@ -81,11 +75,7 @@ const submitForm = async () => {
   // 提交请求
   // 提交请求
   formLoading.value = true
   formLoading.value = true
   try {
   try {
-    // 处理预览图
-    const previewPicUrls = formData.value.previewPicUrls.map((item) => {
-      return item['url'] ? item['url'] : item
-    })
-    const data = { ...formData.value, previewPicUrls } as unknown as DiyPageApi.DiyPageVO
+    const data = formData.value as unknown as DiyPageApi.DiyPageVO
     if (formType.value === 'create') {
     if (formType.value === 'create') {
       await DiyPageApi.createDiyPage(data)
       await DiyPageApi.createDiyPage(data)
       message.success(t('common.createSuccess'))
       message.success(t('common.createSuccess'))

+ 6 - 17
src/views/mall/promotion/diy/template/DiyTemplateForm.vue

@@ -1,11 +1,11 @@
 <template>
 <template>
-  <Dialog :title="dialogTitle" v-model="dialogVisible">
+  <Dialog v-model="dialogVisible" :title="dialogTitle">
     <el-form
     <el-form
       ref="formRef"
       ref="formRef"
+      v-loading="formLoading"
       :model="formData"
       :model="formData"
       :rules="formRules"
       :rules="formRules"
       label-width="100px"
       label-width="100px"
-      v-loading="formLoading"
     >
     >
       <el-form-item label="模板名称" prop="name">
       <el-form-item label="模板名称" prop="name">
         <el-input v-model="formData.name" placeholder="请输入模板名称" />
         <el-input v-model="formData.name" placeholder="请输入模板名称" />
@@ -18,12 +18,12 @@
       </el-form-item>
       </el-form-item>
     </el-form>
     </el-form>
     <template #footer>
     <template #footer>
-      <el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
+      <el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
       <el-button @click="dialogVisible = false">取 消</el-button>
       <el-button @click="dialogVisible = false">取 消</el-button>
     </template>
     </template>
   </Dialog>
   </Dialog>
 </template>
 </template>
-<script setup lang="ts">
+<script lang="ts" setup>
 import * as DiyTemplateApi from '@/api/mall/promotion/diy/template'
 import * as DiyTemplateApi from '@/api/mall/promotion/diy/template'
 
 
 /** 装修模板表单 */
 /** 装修模板表单 */
@@ -57,14 +57,7 @@ const open = async (type: string, id?: number) => {
   if (id) {
   if (id) {
     formLoading.value = true
     formLoading.value = true
     try {
     try {
-      const diyTemplate = await DiyTemplateApi.getDiyTemplate(id)
-      // 处理预览图
-      if (diyTemplate?.previewPicUrls?.length > 0) {
-        diyTemplate.previewPicUrls = diyTemplate.previewPicUrls.map((url: string) => {
-          return { url }
-        })
-      }
-      formData.value = diyTemplate
+      formData.value = await DiyTemplateApi.getDiyTemplate(id)
     } finally {
     } finally {
       formLoading.value = false
       formLoading.value = false
     }
     }
@@ -82,11 +75,7 @@ const submitForm = async () => {
   // 提交请求
   // 提交请求
   formLoading.value = true
   formLoading.value = true
   try {
   try {
-    // 处理预览图
-    const previewPicUrls = formData.value.previewPicUrls.map((item) => {
-      return item['url'] ? item['url'] : item
-    })
-    const data = { ...formData.value, previewPicUrls } as unknown as DiyTemplateApi.DiyTemplateVO
+    const data = formData.value as unknown as DiyTemplateApi.DiyTemplateVO
     if (formType.value === 'create') {
     if (formType.value === 'create') {
       await DiyTemplateApi.createDiyTemplate(data)
       await DiyTemplateApi.createDiyTemplate(data)
       message.success(t('common.createSuccess'))
       message.success(t('common.createSuccess'))

+ 28 - 33
src/views/mall/trade/config/index.vue

@@ -2,12 +2,12 @@
   <ContentWrap>
   <ContentWrap>
     <el-form
     <el-form
       ref="formRef"
       ref="formRef"
+      v-loading="formLoading"
       :model="formData"
       :model="formData"
       :rules="formRules"
       :rules="formRules"
       label-width="120px"
       label-width="120px"
-      v-loading="formLoading"
     >
     >
-      <el-form-item label="hideId" v-show="false">
+      <el-form-item v-show="false" label="hideId">
         <el-input v-model="formData.id" />
         <el-input v-model="formData.id" />
       </el-form-item>
       </el-form-item>
       <el-tabs>
       <el-tabs>
@@ -16,9 +16,9 @@
           <el-form-item label="退款理由" prop="afterSaleRefundReasons">
           <el-form-item label="退款理由" prop="afterSaleRefundReasons">
             <el-select
             <el-select
               v-model="formData.afterSaleRefundReasons"
               v-model="formData.afterSaleRefundReasons"
+              allow-create
               filterable
               filterable
               multiple
               multiple
-              allow-create
               placeholder="请直接输入退款理由"
               placeholder="请直接输入退款理由"
             >
             >
               <el-option
               <el-option
@@ -50,15 +50,15 @@
         <el-tab-pane label="配送">
         <el-tab-pane label="配送">
           <el-form-item label="启用包邮" prop="deliveryExpressFreeEnabled">
           <el-form-item label="启用包邮" prop="deliveryExpressFreeEnabled">
             <el-switch v-model="formData.deliveryExpressFreeEnabled" style="user-select: none" />
             <el-switch v-model="formData.deliveryExpressFreeEnabled" style="user-select: none" />
-            <el-text class="w-full" size="small" type="info"> 商城是否启用全场包邮 </el-text>
+            <el-text class="w-full" size="small" type="info"> 商城是否启用全场包邮</el-text>
           </el-form-item>
           </el-form-item>
           <el-form-item label="满额包邮" prop="deliveryExpressFreePrice">
           <el-form-item label="满额包邮" prop="deliveryExpressFreePrice">
             <el-input-number
             <el-input-number
               v-model="formData.deliveryExpressFreePrice"
               v-model="formData.deliveryExpressFreePrice"
-              placeholder="请输入满额包邮"
-              class="!w-xs"
-              :precision="2"
               :min="0"
               :min="0"
+              :precision="2"
+              class="!w-xs"
+              placeholder="请输入满额包邮"
             />
             />
             <el-text class="w-full" size="small" type="info">
             <el-text class="w-full" size="small" type="info">
               商城商品满多少金额即可包邮,单位:元
               商城商品满多少金额即可包邮,单位:元
@@ -72,7 +72,7 @@
         <el-tab-pane label="分销">
         <el-tab-pane label="分销">
           <el-form-item label="分佣启用" prop="brokerageEnabled">
           <el-form-item label="分佣启用" prop="brokerageEnabled">
             <el-switch v-model="formData.brokerageEnabled" style="user-select: none" />
             <el-switch v-model="formData.brokerageEnabled" style="user-select: none" />
-            <el-text class="w-full" size="small" type="info"> 商城是否开启分销模式 </el-text>
+            <el-text class="w-full" size="small" type="info"> 商城是否开启分销模式</el-text>
           </el-form-item>
           </el-form-item>
           <el-form-item label="分佣模式" prop="brokerageEnabledCondition">
           <el-form-item label="分佣模式" prop="brokerageEnabledCondition">
             <el-radio-group v-model="formData.brokerageEnabledCondition">
             <el-radio-group v-model="formData.brokerageEnabledCondition">
@@ -109,7 +109,7 @@
             </el-text>
             </el-text>
           </el-form-item>
           </el-form-item>
           <el-form-item label="分销海报图">
           <el-form-item label="分销海报图">
-            <UploadImgs v-model="formData.brokeragePosterUrls" width="75px" height="125px" />
+            <UploadImgs v-model="formData.brokeragePosterUrls" height="125px" width="75px" />
             <el-text class="w-full" size="small" type="info">
             <el-text class="w-full" size="small" type="info">
               个人中心分销海报图片,建议尺寸 600x1000
               个人中心分销海报图片,建议尺寸 600x1000
             </el-text>
             </el-text>
@@ -117,10 +117,10 @@
           <el-form-item label="一级返佣比例" prop="brokerageFirstPercent">
           <el-form-item label="一级返佣比例" prop="brokerageFirstPercent">
             <el-input-number
             <el-input-number
               v-model="formData.brokerageFirstPercent"
               v-model="formData.brokerageFirstPercent"
-              placeholder="请输入一级返佣比例"
-              class="!w-xs"
-              :min="0"
               :max="100"
               :max="100"
+              :min="0"
+              class="!w-xs"
+              placeholder="请输入一级返佣比例"
             />
             />
             <el-text class="w-full" size="small" type="info">
             <el-text class="w-full" size="small" type="info">
               订单交易成功后给推广人返佣的百分比
               订单交易成功后给推广人返佣的百分比
@@ -129,10 +129,10 @@
           <el-form-item label="二级返佣比例" prop="brokerageSecondPercent">
           <el-form-item label="二级返佣比例" prop="brokerageSecondPercent">
             <el-input-number
             <el-input-number
               v-model="formData.brokerageSecondPercent"
               v-model="formData.brokerageSecondPercent"
-              placeholder="请输入二级返佣比例"
-              class="!w-xs"
-              :min="0"
               :max="100"
               :max="100"
+              :min="0"
+              class="!w-xs"
+              placeholder="请输入二级返佣比例"
             />
             />
             <el-text class="w-full" size="small" type="info">
             <el-text class="w-full" size="small" type="info">
               订单交易成功后给推广人的推荐人返佣的百分比
               订单交易成功后给推广人的推荐人返佣的百分比
@@ -141,9 +141,9 @@
           <el-form-item label="佣金冻结天数" prop="brokerageFrozenDays">
           <el-form-item label="佣金冻结天数" prop="brokerageFrozenDays">
             <el-input-number
             <el-input-number
               v-model="formData.brokerageFrozenDays"
               v-model="formData.brokerageFrozenDays"
-              placeholder="请输入佣金冻结天数"
-              class="!w-xs"
               :min="0"
               :min="0"
+              class="!w-xs"
+              placeholder="请输入佣金冻结天数"
             />
             />
             <el-text class="w-full" size="small" type="info">
             <el-text class="w-full" size="small" type="info">
               防止用户退款,佣金被提现了,所以需要设置佣金冻结时间,单位:天
               防止用户退款,佣金被提现了,所以需要设置佣金冻结时间,单位:天
@@ -152,10 +152,10 @@
           <el-form-item label="提现最低金额" prop="brokerageWithdrawMinPrice">
           <el-form-item label="提现最低金额" prop="brokerageWithdrawMinPrice">
             <el-input-number
             <el-input-number
               v-model="formData.brokerageWithdrawMinPrice"
               v-model="formData.brokerageWithdrawMinPrice"
-              placeholder="请输入提现最低金额"
-              class="!w-xs"
-              :precision="2"
               :min="0"
               :min="0"
+              :precision="2"
+              class="!w-xs"
+              placeholder="请输入提现最低金额"
             />
             />
             <el-text class="w-full" size="small" type="info">
             <el-text class="w-full" size="small" type="info">
               用户提现最低金额限制,单位:元
               用户提现最低金额限制,单位:元
@@ -164,10 +164,10 @@
           <el-form-item label="提现手续费" prop="brokerageWithdrawFeePercent">
           <el-form-item label="提现手续费" prop="brokerageWithdrawFeePercent">
             <el-input-number
             <el-input-number
               v-model="formData.brokerageWithdrawFeePercent"
               v-model="formData.brokerageWithdrawFeePercent"
-              placeholder="请输入提现手续费"
-              class="!w-xs"
-              :min="0"
               :max="100"
               :max="100"
+              :min="0"
+              class="!w-xs"
+              placeholder="请输入提现手续费"
             />
             />
             <el-text class="w-full" size="small" type="info">
             <el-text class="w-full" size="small" type="info">
               提现手续费百分比,范围 0-100,0 为无提现手续费。例:设置 10,即收取 10% 手续费,提现
               提现手续费百分比,范围 0-100,0 为无提现手续费。例:设置 10,即收取 10% 手续费,提现
@@ -184,21 +184,22 @@
                 {{ dict.label }}
                 {{ dict.label }}
               </el-checkbox>
               </el-checkbox>
             </el-checkbox-group>
             </el-checkbox-group>
-            <el-text class="w-full" size="small" type="info"> 商城开通提现的付款方式 </el-text>
+            <el-text class="w-full" size="small" type="info"> 商城开通提现的付款方式</el-text>
           </el-form-item>
           </el-form-item>
         </el-tab-pane>
         </el-tab-pane>
       </el-tabs>
       </el-tabs>
       <!-- 保存 -->
       <!-- 保存 -->
       <el-form-item>
       <el-form-item>
-        <el-button type="primary" @click="submitForm" :loading="formLoading"> 保存 </el-button>
+        <el-button :loading="formLoading" type="primary" @click="submitForm"> 保存</el-button>
       </el-form-item>
       </el-form-item>
     </el-form>
     </el-form>
   </ContentWrap>
   </ContentWrap>
 </template>
 </template>
 
 
-<script setup lang="ts">
+<script lang="ts" setup>
 import * as ConfigApi from '@/api/mall/trade/config'
 import * as ConfigApi from '@/api/mall/trade/config'
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
 import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
+import { cloneDeep } from 'lodash-es'
 
 
 defineOptions({ name: 'TradeConfig' })
 defineOptions({ name: 'TradeConfig' })
 
 
@@ -253,12 +254,7 @@ const submitForm = async () => {
   // 提交请求
   // 提交请求
   formLoading.value = true
   formLoading.value = true
   try {
   try {
-    const data = {
-      ...formData.value
-    } as unknown as ConfigApi.ConfigVO
-    data.brokeragePosterUrls = formData.value.brokeragePosterUrls.map((item: any) => {
-      return item?.url ? item.url : item
-    })
+    const data = cloneDeep(unref(formData.value)) as unknown as ConfigApi.ConfigVO
     // 金额放大
     // 金额放大
     data.deliveryExpressFreePrice = data.deliveryExpressFreePrice * 100
     data.deliveryExpressFreePrice = data.deliveryExpressFreePrice * 100
     data.brokerageWithdrawMinPrice = data.brokerageWithdrawMinPrice * 100
     data.brokerageWithdrawMinPrice = data.brokerageWithdrawMinPrice * 100
@@ -275,7 +271,6 @@ const getConfig = async () => {
   try {
   try {
     const data = await ConfigApi.getTradeConfig()
     const data = await ConfigApi.getTradeConfig()
     if (data != null) {
     if (data != null) {
-      data.brokeragePosterUrls = data.brokeragePosterUrls.map((url) => ({ url }))
       formData.value = data
       formData.value = data
       // 金额缩小
       // 金额缩小
       formData.value.deliveryExpressFreePrice = data.deliveryExpressFreePrice / 100
       formData.value.deliveryExpressFreePrice = data.deliveryExpressFreePrice / 100