Ver código fonte

Merge branch 'master' of http://47.100.37.243:10191/wutt/manHourHousekeeper

Min 11 meses atrás
pai
commit
fdf602d1d4
15 arquivos alterados com 709 adições e 269 exclusões
  1. 84 30
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/analysis/index.vue
  2. 3 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/api.ts
  3. 105 47
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/attachment.vue
  4. 165 13
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/information.vue
  5. 16 33
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/operationRecord.vue
  6. 82 46
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/products.vue
  7. 5 2
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/relatedProducts.vue
  8. 25 4
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/stageSetting.vue
  9. 86 15
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/detail/index.vue
  10. 2 0
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/api.ts
  11. 127 61
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/index.vue
  12. 6 15
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/detail/components/information.vue
  13. 1 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/Custom.java
  14. 0 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/BusinessOpportunityServiceImpl.java
  15. 2 1
      fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/CustomServiceImpl.java

+ 84 - 30
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/analysis/index.vue

@@ -49,11 +49,27 @@ const dateOptions = [
   }
 ];
 
-const defineDate = ref<[Date, Date] | ''>('');
+type PromptType = {
+  permission?: 0 | 1 | 2 | 3;
+  date?: 0 | 1 | 2;
+  sliceDate: [Date, Date];
+};
 
-const bulletinPrompt = reactive({ permission: undefined, date: undefined });
-const summaryPrompt = reactive({ permission: undefined, date: undefined });
-const stagePrompt = reactive({ permission: undefined, date: undefined });
+const bulletinPrompt = reactive<PromptType>({
+  permission: undefined,
+  date: undefined,
+  sliceDate: [new Date(), new Date()]
+});
+const summaryPrompt = reactive<PromptType>({
+  permission: undefined,
+  date: undefined,
+  sliceDate: [new Date(), new Date()]
+});
+const stagePrompt = reactive<PromptType>({
+  permission: undefined,
+  date: undefined,
+  sliceDate: [new Date(), new Date()]
+});
 
 const requestData = reactive<{
   bulletin: BulletinData['data'] | null;
@@ -104,10 +120,10 @@ const queryStage = async (payload?: RequestProps) => {
 
 watchEffect(() => {
   queryBulletin({
-    ...(bulletinPrompt.date === 'defineDate'
+    ...(bulletinPrompt.date === ('ignore' as any)
       ? {
-          startDate: dayjs(defineDate.value[0]).valueOf(),
-          endData: dayjs(defineDate.value[1]).valueOf()
+          startDate: dayjs(bulletinPrompt.sliceDate[0]).format('YYYY-MM-DD'),
+          endData: dayjs(bulletinPrompt.sliceDate[1]).format('YYYY-MM-DD')
         }
       : { dateType: bulletinPrompt.date }),
     queryType: bulletinPrompt.permission
@@ -116,10 +132,10 @@ watchEffect(() => {
 
 watchEffect(() => {
   queryStage({
-    ...(stagePrompt.date === 'defineDate'
+    ...(stagePrompt.date === ('ignore' as any)
       ? {
-          startDate: dayjs(defineDate.value[0]).valueOf(),
-          endData: dayjs(defineDate.value[1]).valueOf()
+          startDate: dayjs(stagePrompt.sliceDate[0]).format('YYYY-MM-DD'),
+          endData: dayjs(stagePrompt.sliceDate[1]).format('YYYY-MM-DD')
         }
       : { dateType: stagePrompt.date }),
     queryType: stagePrompt.permission
@@ -128,22 +144,29 @@ watchEffect(() => {
 
 watchEffect(() => {
   querySummary({
-    ...(summaryPrompt.date === 'defineDate'
+    ...(summaryPrompt.date === ('ignore' as any)
       ? {
-          startDate: dayjs(defineDate.value[0]).valueOf(),
-          endData: dayjs(defineDate.value[1]).valueOf()
+          startDate: dayjs(summaryPrompt.sliceDate[0]).format('YYYY-MM-DD'),
+          endData: dayjs(summaryPrompt.sliceDate[1]).format('YYYY-MM-DD')
         }
       : { dateType: summaryPrompt.date }),
     queryType: summaryPrompt.permission
   });
 });
+
+watchEffect(() => {
+  console.log(
+    bulletinPrompt.date,
+    '-----',
+    bulletinPrompt.sliceDate,
+    '88888888---watchEffect'
+  );
+});
 </script>
 
 <template>
-  <div
-    class="m-5 bg-white min-h-full p-4 rounded relative flex gap-12 items-start"
-  >
-    <section class="flex-[4]">
+  <div class="m-5 bg-white min-h-full p-4 rounded">
+    <section>
       <div class="flex gap-3 mb-4">
         <div class="w-40">
           <el-select
@@ -171,7 +194,20 @@ watchEffect(() => {
               :label="date.label"
               :value="date.value"
             />
-            <el-option v-if="defineDate" label="自定义" value="defineDate" />
+            <el-option label="自定义" value="ignore">
+              <div class="flex gap-2 w-80">
+                <el-date-picker
+                  size="small"
+                  :clearable="false"
+                  type="daterange"
+                  class="w-12"
+                  v-model="bulletinPrompt.sliceDate"
+                  start-placeholder="开始日期"
+                  end-placeholder="结束日期"
+                />
+                <el-button size="small" type="primary">确认</el-button>
+              </div>
+            </el-option>
           </el-select>
         </div>
       </div>
@@ -270,11 +306,20 @@ watchEffect(() => {
                   :label="date.label"
                   :value="date.value"
                 />
-                <el-option
-                  v-if="defineDate"
-                  label="自定义"
-                  value="defineDate"
-                />
+                <el-option label="自定义" value="ignore">
+                  <div class="flex gap-2 w-80">
+                    <el-date-picker
+                      size="small"
+                      :clearable="false"
+                      type="daterange"
+                      class="w-12"
+                      v-model="summaryPrompt.sliceDate"
+                      start-placeholder="开始日期"
+                      end-placeholder="结束日期"
+                    />
+                    <el-button size="small" type="primary">确认</el-button>
+                  </div>
+                </el-option>
               </el-select>
             </div>
           </div>
@@ -366,11 +411,20 @@ watchEffect(() => {
                   :label="date.label"
                   :value="date.value"
                 />
-                <el-option
-                  v-if="defineDate"
-                  label="自定义"
-                  value="defineDate"
-                />
+                <el-option label="自定义" value="ignore">
+                  <div class="flex gap-2 w-80">
+                    <el-date-picker
+                      size="small"
+                      :clearable="false"
+                      type="daterange"
+                      class="w-12"
+                      v-model="stagePrompt.sliceDate"
+                      start-placeholder="开始日期"
+                      end-placeholder="结束日期"
+                    />
+                    <el-button size="small" type="primary">确认</el-button>
+                  </div>
+                </el-option>
               </el-select>
             </div>
           </div>
@@ -380,7 +434,7 @@ watchEffect(() => {
         </div>
       </div>
     </section>
-    <nav class="flex-1 min-w-60 sticky right-0 top-9 max-lg:hidden">
+    <!-- <nav class="flex-1 min-w-60 sticky right-0 top-9 max-lg:hidden">
       <div class="border border-gray-200 rounded w-3/4 text-sm text-gray-500">
         <div class="p-2" v-for="primission in permissionOptions">
           {{ primission.label }}
@@ -399,6 +453,6 @@ watchEffect(() => {
           />
         </div>
       </div>
-    </nav>
+    </nav> -->
   </div>
 </template>

+ 3 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/api.ts

@@ -15,6 +15,9 @@ export const BUSIESS_GETSATE = `/business-opportunity/getStage`
 export const BUSIESS_SAVESAIE = `/business-opportunity/saveStage`
 export const BUSIESS_ALL = `/business-opportunity/getAll`
 export const BUSIESS_INFO = `/business-opportunity/getInfo`
+export const DETELEFILEFILE = `/business-opportunity/deleteFile`
+export const REFIENAMEFILE = `/business-opportunity/reFileName`
+export const UPLOADFILEFILE = `/business-opportunity/uploadFile`
 
 
 export const stageStatus = [

+ 105 - 47
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/attachment.vue

@@ -3,68 +3,126 @@
         <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">上传</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="name" label="附件名称" width="180" />
+                <el-table-column prop="size" label="附件大小" width="120" />
+                <el-table-column prop="userName" label="上传人" width="120" />
+                <el-table-column prop="createTime" 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="renameDialogVisible" 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" @click="saveEditClue()">保存</el-button>
+                        <el-button @click="renameDialogVisible = 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 { ElMessageBox, UploadRequestOptions } from 'element-plus';
+import { post, uploadFile } from '@/utils/request';
+import { confirmAction, downloadFile } from '@/utils/tools';
+import { ref, reactive, onMounted, onUnmounted, defineEmits, defineExpose, inject, watchEffect } from 'vue'
+import { DETELEFILEFILE, REFIENAMEFILE, UPLOADFILEFILE } from '../api';
 
-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(() => {
+const emits = defineEmits(['refreshData']);
+const globalPopup = inject<GlobalPopup>('globalPopup')
+const props = defineProps<{
+    information: any
+}>()
+
+const attachmenttable = ref([])
+const information = ref<any>({})
+const renameDialogVisible = ref(false)
+const renameVal = ref('')
+
+// 下载文件
+function fileDownload(item: any) {
+    downloadFile(`${item.path}`, item.name)
+}
+
+// 删除文件
+function deteleFile(item: any) {
+    const id = item.id
+    confirmAction(`确定删除【${item.name}】文件吗?`).then(() => {
+        post(DETELEFILEFILE, { id }).then((_res) => {
+            globalPopup?.showSuccess('删除成功')
+            emits('refreshData')
+        })
+    })
+}
+
+// 保存重命名
+function saveEditClue() {
+    if (!renameVal.value) {
+        globalPopup?.showWarning('请输入文件名称')
+        return
+    }
+    const bussinessId = information.value.id
+    post(REFIENAMEFILE, { name: renameVal.value, id: bussinessId }).then((res) => {
+        if (res.code == 'ok') {
+            renameDialogVisible.value = false
+            globalPopup?.showSuccess(res.msg || '')
+            emits('refreshData')
+        }
+    }).catch((_err) => { })
+}
+
+// 显示弹窗
+function showVisible(item: any) {
+    renameVal.value = JSON.parse(JSON.stringify(item.name))
+    renameDialogVisible.value = true
+}
+
+// 上传附件
+async function httpUploadFile(param: UploadRequestOptions) {
+    const bussinessId = information.value.id
+    const formData = new FormData();
+    formData.append('file', param.file)
+    formData.append('id', bussinessId)
+    const res = await uploadFile(UPLOADFILEFILE, formData)
+    if (res.code == 'ok') {
+        globalPopup?.showSuccess(res.msg || '')
+        emits('refreshData');
+        return
+    }
+    globalPopup?.showError(res.msg || '')
+    return res
+}
+
+watchEffect(() => {
+    information.value = props.information
+    attachmenttable.value = props.information.uploadFilePList
 });
+
+// 生命周期钩子
+onMounted(() => { });
 </script>
 <style scoped lang="scss">
 .attachment {

Diferenças do arquivo suprimidas por serem muito extensas
+ 165 - 13
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/information.vue


+ 16 - 33
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/operationRecord.vue

@@ -5,45 +5,28 @@
         </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="creatTime" label="操作时间" width="140" />
+                <el-table-column prop="userName" label="操作人" width="120" />
+                <el-table-column prop="name" 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 props = defineProps<{
+    information: any
+}>()
+
+const operationRecordtable = ref([])
+const information = ref<any>({})
+
+watchEffect(() => {
+    information.value = props.information
+    operationRecordtable.value = props.information.actionLogList
+});
 
-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(() => {
 });

+ 82 - 46
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/products.vue

@@ -3,7 +3,7 @@
         <div class="flex justify-between">
             <div class="title">相关产品</div>
             <div>
-                <el-button type="primary">编辑产品</el-button>
+                <el-button type="primary" @click="showVisible('editProductVisible')">编辑产品</el-button>
             </div>
         </div>
         <div class="flex-1 overflow-auto pt-3">
@@ -31,56 +31,92 @@
                 <el-table-column prop="endTime" label="合计" width="130" />
             </el-table>
         </div>
+
+        <!-- 弹窗 -->
+        <el-dialog v-model="allVisible.editProductVisible" width="1000" :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="editProduct()"
+                            :loading="allLoading.editProductLoading">保存</el-button>
+                        <el-button @click="closeVisible('editProductVisible')">取消</el-button>
+                    </div>
+                </div>
+            </template>
+            <div class="h-[60vh] overflow-y-auto scroll-bar pt-3">
+                <RelatedProducts ref="relatedProductsRef" :productTableList="productTableList" :height="'420px'" />
+            </div>
+        </el-dialog>
     </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'
+import { GETTABLELIST } from '@/pages/product/api';
+import { post } from '@/utils/request';
+
+import RelatedProducts from './relatedProducts.vue'
+
+const props = defineProps<{
+    information: any
+}>()
+
+const information = ref<any>({})
+const relatedTaskstable = ref([])
+const productTableList = ref<any>([])
+const relatedProductsRef = ref<typeof RelatedProducts>()
+const allVisible = reactive({
+    editProductVisible: false
+})
+const allLoading = reactive({
+    editProductLoading: false
+})
+
+function editProduct() {
+    let productTableListData = relatedProductsRef?.value?.returnData()
+    const { id, name, customerId, contactsId, amountOfMoney, expectedTransactionDate, stageId, inchargerId, remark } = information.value
+    const formData = { id, name, customerId, contactsId, amountOfMoney, expectedTransactionDate, stageId, inchargerId, remark }
+    console.log(productTableListData, '<===== 将要提交的数据', formData)
+}
+
+function showVisible(type: keyof typeof allVisible) {
+    allVisible[type] = true
+}
+function closeVisible(type: keyof typeof allVisible) {
+    allVisible[type] = false
+}
+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 {
+                    id,
+                    productId: id,
+                    productName,
+                    productCode,
+                    unit,
+                    unitName,
+                    price,
+                    type,
+                    typeName,
+                    inventory,
+                    quantity: '',
+                    discount: '',
+                    totalPrice: ''
+                }
+            })
+        }
+    })
+}
+
+watchEffect(() => {
+    information.value = props.information
+});
 
-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(() => {
+    getProductTableList()
 });
 </script>
 <style scoped lang="scss">

+ 5 - 2
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/relatedProducts.vue

@@ -1,7 +1,7 @@
 <template>
     <div>
         <el-table ref="productTableRef" :data="productTable" border :row-class-name="tableRowClassName"
-            @row-click="tableRowItem" style="width: 100%;height: 200px">
+            @row-click="tableRowItem" :style="{ width: '100%', height: heightClass }">
             <el-table-column label="序号" width="60" align="center">
                 <template #default="scope">
                     <span>{{ scope.$index + 1 }}</span>
@@ -63,11 +63,13 @@ import { ref, reactive, onMounted, inject, watchEffect } from "vue";
 
 const props = defineProps<{
     productTableList: any,
+    height?: string,
 }>()
 
 const productTable: any = ref([{}])
 const productTableIndex = ref(0) // 可以编辑索引
 const productArrar: any = ref([])
+const heightClass = ref('200px') // 表格高度
 
 type ProductTableField = 'sellingPrice' | 'quantity' | 'discount'
 
@@ -119,8 +121,9 @@ function returnData() {
 }
 
 watchEffect(() => {
-    const { productTableList } = props
+    const { productTableList, height } = props
     productArrar.value = productTableList || []
+    heightClass.value = !height ? '200px' : height
 });
 
 defineExpose({

+ 25 - 4
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/component/stageSetting.vue

@@ -21,7 +21,11 @@
                             </template>
                         </el-table-column>
                         <el-table-column :prop="'name'" :label="'阶段名称'"></el-table-column>
-                        <el-table-column :prop="'plan'" :label="'进度'" width="100"></el-table-column>
+                        <el-table-column :prop="'plan'" :label="'进度'" width="100">
+                            <template #default="scope">
+                                {{ scope.row.plan }} %
+                            </template>
+                        </el-table-column>
                         <el-table-column label="操作" fixed="right" width="200">
                             <template #default="scope">
                                 <el-button link type="primary" size="large" @click="addStage(scope.row)">编辑</el-button>
@@ -117,11 +121,12 @@ function saveState() {
     let data = newList.map((item: stageFormType, index: number) => {
         return {
             ...item,
+            plan: item.plan + '%',
             seq: index
         }
     })
     allLoading.saveLoading = true
-    post(BUSIESS_SAVESAIE, {list: JSON.stringify(data)}).then(() => {
+    post(BUSIESS_SAVESAIE, { list: JSON.stringify(data) }).then(() => {
         globalPopup?.showSuccess('保存成功')
         cancel()
     }).finally(() => {
@@ -134,7 +139,17 @@ function editState(flag: boolean) {
         globalPopup?.showWarning('请输入阶段名称')
         return
     }
-    stageTableList.value.push({ ...stageForm })
+    const listIndex = stageTableList.value.findIndex((item: stageFormType) => item.name == stageForm.name)
+    const newStage = {
+        ...stageForm,
+        plan: stageForm.plan,
+    }
+    if (listIndex != -1) {
+        stageTableList.value.splice(listIndex, 1, newStage)
+    } else {
+        stageTableList.value.push(newStage)
+    }
+
     if (flag) {
         resetStage()
     }
@@ -184,7 +199,13 @@ function getTableList() {
     allLoading.tableLoading = true
     post(BUSIESS_GETSATE, {}).then((res) => {
         const { data } = res
-        let newData = data || []
+        let newData = (data || []).map((item: any) => {
+            let plans = item.plan.indexOf('%') != -1 ? Number(item.plan.replace(/%/g, '')) : Number(item.plan)
+            return {
+                ...item,
+                plan: plans
+            }
+        })
         stageTableList.value = newData.sort(function (a: any, b: any) {
             return a.seq - b.seq;
         });

+ 86 - 15
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/business/detail/index.vue

@@ -1,6 +1,6 @@
 <template>
-  <div class="h-full flex p-3 flex-col businessDetail">
-    <div class="w-full bg-white p-2 mb-2 shadow-md rounded-md flex items-center" v-loading="allLoading.skeletonLoading">
+  <div class="h-full flex p-3 flex-col businessDetail" v-loading="allLoading.skeletonLoading">
+    <div class="w-full bg-white p-2 mb-2 shadow-md rounded-md flex items-center">
       <div class="icon mr-4">
         <el-link :underline="false" @click="backPath()">
           <el-icon class="el-icon--right"><icon-view /></el-icon> 返回商机列表
@@ -18,12 +18,13 @@
           <div class="text-nowrap">{{ item.plan }}</div>
         </div>
       </div>
-      <div class="relative rounded-md flex items-center itemPing backGray endStep item pl-6 pr-6 mr-4">
-        <el-select v-model="stageStatusVal" placeholder="结束" style="width: 100px" class="selectClas">
+      <div class="relative rounded-md flex items-center itemPing backGray endStep item pl-6 pr-6 mr-4 resetStyle">
+        <el-select v-model="stageStatusVal" placeholder="结束" style="width: 100px" class="selectClas"
+          @change="advanceChange()">
           <el-option v-for="(item, index) in stageListOption" :key="index" :label="item.label" :value="item.value" />
         </el-select>
       </div>
-      <div class="bg-[#0052CC] rounded-md text itemPing pl-2 pr-2 flex items-center aloneText">
+      <div class="bg-[#075985] rounded-md text itemPing pl-2 pr-2 flex items-center aloneText" @click="advancementStage()">
         <el-link :underline="false">推进至阶段【验证客户】</el-link>
       </div>
     </div>
@@ -31,28 +32,47 @@
     <div class="flex-1 flex flex-col overflow-y-auto overflow-x-hidden scroll-bar">
       <div class="w-full h-auto flex justify-between">
         <div class="bg-white shadow-md rounded-md" style="width: 46%;">
-          <Information />
+          <Information :information="businessInfo" @refreshData="refreshData" />
         </div>
         <div class="bg-white ml-2 shadow-md rounded-md flex-1">
-          <Attachment />
+          <Attachment :information="businessInfo" @refreshData="refreshData" />
         </div>
       </div>
 
       <div class="w-full h-auto flex justify-between mt-2">
         <div class="bg-white shadow-md rounded-md" style="width: 65%;">
-          <DetailCompinents :data="detailCompinentsData" :information="businessInfo" :formTaskType="1" :filed="'businessOpportunityId'" :disabledList="['taskType', 'businessOpportunityId']" @refreshData="getDetail" />
+          <DetailCompinents :data="detailCompinentsData" :information="businessInfo" :formTaskType="1"
+            :filed="'businessOpportunityId'" :disabledList="['taskType', 'businessOpportunityId']"
+            @refreshData="getDetail" />
         </div>
         <div class="bg-white ml-2 shadow-md rounded-md flex-1">
-          <OperationRecord />
+          <OperationRecord :information="businessInfo" />
         </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 :information="businessInfo" />
         </div>
       </div>
     </div>
+
+    <!-- 弹窗 -->
+    <el-dialog v-model="allVisible.advanceVisible" 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">{{ allText.advanceText }}原因</h4>
+          <div>
+            <el-button type="primary" :loading="allLoading.advanceSaveLoading" @click="advanceSave(true)">保存</el-button>
+            <el-button @click="advanceClose">取消</el-button>
+          </div>
+        </div>
+      </template>
+      <div class="pt-3">
+        <div>请输入{{ allText.advanceText }}原因</div>
+        <el-input v-model.trim="advanceVal" style="width: 100%" class="pb-3" :placeholder="'请输入'" clearable />
+      </div>
+    </el-dialog>
   </div>
 </template>
   
@@ -79,26 +99,77 @@ type stageListType = {
 }
 
 const route = useRoute()
+const globalPopup = inject<GlobalPopup>('globalPopup')
 const detailCompinentsData = ref([])
 const optionVal = ref<any>('')
 const stageStatusVal = ref('')
+const stageStatusValOriginally = ref('')
+const advanceVal = ref('')
 const options = ref<optionType[]>([])
 const allLoading = reactive({
-  skeletonLoading: false
+  skeletonLoading: false,
+  advanceSaveLoading: false
+})
+const allVisible = reactive({
+  advanceVisible: false
+})
+const allText = reactive({
+  advanceText: ''
 })
 
 const businessInfo = ref({})
 const stageListOption = ref<optionType[]>([])
 const stageList = ref<stageListType[]>([])
 
+function refreshData() {
+  getDetail()
+}
+
+function advancementStage() {
+  console.log('点击了推进阶段')
+  advanceSave(false)
+}
+
+function advanceChange() {
+  stageStatusValOriginally.value = JSON.parse(JSON.stringify(stageStatusVal.value))
+  const item: any = stageListOption.value.find((item) => item.value === stageStatusVal.value)
+  console.log(item)
+  if (item.plan == '0%') {
+    advanceVal.value = ''
+    allText.advanceText = item.label
+    allVisible.advanceVisible = true
+    return
+  }
+
+  advanceSave(false)
+}
+
+function advanceClose() {
+  stageStatusVal.value = stageStatusValOriginally.value
+  allVisible.advanceVisible = false
+}
+
+function advanceSave(flag: boolean) {
+  if(!advanceVal && flag) {
+    globalPopup?.showError(`请输入${allText.advanceText}原因`)
+    return
+  }
+  allLoading.advanceSaveLoading = true
+  post('接口', {}).then(() => {
+    globalPopup?.showSuccess('操作成功')
+    getDetail()
+  }).finally(() => {
+    allLoading.advanceSaveLoading = false
+  })
+}
 
 function getDetail() {
-  allLoading.skeletonLoading
+  allLoading.skeletonLoading = true
   post(BUSIESS_INFO, { id: optionVal.value }).then(({ data }) => {
     businessInfo.value = (data || []);
     detailCompinentsData.value = data.taskList || []
   }).finally(() => {
-    allLoading.skeletonLoading
+    allLoading.skeletonLoading = false
   })
 }
 
@@ -123,7 +194,7 @@ function getOptionAll() {
 function getSatge() {
   post(BUSIESS_GETSATE, {}).then(({ data }) => {
     stageList.value = (data || []).sort((a: any, b: any) => { return a.seq - b.seq; }).filter((item: any) => !item.isFinish).map((item: any) => ({ name: item.name, plan: item.plan }))
-    stageListOption.value = (data || []).sort((a: any, b: any) => { return a.seq - b.seq; }).filter((item: any) => item.isFinish).map((item: any) => ({ label: item.name, value: item.id }))
+    stageListOption.value = (data || []).sort((a: any, b: any) => { return a.seq - b.seq; }).filter((item: any) => item.isFinish).map((item: any) => ({ label: item.name, value: item.id, plan: item.plan }))
   })
 }
 
@@ -199,7 +270,7 @@ onMounted(() => {
 }
 </style>
 <style lang="scss">
-.businessDetail {
+.resetStyle {
   .el-select__wrapper {
     background-color: #F4F5F7;
     box-shadow: none !important;

+ 2 - 0
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/api.ts

@@ -3,7 +3,9 @@ export const IMPORTMOD = 'Customer'
 export const PREFIX = '/custom'
 export const GETSYSFILED = '/sys-dict/getListByCode'
 export const GETPERSONNEL = '/user/getSimpleActiveUserList'
+export const URL_TEMPLALE = `/sys-form/getListByCode${MOD}`
 export const URL_TABLELIST = `${PREFIX}/list`
+export const URL_EDITSAVE = `${PREFIX}/insertAndUpdate`
 
 export const stageStatus = [
     { id: 1, name: "赢单", progress: "100%" },

+ 127 - 61
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/customer/index.vue

@@ -5,15 +5,15 @@
         <div class="flex-1 p-3 overflow-y-auto">
           <el-form :model="customerCriteriaForm" label-width="70px" style="max-width: 600px">
             <el-form-item label="客户名称">
-              <el-input v-model="customerCriteriaForm.clueName" clearable placeholder="请输入"></el-input>
+              <el-input v-model="customerCriteriaForm.customName" clearable placeholder="请输入"></el-input>
             </el-form-item>
             <el-form-item label="客户来源">
-              <el-select v-model="customerCriteriaForm.clueSourceId" placeholder="请选择">
-                <el-option v-for="item in fixedData.CustomSources" :key="item.id" :label="item.name" :value="item.id" />
+              <el-select v-model="customerCriteriaForm.customSourceId" placeholder="请选择">
+                <el-option v-for="item in fixedData.ClueSources" :key="item.id" :label="item.name" :value="item.id" />
               </el-select>
             </el-form-item>
             <el-form-item label="电话号码">
-              <el-input v-model="customerCriteriaForm.phone" clearable placeholder="请输入"></el-input>
+              <el-input v-model="customerCriteriaForm.telPhone" clearable placeholder="请输入"></el-input>
             </el-form-item>
             <el-form-item label="邮箱">
               <el-input v-model="customerCriteriaForm.email" clearable placeholder="请输入"></el-input>
@@ -52,57 +52,76 @@
     <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">新建客户</el-button>
-          <el-button type="primary" @click="batchTransfer()">批量转移</el-button>
-          <el-button type="primary" @clicl="batchDelete()">批量删除</el-button>
+          <el-button type="primary" @click="editCustomer(false)">新建客户</el-button>
+          <el-button type="primary">批量转移</el-button>
+          <el-button type="primary">批量删除</el-button>
           <el-button type="primary">回收站</el-button>
           <el-button type="primary">导入</el-button>
           <el-button type="primary">导出</el-button>
         </div>
         <div class="flex-1 w-full overflow-hidden">
-          <el-table ref="clueTableRef" :data="clueTable" border v-loading="allLoading.clueTableLading"
+          <el-table ref="clueTableRef" :data="customerTable" border v-loading="allLoading.customerTableLading"
             style="width: 100%;height: 100%;">
             <el-table-column type="selection" width="55" />
-            <el-table-column prop="clueName" label="客户名称" width="180">
+            <el-table-column prop="customName" label="客户名称" width="180">
               <template #default="scope">
-                <el-button link type="primary" size="large" @click.prevent="toCustomerTableDetail(scope.row)">{{ scope.row.clueName
+                <el-button link type="primary" size="large" @click.prevent="toCustomerTableDetail(scope.row)">{{
+                  scope.row.customName
                 }}</el-button>
               </template>
             </el-table-column>
-            <el-table-column prop="clueSourceId" label="客户来源" width="180"></el-table-column>
-            <el-table-column prop="phone" label="公司电话" width="180"></el-table-column>
-            <el-table-column prop="email" label="邮箱" width="180"></el-table-column>
-            <el-table-column prop="customerIndustryId" label="客户行业" width="180"></el-table-column>
-            <el-table-column prop="customerLevelId" label="客户级别" width="180"></el-table-column>
-            <el-table-column prop="inchargerId" label="负责人" width="190"></el-table-column>
-            <el-table-column prop="createName" label="创建人" width="180"></el-table-column>
-            <el-table-column prop="createTime" label="创建时间" width="180"></el-table-column>
+            <el-table-column prop="customSourceValue" label="客户来源" width="180"></el-table-column>
+            <el-table-column prop="companyPhone" label="公司电话" width="180"></el-table-column>
+            <el-table-column prop="email" label="邮箱" width="200"></el-table-column>
+            <el-table-column prop="customerIndustryValue" label="客户行业" width="180"></el-table-column>
+            <el-table-column prop="customerLevelValue" 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="newCreateTime" 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">新建客户</el-button>
-                <el-button link type="danger" size="large" @click.prevent="deleteRow(scope.$index)">删除</el-button>
+                <el-button link type="primary" size="large" @click="editCustomer(scope.row)">编辑</el-button>
+                <el-button link type="primary" size="large">新建任务</el-button>
+                <el-button link type="danger" size="large">删除</el-button>
               </template>
             </el-table-column>
           </el-table>
         </div>
         <div class="flex justify-end pt-3">
-          <el-pagination layout="total, prev, pager, next, sizes" :total="clueTotalTable" :hide-on-single-page="true" />
+          <el-pagination layout="total, prev, pager, next, sizes" :total="customerTotalTable"
+            :hide-on-single-page="true" />
         </div>
       </div>
     </div>
 
-    <!-- 弹窗 -->
-    
+    <!-- 新建客户 -->
+    <el-dialog v-model="allVisible.editCustomerVisible" width="1000" :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">{{ allText.editCustomerText }}</h4>
+          <div>
+            <el-button type="primary" :loading="allLoading.editCustomerSaveLoading" @click="editCustomerSave(true)">保存并新建</el-button>
+            <el-button type="primary" :loading="allLoading.editCustomerSaveLoading" @click="editCustomerSave(false)">保存</el-button>
+            <el-button @click="closeVisible('editCustomerVisible')">取消</el-button>
+          </div>
+        </div>
+      </template>
+      <div class="h-[60vh] overflow-y-auto scroll-bar pt-3">
+        <div class="ml-4 mr-4">
+          <GenerateForm ref="customerTemplateRef" :data="customerTemplate" :value="customerTemplateValue" />
+        </div>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script lang="ts" setup>
 import { ref, reactive, onMounted, inject } from "vue";
-import { MOD, GETSYSFILED, GETPERSONNEL, URL_TABLELIST } from './api.ts'
+import { MOD, GETSYSFILED, GETPERSONNEL, URL_TABLELIST, URL_TEMPLALE, URL_EDITSAVE } from './api.ts'
 import { getAllListByCode, getFromValue, resetFromValue, getFirstDayOfMonth, getLastDayOfMonth, formatDate } from '@/utils/tools'
 import { post, get } from "@/utils/request";
 import { useRouter, useRoute } from "vue-router";
+import { GenerateForm } from '@zmjs/form-design';
 
 // 定义类型
 interface fixedDataInterface {
@@ -121,9 +140,9 @@ interface personnelInterface {
 }
 
 interface customerCriteriaFormType { // 线索筛选条件类型
-  clueName: string,
-  clueSourceId: string | number,
-  phone: string,
+  customName: string,
+  customSourceId: string | number,
+  telPhone: string,
   email: string,
   customerIndustryId: string | number,
   customerLevelId: string | number,
@@ -135,13 +154,12 @@ interface customerCriteriaFormType { // 线索筛选条件类型
 }
 
 // 定义变量
-const route = useRoute()
 const router = useRouter()
 const globalPopup = inject<GlobalPopup>('globalPopup')
 const customerCriteriaForm = reactive<customerCriteriaFormType>({ // 筛选条件form
-  clueName: '',
-  clueSourceId: '',
-  phone: '',
+  customName: '',
+  customSourceId: '',
+  telPhone: '',
   email: '',
   customerIndustryId: '',
   customerLevelId: '',
@@ -151,60 +169,97 @@ const customerCriteriaForm = reactive<customerCriteriaFormType>({ // 筛选条
   pageIndex: 1,
   pageFrom: 10
 })
-const clueTableTotal = ref(0)
+const customerTable = ref([]) // 线索table数据
+const customerTotalTable = ref(0) // 线索 table 数据总数
 const allLoading = reactive({
-  clueTableLading: false,
+  customerTableLading: false,
+  editCustomerSaveLoading: false
+})
+const allVisible = reactive({
+  editCustomerVisible: false,
+})
+const allText = reactive({
+  editCustomerText: '新建客户',
 })
 const fixedData = reactive({
-  CustomSources: [] as fixedDataInterface[],
+  ClueSources: [] as fixedDataInterface[],
   CustomIndustry: [] as fixedDataInterface[],
   CustomLevel: [] as fixedDataInterface[],
   Personnel: [] as personnelInterface[]
 })
-const clueTable = ref([{ clueName: '客户名称', clueSourceId: '客户来源', id: 123456789 }]) // 线索table数据
-const clueTotalTable = ref(0) // 线索 table 数据总数
 
-// 定义方法
-function searchTable() {
-  getClueTable()
-}
+const customerTemplate = ref({
+  list: [],
+  config: {}
+})
+const customerTemplateRef = ref<typeof GenerateForm>() // 自定义表单dom
+const customerTemplateValue = ref({})
 
-function resetTable() {
-  let newResetForm = resetFromValue(customerCriteriaForm, { startTime: getFirstDayOfMonth(new Date()), endTime: formatDate(new Date()), pageIndex: 1, pageFrom: 10 })
-  Object.assign(customerCriteriaForm, newResetForm)
-  getClueTable()
+
+// 定义方法
+function editCustomerSave(flag: boolean) {
+  customerTemplateRef.value?.getData().then((res: any) => {
+    allLoading.editCustomerSaveLoading = true
+    post(URL_EDITSAVE, { ...res }).then((_res) => {
+      allVisible.editCustomerVisible = flag
+      globalPopup?.showSuccess('保存成功')
+      if(flag) {
+        customerTemplateRef.value?.reset()
+      }
+      getCustomerTable()
+    }).finally(() => {
+      allLoading.editCustomerSaveLoading = false
+    })
+  }).catch((_err: any) => {
+    console.log(_err)
+    globalPopup?.showError('请填写完整')
+  })
 }
 
-function deleteRow(_row: any) {
-  console.log('点击了删除')
+function editCustomer(row: any) { // row 有数据代表编辑
+  if (row) {
+    const templateKey = customerTemplate.value.list.map((item: any) => item.model)
+    console.log(templateKey, '<==== key')
+  } else { // 没有数据代表新建
+    customerTemplateRef.value?.reset()
+  }
+  showVisible('editCustomerVisible')
 }
 
-function batchTransfer() {
-  console.log('点击了批量转移')
+function toCustomerTableDetail(_row: any) {
+  console.log('点击跳转详情')
+  router.push({ path: `${MOD}/detail`, query: { id: _row.id } })
 }
 
-function batchDelete() {
-  console.log('批量删除')
+function searchTable() {
+  getCustomerTable()
 }
 
-function toCustomerTableDetail(_row: any) {
-  console.log('点击跳转详情')
-  router.push({path: `${MOD}/detail`, query: {id: _row.id}})
+function resetTable() {
+  let newResetForm = resetFromValue(customerCriteriaForm, { startTime: getFirstDayOfMonth(new Date()), endTime: formatDate(new Date()), pageIndex: 1, pageFrom: 10 })
+  Object.assign(customerCriteriaForm, newResetForm)
+  getCustomerTable()
 }
 
-function getClueTable() {
+function getCustomerTable() {
   let valueForm = getFromValue(customerCriteriaForm)
-  post(URL_TABLELIST, { ...valueForm}).then((res) => {
+  allLoading.customerTableLading = true
+  post(URL_TABLELIST, { ...valueForm }).then((res) => {
     const { data, total } = res.data
-    clueTable.value = data
-    clueTableTotal.value = total
+    customerTable.value = (data || []).map((item: any) => {
+      return {
+        ...item,
+        newCreateTime: formatDate(new Date(item.createTime)),
+      }
+    })
+    customerTotalTable.value = total
   }).finally(() => {
-
+    allLoading.customerTableLading = false
   })
 }
 
 async function getSystemField() {
-  const systemField = getAllListByCode(['客户来源', '客户行业', '客户级别'])
+  const systemField = getAllListByCode(['线索来源', '客户行业', '客户级别'])
   for (let i in systemField) {
     const { data } = await get(`${GETSYSFILED}?code=${systemField[i]}`)
     for (let key of Object.keys(fixedData)) {
@@ -221,11 +276,22 @@ async function getSystemField() {
       id, name, phone, jobNumber
     }
   })
+
+  const res = await get(URL_TEMPLALE)
+  customerTemplate.value = JSON.parse(res.data[0].config)
+}
+
+function showVisible(type: keyof typeof allVisible) {
+  allVisible[type] = true
+}
+
+function closeVisible(type: keyof typeof allVisible) {
+  allVisible[type] = false
 }
 
 onMounted(() => {
   getSystemField()
-  getClueTable()
+  getCustomerTable()
 })
 </script>
 

+ 6 - 15
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/thread/detail/components/information.vue

@@ -72,12 +72,12 @@
                     <h4 :id="titleId">{{ allText.editClueText }}</h4>
                     <div>
                         <el-button type="primary" @click="saveEditClue()"
-                            v-loading="allLoading.saveBtnLoading">保存</el-button>
+                            :loading="allLoading.saveBtnLoading">保存</el-button>
                         <el-button @click="dialogVisible.editClueDialogVisible = false">取消</el-button>
                     </div>
                 </div>
             </template>
-            <div class="h-[60vh] overflow-y-auto scroll-bar pt-3" v-loading="allLoading.generateFormLading">
+            <div class="h-[60vh] overflow-y-auto scroll-bar pt-3" :loading="allLoading.generateFormLading">
                 <div class="ml-4 mr-4">
                     <GenerateForm ref="generateForm" :data="clueTemplate" :value="editForm" :key="generateFormKey" />
                 </div>
@@ -89,7 +89,7 @@
                 <div class="flex justify-between items-center border-b pb-3 dialog-header">
                     <h4 :id="titleId">{{ allText.clueText }}</h4>
                     <div>
-                        <el-button type="primary" v-loading="allLoading.clueLoading" @click="transferClues()">转移</el-button>
+                        <el-button type="primary" :loading="allLoading.clueLoading" @click="transferClues()">转移</el-button>
                         <el-button @click="dialogVisible.clueDialogVisible = false">取消</el-button>
                     </div>
                 </div>
@@ -228,18 +228,9 @@ function transferClues() {
 }
 
 function claimClues() {
-    ElMessageBox.confirm(
-        `确定认领【${information.value.clueName}】线索吗?`,
-        'Warning',
-        {
-            confirmButtonText: '确定',
-            cancelButtonText: '取消',
-            type: 'warning',
-        }
-    )
-        .then(() => {
-            transferClues()
-        })
+    confirmAction(`确定认领【${information.value.clueName}】线索吗?`).then(() => {
+        transferClues()
+    })
 }
 
 // 保存

+ 1 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/entity/Custom.java

@@ -75,7 +75,7 @@ public class Custom extends Model<Custom> {
     @TableField("customer_industry_id")
     private Integer customerIndustryId;
     @TableField(exist = false)
-    private Integer customerIndustryValue;
+    private String customerIndustryValue;
 
     /**
      * 客户级别id

+ 0 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/BusinessOpportunityServiceImpl.java

@@ -221,7 +221,6 @@ public class BusinessOpportunityServiceImpl extends ServiceImpl<BusinessOpportun
         msg.setMsg("操作成功");
         biMapper.delete(new QueryWrapper<BusinessItemProduct>().eq("business_id",bo.getId()));
         List<BusinessItemProduct> businessItemProducts = JSONArray.parseArray(bo.getBusinessItemProductList(), BusinessItemProduct.class);
-//        biMapper.saveBatch()
         for (BusinessItemProduct businessItemProduct : businessItemProducts) {
             biMapper.insert(businessItemProduct);
         }

+ 2 - 1
fhKeeper/formulahousekeeper/management-crm/src/main/java/com/management/platform/service/impl/CustomServiceImpl.java

@@ -95,11 +95,12 @@ public class CustomServiceImpl extends ServiceImpl<CustomMapper, Custom> impleme
                 return msg;
             }
             if (customMapper.selectCount(new QueryWrapper<Custom>().eq("tel_phone", custom.getTelPhone())) > 0) {
-                msg.setError("电话号码重复了");
+//                msg.setError("电话号码重复了");
                 return msg;
             }
             custom.setCreateTime(new Date());
             custom.setCreatorId(user.getId());
+            custom.setIsDelete(0);
             ActionLog actionLog = new ActionLog();
             actionLog.setCode("custom");
             actionLog.setCreatTime(new Date());