Kaynağa Gözat

提交产品管理文件

Lijy 1 yıl önce
ebeveyn
işleme
d8984a4342
17 değiştirilmiş dosya ile 816 ekleme ve 340 silme
  1. 18 13
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/relatedProducts.vue
  2. 34 6
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/index.vue
  3. 16 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/api.ts
  4. 127 45
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/attachment.vue
  5. 199 23
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/information.vue
  6. 21 33
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/operationRecord.vue
  7. 17 47
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/products.vue
  8. 20 44
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/relatedBusiness.vue
  9. 78 39
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/detail/index.vue
  10. 168 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/deteleTables.vue
  11. 101 40
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/index.vue
  12. 1 6
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/detail/components/attachment.vue
  13. 1 1
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/index.vue
  14. 3 3
      fhKeeper/formulahousekeeper/customerBuler-crm/src/styles/global.scss
  15. 2 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/request.ts
  16. 10 12
      fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/tools.ts
  17. 0 25
      fhKeeper/formulahousekeeper/plugIn/form-design-master/src/components.d.ts

+ 18 - 13
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/relatedProducts.vue

@@ -2,25 +2,25 @@
     <div>
         <el-table ref="productTableRef" :data="productTable" border :row-class-name="tableRowClassName"
             @row-click="tableRowItem" style="width: 100%;height: 200px">
-            <el-table-column label="序号" width="80">
+            <el-table-column label="序号" width="60" align="center">
                 <template #default="scope">
                     <span>{{ scope.$index + 1 }}</span>
                 </template>
             </el-table-column>
             <el-table-column prop="productName" label="产品名称" width="180">
                 <template #default="scope">
-                    <el-select v-model="productTable[scope.$index].productName" placeholder="请选择"
+                    <el-select v-model="productTable[scope.$index].productId" placeholder="请选择"
                         v-if="productTableIndex == scope.$index" clearable @clear="clearTableItem(scope.$index)"
                         @change="selectChange(scope.$index, productTable[scope.$index].productName)">
-                        <el-option v-for="item in productArrar" :key="item.id" :label="item.productName" :value="item.id" />
+                        <el-option v-for="item in productArrar" :key="item.productId" :label="item.productName" :value="item.productId" />
                     </el-select>
                     <span v-else>{{ productTable[scope.$index].productName }}</span>
                 </template>
             </el-table-column>
-            <el-table-column prop="productType" label="产品类型" width="180"></el-table-column>
-            <el-table-column prop="unit" label="单位" width="80"></el-table-column>
+            <el-table-column prop="typeName" label="产品类型" width="180"></el-table-column>
+            <el-table-column prop="unitName" label="单位" width="120"></el-table-column>
             <el-table-column prop="price" label="标准价格" width="120"></el-table-column>
-            <el-table-column prop="stock" label="库存" width="80"></el-table-column>
+            <el-table-column prop="inventory" label="库存" width="80"></el-table-column>
             <el-table-column prop="sellingPrice" label="售价" width="180">
                 <template #default="scope">
                     <el-input-number v-model="productTable[scope.$index].sellingPrice" class="mx-4" :min="0" :max="100000000" controls-position="right" v-if="productTableIndex == scope.$index" />
@@ -39,7 +39,7 @@
                     <span v-else>{{ productTable[scope.$index].discount }}</span>
                 </template>
             </el-table-column>
-            <el-table-column prop="total" label="合计" width="180"></el-table-column>
+            <el-table-column prop="totalPrice" label="合计" width="180"></el-table-column>
             <el-table-column label="操作" fixed="right" width="120">
                 <template #default="scope">
                     <el-button link type="primary" size="large" @click.stop="addTableItem(scope.$index)">添加</el-button>
@@ -52,18 +52,18 @@
 </template>
   
 <script lang="ts" setup>
-import { ref, reactive, onMounted, inject } from "vue";
+import { ref, reactive, onMounted, inject, watchEffect } from "vue";
+
+const props = defineProps<{
+    productTableList: any,
+}>()
 
 const productTable: any = ref([{}])
 const productTableIndex = ref(0) // 可以编辑索引
-const productArrar = ref([
-    { id: 1, productName: '产品1', productType: '类别1', unit: '台', price: '1122', stock: '100', sellingPrice: 0, quantity: 0, discount: 0, total: '' },
-    { id: 2, productName: '产品2', productType: '类别2', unit: '台', price: '2211', stock: '300', sellingPrice: 0, quantity: 0, discount: 0, total: '' },
-])
+const productArrar: any = ref([])
 
 function selectChange(index: number, val: number | string) {
     let newObj = productArrar.value.find((item: any) => item.id == val)
-    console.log(newObj)
     productTable.value.splice(index, 1, newObj)
 }
 
@@ -87,6 +87,11 @@ function clearTableItem(index: number) {
 function deteleTableItem(index: number) {
     productTable.value.splice(index, 1)
 }
+
+watchEffect(() => {
+    const { productTableList } = props
+    productArrar.value = productTableList || []
+});
 </script>
   
 <style lang="scss" scoped></style>

+ 34 - 6
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/index.vue

@@ -109,9 +109,9 @@
         </div>
       </template>
       <div class="h-[60vh] overflow-y-auto scroll-bar">
-        <GenerateForm ref="generateForm" :data="generateFormData" />
+        <!-- <GenerateForm ref="generateForm" :data="generateFormData" /> -->
         <div>相关产品</div>
-        <RelatedProducts />
+        <RelatedProducts :productTableList="productTableList" />
       </div>
     </el-dialog>
   </div>
@@ -122,6 +122,7 @@ import { ref, reactive, onMounted, inject } from "vue";
 import type { FormInstance, FormRules } from 'element-plus'
 import { useRouter, useRoute } from "vue-router";
 import { GETSYSFILED, MOD, GETPERSONNEL, GETGENERATEFOEM } from './api'
+import { GETTABLELIST } from '@/pages/product/api'
 import { post, get } from "@/utils/request";
 import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate } from '@/utils/tools'
 import { GenerateForm } from '@zmjs/form-design';
@@ -166,13 +167,14 @@ const fixedData = reactive({
   BusinessStage: [] as fixedDataInterface[],
   Personnel: [] as personnelInterface[]
 })
+const productTableList = ref([])
 
 
 function editBusiness() {
   generateForm.value?.getData().then((res: any) => {
     console.log('正确')
     console.log(res)
-  }).catch( (_err: any) => {
+  }).catch((_err: any) => {
     globalPopup?.showError('请填写完整')
   })
 }
@@ -214,14 +216,40 @@ async function getSystemField() {
 
 function toBusinessTableDetail(row: any) {
   console.log('点击跳转详情')
-  router.push({ 
-    path: `${MOD}/detail`, 
-    query: { id: row.id } 
+  router.push({
+    path: `${MOD}/detail`,
+    query: { id: row.id }
+  })
+}
+
+function getProductTableList() {
+  post(GETTABLELIST, { pageIndex: -1, pageSize: -1 }).then((res) => {
+    if (res.code == 'ok') {
+      const { record, total } = res.data
+      productTableList.value = record.map((item: any) => {
+        const { id, productName, productCode, unit, unitName, typeName, type, price, inventory } = item
+        return {
+          productId: id,
+          productName,
+          productCode,
+          unit,
+          unitName,
+          price,
+          type,
+          typeName,
+          inventory,
+          quantity: '',
+          discount: '',
+          totalPrice: ''
+        }
+      })
+    }
   })
 }
 
 onMounted(() => {
   getSystemField()
+  getProductTableList()
 })
 </script>
 

+ 16 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/api.ts

@@ -1,8 +1,23 @@
 export const MOD = '/product'
+export const MODUCODE = 'Product'
 export const prefix = '/product'
+export const GETDOEMCODE = '/sys-form/getListByCode'
 export const GETSYSFILED = '/sys-dict/getListByCode'
 export const GETPERSONNEL = '/user/getSimpleActiveUserList'
 export const GETTEMPLATE = `/sys-form/getListByCode${MOD}`
 export const GETTABLELIST = `${prefix}/list`
 export const ADDPRODUCT = `${prefix}/addOrUpdate`
-export const ALLDETELE = `${prefix}/delete`
+export const ALLDETELE = `${prefix}/delete`
+export const UPLOADFILE = `${prefix}/importData`
+export const RECYCLELIST = `${prefix}/recycleList`
+export const DETERDETELE = `${prefix}/batchDeleteProduct`
+export const ROLLBACK = `${prefix}/batchRecoveryProduct`
+export const GETDETAIL = `${prefix}/detail`
+export const GETINCHARGER = `${prefix}/transferIncharger`
+export const GETBUSINESS = `${prefix}/businessListWithProduct`
+export const GETORDER = `${prefix}/orderWithProduct`
+export const UPLOADATTACHMENT = `/attachment/uploadAttachment`
+export const GETCENTERLIST = `/audit-log-center/list`
+export const GETATTACHMENT = `/attachment/attachmentList`
+export const FILEDETELE = `/attachment/delete`
+export const FILERENAME = `/attachment/rename`

+ 127 - 45
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/attachment.vue

@@ -3,67 +3,149 @@
         <div class="flex justify-between">
             <div class="title">附件</div>
             <div>
-                <el-button type="primary">上传</el-button>
+                <el-upload ref="uploadRef" :http-request="httpUploadFile" :limit="1" :show-file-list="false"
+                    element-loading-text="正在上传">
+                    <template #trigger>
+                        <el-button type="primary" :loading="allLoading.uploadLoading">上传</el-button>
+                    </template>
+                </el-upload>
             </div>
         </div>
         <div class="flex-1 overflow-auto pt-3">
             <el-table :data="attachmenttable" border style="width: 100%;height: 200px;">
-                <el-table-column prop="fileName" label="附件名称" width="180" />
-                <el-table-column prop="fileSize" label="附件大小" width="120" />
-                <el-table-column prop="uploader" label="上传人" width="120" />
-                <el-table-column prop="uploadTime" label="上传时间" width="180" />
+                <el-table-column prop="attachmentName" label="附件名称" width="180" />
+                <el-table-column prop="size" label="附件大小" width="120" />
+                <el-table-column prop="creatorName" label="上传人" width="120" />
+                <el-table-column prop="indate" label="上传时间" width="180" />
                 <el-table-column label="操作" width="180" fixed="right">
                     <template #default="scope">
-                        <el-button link type="primary" size="large">下载</el-button>
-                        <el-button link type="primary" size="large">重命名</el-button>
-                        <el-button link type="danger" size="large">删除</el-button>
+                        <el-button link type="primary" size="large" @click="fileDownload(scope.row)">下载</el-button>
+                        <el-button link type="primary" size="large" @click="showVisible(scope.row)">重命名</el-button>
+                        <el-button link type="danger" size="large" @click="deteleFile(scope.row)">删除</el-button>
                     </template>
                 </el-table-column>
             </el-table>
         </div>
+
+        <!-- 弹窗 -->
+        <el-dialog v-model="allVisible.renameVisible" width="800" :show-close="false" top="10vh">
+            <template #header="{ close, titleId, titleClass }">
+                <div class="flex justify-between items-center border-b pb-3 dialog-header">
+                    <h4 :id="titleId">{{ '文件重命名' }}</h4>
+                    <div>
+                        <el-button type="primary" :loading="allLoading.renameLoading" :disabled="!renameVal"
+                            @click="saveEditClue()">保存</el-button>
+                        <el-button @click="allVisible.renameVisible = false">取消</el-button>
+                    </div>
+                </div>
+            </template>
+            <div class="pt-3">
+                <el-input v-model.trim="renameVal" style="width: 100%" class="pb-3" clearable />
+            </div>
+        </el-dialog>
     </div>
 </template>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
+import { get, post, uploadFile } from '@/utils/request';
+import { UploadRequestOptions } from 'element-plus';
+import { ref, reactive, onMounted, onUnmounted, defineEmits, inject, watchEffect } from 'vue'
+import { FILEDETELE, FILERENAME, MODUCODE, UPLOADATTACHMENT } from '../api';
+import { confirmAction, downloadFile } from '@/utils/tools';
+
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const emits = defineEmits(['getFileList']);
+
+const attachmenttable = ref([])
+const information: any = ref({})
+const renameItem: any = ref({})
+const renameVal = ref('')
+const allLoading = reactive({
+    uploadLoading: false,
+    renameLoading: false,
+})
+const allVisible = reactive({
+    renameVisible: false
+})
+
+const props = defineProps<{
+    data: any,
+    information: any
+}>()
+
+// 下载文件
+function fileDownload(item: any) {
+    downloadFile(item.url, `${item.attachmentName}${item.attachmentSuffix}`)
+}
+
+// 保存重命名
+function saveEditClue() {
+    const id = renameItem.value.id
+    allLoading.renameLoading = true
+    post(FILERENAME, { name: renameVal.value, id }).then((res) => {
+        if (res.code == 'ok') {
+            allVisible.renameVisible = false
+            globalPopup?.showSuccess(res.msg || '')
+            emits('getFileList')
+        }
+    }).catch((err) => {
+        globalPopup?.showError(err.msg || '')
+    }).finally(() => {
+        allLoading.renameLoading = false
+    })
+}
+
+// 删除文件
+function deteleFile(item: any) {
+    const id = item.id
+    confirmAction(`确定删除【${item.attachmentName}】文件吗?`).then(() => {
+        post(FILEDETELE, { id }).then((_res) => {
+            globalPopup?.showSuccess('删除成功')
+            emits('getFileList')
+        }).catch((err) => {
+            globalPopup?.showError(err.msg || '')
+        })
+    })
+}
+
+// 显示弹窗
+function showVisible(item: any) {
+    renameItem.value = JSON.parse(JSON.stringify(item))
+    renameVal.value = renameItem.value.attachmentName
+    allVisible.renameVisible = true
+}
+
+// 上传附件
+async function httpUploadFile(param: UploadRequestOptions) {
+    allLoading.uploadLoading = true
+    const id = information.value.id
+    const formData = new FormData();
+    formData.append('file', param.file)
+    formData.append('moduleId', id)
+    formData.append('moduleCode', MODUCODE)
+    const res = await uploadFile(UPLOADATTACHMENT, formData)
+    allLoading.uploadLoading = false
+    if (res.code == 'ok') {
+        globalPopup?.showSuccess('上传成功')
+        emits('getFileList');
+        return
+    }
+    globalPopup?.showError(res.msg || '')
+    return res
+}
+
+// 接收参数赋值
+function receiveAssignment(item: any) {
+    attachmenttable.value = item.data
+    information.value = item.information
+}
+
+watchEffect(() => {
+    receiveAssignment(props)
+});
 
-const attachmenttable = ref([{
-    fileName: '文件附件',
-    fileSize: '3.1MB',
-    uploader: '张三',
-    uploadTime: '2024-04-01',
-}, {
-    fileName: '文件附件',
-    fileSize: '3.1MB',
-    uploader: '张三',
-    uploadTime: '2024-04-01',
-}, {
-    fileName: '文件附件',
-    fileSize: '3.1MB',
-    uploader: '张三',
-    uploadTime: '2024-04-01',
-}, {
-    fileName: '文件附件',
-    fileSize: '3.1MB',
-    uploader: '张三',
-    uploadTime: '2024-04-01',
-}, {
-    fileName: '文件附件',
-    fileSize: '3.1MB',
-    uploader: '张三',
-    uploadTime: '2024-04-01',
-}, {
-    fileName: '文件附件',
-    fileSize: '3.1MB',
-    uploader: '张三',
-    uploadTime: '2024-04-01',
-}, {
-    fileName: '文件附件',
-    fileSize: '3.1MB',
-    uploader: '张三',
-    uploadTime: '2024-04-01',
-}])
 // 生命周期钩子
 onMounted(() => {
+    receiveAssignment(props)
 });
 </script>
 <style scoped lang="scss">

Dosya farkı çok büyük olduğundan ihmal edildi
+ 199 - 23
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/information.vue


+ 21 - 33
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/operationRecord.vue

@@ -5,47 +5,35 @@
         </div>
         <div class="flex-1 overflow-auto pt-5">
             <el-table :data="operationRecordtable" border style="width: 100%;height: 278px;">
-                <el-table-column prop="operatingTime" label="操作时间" width="140" />
-                <el-table-column prop="operator" label="操作人" width="120" />
-                <el-table-column prop="operationContent" label="操作内容" />
+                <el-table-column prop="auditTime" label="操作时间" width="140" />
+                <el-table-column prop="auditorName" label="操作人" width="120" />
+                <el-table-column prop="auditorContent" label="操作内容" />
             </el-table>
         </div>
     </div>
 </template>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
+import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+
+const operationRecordtable = ref([])
+const information: any = ref({})
+
+const props = defineProps<{
+    data: any,
+}>()
+
+// 接收参数赋值
+function receiveAssignment(item: any) {
+    operationRecordtable.value = item.data
+}
+
+watchEffect(() => {
+    receiveAssignment(props)
+});
 
-const operationRecordtable = ref([{
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-}, {
-    operationContent: '转移线索',
-    operator: '张三',
-    operatingTime: '2024-04-01',
-},])
 // 生命周期钩子
 onMounted(() => {
+    receiveAssignment(props)
 });
 </script>
 <style scoped lang="scss">

+ 17 - 47
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/products.vue

@@ -2,9 +2,6 @@
     <div class="relatedTasks pl-4 pr-4 pt-3 pb-3 h-full flex flex-col">
         <div class="flex justify-between">
             <div class="title">相关产品</div>
-            <div>
-                <el-button type="primary">编辑产品</el-button>
-            </div>
         </div>
         <div class="flex-1 overflow-auto pt-3">
             <el-table :data="relatedTaskstable" border style="width: 100%;height: 300px;">
@@ -34,53 +31,26 @@
     </div>
 </template>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
+import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+
+const relatedTaskstable = ref([])
+
+const props = defineProps<{
+    data: any
+}>()
+
+// 接收参数赋值
+function receiveAssignment(item: any) {
+    relatedTaskstable.value = item.data
+}
+
+watchEffect(() => {
+    receiveAssignment(props)
+});
 
-const relatedTaskstable = ref([{
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}])
 // 生命周期钩子
 onMounted(() => {
+    receiveAssignment(props)
 });
 </script>
 <style scoped lang="scss">

+ 20 - 44
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/component/relatedBusiness.vue

@@ -22,53 +22,29 @@
     </div>
 </template>
 <script lang="ts" setup>
-import { ref, reactive, onMounted, onUnmounted, defineExpose, inject } from 'vue'
+import { ref, reactive, onMounted, onUnmounted, defineExpose, inject, watchEffect } from 'vue'
+
+const relatedTaskstable = ref([])
+const information: any = ref({})
+
+const props = defineProps<{
+    data: any,
+    information: any
+}>()
+
+// 接收参数赋值
+function receiveAssignment(item: any) {
+    relatedTaskstable.value = item.data
+    information.value = item.information
+}
+
+watchEffect(() => {
+    receiveAssignment(props)
+});
 
-const relatedTaskstable = ref([{
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}, {
-    taskName: '任务名称20240316-tempalsbls',
-    priority: '中',
-    status: '进行中',
-    executor: '张三',
-    startTime: '2024-04-01',
-    endTime: '2024-04-01',
-}])
 // 生命周期钩子
 onMounted(() => {
+    receiveAssignment(props)
 });
 </script>
 <style scoped lang="scss">

+ 78 - 39
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/detail/index.vue

@@ -7,34 +7,34 @@
         </el-link>
       </div>
       <div class="mr-8">
-        <el-select v-model="value" placeholder="请选择" style="width: 150px">
-          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
+        <el-select v-model="value" placeholder="请选择" style="width: 150px" @change="getDetail(false)">
+          <el-option v-for="item in options" :key="item.id" :label="item.productName" :value="item.id" />
         </el-select>
       </div>
     </div>
     <!-- 内容 -->
-    <div class="flex-1 flex flex-col overflow-y-auto overflow-x-hidden scroll-bar">
+    <div class="flex-1 flex flex-col overflow-y-auto overflow-x-hidden scroll-bar" v-loading="pageLoading">
       <div class="w-full h-auto flex justify-between">
         <div class="bg-white shadow-md rounded-md" style="width: 46%;">
-          <Information />
+          <Information :data="information" @getInformationData="getInformationData" />
         </div>
         <div class="bg-white ml-2 shadow-md rounded-md flex-1">
-          <Attachment />
+          <Attachment :data="attachment" :information="information" @getFileList="getFileList" />
         </div>
       </div>
 
       <div class="w-full h-auto flex justify-between mt-2">
         <div class="bg-white shadow-md rounded-md" style="width: 65%;">
-          <RelatedBusiness />
+          <RelatedBusiness :data="relatedBusiness" :information="information" />
         </div>
         <div class="bg-white ml-2 shadow-md rounded-md flex-1">
-          <OperationRecord />
+          <OperationRecord :data="operationRecord" />
         </div>
       </div>
 
       <div class="w-full h-auto flex justify-between mt-2">
         <div class="bg-white shadow-md rounded-md w-full">
-          <Products />
+          <Products :data="products" />
         </div>
       </div>
     </div>
@@ -45,6 +45,7 @@
 import { ref, reactive, onMounted, inject } from "vue";
 import type { FormInstance, FormRules } from 'element-plus'
 import { Edit, ArrowLeft as IconView } from '@element-plus/icons-vue'
+import { useRoute } from "vue-router";
 import { backPath } from '../../../utils/tools'
 
 import Information from '../component/information.vue'
@@ -52,40 +53,78 @@ import Attachment from '../component/attachment.vue'
 import RelatedBusiness from '../component/relatedBusiness.vue';
 import OperationRecord from '../component/operationRecord.vue';
 import Products from '../component/products.vue';
+import { GETBUSINESS, GETDETAIL, GETCENTERLIST, GETORDER, MODUCODE, GETATTACHMENT, GETTABLELIST } from "../api";
+import { post } from "@/utils/request";
+
+const route = useRoute()
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const addressParameters: any = ref(0) // 地址上的参数
+const information = ref({}) // 基本信息
+const attachment = ref([]) // 附件
+const relatedBusiness = ref([]) // 相关商机
+const operationRecord = ref([]) // 操作记录
+const products = ref([]) // 相关产品
+
+const pageLoading = ref(false)
 
 const value = ref('')
-const stageStatusVal = ref('')
-const options = [
-  {
-    value: 'Option1',
-    label: 'Option1',
-  },
-  {
-    value: 'Option2',
-    label: 'Option2',
-  },
-  {
-    value: 'Option3',
-    label: 'Option3',
-  },
-  {
-    value: 'Option4',
-    label: 'Option4',
-  },
-  {
-    value: 'Option5',
-    label: 'Option5',
-  },
-]
-
-
-function handleScroll(event: any) { // 滚表横向滚动
-  if (event.deltaY) {
-    event.preventDefault();
-    const element = event.currentTarget;
-    element.scrollLeft += event.deltaY;
+const options: any = ref([])
+
+function getInformationData(val: any = false) {
+  const id = val ? val : addressParameters.value
+  post(GETDETAIL, { id }).then((res) => {
+    information.value = res.data
+  })
+}
+
+function getFileList(val: any = false) {
+  const id = val ? val : addressParameters.value
+  post(GETATTACHMENT, { moduleId: id, moduleCode: MODUCODE }).then((res) => {
+    attachment.value = res.data
+  })
+}
+
+async function getDetail(flag: boolean) {
+  try {
+    const id = flag ? addressParameters.value : value.value
+    pageLoading.value = true
+
+    await Promise.all([
+      getInformationData(id),
+      getFileList(id),
+      post(GETCENTERLIST, { id, moduleCode: MODUCODE }).then((res) => {
+        operationRecord.value = res.datag
+      }),
+      post(GETORDER, { id }).then((res) => {
+        products.value = res.data
+      }),
+      post(GETBUSINESS, { id }).then((res) => {
+        relatedBusiness.value = res.data
+      })
+    ])
+
+    pageLoading.value = false
+  } catch (error) {
+    pageLoading.value = false
+    console.log(error, '<==== 加载错误')
   }
 }
+
+function getProductList() {
+  post(GETTABLELIST, { pageIndex: -1, pageSize: -1 }).then((res) => {
+    const { record } = res.data
+    options.value = record
+  }).catch(() => {
+    globalPopup?.showError('产品列表获取失败')
+  })
+}
+
+onMounted(() => {
+  const { id } = route.query
+  addressParameters.value = id
+  getProductList()
+  getDetail(true)
+})
 </script>
   
 <style lang="scss" scoped>
@@ -144,7 +183,7 @@ function handleScroll(event: any) { // 滚表横向滚动
     padding-bottom: 4px;
   }
 
-  .selectClas >>> .el-select__wrapper {
+  .selectClas>>>.el-select__wrapper {
     background-color: none !important;
     box-shadow: none !important;
   }

+ 168 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/deteleTables.vue

@@ -0,0 +1,168 @@
+<template>
+    <el-dialog v-model="deteleClueDialogVisible" width="1000" :before-close="beForeCancel" :show-close="false" top="10vh">
+        <template #header="{ close, titleId, titleClass }">
+            <div class="flex justify-between items-center border-b pb-3 dialog-header">
+                <h4 :id="titleId">产品回收站</h4>
+                <div>
+                    <el-button type="primary" @click="batchRestore()"
+                        v-loading="allLoading.batchRecoveryLoading">批量恢复</el-button>
+                    <el-button type="primary" @click="batchDeletes()"
+                        v-loading="allLoading.batchDeteleLoading">批量删除</el-button>
+                    <el-button @click="cancel()">取消</el-button>
+                </div>
+            </div>
+        </template>
+        <div class="h-[60vh] flex flex-col">
+            <div class="flex-1 w-full overflow-hidden">
+                <el-table ref="clueTableRef" :data="deteleClueTable" border v-loading="allLoading.tableLoading"
+                    style="width: 100%;height: 100%;">
+                    <el-table-column type="selection" width="55" />
+                    <el-table-column prop="productCode" label="产品编号" width="180"></el-table-column>
+                    <el-table-column prop="productName" label="产品名称" width="180"></el-table-column>
+                    <el-table-column prop="typeName" label="产品类别" width="180"></el-table-column>
+                    <el-table-column prop="unitName" label="单位" width="180"></el-table-column>
+                    <el-table-column prop="price" label="标准价格(元)" width="180"></el-table-column>
+                    <el-table-column prop="inventory" label="库存" width="180"></el-table-column>
+                    <el-table-column prop="status" label="状态" width="180"></el-table-column>
+                    <el-table-column prop="inchargerName" label="负责人" width="190"></el-table-column>
+                    <el-table-column prop="creatorName" label="创建人" width="180"></el-table-column>
+                    <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
+                    <el-table-column label="操作" fixed="right" width="120">
+                        <template #default="scope">
+                            <el-button link type="primary" size="large" @click="restoreItemRow([scope.row])">恢复</el-button>
+                            <el-button link type="danger" size="large" @click="deteItemRow([scope.row])">删除</el-button>
+                        </template>
+                    </el-table-column>
+                </el-table>
+            </div>
+            <div class="flex justify-end pt-3">
+                <el-pagination layout="total, prev, pager, next, sizes" :page-size="tableForm.pageSize"
+                    @size-change="handleSizeChange" @current-change="handleCurrentChange" :total="clueTotalTable"
+                    :hide-on-single-page="true" />
+            </div>
+        </div>
+    </el-dialog>
+</template>
+<script lang="ts" setup>
+import { post } from '@/utils/request';
+import { ref, reactive, onMounted, watchEffect, watch, inject } from 'vue'
+import { DETERDETELE, RECYCLELIST, ROLLBACK } from './api';
+import { ElTable } from 'element-plus';
+import { confirmAction } from '@/utils/tools';
+
+const emits = defineEmits(['showDeteleProduct']);
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const deteleClueTable = ref([])
+const deteleClueDialogVisible = ref(false)
+const clueTotalTable = ref(0)
+const allLoading = reactive({
+    batchRecoveryLoading: false,
+    batchDeteleLoading: false,
+    tableLoading: false
+})
+
+const tableForm = reactive({
+    pageIndex: 1,
+    pageSize: 10
+})
+
+const clueTableRef = ref<InstanceType<typeof ElTable>>() // 产品table dom
+
+const props = defineProps<{
+    visibles: boolean
+}>()
+
+watch(() => props.visibles, (newVal) => {
+    deteleClueDialogVisible.value = newVal
+    if (newVal) {
+        getTableList()
+    }
+})
+
+function batchRestore() {
+    const data = clueTableRef.value && clueTableRef.value.getSelectionRows()
+    if (!data.length) {
+        globalPopup?.showWarning('请选择需要恢复的数据')
+        return
+    }
+    restoreItemRow(data)
+}
+
+function batchDeletes() {
+    const data = clueTableRef.value && clueTableRef.value.getSelectionRows()
+    if (!data.length) {
+        globalPopup?.showWarning('请选择需要删除的数据')
+        return
+    }
+    deteItemRow(data)
+}
+
+function deteItemRow(items: any[]) {
+    const ids = items.map((item: any) => item.id).join(',')
+    const str = items.map((item: any) => item.productName).join(',')
+    confirmAction(`确定${items.length > 1 ? '批量删除这些' : '删除'}【${str}】产品吗?`, '', 'warning').then(() => {
+        post(DETERDETELE, { ids }).then(res => {
+            if (res.code != 'ok') {
+                globalPopup?.showError(res.msg)
+                return
+            }
+            globalPopup?.showSuccess('删除成功')
+            getTableList()
+        })
+    })
+}
+
+function restoreItemRow(items: any[]) {
+    const ids = items.map((item: any) => item.id).join(',')
+    const str = items.map((item: any) => item.productName).join(',')
+    confirmAction(`确定${items.length > 1 ? '批量恢复这些' : '恢复'}【${str}】产品吗?`, '', 'warning').then(() => {
+        post(ROLLBACK, { ids }).then(res => {
+            if (res.code != 'ok') {
+                globalPopup?.showError(res.msg)
+                return
+            }
+            globalPopup?.showSuccess('恢复成功')
+            getTableList()
+        })
+    })
+}
+
+function getTableList() {
+    allLoading.tableLoading = true
+    post(RECYCLELIST, { ...tableForm }).then((res) => {
+        if (res.code == 'ok') {
+            const { record, total } = res.data
+            deteleClueTable.value = record
+            clueTotalTable.value = total
+        }
+    }).finally(() => {
+        allLoading.tableLoading = false
+    })
+}
+
+function handleSizeChange(val: number) {
+    tableForm.pageIndex = 1
+    tableForm.pageSize = val
+    getTableList()
+}
+
+function handleCurrentChange(val: number) {
+    tableForm.pageIndex = val
+    getTableList()
+}
+
+function cancel() {
+    emits('showDeteleProduct', false)
+}
+
+function beForeCancel(done: () => void) {
+    emits('showDeteleProduct', false)
+    done()
+}
+
+onMounted(() => {
+
+})
+
+</script>
+<style lang="scss" scoped></style>

+ 101 - 40
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/product/index.vue

@@ -39,10 +39,10 @@
     <div class="flex-1 p-5 overflow-auto">
       <div class="bg-white w-full h-full p-3 shadow-md rounded-md flex flex-col">
         <div class="flex justify-end pb-3">
-          <el-button type="primary" @click="editProduct(true)">新建产品</el-button>
-          <el-button type="primary">批量删除</el-button>
-          <el-button type="primary">回收站</el-button>
-          <el-button type="primary">导入</el-button>
+          <el-button type="primary" @click="editProduct(false)">新建产品</el-button>
+          <el-button type="primary" @click="batchDelete()">批量删除</el-button>
+          <el-button type="primary" @click="showDeteleProduct(true)">回收站</el-button>
+          <el-button type="primary" @click="dialogVisible.importVisible = true">导入</el-button>
           <el-button type="primary">导出</el-button>
         </div>
         <div class="flex-1 w-full overflow-hidden">
@@ -57,17 +57,21 @@
                 }}</el-button>
               </template>
             </el-table-column>
-            <el-table-column prop="type" label="产品类别" width="180"></el-table-column>
-            <el-table-column prop="unit" label="单位" width="180"></el-table-column>
-            <el-table-column prop="price" label="标准价格" width="180"></el-table-column>
+            <el-table-column prop="typeName" label="产品类别" width="180"></el-table-column>
+            <el-table-column prop="unitName" label="单位" width="180"></el-table-column>
+            <el-table-column prop="price" label="标准价格(元)" width="180"></el-table-column>
             <el-table-column prop="inventory" label="库存" width="180"></el-table-column>
-            <el-table-column prop="status" label="状态" width="180"></el-table-column>
-            <el-table-column prop="inchargerId" label="负责人" width="190"></el-table-column>
-            <el-table-column prop="creatorId" label="创建人" width="180"></el-table-column>
+            <el-table-column prop="status" label="状态" width="180">
+              <template #default="scope">
+                {{ scope.row.status == 1 ? '上架' : '下架' }}
+              </template>
+            </el-table-column>
+            <el-table-column prop="inchargerName" label="负责人" width="190"></el-table-column>
+            <el-table-column prop="creatorName" label="创建人" width="180"></el-table-column>
             <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
             <el-table-column label="操作" fixed="right" width="200">
               <template #default="scope">
-                <el-button link type="primary" size="large">编辑</el-button>
+                <el-button link type="primary" size="large" @click.stop="editProduct(scope.row)">编辑</el-button>
                 <el-button link type="danger" size="large" @click.stop="deteleRow([scope.row])">删除</el-button>
               </template>
             </el-table-column>
@@ -75,7 +79,8 @@
         </div>
         <div class="flex justify-end pt-3">
           <el-pagination layout="total, prev, pager, next, sizes" :page-size="filterProductForm.pageSize"
-            @size-change="handleSizeChange" @current-change="handleCurrentChange" :total="productTableTotal" :hide-on-single-page="true" />
+            @size-change="handleSizeChange" @current-change="handleCurrentChange" :total="productTableTotal"
+            :hide-on-single-page="true" />
         </div>
       </div>
     </div>
@@ -86,8 +91,8 @@
         <div class="flex justify-between items-center border-b pb-3 dialog-header">
           <h4 :id="titleId">{{ allText.editClueText }}</h4>
           <div>
-            <el-button type="primary" @click="saveProductRow(true)" v-loading="allLoading.saveLoading">保存并新建</el-button>
-            <el-button type="primary" @click="saveProductRow(false)" v-loading="allLoading.saveLoading">保存</el-button>
+            <el-button type="primary" @click="saveProductRow(true)" :loading="allLoading.saveLoading">保存并新建</el-button>
+            <el-button type="primary" @click="saveProductRow(false)" :loading="allLoading.saveLoading">保存</el-button>
             <el-button @click="dialogVisible.editProductVisible = false">取消</el-button>
           </div>
         </div>
@@ -99,17 +104,40 @@
       </div>
     </el-dialog>
 
+    <el-dialog v-model="dialogVisible.importVisible" width="680" :show-close="false" top="10vh">
+      <template #header="{ close, titleId, titleClass }">
+        <div class="flex justify-between items-center border-b pb-3 dialog-header">
+          <h4 :id="titleId">导入产品</h4>
+          <div class="flex">
+            <el-upload class="upload-demo mr-3" :limit="1" :show-file-list="false" accept=".xlsx" :http-request="importProducts">
+              <el-button type="primary" :loading="allLoading.importLoading">导入</el-button>
+            </el-upload>
+            <el-button @click="dialogVisible.importVisible = false">取消</el-button>
+          </div>
+        </div>
+      </template>
+      <div class="p-8">
+        <div class="ml-4 mr-4">
+          <div class="flex items-center">1、点击下载 <el-link type="primary">产品导入模板.xlsx</el-link></div>
+          <div class="mt-4">2、填写excel文件、产品编号、产品名称、产品类别、标准价格、库存、状态必填</div>
+        </div>
+      </div>
+    </el-dialog>
+
+    <DeteleTables :visibles="dialogVisible.deteleProductDialogVisible" @showDeteleProduct="showDeteleProduct" />
+
   </div>
 </template>
 
 <script lang="ts" setup>
 import { ref, reactive, onMounted, inject } from "vue";
-import { GETSYSFILED, MOD, GETPERSONNEL, GETTEMPLATE, GETTABLELIST, ADDPRODUCT, ALLDETELE } from './api'
+import { GETSYSFILED, MOD, GETPERSONNEL, GETTEMPLATE, GETTABLELIST, ADDPRODUCT, ALLDETELE, UPLOADFILE } from './api'
 import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate, createTaskFromType, confirmAction } from '@/utils/tools'
-import { FormInstance, FormRules, ElMessageBox, ElTable } from 'element-plus'
-import { post, get } from "@/utils/request";
+import { FormInstance, FormRules, ElMessageBox, ElTable, UploadRequestOptions } from 'element-plus'
+import { post, get, uploadFile } from "@/utils/request";
 import { useRouter, useRoute } from "vue-router";
 import { GenerateForm } from '@zmjs/form-design';
+import DeteleTables from "./deteleTables.vue";
 
 const router = useRouter()
 const globalPopup = inject<GlobalPopup>('globalPopup')
@@ -128,12 +156,15 @@ const allLoading = reactive({
   productTableLading: false,
   generateFormLading: false,
   saveLoading: false,
+  importLoading: false
 })
 const dialogVisible = reactive({
   editProductVisible: false,
   taskModalVisible: false,
   clueDialogVisible: false,
-  deteleClueDialogVisible: false
+  deteleClueDialogVisible: false,
+  importVisible: false,
+  deteleProductDialogVisible: false
 })
 const allText = reactive({
   editClueText: '新建产品',
@@ -154,17 +185,31 @@ const genereditForm = ref({}) // 编辑表单
 const generateFormKey = ref(1)
 
 // 方法定义
+function batchDelete() {
+  const data = productTableRef.value && productTableRef.value.getSelectionRows()
+  if (!data.length) {
+    globalPopup?.showWarning('请选择数据')
+    return
+  }
+  deteleRow(data)
+}
+
+function showDeteleProduct(flag: boolean) {
+  if(!flag) {
+    getProductTableList()
+  }
+  dialogVisible.deteleProductDialogVisible = flag
+}
+
 function deteleRow(items: any[]) {
   let ids = items.map(item => item.id).join(',')
   let str = items.map(item => item.productName).join(',')
-  confirmAction(`确定${items.length > 1 ? '批量删除' : '删除'}【${str}】线索吗?`).then(() => {
-    post(ALLDETELE, { ids: ids }).then(res => {
-      if (res.code != 'ok') {
-        globalPopup?.showError(res.msg)
-        return
-      }
+  confirmAction(`确定${items.length > 1 ? '批量删除' : '删除'}【${str}】产品吗?`).then(() => {
+    post(ALLDETELE, { ids: ids }).then((_res) => {
       globalPopup?.showSuccess('删除成功')
       getProductTableList()
+    }).catch((err) => {
+      globalPopup?.showError(err.msg)
     })
   })
 }
@@ -172,42 +217,45 @@ function deteleRow(items: any[]) {
 async function saveProductRow(flag: boolean) {
   const data = await generateForm.value.getData()
   let newData = { ...genereditForm.value, ...data }
+  delete newData.createTime
   allLoading.saveLoading = true
-  post(ADDPRODUCT, { ...newData }).then((res) => {
-    console.log(res)
-    if(res.code != 'ok') {
-      globalPopup?.showError(res.msg)
-      return
-    }
+  post(ADDPRODUCT, { ...newData }).then(() => {
     globalPopup?.showSuccess('保存成功')
-    if (!flag) {
+    if (flag) {
       genereditForm.value = {}
       generateForm.value && generateForm.value.reset()
-      generateFormKey.value++
     }
+    getProductTableList()
     dialogVisible.editProductVisible = flag
-  }).catch(() => {
-    dialogVisible.editProductVisible = flag
+  }).catch((err) => {
+    globalPopup?.showError(err.msg)
   }).finally(() => {
     allLoading.saveLoading = false
   })
 }
 
-function editProduct(_flag: boolean) {
+function editProduct(item: any) {
   dialogVisible.editProductVisible = true
   allLoading.generateFormLading = true
+  if (item) {
+    genereditForm.value = item
+    allText.editClueText = '编辑产品'
+  }
+  if (!item) {
+    genereditForm.value = {}
+  }
   setTimeout(() => {
     generateForm.value && generateForm.value.reset()
     generateFormKey.value++
     allLoading.generateFormLading = false
-  }, 1000)
+  }, 500)
 }
 
 function getProductTableList() {
   allLoading.productTableLading = true
   let valueForm = getFromValue(filterProductForm)
   post(GETTABLELIST, { ...valueForm }).then((res) => {
-    if(res.code == 'ok') {
+    if (res.code == 'ok') {
       const { record, total } = res.data
       productTableList.value = record
       productTableTotal.value = total
@@ -217,6 +265,19 @@ function getProductTableList() {
   })
 }
 
+async function importProducts(param: UploadRequestOptions) {
+  allLoading.importLoading = true
+  const formData = new FormData();
+  formData.append('multipartFile', param.file)
+  const res = await uploadFile(UPLOADFILE, formData)
+  allLoading.importLoading = false
+  if (res.code == 'ok') {
+    globalPopup?.showSuccess(res.msg || '')
+    return
+  }
+  globalPopup?.showError(res.msg || '')
+}
+
 function handleSizeChange(val: number) {
   filterProductForm.pageIndex = 1
   filterProductForm.pageSize = val
@@ -235,9 +296,9 @@ function resetFilter() {
 }
 
 function toProductDetail(row: any) {
-  router.push({ 
-    path: `${MOD}/detail`, 
-    query: { id: row.id } 
+  router.push({
+    path: `${MOD}/detail`,
+    query: { id: row.id }
   })
 }
 

+ 1 - 6
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/detail/components/attachment.vue

@@ -64,12 +64,7 @@ const props = defineProps<{
 
 // 下载文件
 function fileDownload(item: any) {
-    const id = item.id
-    post(DOWNFILE, { id }).then((res) => {
-        downloadFile(res, item.name)
-    }).catch((err) => {
-        downloadFile(err, item.name)
-    })
+    downloadFile(`${item.path}`, item.name)
 }
 
 // 删除文件

+ 1 - 1
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/index.vue

@@ -139,7 +139,7 @@
     <DeteleTables :visibles="dialogVisible.deteleClueDialogVisible" @showDeteleClue="showDeteleClue" />
 
     <TaskModal :visible="dialogVisible.taskModalVisible" :edit-form="createTaskFromType(3)" :save-loading="'1'"
-      @close="closeTaskModal" @submit="submitForm" />
+      @close="closeTaskModal" @submit="submitForm" :title="'新建任务'" :disabled-list="['taskType', 'clueId']" />
   </div>
 </template>
 

+ 3 - 3
fhKeeper/formulahousekeeper/customerBuler-crm/src/styles/global.scss

@@ -47,7 +47,7 @@ $modena: #6f4afe;
   height: 0px;
 }
 
-.el-dialog__header,.el-dialog__body{
-  margin: 0;
-  padding: 0;
+.el-dialog__header, .el-dialog__body{
+  margin: 0 !important;
+  padding: 0 !important;
 }

+ 2 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/request.ts

@@ -45,13 +45,13 @@ instance.interceptors.response.use(
 );
 
 // 封装GET请求
-export async function get(url: string, params?: any): Promise<any> {
+export async function get(url: string, params?: any, file: boolean = false): Promise<any> {
   return new Promise((resolve, reject) => {
     instance
       .get(url, { params })
       .then(({ data }: any) => {
         const { code } = data;
-        if (code === "ok") {
+        if (code === "ok" || file) {
           resolve(data);
           return;
         }

+ 10 - 12
fhKeeper/formulahousekeeper/customerBuler-crm/src/utils/tools.ts

@@ -1,5 +1,6 @@
 import { defalutModalForm } from '@/components/TaskModal/api'
 import { ElMessageBox } from 'element-plus';
+import { get } from './request';
 /**
  * 判断值是否为空
  * @param value 值
@@ -155,20 +156,17 @@ export function createTaskFromType(taskType: TASK_VALUE_TYPE) {
 
 /**
  * 下载文件
- * @param dataFile 接口返回的数据
+ * @param fileData 接口返回的数据 或 文件地址
  * @param fileName 文件名称
  */
-export function downloadFile(dataFile: any, fileName: string) {
-  const data = dataFile;
-  const blob = new Blob([data]);
-  const url = window.URL.createObjectURL(blob);
-  const a = document.createElement('a');
-  a.href = url;
-  a.download = fileName;
-  document.body.appendChild(a);
-  a.click();
-  window.URL.revokeObjectURL(url);
-  document.body.removeChild(a);
+export async function downloadFile(fileData: any, fileName: string) {
+  const url=fileData;
+  const link = document.createElement('a');
+  link.href = url;
+  link.setAttribute('download', fileName);
+  document.body.appendChild(link);
+  link.click();
+  document.body.removeChild(link);
 };
 
 /**

+ 0 - 25
fhKeeper/formulahousekeeper/plugIn/form-design-master/src/components.d.ts

@@ -6,31 +6,6 @@ declare module 'vue' {
   export interface GlobalComponents {
     CodeEditor: typeof import('./components/CodeEditor.vue')['default']
     ComponentGroup: typeof import('./components/ComponentGroup.vue')['default']
-    ElButton: typeof import('element-plus/es')['ElButton']
-    ElCascader: typeof import('element-plus/es')['ElCascader']
-    ElCheckbox: typeof import('element-plus/es')['ElCheckbox']
-    ElCheckboxGroup: typeof import('element-plus/es')['ElCheckboxGroup']
-    ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
-    ElDialog: typeof import('element-plus/es')['ElDialog']
-    ElDivider: typeof import('element-plus/es')['ElDivider']
-    ElForm: typeof import('element-plus/es')['ElForm']
-    ElFormItem: typeof import('element-plus/es')['ElFormItem']
-    ElImage: typeof import('element-plus/es')['ElImage']
-    ElInput: typeof import('element-plus/es')['ElInput']
-    ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
-    ElOption: typeof import('element-plus/es')['ElOption']
-    ElRadio: typeof import('element-plus/es')['ElRadio']
-    ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
-    ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
-    ElRate: typeof import('element-plus/es')['ElRate']
-    ElSelect: typeof import('element-plus/es')['ElSelect']
-    ElSlider: typeof import('element-plus/es')['ElSlider']
-    ElSpace: typeof import('element-plus/es')['ElSpace']
-    ElSwitch: typeof import('element-plus/es')['ElSwitch']
-    ElTable: typeof import('element-plus/es')['ElTable']
-    ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
-    ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
-    ElUpload: typeof import('element-plus/es')['ElUpload']
   }
 }