Эх сурвалжийг харах

客户检索;英文客户列表;临时权限列表;终止权限列表;正式客户共享

Karsa 8 сар өмнө
parent
commit
619ecc3ca3
36 өөрчлөгдсөн 9272 нэмэгдсэн , 614 устгасан
  1. 2 0
      package.json
  2. 140 16
      pnpm-lock.yaml
  3. 43 1
      src/api/modules/crmApi.js
  4. 1 1
      src/router/modules/approvalRoutes.js
  5. 76 65
      src/router/modules/customRoutes.js
  6. 2 1
      src/styles/element.scss
  7. 419 0
      src/utils/tinymce_zh_CN.js
  8. 3 3
      src/views/custom_manage/custom/approvalList.vue
  9. 498 0
      src/views/custom_manage/custom/components/Capplydialog.vue
  10. 194 0
      src/views/custom_manage/custom/components/CauthList.vue
  11. 171 0
      src/views/custom_manage/custom/components/CompleteInfo.vue
  12. 903 0
      src/views/custom_manage/custom/components/Contactdialog.vue
  13. 335 0
      src/views/custom_manage/custom/components/ContractInfo.vue
  14. 252 0
      src/views/custom_manage/custom/components/CpessionTableEquity.vue
  15. 99 0
      src/views/custom_manage/custom/components/FreezAuthList.vue
  16. 241 0
      src/views/custom_manage/custom/components/TotalDayDialog.vue
  17. 1 1
      src/views/custom_manage/custom/components/accumulativeFrequencyDlg.vue
  18. 150 0
      src/views/custom_manage/custom/components/customRemarkDialog.vue
  19. 105 0
      src/views/custom_manage/custom/components/permissionDetail.vue
  20. 257 0
      src/views/custom_manage/custom/components/premissionView.vue
  21. 165 0
      src/views/custom_manage/custom/customCityList.vue
  22. 925 0
      src/views/custom_manage/custom/customDetail.vue
  23. 392 489
      src/views/custom_manage/custom/customSearch.vue
  24. 1347 0
      src/views/custom_manage/custom/customShareList.vue
  25. 779 30
      src/views/custom_manage/custom/hooks/customlistHook.js
  26. 4 6
      src/views/custom_manage/customEn/components/ContactSaveEnDia.vue
  27. 195 0
      src/views/custom_manage/customEn/components/ToDoTotalEdit.vue
  28. 128 0
      src/views/custom_manage/customEn/components/UnDoStatistic.vue
  29. 0 0
      src/views/custom_manage/customEn/components/clickNumberDetailDia.vue
  30. 134 0
      src/views/custom_manage/customEn/components/historyToDoDiaEn.vue
  31. 85 0
      src/views/custom_manage/customEn/components/reportVarietyEnSet.vue
  32. 161 0
      src/views/custom_manage/customEn/components/todoDialogEn.vue
  33. 569 0
      src/views/custom_manage/customEn/customListEn.vue
  34. 488 0
      src/views/custom_manage/customEn/editCustomEn.vue
  35. 2 1
      src/views/custom_manage/customEn/limitContactListEn.vue
  36. 6 0
      static/css/skin.min.css

+ 2 - 0
package.json

@@ -15,6 +15,7 @@
     "@fullcalendar/interaction": "^6.1.11",
     "@fullcalendar/timegrid": "^6.1.11",
     "@fullcalendar/vue3": "^6.1.11",
+    "@tinymce/tinymce-vue": "5.1.0",
     "@vueuse/core": "^10.9.0",
     "axios": "^1.6.7",
     "clipboard": "^2.0.11",
@@ -29,6 +30,7 @@
     "moment": "^2.30.1",
     "pinia": "^2.1.7",
     "sortablejs": "^1.15.2",
+    "tinymce": "6.0.0",
     "v-distpicker": "2.1.0",
     "vue": "^3.4.19",
     "vue-datepicker-next": "^1.0.3",

+ 140 - 16
pnpm-lock.yaml

@@ -17,6 +17,9 @@ dependencies:
   '@fullcalendar/vue3':
     specifier: ^6.1.11
     version: 6.1.11(@fullcalendar/core@6.1.11)(vue@3.4.20)
+  '@tinymce/tinymce-vue':
+    specifier: 5.1.0
+    version: 5.1.0(vue@3.4.20)
   '@vueuse/core':
     specifier: ^10.9.0
     version: 10.9.0(vue@3.4.20)
@@ -59,6 +62,9 @@ dependencies:
   sortablejs:
     specifier: ^1.15.2
     version: 1.15.2
+  tinymce:
+    specifier: 6.0.0
+    version: 6.0.0
   v-distpicker:
     specifier: 2.1.0
     version: 2.1.0
@@ -71,6 +77,9 @@ dependencies:
   vue-froala-wysiwyg:
     specifier: ^4.1.4
     version: 4.1.4
+  vue-qr:
+    specifier: ^4.0.9
+    version: 4.0.9
   vue-router:
     specifier: ^4.3.0
     version: 4.3.0(vue@3.4.20)
@@ -632,6 +641,15 @@ packages:
     resolution: {integrity: sha512-Ccy0NlLkzr0Ex2FKvh2X+OyERHXJ88XJ1MXtsI9y9fGexlaXaVTPzBCRBwIxFkORuOb+uBqeu+RqnpgYTEZRUQ==}
     dev: false
 
+  /@tinymce/tinymce-vue@5.1.0(vue@3.4.20):
+    resolution: {integrity: sha512-Z4R8zaOKrAXBhHWsq+qUlwHY+rvze2RgxHDrZ5+qTYkGvRofW5880HLG9gvv6TRPVsNSQBNMdsaOjJ/eueccgA==}
+    peerDependencies:
+      vue: ^3.0.0
+    dependencies:
+      tinymce: 6.0.0
+      vue: 3.4.20
+    dev: false
+
   /@types/estree@1.0.5:
     resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
     dev: true
@@ -647,11 +665,11 @@ packages:
     dev: false
 
   /@types/web-bluetooth@0.0.16:
-    resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==, tarball: https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz}
+    resolution: {integrity: sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ==}
     dev: false
 
   /@types/web-bluetooth@0.0.20:
-    resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==, tarball: https://registry.npmmirror.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz}
+    resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
     dev: false
 
   /@vitejs/plugin-vue@5.0.4(vite@5.1.4)(vue@3.4.20):
@@ -817,7 +835,7 @@ packages:
     resolution: {integrity: sha512-KTEngal0aiUvNJ6I1Chk5Ew5XqChsFsxP4GKAYXWb99zKJWjNU72p2FWEOmZWHxHcqtniOJsgnpd3zizdpfEag==}
 
   /@vueuse/core@10.9.0(vue@3.4.20):
-    resolution: {integrity: sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==, tarball: https://registry.npmmirror.com/@vueuse/core/-/core-10.9.0.tgz}
+    resolution: {integrity: sha512-/1vjTol8SXnx6xewDEKfS0Ra//ncg4Hb0DaZiwKf7drgfMsKFExQ+FnnENcN6efPen+1kIzhLQoGSy0eDUVOMg==}
     dependencies:
       '@types/web-bluetooth': 0.0.20
       '@vueuse/metadata': 10.9.0
@@ -829,7 +847,7 @@ packages:
     dev: false
 
   /@vueuse/core@9.13.0(vue@3.4.20):
-    resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==, tarball: https://registry.npmmirror.com/@vueuse/core/-/core-9.13.0.tgz}
+    resolution: {integrity: sha512-pujnclbeHWxxPRqXWmdkKV5OX4Wk4YeK7wusHqRwU0Q7EFusHoqNA/aPhB6KCh9hEqJkLAJo7bb0Lh9b+OIVzw==}
     dependencies:
       '@types/web-bluetooth': 0.0.16
       '@vueuse/metadata': 9.13.0
@@ -841,15 +859,15 @@ packages:
     dev: false
 
   /@vueuse/metadata@10.9.0:
-    resolution: {integrity: sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==, tarball: https://registry.npmmirror.com/@vueuse/metadata/-/metadata-10.9.0.tgz}
+    resolution: {integrity: sha512-iddNbg3yZM0X7qFY2sAotomgdHK7YJ6sKUvQqbvwnf7TmaVPxS4EJydcNsVejNdS8iWCtDk+fYXr7E32nyTnGA==}
     dev: false
 
   /@vueuse/metadata@9.13.0:
-    resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==, tarball: https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.13.0.tgz}
+    resolution: {integrity: sha512-gdU7TKNAUVlXXLbaF+ZCfte8BjRJQWPCa2J55+7/h+yDtzw3vOoGQDRXzI6pyKyo6bXFT5/QoPE4hAknExjRLQ==}
     dev: false
 
   /@vueuse/shared@10.9.0(vue@3.4.20):
-    resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==, tarball: https://registry.npmmirror.com/@vueuse/shared/-/shared-10.9.0.tgz}
+    resolution: {integrity: sha512-Uud2IWncmAfJvRaFYzv5OHDli+FbOzxiVEQdLCKQKLyhz94PIyFC3CHcH7EDMwIn8NPtD06+PNbC/PiO0LGLtw==}
     dependencies:
       vue-demi: 0.14.7(vue@3.4.20)
     transitivePeerDependencies:
@@ -858,7 +876,7 @@ packages:
     dev: false
 
   /@vueuse/shared@9.13.0(vue@3.4.20):
-    resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==, tarball: https://registry.npmmirror.com/@vueuse/shared/-/shared-9.13.0.tgz}
+    resolution: {integrity: sha512-UrnhU+Cnufu4S6JLCPZnkWh0WwZGUp72ktOF2DFptMlOs3TOdVv8xJN53zhHGARmVOsz5KqOls09+J1NR6sBKw==}
     dependencies:
       vue-demi: 0.14.7(vue@3.4.20)
     transitivePeerDependencies:
@@ -906,6 +924,10 @@ packages:
       regenerator-runtime: 0.11.1
     dev: false
 
+  /balanced-match@1.0.2:
+    resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+    dev: false
+
   /base64-arraybuffer@0.2.0:
     resolution: {integrity: sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==}
     engines: {node: '>= 0.6.0'}
@@ -916,6 +938,12 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
+  /brace-expansion@2.0.1:
+    resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+    dependencies:
+      balanced-match: 1.0.2
+    dev: false
+
   /braces@3.0.2:
     resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==}
     engines: {node: '>=8'}
@@ -948,7 +976,7 @@ packages:
     dev: true
 
   /clipboard@2.0.11:
-    resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==, tarball: https://registry.npmmirror.com/clipboard/-/clipboard-2.0.11.tgz}
+    resolution: {integrity: sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==}
     dependencies:
       good-listener: 1.2.2
       select: 1.1.2
@@ -1037,13 +1065,20 @@ packages:
       ms: 2.1.2
     dev: true
 
+  /decompress-response@6.0.0:
+    resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
+    engines: {node: '>=10'}
+    dependencies:
+      mimic-response: 3.1.0
+    dev: false
+
   /delayed-stream@1.0.0:
     resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
     engines: {node: '>=0.4.0'}
     dev: false
 
   /delegate@3.2.0:
-    resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==, tarball: https://registry.npmmirror.com/delegate/-/delegate-3.2.0.tgz}
+    resolution: {integrity: sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==}
     dev: false
 
   /element-plus@2.4.4(vue@3.4.20):
@@ -1148,6 +1183,10 @@ packages:
     resolution: {integrity: sha512-oWF8SZNtLvfweURV5T0WYO69ZQpB1LQiGO2e6zoYRAlOwmqlW5yqLWfGi0tfn99qOgZ/4dxqBBDxqfOsRCQFiA==}
     dev: false
 
+  /fs.realpath@1.0.0:
+    resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
+    dev: false
+
   /fsevents@2.3.3:
     resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
     engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -1163,13 +1202,25 @@ packages:
       is-glob: 4.0.3
     dev: true
 
+  /glob@8.1.0:
+    resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==}
+    engines: {node: '>=12'}
+    deprecated: Glob versions prior to v9 are no longer supported
+    dependencies:
+      fs.realpath: 1.0.0
+      inflight: 1.0.6
+      inherits: 2.0.4
+      minimatch: 5.1.6
+      once: 1.4.0
+    dev: false
+
   /globals@11.12.0:
     resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
     engines: {node: '>=4'}
     dev: true
 
   /good-listener@1.2.2:
-    resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==, tarball: https://registry.npmmirror.com/good-listener/-/good-listener-1.2.2.tgz}
+    resolution: {integrity: sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==}
     dependencies:
       delegate: 3.2.0
     dev: false
@@ -1194,6 +1245,18 @@ packages:
     resolution: {integrity: sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==}
     dev: true
 
+  /inflight@1.0.6:
+    resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
+    deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
+    dependencies:
+      once: 1.4.0
+      wrappy: 1.0.2
+    dev: false
+
+  /inherits@2.0.4:
+    resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+    dev: false
+
   /is-binary-path@2.1.0:
     resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
     engines: {node: '>=8'}
@@ -1226,6 +1289,10 @@ packages:
     resolution: {integrity: sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==}
     dev: false
 
+  /js-binary-schema-parser@2.0.3:
+    resolution: {integrity: sha512-xezGJmOb4lk/M1ZZLTR/jaBHQ4gG/lqQnJqdIv4721DMggsa1bDVlHXNeHYogaIEHD9vCRv0fcL4hMA+Coarkg==}
+    dev: false
+
   /js-md5@0.8.3:
     resolution: {integrity: sha512-qR0HB5uP6wCuRMrWPTrkMaev7MJZwJuuw4fnwAzRgP4J4/F8RwtodOKpGp4XpqsLBFzzgqIO42efFAyz2Et6KQ==}
     dev: false
@@ -1288,6 +1355,18 @@ packages:
       mime-db: 1.52.0
     dev: false
 
+  /mimic-response@3.1.0:
+    resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
+    engines: {node: '>=10'}
+    dev: false
+
+  /minimatch@5.1.6:
+    resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
+    engines: {node: '>=10'}
+    dependencies:
+      brace-expansion: 2.0.1
+    dev: false
+
   /moment@2.30.1:
     resolution: {integrity: sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==}
     dev: false
@@ -1310,6 +1389,16 @@ packages:
     resolution: {integrity: sha512-Wj7+EJQ8mSuXr2iWfnujrimU35R2W4FAErEyTmJoJ7ucwTn2hOUSsRehMb5RSYkxXGTM7Y9QpvPmp++w5ftoJw==}
     dev: false
 
+  /once@1.4.0:
+    resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+    dependencies:
+      wrappy: 1.0.2
+    dev: false
+
+  /parenthesis@3.1.8:
+    resolution: {integrity: sha512-KF/U8tk54BgQewkJPvB4s/US3VQY68BRDpH638+7O/n58TpnwiwnOtGIOsT2/i+M78s61BBpeC83STB88d8sqw==}
+    dev: false
+
   /path-key@3.1.1:
     resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
     engines: {node: '>=8'}
@@ -1405,7 +1494,7 @@ packages:
     dev: true
 
   /select@1.1.2:
-    resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==, tarball: https://registry.npmmirror.com/select/-/select-1.1.2.tgz}
+    resolution: {integrity: sha512-OwpTSOfy6xSs1+pwcNrv0RBMOzI39Lp3qQKUTPVVPRjCdNa5JH/oPRiqsesIskK8TVgmRiHwO4KXlV2Li9dANA==}
     dev: false
 
   /shebang-command@2.0.0:
@@ -1420,12 +1509,24 @@ packages:
     engines: {node: '>=8'}
     dev: true
 
+  /simple-concat@1.0.1:
+    resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
+    dev: false
+
+  /simple-get@4.0.1:
+    resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
+    dependencies:
+      decompress-response: 6.0.0
+      once: 1.4.0
+      simple-concat: 1.0.1
+    dev: false
+
   /sortablejs@1.14.0:
-    resolution: {integrity: sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==, tarball: https://registry.npmmirror.com/sortablejs/-/sortablejs-1.14.0.tgz}
+    resolution: {integrity: sha512-pBXvQCs5/33fdN1/39pPL0NZF20LeRbLQ5jtnheIPN9JQAaufGjKdWduZn4U7wCtVuzKhmRkI0DFYHYRbB2H1w==}
     dev: false
 
   /sortablejs@1.15.2:
-    resolution: {integrity: sha512-FJF5jgdfvoKn1MAKSdGs33bIqLi3LmsgVTliuX6iITj834F+JRQZN90Z93yql8h0K2t0RwDPBmxwlbZfDcxNZA==, tarball: https://registry.npmmirror.com/sortablejs/-/sortablejs-1.15.2.tgz}
+    resolution: {integrity: sha512-FJF5jgdfvoKn1MAKSdGs33bIqLi3LmsgVTliuX6iITj834F+JRQZN90Z93yql8h0K2t0RwDPBmxwlbZfDcxNZA==}
     dev: false
 
   /source-map-js@1.0.2:
@@ -1442,6 +1543,12 @@ packages:
     deprecated: Please use @jridgewell/sourcemap-codec instead
     dev: false
 
+  /string-split-by@1.0.0:
+    resolution: {integrity: sha512-KaJKY+hfpzNyet/emP81PJA9hTVSfxNLS9SFTWxdCnnW1/zOOwiV248+EfoX7IQFcBaOp4G5YE6xTJMF+pLg6A==}
+    dependencies:
+      parenthesis: 3.1.8
+    dev: false
+
   /supports-color@5.5.0:
     resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
     engines: {node: '>=4'}
@@ -1450,7 +1557,11 @@ packages:
     dev: true
 
   /tiny-emitter@2.1.0:
-    resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==, tarball: https://registry.npmmirror.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz}
+    resolution: {integrity: sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==}
+    dev: false
+
+  /tinymce@6.0.0:
+    resolution: {integrity: sha512-y4b5OhxScZiFovTgEFzI+2zEDSMfbJSQ4hfcYPg9HXvudxvDIHjc3fF73m0Sys5h8YtpWPG1fT9iJsjSnwuo2A==}
     dev: false
 
   /to-fast-properties@2.0.0:
@@ -1553,6 +1664,15 @@ packages:
       - typescript
     dev: false
 
+  /vue-qr@4.0.9:
+    resolution: {integrity: sha512-pAISV94T0MNEYA3NGjykUpsXRE2QfaNxlu9ZhEL6CERgqNc21hJYuP3hRVzAWfBQlgO18DPmZTbrFerJC3+Ikw==}
+    dependencies:
+      glob: 8.1.0
+      js-binary-schema-parser: 2.0.3
+      simple-get: 4.0.1
+      string-split-by: 1.0.0
+    dev: false
+
   /vue-router@4.3.0(vue@3.4.20):
     resolution: {integrity: sha512-dqUcs8tUeG+ssgWhcPbjHvazML16Oga5w34uCUmsk7i0BcnskoLGwjpa15fqMr2Fa5JgVBrdL2MEgqz6XZ/6IQ==}
     peerDependencies:
@@ -1596,7 +1716,7 @@ packages:
       '@vue/shared': 3.4.20
 
   /vuedraggable@4.1.0(vue@3.4.20):
-    resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==, tarball: https://registry.npmmirror.com/vuedraggable/-/vuedraggable-4.1.0.tgz}
+    resolution: {integrity: sha512-FU5HCWBmsf20GpP3eudURW3WdWTKIbEIQxh9/8GE806hydR9qZqRRxRE3RjqX7PkuLuMQG/A7n3cfj9rCEchww==}
     peerDependencies:
       vue: ^3.0.1
     dependencies:
@@ -1611,3 +1731,7 @@ packages:
     dependencies:
       isexe: 2.0.0
     dev: true
+
+  /wrappy@1.0.2:
+    resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+    dev: false

+ 43 - 1
src/api/modules/crmApi.js

@@ -129,6 +129,10 @@ const customInterence = {
     // return http.get('/custom/seller/check/list',params)
     return http.get("/custom/seller/check/listV2", params);
   },
+  /* 获取正式客户共享-原销售列表 */
+  getShareSale:(params)=>{
+    return http.get("/custom/seller/check/Sharelist2",params)
+  },
   /* 客户详情
 		CompanyId 
 	*/
@@ -481,6 +485,12 @@ const customInterence = {
   salesShareList: (params) => {
     return http.get("/custom/seller/share/list", params);
   },
+  /**
+   * 获取分配销售列表,根据用户角色返回 共享客户组 or 权益销售组
+   */
+  getShareSaleList:(params)=>{
+    return http.get("/custom/seller/share/list", params);
+  },
   /**
    * 获取 共享客户列表
    * SortParam 排序字段
@@ -1265,4 +1275,36 @@ const customAllInterence = {
     },
 }
 
-export { customInterence,customAllInterence, equityContacts,etaTrialInterence};
+/* X类客户评分 */
+const xClassCustomApi = {
+  //模板 列表
+  enterScoreDetail:(params)=>{
+      return http.get("/cygx/enterScore/detail",params)
+  },
+   //添加/ 更新录分
+   enterScoreUpdate:(params)=>{
+    return http.post("/cygx/enterScore/update",params)
+  },  
+  // X试用类客户检索
+  enterScoreSearchlist:(params)=>{
+      return http.get("/cygx/enterScore/company/searchlist",params)
+  },
+  // 录分列表接口
+  enterScoreList:(params)=>{
+    return http.get("/cygx/enterScore/list",params)
+  },
+  // 录分列表接口
+  enterScoreDelete:(params)=>{
+    return http.post("/cygx/enterScore/delete",params)
+  },  
+  // 评分总览接口
+  enterScoreScoreOverview:(params)=>{
+    return http.get("/cygx/enterScore/scoreOverview",params)
+  }, 
+  // 排名总览接口
+  enterScoreRankingOverview:(params)=>{
+    return http.get("/cygx/enterScore/rankingOverview",params)
+  }, 
+}
+
+export { customInterence,customAllInterence, equityContacts,etaTrialInterence,xClassCustomApi};

+ 1 - 1
src/router/modules/approvalRoutes.js

@@ -47,7 +47,7 @@ export default [
 			},
 			{
 				path: 'approvalList',
-				component: () => import('@/views/custom_manage/approvalList.vue'),
+				component: () => import('@/views/custom_manage/custom/approvalList.vue'),
 				name: 'approvalList',
 				hidden: false,
 				meta: {

+ 76 - 65
src/router/modules/customRoutes.js

@@ -31,22 +31,26 @@ export default [
           keepAlive: false,
         },
       },
-      // {
-      //   path: "customShareList",
-      //   component: () => import("@/views/custom_manage/customList/customShareList.vue"),
-      //   name: "正式客户共享",
-      //   hidden: false,
-      // },
-      // {
-      //   path: 'customCityList',
-      //   component: () => import('@/views/custom_manage/customList/customCityList.vue'),
-      //   name: '查看同城客户',
-      //   hidden: false,
-      //   meta: {
-      //       pathFrom: 'customShareList',
-      //       pathName: '正式客户共享'
-      //   }
-      // },
+      {
+        path: "customShareList",
+        component: () => import("@/views/custom_manage/custom/customShareList.vue"),
+        name: "customShareList",
+        hidden: false,
+        meta: {
+          title: '正式客户共享'
+        }
+      },
+      {
+        path: 'customCityList',
+        component: () => import('@/views/custom_manage/custom/customCityList.vue'),
+        name: 'customCityList',
+        hidden: false,
+        meta: {
+          title: '查看同城客户',
+          pathFrom: 'customShareList',
+          pathName: '正式客户共享'
+        }
+      },
       {
         path: "customAllList",
         component: () => import("@/views/custom_manage/custom/customAllList.vue"),
@@ -56,12 +60,15 @@ export default [
           title: '全量客户列表'
         }
       },
-      // {
-      //   path: "customListEn",
-      //   component: () => import("@/views/custom_manage/customList/customListEn.vue"),
-      //   name: "英文客户列表",
-      //   hidden: false,
-      // },
+      {
+        path: "customListEn",
+        component: () => import("@/views/custom_manage/customEn/customListEn.vue"),
+        name: "customListEn",
+        hidden: false,
+        meta: {
+          title: '英文客户列表'
+        }
+      },
       {
         path: "overseasCustomList",
         component: () => import("@/views/custom_manage/overseas/overseasCustomList.vue"),
@@ -73,7 +80,7 @@ export default [
       },
       {
         path: "trialContactListEn",
-        component: () => import("@/views/custom_manage/custom/limitContactListEn.vue"),
+        component: () => import("@/views/custom_manage/customEn/limitContactListEn.vue"),
         name: "trialContactListEn",
         hidden: false,
         meta: {
@@ -82,7 +89,7 @@ export default [
       },
       {
         path: "freezeContactListEn",
-        component: () => import("@/views/custom_manage/custom/limitContactListEn.vue"),
+        component: () => import("@/views/custom_manage/customEn/limitContactListEn.vue"),
         name: "freezeContactListEn",
         hidden: false,
         meta: {
@@ -120,47 +127,51 @@ export default [
       //     keepAlive: false,
       //   },
       // },
-      // {
-      //   path: "addCustomEn",
-      //   component: () => import("@/views/custom_manage/customList/editCustomEn.vue"),
-      //   name: "新增英文客户",
-      //   hidden: true,
-      //   meta: {
-      //     pathFrom: "customListEn",
-      //     pathName: "英文客户列表",
-      //   },
-      // },
-      // {
-      //   path: "editCustomEn",
-      //   component: () => import("@/views/custom_manage/customList/editCustomEn.vue"),
-      //   name: "编辑英文客户",
-      //   hidden: true,
-      //   meta: {
-      //     pathFrom: "customListEn",
-      //     pathName: "英文客户列表",
-      //   },
-      // },
-      // {
-      //   path: "customDetail",
-      //   name: "客户详情",
-      //   component: () => import("@/views/custom_manage/customList/customDetail.vue"),
-      //   hidden: true,
-      //   meta: {
-      //     pathFrom: "customList",
-      //     pathName: "客户列表",
-      //     keepAlive: false,
-      //   },
-      // },
-      // {
-      //   path: "detailCustomEn",
-      //   component: () => import("@/views/custom_manage/customList/editCustomEn.vue"),
-      //   name: "英文客户详情",
-      //   hidden: true,
-      //   meta: {
-      //     pathFrom: "customListEn",
-      //     pathName: "英文客户列表",
-      //   },
-      // },
+      {
+        path: "addCustomEn",
+        component: () => import("@/views/custom_manage/customEn/editCustomEn.vue"),
+        name: "addCustomEn",
+        hidden: true,
+        meta: {
+          pathFrom: "customListEn",
+          pathName: "英文客户列表",
+          title: '新增英文客户'
+        },
+      },
+      {
+        path: "editCustomEn",
+        component: () => import("@/views/custom_manage/customEn/editCustomEn.vue"),
+        name: "editCustomEn",
+        hidden: true,
+        meta: {
+          pathFrom: "customListEn",
+          pathName: "英文客户列表",
+          title: '编辑英文客户'
+        },
+      },
+      {
+        path: "customDetail",
+        name: "customDetail",
+        component: () => import("@/views/custom_manage/custom/customDetail.vue"),
+        hidden: true,
+        meta: {
+          pathFrom: "customList",
+          pathName: "客户列表",
+          keepAlive: false,
+          title: '客户详情'
+        },
+      },
+      {
+        path: "detailCustomEn",
+        component: () => import("@/views/custom_manage/customEn/editCustomEn.vue"),
+        name: "detailCustomEn",
+        hidden: true,
+        meta: {
+          pathFrom: "customListEn",
+          pathName: "英文客户列表",
+          title: '英文客户详情'
+        },
+      },
       // {
       //   path: "pickCustom",
       //   name: "领取客户",

+ 2 - 1
src/styles/element.scss

@@ -60,7 +60,7 @@ button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusri
 .el-submenu .el-menu-item{ padding:0 70px 0 45px !important; }
 .menu-collapsed .el-submenu .el-menu-item{ padding:0 85px 0 30px !important; }
 .box-card{ margin-bottom:20px !important; padding-bottom:30px; }
-.el-dialog .el-input{ width:60%; }
+.el-dialog .el-input{ width:100%; }
 .el-dialog .el-select>.el-input{ width:100%; }
 .el-dialog .el-dialog__headerbtn{ font-size:24px; padding:10px; top:3px; right:10px; }  // 右上角X
 .el-dialog .el-dialog__header{ background:$color-primary; color:#fff; padding:15px 0 15px 25px; text-align:left; }
@@ -82,6 +82,7 @@ button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusri
 .el-message-box__header .el-message-box__title{ color:#5882EF !important; }  //确认弹窗
 .confirmButton{ margin-left:-80px !important; }
 .cancelButton{ margin-right:-80px !important; }
+.el-form .el-form-item__label{ font-size: 14px; }
 
 /* reset 表格头 */
 .el-table th.is-leaf {

+ 419 - 0
src/utils/tinymce_zh_CN.js

@@ -0,0 +1,419 @@
+import tinymce from "tinymce";
+/* eslint-disable */
+tinymce.addI18n('zh_CN', {
+    "Redo": "恢复",
+    "Undo": "撤销",
+    "Cut": "剪切",
+    "Copy": "复制",
+    "Paste": "粘贴",
+    "Select all": "全选",
+    "New document": "新建文档",
+    "Ok": "确定",
+    "Cancel": "取消",
+    "Visual aids": "网格线",
+    "Bold": "粗体",
+    "Italic": "斜体",
+    "Underline": "下划线",
+    "Strikethrough": "删除线",
+    "Superscript": "上标",
+    "Subscript": "下标",
+    "Clear formatting": "清除格式",
+    "Align left": "左对齐",
+    "Align center": "居中",
+    "Align right": "右对齐",
+    "Justify": "两端对齐",
+    "Bullet list": "符号列表",
+    "Numbered list": "数字列表",
+    "Decrease indent": "减少缩进",
+    "Increase indent": "增加缩进",
+    "Close": "关闭",
+    "Formats": "格式",
+    "Your browser doesn't support direct access to the clipboard. Please use the Ctrl+X\/C\/V keyboard shortcuts instead.": "当前浏览器不支持访问剪贴板,请使用快捷键Ctrl+X/C/V复制粘贴",
+    "Headers": "标题",
+    "Header 1": "标题1",
+    "Header 2": "标题2",
+    "Header 3": "标题3",
+    "Header 4": "标题4",
+    "Header 5": "标题5",
+    "Header 6": "标题6",
+    "Headings": "标题",
+    "Heading 1": "标题1",
+    "Heading 2": "标题2",
+    "Heading 3": "标题3",
+    "Heading 4": "标题4",
+    "Heading 5": "标题5",
+    "Heading 6": "标题6",
+    "Preformatted": "预格式化",
+    "Div": "Div区块",
+    "Pre": "预格式文本",
+    "Code": "代码",
+    "Paragraph": "段落",
+    "Blockquote": "引用",
+    "Inline": "文本",
+    "Blocks": "区块",
+    "Paste is now in plain text mode. Contents will now be pasted as plain text until you toggle this option off.": "当前为纯文本粘贴模式,再次点击可以回到普通粘贴模式。",
+    "Fonts": "字体",
+    "Font Sizes": "字号",
+    "Class": "Class",
+    "Browse for an image": "浏览图像",
+    "OR": "或",
+    "Drop an image here": "拖放一张图片文件至此",
+    "Upload": "上传",
+    "Block": "块",
+    "Align": "对齐",
+    "Default": "默认",
+    "Circle": "空心圆",
+    "Disc": "实心圆",
+    "Square": "方块",
+    "Lower Alpha": "小写英文字母",
+    "Lower Greek": "小写希腊字母",
+    "Lower Roman": "小写罗马字母",
+    "Upper Alpha": "大写英文字母",
+    "Upper Roman": "大写罗马字母",
+    "Anchor...": "锚点...",
+    "Name": "名称",
+    "Id": "id",
+    "Id should start with a letter, followed only by letters, numbers, dashes, dots, colons or underscores.": "id应该以字母开头,后跟字母、数字、横线、点、冒号或下划线。",
+    "You have unsaved changes are you sure you want to navigate away?": "你对文档的修改尚未保存,确定离开吗?",
+    "Restore last draft": "恢复上次的草稿",
+    "Special characters...": "特殊字符...",
+    "Source code": "HTML源码",
+    "Insert\/Edit code sample": "插入/编辑代码示例",
+    "Language": "语言",
+    "Code sample...": "代码示例...",
+    "Color Picker": "选取颜色",
+    "R": "R",
+    "G": "G",
+    "B": "B",
+    "Left to right": "从左到右",
+    "Right to left": "从右到左",
+    "Emoticons...": "表情符号...",
+    "Metadata and Document Properties": "元数据和文档属性",
+    "Title": "标题",
+    "Keywords": "关键词",
+    "Description": "描述",
+    "Robots": "机器人",
+    "Author": "作者",
+    "Encoding": "编码",
+    "Fullscreen": "全屏",
+    "Action": "操作",
+    "Shortcut": "快捷键",
+    "Help": "帮助",
+    "Address": "地址",
+    "Focus to menubar": "移动焦点到菜单栏",
+    "Focus to toolbar": "移动焦点到工具栏",
+    "Focus to element path": "移动焦点到元素路径",
+    "Focus to contextual toolbar": "移动焦点到上下文菜单",
+    "Insert link (if link plugin activated)": "插入链接 (如果链接插件已激活)",
+    "Save (if save plugin activated)": "保存(如果保存插件已激活)",
+    "Find (if searchreplace plugin activated)": "查找(如果查找替换插件已激活)",
+    "Plugins installed ({0}):": "已安装插件 ({0}):",
+    "Premium plugins:": "优秀插件:",
+    "Learn more...": "了解更多...",
+    "You are using {0}": "你正在使用 {0}",
+    "Plugins": "插件",
+    "Handy Shortcuts": "快捷键",
+    "Horizontal line": "水平分割线",
+    "Insert\/edit image": "插入/编辑图片",
+    "Image description": "图片描述",
+    "Source": "地址",
+    "Dimensions": "大小",
+    "Constrain proportions": "保持宽高比",
+    "General": "常规",
+    "Advanced": "高级",
+    "Style": "样式",
+    "Vertical space": "垂直边距",
+    "Horizontal space": "水平边距",
+    "Border": "边框",
+    "Insert image": "插入图片",
+    "Image...": "图片...",
+    "Image list": "图片列表",
+    "Rotate counterclockwise": "逆时针旋转",
+    "Rotate clockwise": "顺时针旋转",
+    "Flip vertically": "垂直翻转",
+    "Flip horizontally": "水平翻转",
+    "Edit image": "编辑图片",
+    "Image options": "图片选项",
+    "Zoom in": "放大",
+    "Zoom out": "缩小",
+    "Crop": "裁剪",
+    "Resize": "调整大小",
+    "Orientation": "方向",
+    "Brightness": "亮度",
+    "Sharpen": "锐化",
+    "Contrast": "对比度",
+    "Color levels": "色阶",
+    "Gamma": "伽马值",
+    "Invert": "反转",
+    "Apply": "应用",
+    "Back": "后退",
+    "Insert date\/time": "插入日期/时间",
+    "Date\/time": "日期/时间",
+    "Insert\/Edit Link": "插入/编辑链接",
+    "Insert\/edit link": "插入/编辑链接",
+    "Text to display": "显示文字",
+    "Url": "地址",
+    "Open link in...": "链接打开方式...",
+    "Current window": "当前窗口打开",
+    "None": "在当前窗口/框架打开",
+    "New window": "在新窗口打开",
+    "Remove link": "删除链接",
+    "Anchors": "锚点",
+    "Link...": "链接...",
+    "Paste or type a link": "粘贴或输入链接",
+    "The URL you entered seems to be an email address. Do you want to add the required mailto: prefix?": "你所填写的URL地址为邮件地址,需要加上mailto:前缀吗?",
+    "The URL you entered seems to be an external link. Do you want to add the required http:\/\/ prefix?": "你所填写的URL地址属于外部链接,需要加上http://:前缀吗?",
+    "Link list": "链接列表",
+    "Insert video": "插入视频",
+    "Insert\/edit video": "插入/编辑视频",
+    "Insert\/edit media": "插入/编辑媒体",
+    "Alternative source": "替代资源",
+    "Alternative image URL": "资源备用地址",
+    "Media poster (Image URL)": "封面(图片地址)",
+    "Paste your embed code below:": "将内嵌代码粘贴在下面:",
+    "Embed": "内嵌",
+    "Media...": "多媒体...",
+    "Nonbreaking space": "不间断空格",
+    "Page break": "分页符",
+    "Paste as text": "粘贴为文本",
+    "Preview": "预览",
+    "Print...": "打印...",
+    "Save": "保存",
+    "Find": "查找",
+    "Replace with": "替换为",
+    "Replace": "替换",
+    "Replace all": "替换全部",
+    "Previous": "上一个",
+    "Next": "下一个",
+    "Find and replace...": "查找并替换...",
+    "Could not find the specified string.": "未找到搜索内容。",
+    "Match case": "区分大小写",
+    "Find whole words only": "全单词匹配",
+    "Spell check": "拼写检查",
+    "Ignore": "忽略",
+    "Ignore all": "忽略全部",
+    "Finish": "完成",
+    "Add to Dictionary": "添加到字典",
+    "Insert table": "插入表格",
+    "Table properties": "表格属性",
+    "Delete table": "删除表格",
+    "Cell": "单元格",
+    "Row": "行",
+    "Column": "列",
+    "Cell properties": "单元格属性",
+    "Merge cells": "合并单元格",
+    "Split cell": "拆分单元格",
+    "Insert row before": "在上方插入",
+    "Insert row after": "在下方插入",
+    "Delete row": "删除行",
+    "Row properties": "行属性",
+    "Cut row": "剪切行",
+    "Copy row": "复制行",
+    "Paste row before": "粘贴到上方",
+    "Paste row after": "粘贴到下方",
+    "Insert column before": "在左侧插入",
+    "Insert column after": "在右侧插入",
+    "Delete column": "删除列",
+    "Cols": "列",
+    "Rows": "行",
+    "Width": "宽",
+    "Height": "高",
+    "Cell spacing": "单元格外间距",
+    "Cell padding": "单元格内边距",
+    "Show caption": "显示标题",
+    "Left": "左对齐",
+    "Center": "居中",
+    "Right": "右对齐",
+    "Cell type": "单元格类型",
+    "Scope": "范围",
+    "Alignment": "对齐方式",
+    "H Align": "水平对齐",
+    "V Align": "垂直对齐",
+    "Top": "顶部对齐",
+    "Middle": "垂直居中",
+    "Bottom": "底部对齐",
+    "Header cell": "表头单元格",
+    "Row group": "行组",
+    "Column group": "列组",
+    "Row type": "行类型",
+    "Header": "表头",
+    "Body": "表体",
+    "Footer": "表尾",
+    "Border color": "边框颜色",
+    "Insert template...": "插入模板...",
+    "Templates": "模板",
+    "Template": "模板",
+    "Text color": "文字颜色",
+    "Background color": "背景色",
+    "Custom...": "自定义...",
+    "Custom color": "自定义颜色",
+    "No color": "无",
+    "Remove color": "删除颜色",
+    "Table of Contents": "目录",
+    "Show blocks": "显示区块边框",
+    "Show invisible characters": "显示不可见字符",
+    "Word count": "字数统计",
+    "Words: {0}": "字数:{0}",
+    "{0} words": "{0} 个字",
+    "File": "文件",
+    "Edit": "编辑",
+    "Insert": "插入",
+    "View": "查看",
+    "Format": "格式",
+    "Table": "表格",
+    "Tools": "工具",
+    "Powered by {0}": "Powered by {0}",
+    "Rich Text Area. Press ALT-F9 for menu. Press ALT-F10 for toolbar. Press ALT-0 for help": "在编辑区按ALT+F9打开菜单,按ALT+F10打开工具栏,按ALT+0查看帮助",
+    "Image title": "图片标题",
+    "Border width": "边框宽度",
+    "Border style": "边框样式",
+    "Error": "错误",
+    "Warn": "警告",
+    "Valid": "有效",
+    "To open the popup, press Shift+Enter": "此快捷为软回车(插入<br>)",
+    "Rich Text Area. Press ALT-0 for help.": "编辑区. 按Alt+0键打开帮助",
+    "System Font": "默认字体",
+    "Failed to upload image: {0}": "图片上传失败: {0}",
+    "Failed to load plugin: {0} from url {1}": "插件加载失败: {0} - {1}",
+    "Failed to load plugin url: {0}": "插件加载失败: {0}",
+    "Failed to initialize plugin: {0}": "插件初始化失败: {0}",
+    "example": "示例",
+    "Search": "查找",
+    "All": "全部",
+    "Currency": "货币",
+    "Text": "文本",
+    "Quotations": "引用",
+    "Mathematical": "数学运算符",
+    "Extended Latin": "拉丁语扩充",
+    "Symbols": "符号",
+    "Arrows": "箭头",
+    "User Defined": "自定义",
+    "dollar sign": "美元",
+    "currency sign": "货币",
+    "euro-currency sign": "欧元",
+    "colon sign": "冒号",
+    "cruzeiro sign": "克鲁赛罗币",
+    "french franc sign": "法郎",
+    "lira sign": "里拉",
+    "mill sign": "密尔",
+    "naira sign": "奈拉",
+    "peseta sign": "比塞塔",
+    "rupee sign": "卢比",
+    "won sign": "韩元",
+    "new sheqel sign": "新谢克尔",
+    "dong sign": "越南盾",
+    "kip sign": "老挝基普",
+    "tugrik sign": "图格里克",
+    "drachma sign": "德拉克马",
+    "german penny symbol": "德国便士",
+    "peso sign": "比索",
+    "guarani sign": "瓜拉尼",
+    "austral sign": "澳元",
+    "hryvnia sign": "格里夫尼亚",
+    "cedi sign": "塞地",
+    "livre tournois sign": "里弗弗尔",
+    "spesmilo sign": "一千spesoj的货币符号,该货币未使用",
+    "tenge sign": "坚戈",
+    "indian rupee sign": "印度卢比",
+    "turkish lira sign": "土耳其里拉",
+    "nordic mark sign": "北欧马克",
+    "manat sign": "马纳特",
+    "ruble sign": "卢布",
+    "yen character": "日元",
+    "yuan character": "人民币元",
+    "yuan character, in hong kong and taiwan": "元的繁体字",
+    "yen\/yuan character variant one": "元(大写)",
+    "Loading emoticons...": "正在加载表情文字...",
+    "Could not load emoticons": "不能加载表情文字",
+    "People": "人类",
+    "Animals and Nature": "动物和自然",
+    "Food and Drink": "食物和饮品",
+    "Activity": "活动",
+    "Travel and Places": "旅游和地点",
+    "Objects": "物件",
+    "Flags": "旗帜",
+    "Characters": "字数",
+    "Characters (no spaces)": "字数(不含空格)",
+    "Error: Form submit field collision.": "错误: 表单提交字段冲突.",
+    "Error: No form element found.": "错误: 未找到可用的form.",
+    "Update": "更新",
+    "Color swatch": "颜色样本",
+    "Turquoise": "青绿",
+    "Green": "绿色",
+    "Blue": "蓝色",
+    "Purple": "紫色",
+    "Navy Blue": "海军蓝",
+    "Dark Turquoise": "深蓝绿色",
+    "Dark Green": "暗绿",
+    "Medium Blue": "中蓝",
+    "Medium Purple": "中紫",
+    "Midnight Blue": "深蓝",
+    "Yellow": "黄色",
+    "Orange": "橙色",
+    "Red": "红色",
+    "Light Gray": "浅灰",
+    "Gray": "灰色",
+    "Dark Yellow": "暗黄",
+    "Dark Orange": "暗橙",
+    "Dark Red": "暗红",
+    "Medium Gray": "中灰",
+    "Dark Gray": "深灰",
+    "Black": "黑色",
+    "White": "白色",
+    "Switch to or from fullscreen mode": "切换全屏模式",
+    "Open help dialog": "打开帮助对话框",
+    "history": "历史",
+    "styles": "样式",
+    "formatting": "格式化",
+    "alignment": "对齐",
+    "indentation": "缩进",
+    "permanent pen": "记号笔",
+    "comments": "注释",
+    "Anchor": "锚点",
+    "Special character": "特殊字符",
+    "Code sample": "代码示例",
+    "Color": "颜色",
+    "Emoticons": "表情",
+    "Document properties": "文档属性",
+    "Image": "图片",
+    "Insert link": "插入链接",
+    "Target": "目标",
+    "Link": "链接",
+    "Poster": "封面",
+    "Media": "音视频",
+    "Print": "打印",
+    "Prev": "上一个",
+    "Find and replace": "查找并替换",
+    "Whole words": "全字匹配",
+    "Spellcheck": "拼写检查",
+    "Caption": "标题",
+    "Insert template": "插入模板",
+    //以下为补充汉化内容 by 莫若卿
+    "Code view": "代码区域",
+    "Select...": "选择...",
+    "Format Painter": "格式刷",
+    "No templates defined.": "无内置模板",
+    "Special character...": "特殊字符...",
+    "Open link": "打开链接",
+    "None": "无",
+    "Count": "统计",
+    "Document": "整个文档",
+    "Selection": "选取部分",
+    "Words": "字词数",
+    "{0} characters": "{0} 个字符",
+    "Alternative source URL": "替代资源地址",
+    "Alternative description": "替代说明文字",
+    "Accessibility": "可访问性",
+    "Image is decorative": "仅用于装饰",
+    //5.6新增
+    "Line height": "行高",
+    "Cut column": "剪切列",
+    "Copy column": "复制列",
+    "Paste column before": "粘贴到前方",
+    "Paste column after": "粘贴到后方",
+    "Copy column": "复制列",
+    //帮助窗口内的文字
+    "Version": "版本",
+    "Keyboard Navigation": "键盘导航",
+    "Open popup menu for split buttons": "该组合键的作用是软回车(插入br)",
+});

+ 3 - 3
src/views/custom_manage/approvalList.vue → src/views/custom_manage/custom/approvalList.vue

@@ -17,9 +17,9 @@ import { Search } from "@element-plus/icons-vue";
 import { customInterence } from "@/api/api.js";
 import { formatTime } from '@/utils/date'
 import { onBeforeRouteLeave, useRouter } from "vue-router";
-import ContractInfo from './components/ContractInfo.vue'
-import CapprovalDia from './components/CapprovalDia.vue'
-import Capplydia from './components/Capplydia.vue'
+import ContractInfo from '../components/ContractInfo.vue'
+import CapprovalDia from '../components/CapprovalDia.vue'
+import Capplydia from '../components/Capplydia.vue'
 import { ElMessage, ElMessageBox } from 'element-plus';
 
 const router = useRouter()

+ 498 - 0
src/views/custom_manage/custom/components/Capplydialog.vue

@@ -0,0 +1,498 @@
+<script setup>
+import { ref,watch,computed } from 'vue'
+import { customInterence } from '@/api/api.js'
+import { ElMessage } from 'element-plus'
+import FreezAuthList  from './FreezAuthList.vue'
+
+const props = defineProps({
+  /* 客户信息 */
+		formdata:{
+			type:Object,
+			default:{}
+		},
+		/* 标题 */
+		title:{
+			type:String
+		},
+		isApply:{
+			type:Boolean
+		},
+		contactFormData:{
+			type:Object,
+			default:{}
+		}
+})
+const emit = defineEmits(['cancelHandle'])
+
+const isRoleType = computed(()=>{
+    let type = localStorage.getItem('RoleType') || '';
+    return type;			
+  }
+)
+
+
+watch(
+  () =>props.formdata,
+  (newval) => {
+    reason.value = newval.ApplyReasons || '';
+    props.title === '申请延期'&&getAuth(newval);
+    props.title !== '申请延期'&&getAuthAll(newval);
+  }
+)
+
+
+// 获取权限
+const authList = ref([]) 
+function getAuth(item) {
+  authList.value = [];
+  if(!item.CompanyId) return
+  customInterence.lookauth({
+    CompanyId:item.CompanyId,
+    LookType:1
+  }).then(res => {
+    if(res.Ret === 200) {
+      let auth = [];
+      res.Data.List ?	res.Data.List.forEach(item=> {
+        auth.push(item.Items)
+      }) : res.Data.ListRai.forEach(item=> {
+        auth.push(item.Items)
+      })
+      let auth_all = auth.flat(Infinity);
+      authList.value = auth_all.filter(auth => {
+        return auth.Status === '试用'
+      })
+      getRowSpan();
+    }
+  })
+}
+
+/* 申请解冻 申请领取获取所有权限 */
+function getAuthAll(item) {
+  if(!item.CompanyId){
+    return
+  }
+  authList.value = [];
+  customInterence.allAuth({
+    CompanyId:item.CompanyId,
+    CompanyType:item.CompanyType
+  }).then(res=> {
+    if(res.Ret === 200) {
+      let auth = [];
+      const roleType=localStorage.getItem('RoleType')
+                // let auth_arr = item.CompanyType === 'ficc' ? res.Data.FiccPermissionList : res.Data.PermissionList;
+                let auth_arr = roleType === 'ficc' ? res.Data.FiccPermissionList : res.Data.PermissionList;
+
+      auth_arr.forEach(item=> {
+        let obj = {
+          checkAll:item.CheckList&&item.CheckList.length===item.Items.length?true:false,
+          isIndeterminate:item.CheckList&&item.CheckList.length>0 && item.CheckList.length<item.Items.length,
+          defaultAuth:item.CheckList,
+          ...item,
+        }
+        auth.push(obj)
+      })
+      authList.value = auth;
+    }
+  })
+}
+
+
+const selectArr = ref([])
+function handleSelectionChange(val) {
+  selectArr.value = val.map((item,index)=>{return item.ChartPermissionId});
+}
+
+
+const reason = ref('')//有申请理由回显
+const pickData = ref({})//如果是申请领取并且移动联系人后提交申请用此数据
+/* 提交申请 */
+function saveHandle() {
+      
+  if(!reason.value) {
+    ElMessage.warning('请填写申请理由!')
+  }else {
+        let params_public = {};
+        if(props.title === '申请解冻' || props.title === '申请领取') {
+            /* 处理权限列表 */
+            let checkArr = [];
+            authList.value.forEach(item => {
+              if(item.CheckList.length) {
+                  checkArr.push(item.CheckList)
+              }
+            })
+            let PermissionIds = checkArr.flat(Infinity).join(',');
+            params_public = {
+              ApplyRemark:reason.value,
+              CompanyId:props.formdata.CompanyId,
+              CompanyApprovalId:props.formdata.CompanyApprovalId?parseInt(props.formdata.CompanyApprovalId):0,
+              PermissionIds
+            }
+        }
+
+    switch (props.title) {
+      case '申请延期':
+        if(selectArr.value.length || isRoleType.value=='权益') { // 权益不进行校验
+          customInterence.applyDelay({
+            ApplyRemark:reason.value,
+            CompanyId:props.formdata.CompanyId,
+            CompanyApprovalId:props.formdata.CompanyApprovalId?parseInt(props.formdata.CompanyApprovalId):0,
+            PermissionIds:selectArr.value.join(',')
+          }).then(res => {
+            if(res.Ret === 200) {
+              ElMessage.success(res.Msg);
+              cancelHandle(1);
+            }
+          })
+        }else {
+          ElMessage.warning('请勾选需要延期的品种!')
+        }
+        break;
+      case '申请解冻':
+        console.log(params_public.PermissionIds);
+        if(params_public.PermissionIds=='1'){
+          ElMessage.warning('请选择权限!')
+        }else{
+          customInterence.applyThaw(params_public).then(res => {
+            if(res.Ret === 200) {
+              ElMessage.success(res.Msg);
+              cancelHandle(1);
+            }
+          })
+        }
+        break;
+      case '申请领取':
+        if(params_public.PermissionIds!='1'&&params_public.PermissionIds!='') {
+          // customInterence.applyPick(params_public).then(res => {
+          // 	if(res.Ret === 200) {
+          // 		this.$message.success(res.Msg);
+          // 		this.cancelHandle(1);
+          // 	}
+          // })
+          handleApplyPick(params_public)
+        }else{
+          ElMessage.warning('请选择权限!')
+        }
+        
+        break;
+    
+      default:
+        break;
+    }
+  }
+}
+// 申请领取 
+async function handleApplyPick(pickdata){
+  // 从客户审批列表发起的申请
+  if(!props.contactFormData.CompanyId){
+    let pickRes=await customInterence.applyPick(pickdata)
+    if(pickRes.Ret === 200) {
+      ElMessage.success(pickRes.Msg);
+      cancelHandle(1);
+    }
+    return
+  }
+  let addRes=await customInterence.concactAdd({
+    CompanyId:Number(props.contactFormData.CompanyId),
+            Email: props.contactFormData.mail || props.contactFormData.mailQY||'',
+            DepartmentName: props.contactFormData.depart,
+            IsMaker: Number(props.contactFormData.desiger),
+            MobileOne: props.contactFormData.tel1 || props.contactFormData.telQY,
+            MobileTwo: props.contactFormData.tel2,
+            Position: props.contactFormData.post,
+            RealName: props.contactFormData.name,
+            Sex: Number(props.contactFormData.sex),
+            Source: props.contactFormData.Source,
+            BusinessCardUrl: props.contactFormData.carte,
+            RegionType: props.contactFormData.RegionType,
+  })
+  if(addRes.Ret===200){
+    let pickRes=await customInterence.applyPick(pickdata)
+    if(pickRes.Ret === 200) {
+      ElMessage.success(pickRes.Msg);
+      cancelHandle(1);
+    }
+  }else if(addRes.Ret==600){
+    // 如果是本客户中存在的联系人直接发起申请
+    if(addRes.Data.CompanyId==props.contactFormData.CompanyId){
+      let pickRes=await customInterence.applyPick(pickdata)
+      if(pickRes.Ret === 200) {
+        ElMessage.success(pickRes.Msg);
+        cancelHandle(1);
+      }
+    }else{
+      pickData.value=pickdata
+      canMove.value = addRes.Data.HasMove;
+      userData.value = [];
+      userData.value.push(addRes.Data);
+      isHaveUser.value = true;
+    }
+    
+  }
+  
+}
+
+const canMove = ref(false)//是否显示移动按钮
+const userData  = ref([])//已存在联系人
+const isHaveUser = ref(false)//已存在联系人弹窗
+//移动联系人
+async function moveSale(){
+  let userId = userData.value[0].UserId;
+      let SellerId=localStorage.getItem('AdminId')
+  let res=await customInterence.moveUser({
+    CompanyId: Number(props.contactFormData.CompanyId),
+    BusinessCardUrl:props.contactFormData.carte,
+    DepartmentName:props.contactFormData.depart,
+    Email:props.contactFormData.mail || props.contactFormData.mailQY,
+    IsMaker:Number(props.contactFormData.desiger),
+    Mobile:props.contactFormData.tel1 || props.contactFormData.telQY,
+    Position:props.contactFormData.post,
+    RegionType:"",
+    RealName:props.contactFormData.name,
+    Remark:"",
+    SellerId:Number(SellerId),
+    Sex:Number(props.contactFormData.sex),
+    UserId:Number(userId),
+  })
+  if(res.Ret===200){
+    isHaveUser.value=false
+    let pickRes=await customInterence.applyPick(pickData.value)
+    if(pickRes.Ret === 200) {
+      ElMessage.success(pickRes.Msg);
+      cancelHandle(1);
+    }
+  }
+}
+//  取消联系人重复弹窗
+function cancelHandle2() {
+  canMove.value = "";
+  isHaveUser.value = false;
+}
+
+/* 取消弹窗 */
+function cancelHandle(type) {
+  reason.value = '';
+  emit('cancelHandle',type);
+}
+
+
+/* 处理合并数组 */
+const rowSpanArr = ref([])
+let position = ref(0)
+function getRowSpan() {
+  rowSpanArr.value = [];
+  /* [2,0,1] */
+  authList.value.forEach((item, index) => {
+    if (index === 0) {
+      rowSpanArr.value.push(1);
+      position.value = 0;
+    } else {
+      if (authList.value[index].ClassifyName === authList.value[index - 1].ClassifyName) {
+        rowSpanArr.value[position.value] += 1; //项目名称相同,合并到同一个数组中
+        rowSpanArr.value.push(0);
+        authList.value[index].ClassifyName = authList.value[index - 1].ClassifyName;
+      } else {
+        rowSpanArr.value.push(1);
+        position.value = index;
+      }
+    }
+  });
+}
+/* 合并行规则 */
+function objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+  if(isRoleType.value !='ficc') return
+  if (columnIndex === 0) {
+    const _row = rowSpanArr.value[rowIndex];
+      return {
+        rowspan: _row,
+        colspan: 1
+      };
+  }
+}
+
+
+</script>
+<template>
+  <div class="Capplydia_container">
+    <el-dialog
+    :model-value="isApply"
+    :close-on-click-modal="false"
+    :modal-append-to-body='false'
+    @close="cancelHandle"
+    class="apply_dialog"
+    center
+    top="5vh"
+    draggable
+    width="1000px">
+      <template #header>
+        <div style="display:flex;alignItems:center;">
+          <img :src="title=='申请领取'?$icons.pick:title=='申请解冻'?$icons.lock:title=='申请延期'?$icons.delay:''" style="color:#fff;width:16px;height:16px;marginRight:5px;">
+          <span style="fontSize:16px;">{{title}}</span>
+        </div>
+      </template>
+      <div class="dialog_cont">
+        <div class="detail_info" v-if="title=='申请领取' || isRoleType=='ficc'">
+          <!-- 申请领取 -->
+          <template v-if="title=='申请领取'">	
+            <div class="info_item">
+              <span style="width:50%;">客户名称:{{formdata.CompanyName}}</span>
+              <span>客户状态:{{formdata.Status}}</span>
+            </div>
+            <div class="info_item">
+              <span style="width:250px;">原销售:{{formdata.SellerName}}</span>
+            </div>
+          </template>
+          <!-- 申请解冻 -->
+          <template v-else-if="title=='申请解冻'">
+            <div class="info_item">
+              <span style="width:50%;">客户名称:{{formdata.CompanyName}}</span>
+              <span style="width:120px">客户状态:{{formdata.Status}}</span>
+            </div>
+            <div class="info_item">
+              <span style="width:250px;">冻结期限:{{formdata.FreezeStartDate}}-{{formdata.FreezeEndDate}}</span>
+              <span style="width:120px">到期天数:{{formdata.FreezeExpireDays}}</span>
+            </div>
+          </template>
+          <!-- 申请延期 -->
+          <template v-else-if="title=='申请延期'">	
+            <div class="info_item">
+              <span style="width:50%;">客户名称:{{formdata.CompanyName}}</span>
+              <!-- <span style="width:120px">客户状态:{{formdata.Status}}</span> -->
+            </div>
+              <!-- <div class="info_item">
+                <span style="width:250px;">服务期限:{{formdata.StartDate}}-{{formdata.EndDate}}</span>
+                <span style="width:120px">到期天数:{{formdata.ExpireDay}}</span>
+              </div> -->
+            <div class="info_item">
+              <span style="width:250px;">请选择需要延期的品种:</span>
+            </div>
+            <el-table
+            :data="authList"
+            :span-method="objectSpanMethod"
+            @selection-change="handleSelectionChange"
+            border	
+            max-height="300"
+            style="margin-top: 20px">
+              <el-table-column v-if="isRoleType" label="所属类目" align="center">
+                <template #default="scope">{{scope.row.ClassifyName}}</template>
+              </el-table-column>
+              <el-table-column :label="isRoleType != 'ficc'?'行业':'品种'" align="center">
+                <template #default="scope">{{scope.row.PermissionName}}</template>
+              </el-table-column>
+              <el-table-column label="状态" align="center">
+                <template #default="scope">{{scope.row.Status}}</template>
+              </el-table-column>
+              <el-table-column label="服务期限" align="center" min-width="200">
+                <template #default="scope">{{scope.row.StartDate+'-'+scope.row.EndDate}}</template>
+              </el-table-column>
+              <el-table-column label="剩余天数" align="center">
+                <template #default="scope">{{scope.row.ExpireDay}}</template>
+              </el-table-column>
+              <el-table-column
+                type="selection"
+                width="50">
+              </el-table-column>
+            </el-table>
+          </template>
+          <!-- 申请解冻和申请领取勾选权限 -->
+          <FreezAuthList :autharr="authList" v-if="title!=='申请延期'"/>
+        </div>
+        <div class="bot_form">
+          <div>
+            <label style="display:block;marginBottom:10px;fontSize:16px;position:relative;padding-left:18px;">
+              <i style="color:#f00;fontSize:20px;position:absolute;left:0;top:20%;">*</i>
+              申请理由
+            </label>
+            <el-input type="textarea" v-model="reason" rows="4" style="width:100%;" placeholder="输入理由"></el-input>
+          </div>
+        </div>
+      </div>	
+      <div style="display:flex;justify-content:center;margin:75px 0 50px;">
+        <el-button type="primary" style="width:80px;marginRight:24px;" @click="saveHandle">确定</el-button>
+        <el-button  type="primary" plain style="width:80px;" @click="cancelHandle">取消</el-button>
+      </div>
+    </el-dialog>
+
+	<!-- 用户已存在弹窗 -->
+    <el-dialog
+      title="提示"
+      :model-value="isHaveUser"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      @close="cancelHandle2"
+      center
+      top="25vh"
+      width="700px"
+      draggable
+    >
+      <div style="font-size: 15px; color: #606266; margin-bottom: 10px">
+        检测系统中已存在以下联系人 <span v-if="!canMove">(请联系对应销售处理)</span>
+      </div>
+      <el-table :data="userData" border>
+        <el-table-column align="center" label="联系人">
+          <template #default="scope">{{ scope.row.RealName }}</template>
+        </el-table-column>
+        <el-table-column align="center" label="手机号/邮箱" width="300">
+          <template #default="scope">
+            {{ scope.row.Mobile }}
+            {{ scope.row.Mobile && scope.row.Email ? "/" : "" }}
+            {{ scope.row.Email }}
+          </template>
+        </el-table-column>
+
+        <el-table-column align="center" label="销售">
+          <template #default="scope">{{ scope.row.SellerRealName }}</template>
+        </el-table-column>
+        <el-table-column align="center" label="关联客户">
+          <template #default="scope">{{ scope.row.CompanyName }}</template>
+        </el-table-column>
+      </el-table>
+      <div style="display: flex; justify-content: center; margin: 30px 0">
+        <template v-if="canMove">
+          <el-button type="primary" style="margin-right: 24px" @click="moveSale"
+            >移动至当前客户</el-button
+          >
+          <el-button
+            type="primary"
+            plain
+            style="width: 80px"
+            @click="cancelHandle2"
+            >取消</el-button
+          >
+        </template>
+        <el-button
+          type="primary"
+          style="width: 100px"
+          v-else
+          @click="cancelHandle2"
+          >知道了</el-button
+        >
+      </div>
+    </el-dialog>
+	</div>
+</template>
+<style scoped lang="scss">
+.Capplydia_container {
+	
+	.dialog_cont {
+		.detail_info {
+			border: 1px solid #AAB4CC;
+			border-radius: 4px;
+			padding: 30px 40px 30px 20px;
+			.info_item {
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				font-size: 16px;
+				color: #666;
+				margin-bottom: 20px;
+				&:last-child {
+					margin-bottom: 0;
+				}
+			}
+		}
+		.bot_form {
+			margin-top: 30px;
+		}
+	}
+}
+</style>

+ 194 - 0
src/views/custom_manage/custom/components/CauthList.vue

@@ -0,0 +1,194 @@
+<script setup>
+import { ref } from 'vue'
+import { ElMessage } from 'element-plus'
+import { customInterence } from '@/api/api.js'
+
+
+const props = defineProps({
+  id: {
+    type:Number,
+  },
+  autharr:{
+    type:Array,
+    default:[]
+  }
+})
+const emit = defineEmits(['addOver','close'])
+
+
+const qyCheckList = ref([])
+/* 确认新增 */
+function addHandle() {
+	let checkArr = [];
+	// ficc和权益合并
+	if(props.autharr[0] && props.autharr[0].RaiMerge != 2){
+		props.autharr.forEach(item => {
+			if(item.CheckList.length) {
+				checkArr.push(item.CheckList)
+			}
+		})
+	}else{
+		// 权益拆分
+		checkArr = qyCheckList.value
+	}
+	customInterence.addTryout({
+		CompanyId:props.id,
+		ChartPermissionId:checkArr.join()
+	}).then(res => {
+		if(res.Ret===200) {
+			ElMessage.success(res.Msg)
+			emit('addOver')
+		}
+	})
+}
+
+/* 选择全选或取消全选 */
+function handleCheckAll(item) {
+	// 取到所有的子菜单id
+	let ids = item.Items.map(item =>{
+		return item.ChartPermissionId
+	})
+	item.CheckList = item.checkAll ? ids : [];
+			item.isIndeterminate = false;
+}
+
+/* 复选框組选中时 */
+function handleChecked(item) {
+	if(item.RaiMerge==1){
+		// 权益合并
+		item.Items.map((it,i)=>{
+			if(item.CheckList.includes(it.ChartPermissionId) && it.PermissionType==1){
+				// 主观被选上,将客观的ID也push上
+				let ob=item.Items.find(pe => pe.PermissionName == it.PermissionName && pe.PermissionType==2)
+				item.CheckList.push(ob?ob.ChartPermissionId:0)
+			}else if(!item.CheckList.includes(it.ChartPermissionId) && it.PermissionType==1){
+				// 主观被去除,将客观的ID也去除
+				let ob=item.Items.find(pe => pe.PermissionName == it.PermissionName && pe.PermissionType==2)
+				let obIndex = item.CheckList.indexOf(ob?ob.ChartPermissionId:0)
+				if(obIndex!=-1){
+					item.CheckList.splice(obIndex,1)
+				}
+			}
+		})
+	}
+	item.CheckList = [...new Set(item.CheckList)]
+	let len = item.Items.filter(it => item.CheckList.includes(it.ChartPermissionId)).length
+	item.checkAll = len === item.Items.length;
+	item.isIndeterminate = len > 0 && len < item.Items.length;
+}
+
+// 权益选择套餐方法
+// 合并单元格
+function spanMethod({ row, rowIndex, column,columnIndex  }){
+	if(Object.values(row)[columnIndex].merge){
+		if(rowIndex == 1){
+			return [2,1]
+		}else if(rowIndex == 2){
+			return [0,0]
+		}
+	}
+}
+
+function handleCheckQY(item){
+	// 全选
+	if(item.isCheckAll){
+		if(["客观","主观"].includes(item.value)){
+			qyCheckList.value = [...new Set([...qyCheckList.value,...item.ids])]
+		}else{
+			qyCheckList.value = [...new Set([...qyCheckList.value,...item.bothIds])]
+		}
+	}else{ //全部不选
+		if(["客观","主观"].includes(item.value)){
+			item.ids.map(pId =>{
+				// 需要删除的索引
+				let deleteIndex = qyCheckList.value.findIndex(id=> id==pId && !(props.autharr[0].defaultAuth.includes(id)));
+				if(deleteIndex!=-1) qyCheckList.value.splice(deleteIndex,1)
+			})
+		}else{
+			item.bothIds.map(pId =>{
+				// 需要删除的索引
+				let deleteIndex = qyCheckList.value.findIndex(id=> id==pId && !(props.autharr[0].defaultAuth.includes(id)));
+				if(deleteIndex!=-1) qyCheckList.value.splice(deleteIndex,1)
+			})
+		}
+	}
+}
+
+
+</script>
+<template>
+<div class="CauthList_container" >
+		<span style="fontSize:16px;">请选择新增试用的品种:</span>
+		<!-- 权益合并的和FICC -->
+		<ul class="menu_lists" style="marginBottom:40px;" v-if="autharr[0] && autharr[0].RaiMerge != 2">
+			<li v-for="item in autharr" :key="item.ClassifyName" class="menu_item">
+				<el-checkbox :indeterminate="item.isIndeterminate" v-model="item.checkAll" :disabled="item.defaultAuth.length" style="marginRight:30px;fontWeight:bold;minWidth:90px;" @change="handleCheckAll(item)">{{item.ClassifyName+':'}}</el-checkbox>
+				<el-checkbox-group v-model="item.CheckList"  @change="handleChecked(item)">
+					<!-- PermissionType 为2 代表的是权益区分主客观的客观 1表示权益区分主客观的主观 0表示为不区分主客观的行业包括FICC的 -->
+					<el-checkbox v-for="list in item.Items.filter(it => it.PermissionType!=2)" :label="list.ChartPermissionId" :key="list.ChartPermissionId" class="list_item" :disabled="item.defaultAuth.indexOf(list.ChartPermissionId)!=-1" >{{list.PermissionName}}</el-checkbox>
+				</el-checkbox-group>
+			</li>
+		</ul>
+		<!-- 权益拆分 -->
+		<div v-if="autharr[0] && autharr[0].RaiMerge == 2" class="qy_menuList">
+			<el-table :data="autharr[0].dataList" :show-header="false" border :span-method="spanMethod">
+				<el-table-column align="center" :width="autharr[0].dataList[0][key].width?autharr[0].dataList[0][key].width:''" 
+				v-for="key in Object.keys(autharr[0].dataList[0])" :key="key">
+					<template #default="scope">
+						<!-- 主客观 区分的品种+复选框-->
+						<el-checkbox :label="scope.row[key].value" @change="handleCheckQY(scope.row[key])"
+						v-model="scope.row[key].isCheckAll" :disabled="scope.row[key].isDisabled"
+						:indeterminate="scope.row[key].isIndeterminate"
+						v-if="(scope.row[key].ids && scope.row[key].ids.length) || (scope.row[key].bothIds&& scope.row[key].bothIds.length)"></el-checkbox>
+						<!-- 不区分 只有复选框-->
+						<el-checkbox-group v-model="qyCheckList" v-else-if="typeof(scope.row[key].value)=='number'">
+							<el-checkbox :label="scope.row[key].value" class="checkbox-flex"
+							:disabled="scope.row[key].isDisabled">{{''}}</el-checkbox>
+						</el-checkbox-group>
+						<!-- 只有品种名称 -->
+						<template v-else>
+							{{scope.row[key].value}}
+						</template>
+					</template>
+				</el-table-column>
+			</el-table>
+		</div>
+
+		<div style="display:flex;justify-content:center;margin:75px 0 26px;">
+			<el-button type="primary" style="width:80px;marginRight:24px;" @click="addHandle">确定</el-button>
+			<el-button  style="width:80px;" @click="emit('close')">取消</el-button>
+		</div>
+</div>
+</template>
+<style lang='scss' scoped>
+.CauthList_container {
+	.menu_lists {
+		padding: 30px 0;
+		border-radius: 4px;
+		.menu_item {
+			display: flex;
+			// align-items: center;
+			margin-bottom: 30px;
+			&:last-child {
+				margin-bottom: 0;
+			}
+			.list_item {
+				margin-right: 20px;
+				margin-bottom: 10px;
+				&:last-child {
+					margin-right: 0;
+				}
+			}
+		}
+	}
+	.qy_menuList{
+		margin-top:45px;
+		.checkbox-flex{
+			display: flex;
+			flex-direction: column;
+			align-items: center;
+			justify-content: center;
+		}
+	}
+}
+</style>

+ 171 - 0
src/views/custom_manage/custom/components/CompleteInfo.vue

@@ -0,0 +1,171 @@
+<script setup>
+import { reactive, ref, watch } from 'vue'
+import { ElMessageBox } from 'element-plus'
+import { customInterence } from '@/api/api.js'
+import{province_sorce,city_sorce} from '@/utils/distpicker';
+
+const props = defineProps({
+  form:{
+    type: Object
+  }
+})
+const emit = defineEmits(['cancel'])
+
+const formRule = ref({
+    name:[{ required: true, message: '请填写客户名称', trigger: 'blur' }],
+    CreditCode:[{ required: true, message: '请填写社会信用码', trigger: 'blur' }],
+    City:[{ required: true, message: '请选择地址', trigger: 'change' }],
+    Source:[{ required: true, message: '请选择客户来源', trigger: 'change' }],
+    IndustryId:[{ required: true, message: '请选择行业', trigger: 'change' }],
+})
+
+const formData = reactive({})
+
+/* 获取客户来源数据 */
+const fromArr = ref([])//来源选项数据
+function getCustomerSourceList(){
+  customInterence.customerSourceList({}).then(res=>{
+    if(res.Ret===200){
+      fromArr.value=res.Data.List
+    }
+  })
+}
+getCustomerSourceList()
+
+/* 获取行业选项数据 */
+const tradeArr = ref([])//行业选项数据
+function getIndustry() {
+  let type = localStorage.getItem('RoleType') || '';
+  customInterence.getindustry({
+    Classify:type
+  }).then(res => {
+    if(res.Ret === 200) {
+      tradeArr.value = res.Data.List || [];
+    }
+  })
+}
+getIndustry()
+
+
+function cancelHandle(refresh=false){
+  emit('cancel',refresh)
+}
+
+//选择地区
+function selectRegion(e) {
+  formData.value.Province =e.province.value=='省'?'':e.province.value;
+  formData.value.City = e.city.value=='市'?'':e.city.value;
+}
+
+const formRef = ref(null)
+async function handleConfirm(){
+    formRef.value.validate(async (valid) => {
+        if(valid){
+            let IndustryName=''
+            tradeArr.value.forEach(item=>{
+                if(item.IndustryId==formData.IndustryId){
+                    IndustryName=item.IndustryName
+                }
+            })
+            let res=await customInterence.completeInfo({
+                CompanyId:formData.CompanyId,
+                CompanyName:formData.name,
+                CreditCode:formData.CreditCode,
+                Province:formData.Province,
+                City:formData.City,
+                IndustryId:Number(formData.IndustryId)||0,
+                IndustryName:IndustryName,
+                Source:formData.Source
+            })
+            if(res.Ret===200){
+                cancelHandle(true)
+                ElMessageBox('信息补全成功,请重新点击相应操作','提示', {
+                    confirmButtonText: '知道了',
+                    showCancelButton:false,
+                    type: 'success'
+                })
+            }
+        }
+    })
+}
+
+watch(
+  () => props.form,
+  (nval) => {
+    formData.value=nval
+      if(nval.flag){
+          //跨部门
+          formRule.value.Source[0].required=false
+          formRule.value.IndustryId[0].required=false
+      }
+      //海外去掉地址
+      if(nval.RegionType=='海外'){
+          formRule.value.City[0].required=false
+      }
+  }
+)
+
+</script>
+<template>
+<div>
+  <el-dialog
+	:model-value="form.show"
+	:close-on-click-modal="false"
+	:modal-append-to-body='false'
+	@before-close="cancelHandle(false)"
+	class="self_dialog"
+	center
+  draggable
+	width="600px">
+    <template #header>
+      <div>
+          <span style="font-size:16px;">请先补全客户基本信息</span>
+      </div>
+    </template>
+
+    <el-form ref="formRef" :model="formData" :rules="formRule" label-width="100px">
+        <el-form-item label="客户全称" prop="name" >
+            <el-input  v-model="formData.name" style="width:400px" :disabled="formData.nameDisable"></el-input>
+        </el-form-item>
+        <el-form-item label="社会信用码" prop="CreditCode">
+            <el-input v-model="formData.CreditCode" placeholder="请填写社会信用码" style="width:400px" :disabled="formData.CreditCodeDisable"></el-input>
+        </el-form-item>
+        <el-form-item label="客户地址" prop="City" v-if="formData.RegionType!='海外'" >
+            <v-distpicker :province-source="province_sorce"
+            :city-source="city_sorce"  :disabled="formData.CityDisable" :province="formData.Province" :city="formData.City" hide-area  @selected="selectRegion"></v-distpicker>
+        </el-form-item>
+        <div v-if="!formData.flag">
+            <el-form-item label="客户来源" prop="Source">
+                <el-select v-model="formData.Source" :disabled="formData.SourceDisable" placeholder="请选择客户来源" style="width:400px">
+                    <el-option
+                    v-for="item in fromArr"
+                    :key="item.SourceId"
+                    :label="item.SourceName"
+                    :value="item.SourceName">
+                    </el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item label="行业" prop="IndustryId">
+                <el-select v-model="formData.IndustryId" :disabled="formData.IndustryIdDisable" placeholder="请选择行业" style="width:400px">
+                    <el-option
+                    v-for="item in tradeArr"
+                    :key="item"
+                    :label="item.IndustryName"
+                    :value="item.IndustryId">
+                    </el-option>
+                </el-select>
+            </el-form-item>
+        </div>
+        <div style="text-align:center;margin:30px 0">
+            <el-button type="primary" @click="handleConfirm">确定</el-button>
+            <el-button type="primary" plain @click="cancelHandle(false)">取消</el-button>
+        </div>
+    </el-form>
+  </el-dialog>
+</div>
+</template>
+<style scoped lang="scss">
+:deep(.distpicker-address-wrapper) select {
+	width: 198px;
+}
+</style>

+ 903 - 0
src/views/custom_manage/custom/components/Contactdialog.vue

@@ -0,0 +1,903 @@
+<script setup>
+import { computed, ref,watch } from "vue";
+import { validateTel, validatePwd } from "@/utils/validate.js";
+import { ElMessage } from 'element-plus'
+import $ from 'jquery'
+import { customInterence, departInterence } from "@/api/api.js";
+
+const props = defineProps({
+  isShowclose: {
+    type: Boolean,
+    default: true,
+  },
+  userId: {
+    type: Number,
+  },
+  id: {
+    type: String,
+  },
+  name: {
+    type: String,
+  },
+  isAddContact: {
+    type: Boolean,
+  },
+  userForm: {
+    type: Object,
+  },
+  title: {
+    type: String,
+  },
+  needCard: {
+    type: Boolean,
+    default: false,
+    required: false,
+  },
+  regionType: {
+    type: String,
+    required: false,
+  },
+  // 是否是领取流失
+  isPickLoss: {
+    type: Boolean,
+    default: false,
+  },
+  // 是否是领取权益/ficc
+  isPickOther: {
+    type: Boolean,
+    default: false,
+  },
+  /* 是否是新增客户入口 */
+  isAddUser: {
+    type: Boolean,
+    default: false,
+  },
+  /* 是否是编辑客户入口 */
+  isEditUser: {
+    type: Boolean,
+    default: false,
+  },
+  // 是否为领取自己的流失客户
+  isPickSelf: {
+    type: Boolean,
+    default: false
+  },
+  custom_name:{
+    type:Object,
+    default: '',
+  }
+})
+const emit = defineEmits(['addContactNext','cancel'])
+
+
+const ProductName = computed(() => {
+  let type = localStorage.getItem("RoleType") || "";
+  if (type == "ficc") {
+    return "ficc";
+  } else if (type == "权益") {
+    return "权益";
+  } else {
+    return "ficc";
+  }
+})
+
+
+function validateMobile (rule, value, callback) {
+  if (!/^\d+$/.test(value) && value) {
+    callback(new Error("请输入正确的手机号格式"));
+  } else {
+    callback();
+  }
+}
+const userRule = {
+  name: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
+  sex: [{ required: true, message: "性别不能为空", trigger: "change" }],
+  tel1: [
+    // { required: true, message: '至少输入一个手机号或邮箱', trigger: 'blur' },
+    { validator: validateMobile, trigger: "blur" },
+    // { pattern: /^\d|^\+/, message: '  请输入正确的手机号码' }
+  ],
+
+  mailQY: [
+    { required: true, message: "请输入邮箱地址", trigger: "blur" },
+    {
+      type: "email",
+      message: "请输入正确的邮箱地址",
+      trigger: ["blur", "change"],
+    },
+  ],
+  telQY: [{ required: true, message: "请输入手机号", trigger: "blur" },
+    //  { pattern: /^\d|^\+/, message: '  请输入正确的手机号码' }
+  ],
+  desiger: [
+    { required: true, message: "请选择是否为决策人", trigger: "change" },
+  ],
+  carte: [
+    { required: props.needCard, message: "名片不能为空", trigger: "change" },
+  ],
+}
+
+watch(
+  () => props.isAddContact,
+  (nval) => {
+    if(!nval) return
+
+    getPhoneCode()
+    if (props.userForm.Source) {
+      this.userFormIndeterminacy = props.userForm.Source
+    } else {
+      props.userForm.Source = this.userFormIndeterminacy || 'add_user'
+    }
+  }
+)
+
+
+const telCodeArr = ref([])
+function getPhoneCode(){
+    departInterence.getPhoneAreaCode().then(res=>{
+        if(res.Ret!==200) return 
+        telCodeArr.value = res.Data&&res.Data.map(i=>{
+            return {
+                value:i.Value,
+                label:i.Name
+            }
+        })
+    })
+}
+
+// 领取自己的流失客户点击下一步
+const userFormRef = ref(null)
+function handleNext() {
+  userFormRef.value.validate((valid) => {
+    if (valid) {
+      // 海外电话邮箱必填
+      if (props.regionType == '海外') {
+        // 权益
+        if (ProductName.value == '权益') {
+          if (!props.userForm.telQY) {
+            ElMessage.warning("请填写手机号");
+            return
+          }
+          if (!props.userForm.mailQY) {
+            ElMessage.warning("请填写邮箱");
+            return
+          }
+        } else {
+          if (!props.userForm.tel1) {
+            ElMessage.warning("请填写手机号");
+            return
+          }
+          if (!props.userForm.mail) {
+            ElMessage.warning("请填写邮箱");
+            return
+          }
+        }
+      }
+
+      if (ProductName.value == 'ficc' || ProductName.value == 'admin' || (props.regionType == '国内' && ProductName.value == '权益')) {
+        if (!props.userForm.tel1 && !props.userForm.mail) {
+          ElMessage.warning("至少输入一个手机号或邮箱");
+          return
+        }
+      }
+
+      if (ProductName.value == '权益' && props.regionType !== '国内') {
+        if (!props.userForm.telQY && !props.userForm.mailQY) {
+          ElMessage.warning("至少输入一个手机号或邮箱");
+          return
+        }
+      }
+
+      emit('addContactNext', { formData: { ...props.userForm, RegionType: props.regionType, CompanyId: props.id } })
+    }
+  })
+
+}
+
+
+const typeArr = ref([]) //公司列表
+function focusGetCompany() {
+  customInterence
+    .companySearch({
+      KeyWord: "##",
+    })
+    .then((res) => {
+      if (res.Ret === 200) {
+        typeArr.value = res.Data.List || [];
+      }
+    });
+}
+
+/* 过滤公司 */
+function getCompany(query) {
+  if (query) {
+    customInterence
+      .companySearch({
+        KeyWord: query,
+      })
+      .then((res) => {
+        if (res.Ret === 200) {
+          typeArr.value = res.Data.List || [];
+        }
+      });
+  } else {
+    typeArr.value = [];
+  }
+}
+
+
+const btnLoading = ref(false)
+/* 保存 */
+function saveUser() {
+  
+  userFormRef.value.validate((valid, key) => {
+    if (valid) {
+      btnLoading.value=true;
+      if (props.title == "新增联系人") {
+        customInterence
+          .concactAdd({
+            CompanyId:
+              props.name == props.userForm.companyName
+                ? Number(props.id)
+                : Number(props.userForm.companyName),
+            Email: props.userForm.mail || props.userForm.mailQY,
+            DepartmentName: props.userForm.depart,
+            IsMaker: Number(props.userForm.desiger),
+            CountryCode: props.userForm.telCode,
+            MobileOne: props.userForm.tel1 || props.userForm.telQY,
+            MobileTwo: props.userForm.tel2,
+            Position: props.userForm.post,
+            RealName: props.userForm.name,
+            Sex: Number(props.userForm.sex),
+            Source: props.userForm.Source,
+            BusinessCardUrl: props.userForm.carte,
+            RegionType: props.regionType,
+            CompanyName:props.custom_name
+          })
+          .then((res) => {
+            if (res.Ret === 200) {
+              !props.isPickOther &&
+                !props.isPickLoss &&
+                ElMessage.success(res.Msg);
+              emit("cancel", 1, res.Data);
+            } else if (res.Ret === 600) {
+              canMove.value = res.Data.HasMove;
+              userData.value = [];
+              userData.value.push(res.Data);
+              isHaveUser.value = true;
+            }
+            btnLoading.value=false
+          });
+      } else {
+        customInterence
+          .concactEdit({
+            UserId: props.userId,
+            CompanyId:
+              props.name == props.userForm.companyName
+                ? Number(props.id)
+                : Number(props.userForm.companyName),
+            Email: props.userForm.mailQY,
+            DepartmentName: props.userForm.depart,
+            IsMaker: Number(props.userForm.desiger),
+            CountryCode: props.userForm.telCode,
+            MobileOne: props.userForm.telQY,
+            MobileTwo: props.userForm.tel2,
+            Position: props.userForm.post,
+            RealName: props.userForm.name,
+            Sex: Number(props.userForm.sex),
+            Source: props.userForm.Source,
+            BusinessCardUrl: props.userForm.carte,
+            RegionType: props.regionType,
+          })
+          .then((res) => {
+            if (res.Ret === 200) {
+              ElMessage.success(res.Msg);
+              emit("cancel", 1);
+            } else if (res.Ret === 600) {
+              canMove.value = res.Data.HasMove;
+              userData.value = [];
+              userData.value.push(res.Data);
+              isHaveUser.value = true;
+            }
+            btnLoading.value=false
+          });
+      }
+    }
+  });
+  
+}
+
+function saveUserFicc() {
+     
+  if (ProductName.value == '权益' && !props.userForm.mail && !props.userForm.tel1) {
+    ElMessage.warning("至少输入一个手机号或邮箱");
+    return;
+  }
+  if (
+    ProductName.value == "ficc" &&
+    props.userForm.mail == "" &&
+    props.userForm.tel1 == ""
+  ) {
+    ElMessage.warning("至少输入一个手机号或邮箱");
+    return;
+  } else {
+    var num = 0;
+    userFormRef.value.validateField(
+      ["name", "sex", "tel1", "desiger", "carte"],
+      (emailError) => {
+        if (!emailError) {
+          num += 1;
+        } else {
+          return false;
+        }
+      }
+    );
+
+    if (num === 5) {
+      btnLoading.value=true;
+      if (props.title == "新增联系人") {
+        customInterence
+          .concactAdd({
+            CompanyId:
+              props.name == props.userForm.companyName
+                ? Number(props.id)
+                : Number(props.userForm.companyName),
+            Email: props.userForm.mail || props.userForm.mailQY,
+            DepartmentName: props.userForm.depart,
+            IsMaker: Number(props.userForm.desiger),
+            CountryCode: props.userForm.telCode,
+            MobileOne: props.userForm.tel1 || props.userForm.telQY,
+            MobileTwo: props.userForm.tel2,
+            Position: props.userForm.post,
+            RealName: props.userForm.name,
+            Sex: Number(props.userForm.sex),
+            Source: props.userForm.Source,
+            BusinessCardUrl: props.userForm.carte,
+            RegionType: props.regionType,
+            CompanyName:props.custom_name
+          })
+          .then((res) => {
+            if (res.Ret === 200) {
+              !props.isPickOther &&
+                !props.isPickLoss &&
+                ElMessage.success(res.Msg);
+              emit("cancel", 1, res.Data);
+            } else if (res.Ret === 600) {
+              canMove.value = res.Data.HasMove;
+              userData.value = [];
+              userData.value.push(res.Data);
+              isHaveUser.value = true;
+            }
+            btnLoading.value=false
+          });
+      } else {
+
+        customInterence
+          .concactEdit({
+            UserId: props.userId,
+            CompanyId:
+              props.name == props.userForm.companyName
+                ? Number(props.id)
+                : Number(props.userForm.companyName),
+            Email: props.userForm.mail,
+            DepartmentName: props.userForm.depart,
+            IsMaker: Number(props.userForm.desiger),
+            CountryCode: props.userForm.telCode,
+            MobileOne: props.userForm.tel1,
+            MobileTwo: props.userForm.tel2,
+            Position: props.userForm.post,
+            RealName: props.userForm.name,
+            Sex: Number(props.userForm.sex),
+            Source: props.userForm.Source,
+            BusinessCardUrl: props.userForm.carte,
+            RegionType: props.regionType,
+          })
+          .then((res) => {
+            if (res.Ret === 200) {
+              ElMessage.success(res.Msg);
+              emit("cancel", 1);
+            } else if (res.Ret === 600) {
+              canMove.value = res.Data.HasMove;
+              userData.value = [];
+              userData.value.push(res.Data);
+              isHaveUser.value = true;
+            }
+            btnLoading.value=false
+          });
+      }
+    }
+  }
+}
+
+/* 取消弹窗 */
+function cancelHandle() {
+  userFormRef.value.resetFields();
+  emit("cancel");
+}
+
+
+/* 移动 */
+const userData = ref([]) //已存在的联系人
+const canMove = ref("") //是否显示移动按钮
+const isHaveUser = ref(false) //已存在联系人弹窗
+function moveSale() {
+  let userId = userData.value[0].UserId;
+  let SellerId = localStorage.getItem('AdminId')
+  customInterence
+    .moveUser({
+      CompanyId: Number(props.id),
+      BusinessCardUrl: props.userForm.carte,
+      DepartmentName: props.userForm.depart,
+      Email: props.userForm.mail || props.userForm.mailQY,
+      IsMaker: Number(props.userForm.desiger),
+      CountryCode: props.userForm.telCode,
+      Mobile: props.userForm.tel1 || props.userForm.telQY,
+      Position: props.userForm.post,
+      RegionType: "",
+      RealName: props.userForm.name,
+      Remark: "",
+      SellerId: Number(SellerId),
+      Sex: Number(props.userForm.sex),
+      UserId: Number(userId),
+    })
+    .then((res) => {
+      if (res.Ret === 200) {
+        !props.isPickOther &&
+          !props.isPickLoss &&
+          ElMessage.success("移动成功!");
+        isHaveUser.value = false;
+        emit("cancel", 1, userId);
+      }
+    });
+}
+//  取消联系人重复弹窗
+function cancelHandle2() {
+  canMove.value = "";
+  isHaveUser.value = false;
+}
+
+
+// 点击我知道了
+function knowHandle() {
+  // 已重复联系人所属公司id
+  let re_id = userData.value[0].CompanyId;
+  let userId = userData.value[0].UserId; //重复联系人的id
+
+  if (props.isPickLoss && re_id === Number(props.id)) {
+    // 领取流失客户且重复联系人在当前客户下继续领取
+    emit("cancel", 1, userId);
+  } else if (props.isPickOther && re_id === Number(props.id)) {
+    // 领取其他类型客户且重复联系人在当前客户下继续领取
+    emit("cancel", 1, userId);
+  } else if (props.isAddUser && re_id !== Number(props.id)) {
+    // 新增客户入口且重复联系人不在当前客户下
+    ElMessage.warning("新增失败");
+  } else if (props.isEditUser && re_id !== Number(props.id)) {
+    // 编辑客户入口且重复联系人不在当前客户下
+    ElMessage.warning("添加失败");
+  }
+
+  /* 领取流失客户或其他类型且联系人重复且不存在当前客户下 */
+  if (
+    (props.isPickLoss && re_id != Number(props.id)) ||
+    (props.isPickOther && re_id != Number(props.id))
+  ) {
+    ElMessage.warning("领取失败");
+  }
+  canMove.value = "";
+  isHaveUser.value = false;
+}
+
+/* 预览 */
+function preview() {
+  $("#img").click();
+}
+
+function clickinput() {
+  //上传模拟点击
+  // debugger
+  $("#fileCard").click();
+}
+
+
+const uploadloading = ref(false)
+// 选择文件上传
+function fileSelected() {
+  //选择文件上传
+  if (document.getElementById("fileCard").files[0]) {
+    let hostfile = document.getElementById("fileCard").files[0];
+    let size = Math.floor(hostfile.size / 1024 / 1024);
+    if (size > 200) {
+      ElMessage.error("上传文件大小不能大于200M!");
+      hostfile = {};
+      return false;
+    }
+    if (
+      hostfile.name.toLowerCase().includes(".png") ||
+      hostfile.name.toLowerCase().includes(".jpg") ||
+      hostfile.name.toLowerCase().includes(".jpeg")
+    ) {
+      let form = new FormData();
+      form.append("file", hostfile); //hostfile.name
+      uploadloading.value = true;
+      customInterence.upload(form).then((res) => {
+        if (res.Ret === 200) {
+          // that.$message.success( '上传成功' );
+          props.userForm.carte = res.Data.ResourceUrl;
+        }
+        uploadloading.value = false;
+        $("#fileCard").val("");
+        hostfile = {};
+      });
+    } else {
+      ElMessage.error("上传文件格式不正确!");
+    }
+  }
+}
+
+
+
+</script>
+<template>
+  <div v-if="isAddContact">
+    <el-dialog
+      :model-value="isAddContact"
+      :close-on-press-escape="false"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      :show-close="false"
+      class="concact_dialog"
+      center
+      width="900px"
+    >
+      <template #header>
+        <div
+          style="display: flex; align-items: center; position: relative"
+        >
+          <img
+            :src="title == '新增联系人' ? $icons.add : $icons.edit"
+            style="color: #fff; width: 16px; height: 16px; margin-right: 5px"
+          />
+          <span style="font-size: 16px">{{ title }}</span>
+          <i
+            class="el-icon-close"
+            style="
+              font-size: 24px;
+              cursor: pointer;
+              position: absolute;
+              right: 20px;
+              top: 50%;
+              transform: translateY(-50%);
+            "
+            @click="cancelHandle"
+          ></i>
+        </div>
+      </template>
+      <el-form
+        @submit.prevent
+        :model="userForm"
+        inline
+        :rules="userRule"
+        ref="userFormRef"
+        label-width="90px"
+        class="demo-ruleForm"
+        style="margin-top: 15px"
+      >
+        <el-form-item label="姓名" prop="name" style="margin-right: 30px">
+          <el-input
+            v-model="userForm.name"
+            placeholder="请输入姓名"
+            style="width: 315px"
+            clearable
+          >
+          </el-input>
+        </el-form-item>
+        <el-form-item label="性别" prop="sex" style="width: 370px">
+          <el-radio-group v-model="userForm.sex" size="medium">
+            <el-radio :label="1" style="width: 50px">男</el-radio>
+            <el-radio :label="2" style="width: 50px; margin-left: 0"
+              >女</el-radio
+            >
+          </el-radio-group>
+        </el-form-item>
+        <!-- FICC填写手机号 -->
+        <el-form-item
+          v-show="
+            ProductName == 'ficc' ||
+            ProductName == 'admin' ||
+            (props.regionType == '国内' && ProductName == '权益')
+          "
+          label="手机号"
+          prop="tel1"
+          style=""
+        >
+          <el-select
+            v-model="userForm.telCode"
+            placeholder="区号"
+            style="width: 90px"
+          >
+            <el-option
+              v-for="item in telCodeArr"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+          <el-input
+            v-model="userForm.tel1"
+            placeholder="手机号和邮箱至少填写一个"
+            style="width: 220px"
+            clearable
+          >
+          </el-input>
+        </el-form-item>
+        <!-- 权益填写手机号 -->
+        <el-form-item
+          v-if="
+            (ProductName == '权益' && props.regionType == '海外') ||
+            (ProductName == '权益' && props.regionType !== '国内')
+          "
+          label="手机号"
+          prop="telQY"
+          style=""
+        >
+          <el-select
+            v-model="userForm.telCode"
+            placeholder="区号"
+            style="width: 90px"
+          >
+            <el-option
+              v-for="item in telCodeArr"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            >
+            </el-option>
+          </el-select>
+          <el-input
+            v-model="userForm.telQY"
+            placeholder="请输入手机号"
+            style="width: 220px"
+            clearable
+          >
+          </el-input>
+        </el-form-item>
+
+        <!-- FICC填写邮箱 -->
+        <el-form-item
+          v-show="
+            ProductName == 'ficc' ||
+            ProductName == 'admin' ||
+            (props.regionType == '国内' && ProductName == '权益')
+          "
+          label="邮箱"
+          prop="mail"
+          style="marginright: 30px"
+        >
+          <el-input
+            v-model="userForm.mail"
+            placeholder="请输入邮箱"
+            style="width: 280px"
+            clearable
+          >
+          </el-input>
+        </el-form-item>
+        <!-- 权益填写邮箱 -->
+        <el-form-item
+          v-if="
+            (ProductName == '权益' && props.regionType == '海外') ||
+            (ProductName == '权益' && props.regionType !== '国内')
+          "
+          label="邮箱"
+          prop="mailQY"
+          style="margin-right: 30px"
+        >
+          <el-input
+            v-model="userForm.mailQY"
+            placeholder="请输入邮箱"
+            style="width: 280px"
+            clearable
+          >
+          </el-input>
+        </el-form-item>
+        <el-form-item label="职位" prop="post">
+          <el-input
+            v-model="userForm.post"
+            placeholder="请输入职位"
+            style="width: 315px"
+            clearable
+          >
+          </el-input>
+        </el-form-item>
+        <el-form-item label="是否KP" prop="desiger" style="margin-right: 30px">
+          <el-select
+            v-model="userForm.desiger"
+            placeholder="请选择是否是KP"
+            style="width: 280px"
+          >
+            <el-option
+              v-for="(item, index) in ['否', '是']"
+              :key="item"
+              :label="item"
+              :value="index"
+            >
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="部门" prop="depart">
+          <el-input
+            v-model="userForm.depart"
+            placeholder="请输入部门"
+            style="width: 315px"
+            clearable
+          >
+          </el-input>
+        </el-form-item>
+        
+        <el-form-item label="个人名片" prop="carte" style="width: 100%">
+          <input
+            type="file"
+            name="file"
+            @change="fileSelected"
+            id="fileCard"
+            class="true-file"
+            style="display: none"
+          />
+          <el-button
+            type="primary"
+            size="medium"
+            @click="clickinput"
+            v-if="!userForm.carte"
+            >点击上传</el-button
+          >
+          <div class="img_item" v-if="userForm.carte">
+            <el-image
+              :src="userForm.carte"
+              alt=""
+              style="background: #aaa; width: 280px; height: 180px"
+              :preview-src-list="userForm.carte.split(',')"
+              id="img"
+            />
+            <i
+              class="el-icon-zoom-in"
+              style="position: absolute; right: 20px; top: 20px; color: #fff"
+              @click="preview"
+            ></i>
+            <span
+              style="
+                position: absolute;
+                right: 12px;
+                bottom: 1px;
+                color: #409eff;
+                font-size: 16px;
+                cursor: pointer;
+              "
+              @click.stop="clickinput"
+              >重新上传</span
+            >
+          </div>
+        </el-form-item>
+      </el-form>
+      <div
+        style="display: flex; justify-content: center; margin: 30px 0 55px"
+        v-if="!isPickSelf"
+      >
+        <el-button
+          v-if="ProductName == '权益' && props.regionType == '海外'"
+          type="primary"
+          :loading="btnLoading"
+          style="width: 80px; margin-right: 24px"
+          @click="saveUser"
+          :style="!isShowclose ? 'width:120px' : ''"
+          >确定
+        </el-button>
+        <el-button
+          v-else
+          type="primary"
+          style="width: 80px; margin-right: 24px"
+          @click="saveUserFicc"
+          :loading="btnLoading"
+          :style="!isShowclose ? 'width:120px' : ''"
+          >确定</el-button
+        >
+        <el-button
+          type="primary"
+          plain
+          style="width: 80px"
+          @click="cancelHandle"
+          v-if="isShowclose"
+          >取消</el-button
+        >
+      </div>
+      <div
+        style="display: flex; justify-content: center; margin: 30px 0 55px"
+        v-else
+      >
+        <el-button
+          type="primary"
+          style="width: 80px; margin-right: 24px"
+          @click="handleNext"
+          >下一步</el-button
+        >
+        <el-button
+          type="primary"
+          plain
+          style="width: 80px"
+          @click="cancelHandle"
+          >取消</el-button
+        >
+      </div>
+    </el-dialog>
+  </div>
+  <!-- 用户已存在弹窗 -->
+  <el-dialog
+    title="提示"
+    :model-value="isHaveUser"
+    :close-on-click-modal="false"
+    :modal-append-to-body="false"
+    @close="cancelHandle2"
+    center
+    top="25vh"
+    width="700px"
+  >
+    <div style="font-size: 15px; color: #606266; margin-bottom: 10px">
+      检测系统中已存在以下联系人
+      <span v-if="!canMove">(请联系对应销售处理)</span>
+    </div>
+    <el-table :data="userData" border>
+      <el-table-column align="center" label="联系人">
+        <template #default="scope">{{ scope.row.RealName }}</template>
+      </el-table-column>
+      <el-table-column align="center" label="手机号/邮箱" width="300">
+        <template #default="scope">
+          {{ scope.row.Mobile }}
+          {{ scope.row.Mobile && scope.row.Email ? "/" : "" }}
+          {{ scope.row.Email }}
+        </template>
+      </el-table-column>
+
+      <el-table-column align="center" label="销售">
+        <template #default="scope">{{ scope.row.SellerRealName }}</template>
+      </el-table-column>
+      <el-table-column align="center" label="关联客户">
+        <template #default="scope">{{ scope.row.CompanyName }}</template>
+      </el-table-column>
+    </el-table>
+    <div style="display: flex; justify-content: center; margin: 30px 0">
+      <template v-if="canMove">
+        <el-button type="primary" style="margin-right: 24px" @click="moveSale"
+          >移动至当前客户</el-button
+        >
+        <el-button
+          type="primary"
+          plain
+          style="width: 80px"
+          @click="cancelHandle2"
+          >取消</el-button
+        >
+      </template>
+      <el-button
+        type="primary"
+        style="width: 100px"
+        v-else
+        @click="knowHandle()"
+        >知道了</el-button
+      >
+    </div>
+  </el-dialog>
+</template>
+<style scoped lang="scss">
+.concact_dialog {
+  .el-form-item__label {
+    width: 90px !important;
+  }
+
+  .img_item {
+    position: relative;
+    width: 280px;
+    height: 180px;
+    border-radius: 4px;
+  }
+}
+</style>

+ 335 - 0
src/views/custom_manage/custom/components/ContractInfo.vue

@@ -0,0 +1,335 @@
+<script setup>
+import { ref, watch } from 'vue'
+import { useRouter } from 'vue-router'
+import { ElMessage } from 'element-plus'
+import { customInterence } from '@/api/api.js'
+import {CalculationDate} from '@/utils/CalculationDate'
+
+const props = defineProps({
+  initData: {
+    type: Object
+  },
+})
+const emit = defineEmits(['contractInfoDialogClose'])
+
+
+async function handleSubmit(){
+  const res=await customInterence.sysCustomeApply({
+    CompanyApprovalId:props.initData.cusdata.CompanyApprovalId||0,
+    CompanyId:props.initData.cusdata.CompanyId,
+    ContractId:props.info.ContractDetail.ContractId
+  })
+  if(res.Ret===200){
+    ElMessage.success('申请成功')
+    handleClose('updateList')
+  }
+}
+
+function handlePreviewContract(){
+  const url=info.value.ContractDetail.CheckBackFileUrl
+  if(!url){
+    ElMessage.warning('文件错误')
+    return
+  }
+  const reg = /\.(pdf)$/;
+  // pdf
+  if(reg.test(url)){
+    window.open(url,'_blank');
+  }else{
+    window.open('https://view.officeapps.live.com/op/view.aspx?src='+url,'_blank');
+  }
+}
+
+function handleClose(e) {
+  search.value=''
+  info.value={}
+  emit("contractInfoDialogClose",e);
+}
+
+
+async function handleSelect(e){
+  search.value=e.CompanyName
+  const res=await customInterence.sysContractDetail({ContractId:e.ContractId})
+  if(res.Ret===200){
+    info.value=res.Data
+    info.value.PermissionList=res.Data.PermissionList.filter(item=>{
+      return item.CheckList.length>0
+    })
+  }
+}
+
+
+const search = ref("")
+const showCustomeInfo = ref(false)
+const info = ref({})
+const cusInfo = ref(null)
+async function init(){
+  let res=await customInterence.contractSearch({CreditCode:props.initData.cusdata.CreditCode})
+  if(res.Ret===200){
+    if(res.Data){
+      const res2=await customInterence.sysContractDetail({ContractId:res.Data[0].ContractId})
+      if(res2.Ret===200){
+        info.value=res2.Data
+        info.value.PermissionList=res2.Data.PermissionList.filter(item=>{
+          return item.CheckList.length>0
+        })
+      }
+    }
+  }
+
+  // 获取客户详情
+  let cus=await customInterence.customDetail({CompanyId:props.initData.cusdata.CompanyId})
+  if(cus.Ret===200){
+    if(cus.Data.CreateAuth===1){
+      cusInfo.value={Item:cus.Data.Item,info:cus.Data.FiccItem}
+    }else{
+      cusInfo.value={Item:cus.Data.Item,info:cus.Data.RaiItem}
+    }
+    
+  }
+}
+
+// 申请内容搜索
+async function handleSearchResult(queryString, cb) {
+  cb([])
+  let res=await customInterence.contractSearch({Keyword:queryString})
+  if(res.Ret===200&&res.Data){
+    cb(res.Data)
+  }
+}
+
+watch(() => props.initData.show,
+  (nval) => {
+    if (nval) {
+        init()
+    }
+  }
+)
+
+function formatType(e) {
+  if (e === "申请转正") {
+    return "试用转正式";
+  } else {
+    return e;
+  }
+}
+
+function formatDate(e){
+  if(e==='0001-01-01T00:00:00Z'){
+    return ''
+  }else{
+    return e.split('T')[0].replace(/-/g,'.')
+  }
+}
+
+//计算多少年
+function formateYear(start, end) {
+  if (start) {
+    // let starttime = new Date(start);
+    // let endtime = new Date(end);
+    // let difftime = endtime - starttime;
+    // let ret = parseFloat((difftime / (1000 * 60 * 60 * 24 * 365)).toFixed(1));
+    // return ret;
+    return `${CalculationDate(start,end)}`
+  } else {
+    return "";
+  }
+}
+
+
+</script>
+<template>
+  <div>
+    <el-dialog 
+        :model-value="initData.show" 
+        :modal-append-to-body="false" 
+        class="dialog-body-no" 
+        top="5vh" 
+        @close="handleClose"
+        draggable
+        width="55%"
+    >
+      <template #header>
+        <div>
+          <img width="15" src="../../../assets/img/cus_m/man.png" alt="" style="margin-right: 15px" /><span>{{ initData.type }}</span>
+        </div>
+      </template>
+
+      <div class="contractinfo-wrap">
+        <div class="top">
+          <div>
+            <span style="margin-right: 20px; color: #333">申请内容:{{ formatType(initData.type) }}</span>
+          </div>
+          <span 
+                style="border: 1px solid #409eff; color: #409eff; padding: 2px 10px; border-radius: 4px; cursor: pointer"
+                @click="showCustomeInfo=true"
+            >客户信息</span>
+        </div>
+        <div class="search-wrap">
+          <el-autocomplete 
+            clearable 
+            v-model="search" 
+            :fetch-suggestions="handleSearchResult" 
+            placeholder="请输入公司全称搜合同" 
+            @select="handleSelect" 
+            style="width: 100%" 
+            prefix-icon="el-icon-search"
+          >
+            <template #default="scope">
+                <span style="margin-right:40px;width:450px;display:inline-block">{{scope.item.CompanyName}}</span>
+                <span style="margin-right:40px">{{scope.item.ContractType}}</span>
+                <span style="margin-right:40px">{{formatDate(scope.item.StartDateStr)}}~{{formatDate(scope.item.EndDateStr)}}</span>
+                <span>{{scope.item.Price}}元</span>
+            </template>
+          </el-autocomplete>
+        </div>
+
+        <div class="content">
+          <div v-if="info&&info.ContractDetail">
+            <div class="table-wrap" >
+              <div class="flex">
+                <div class="table-item" style="flex: 1;display:flex">甲方名称:{{info.ContractDetail.CompanyName}} 
+                  <span 
+                    style="margin-left:10px;border: 1px solid #409eff; color: #409eff; padding: 2px; border-radius: 4px; cursor: pointer;flex-shrink:0;height:20px"
+                    @click="handlePreviewContract"
+                  >预览合同</span>
+                </div>
+                <div class="table-item" style="flex: 1">合同期限:{{formatDate(info.ContractDetail.StartDate)}}~{{formatDate(info.ContractDetail.EndDate)}}(有效期:{{ formateYear(info.ContractDetail.StartDate,info.ContractDetail.EndDate) }})</div>
+              </div>
+              <div class="flex">
+                <div class="table-item" style="flex: 1">合同金额:{{info.ContractDetail.Price}}元</div>
+                <div class="table-item" style="flex: 1">付款方式:{{info.ContractDetail.PayRemark}}</div>
+              </div>
+              <div class="flex">
+                <div class="table-item" style="flex: 1">付款渠道:{{info.ContractDetail.PayChannel}}</div>
+                <div class="table-item" style="flex: 1">合同类型:{{info.ContractDetail.ContractType}}</div>
+              </div>
+              <div class="table-item">
+                <div class="flex">
+                  <h2 style="font-size: 14px; color: #333; margin-right: 20px">购买品种:</h2>
+                  <ul style="flex: 1">
+                    <li v-for="item in info.PermissionList" :key="item.ClassifyName">
+                      <span>{{item.ClassifyName}}:</span>
+                      <template v-for="tag in item.Items">
+                        <el-tag 
+                          size="small"  
+                          :key="tag.ChartPermissionId" 
+                          style="margin:0 8px 5px"
+                          v-if="item.CheckList.includes(tag.ChartPermissionId)"
+                        >{{tag.PermissionName}}</el-tag>
+                      </template>
+                      
+                    </li>
+                  </ul>
+                </div>
+              </div>
+            </div>
+            <div style="text-align: center; padding: 59px 0 20px 0">
+                <el-button style="width:152px;margin-right:30px" type="primary" @click="handleSubmit">提交</el-button>
+                <el-button style="width:152px" type="primary" plain @click="handleClose">取消</el-button>
+            </div>
+          </div>
+          <div v-else style="text-align:center;padding:50px 0 200px 0">
+            <img width="135" src="../../../assets/img/cus_m/nodata.png" alt="">
+            <p style="font-size:14px;color:#AAB4CC">暂无结果</p>
+          </div>
+        </div>
+      </div>
+    </el-dialog>
+
+    <el-dialog 
+        :model-value="showCustomeInfo" 
+        :modal-append-to-body="false" 
+        class="cus-dialog"
+        width="660px"
+        top="20vh"
+        draggable
+    >   
+        <template #header>
+          <div style="color:#333;font-size:16px;font-weight:bold">客户基本信息</div>
+        </template>
+        <div v-if="cusInfo" class="contractinfo-wrap">
+            <div class="table-wrap">
+              <div class="flex">
+                <div class="table-item" style="flex: 1;padding:14px 20px">客户名称:{{cusInfo.Item.CompanyName}}</div>
+                <div class="table-item" style="flex: 1;padding:14px 20px">地址:{{cusInfo.Item.Province}}{{cusInfo.Item.City}}{{cusInfo.Item.Address}}</div>
+              </div>
+              <div class="flex">
+                <div class="table-item" style="flex: 1;padding:14px 20px">社会信用码:{{cusInfo.Item.CreditCode}}</div>
+                <div class="table-item" style="flex: 1;padding:14px 20px">客户状态:{{cusInfo.info.Status}}</div>
+              </div>
+              <div class="flex">
+                <div class="table-item" style="flex: 1;padding:14px 20px">客户来源:{{cusInfo.info.Source}}</div>
+                <div class="table-item" style="flex: 1;padding:14px 20px">行业:{{cusInfo.info.IndustryName}}</div>
+              </div>
+              <div class="flex">
+                <div class="table-item" style="flex: 1;padding:14px 20px">所属销售:{{cusInfo.info.SellerName}}</div>
+                <div class="table-item" style="flex: 1;padding:14px 20px">备注:{{cusInfo.info.Reasons}}</div>
+              </div>
+            </div>
+            <div style="text-align:center;margin-top:40px;margin-bottom:33px">
+                <el-button type="primary" style="width:200px" @click="showCustomeInfo=false">知道了</el-button>
+            </div>
+        </div>
+    </el-dialog>
+  </div>  
+</template>
+<style lang="scss" scoped>
+.cus-dialog {
+  :deep(.el-dialog__header) {
+    background-color: #fff;
+    border-bottom: 1px solid #DCDFE6;
+    .el-dialog__close.el-icon.el-icon-close {
+      color: #666;
+    }
+  }  
+}
+:deep(.dialog-body-no) {
+  .el-dialog__body {
+    padding: 20px 0 !important;
+  }
+  .el-input {
+    width: 100%;
+  }
+  .el-dialog {
+    min-width: 750px;
+  }
+}
+.contractinfo-wrap {
+  .top {
+    display: flex;
+    justify-content: space-between;
+    padding: 10px 30px 30px 30px;
+    border-bottom: 1px solid #dcdfe6;
+    align-items: center;
+  }
+  .search-wrap{
+    padding: 30px;
+  }
+  .content {
+    padding: 0px 30px;
+  }
+  .table-wrap {
+    border-top: 1px solid #dcdfe6;
+    border-left: 1px solid #dcdfe6;
+    .flex {
+      display: flex;
+    }
+    .table-item {
+      border-bottom: 1px solid #dcdfe6;
+      border-right: 1px solid #dcdfe6;
+      padding: 14px 40px;
+      li {
+        padding-bottom: 17px;
+        margin-bottom: 17px;
+        border-bottom: 1px dashed #dcdfe6;
+      }
+      li:last-child {
+        border-bottom: none;
+        margin-bottom: 0;
+        padding-bottom: 0;
+      }
+    }
+  }
+}
+</style>

+ 252 - 0
src/views/custom_manage/custom/components/CpessionTableEquity.vue

@@ -0,0 +1,252 @@
+<script setup>
+import { ref } from 'vue'
+
+/**权益权限ID
+ * 科技-主观(20)-客观(37)
+ * 消费-主观(21)-客观(38)
+ * 医药-主观(22)-客观(39)
+ * 智造-主观(19)-客观(36)
+ * 策略(23)
+ * 专家(29)
+ * 固收(53)
+ * 调研(54)
+ * 路演服务(30)
+ * 研选订阅(31)
+ * 研选扣点包(52)
+ */
+const props = defineProps({
+  authList: {
+    type: Array,
+  },
+  /* 页面来源 */
+  fromType: {
+    type: String,
+  },
+  /* 表单位置 */
+  form: {
+    type: Number,
+  },
+})
+const emit = defineEmits(['selectAuthHandle','selectAuthHandle2'])
+
+ 
+const isMerge = ref(false)
+const filterAuth = ref([])//权限表格
+const indexArrEquity = ref([])//权益
+const spanArrEquity = ref([])
+const	posEquity = ref(0)
+const authTableRef = ref(null)
+function init() {
+  /* 处理表格数据格式 */
+  filterAuth.value = props.authList.map((item) => {
+    return item.Items;
+  });
+  filterAuth.value = filterAuth.value.flat(Infinity);
+  /* 选中的id数组 */
+  //查看是否领取但无权限
+  let bol_have = props.authList.some((item) => item.CheckList.length);
+  let select = props.authList.map((item) => {
+    return item.CheckList;
+  });
+  select = bol_have ? select.flat(Infinity) : [];
+  /* 默认勾选中的表格项 */
+  let check_Auth = filterAuth.value.filter((item) => {
+    return select.includes(item.ChartPermissionId);
+  });
+  if (props.fromType === 'edit') {
+    /* 展示表格选中的key */
+    nextTick(() => {
+      if (check_Auth.length > 0) {
+        check_Auth.forEach((item) => {
+          authTableRef.value.toggleRowSelection(item, true);
+        });
+      }
+    });
+  }else {
+    /* 显示只有权限的数组 */
+    filterAuth.value = [];
+    check_Auth.map(item =>{
+      // 排序 以防合并问题
+      if(item.Status === '正式' || item.Status === '试用' || item.Status === '永续'||item.Status=='关闭'){
+        if(item.PermissionType==1){
+          //主观 找客观
+          filterAuth.value.push(item)
+          let ob = check_Auth.find(it => it.PermissionName == item.PermissionName && it.PermissionType!=1)
+          ob && filterAuth.value.push(ob)
+        }else if(item.PermissionType==0){
+          filterAuth.value.push(item)
+        }else{
+          // 客观
+          if(!filterAuth.value.find(t => t.ChartPermissionId == item.ChartPermissionId)){
+            filterAuth.value.push(item)
+          }
+        }
+      }
+    })
+    isMerge.value = filterAuth.value.some((item) => !item.IsMerge)
+  }
+  
+  getRowSpan();
+}
+
+
+/* 处理合并数组 */
+function getRowSpan() {
+  filterAuth.value.map((v, i, s) => {
+    if (!v.PermissionTypeName) {
+    indexArrEquity.value.push(i);
+    }
+  });
+  for (var i = 0; i < filterAuth.value.length; i++) {
+    let element = filterAuth.value[i]
+    if (i === 0) {
+      spanArrEquity.value.push(1);
+      posEquity.value = 0;
+    } else {
+      // 判断当前元素与上一个元素是否相同(line为标记)
+      if (element.PermissionName === filterAuth.value[i - 1].PermissionName) {
+        if(element.IsMerge){
+          // 主客观都有,需要合并
+          spanArrEquity.value[posEquity.value] += 1;
+          spanArrEquity.value.push(0);
+        }else{
+          // 主客观都有 不需要合并,说明是服务期限或者状态不一样
+          spanArrEquity.value[posEquity] += 0.5;
+          spanArrEquity.value.push(0.5);
+        }
+      } else {
+        spanArrEquity.value.push(1);
+        posEquity.value = i;
+      }
+    }
+  }
+}
+
+/* 合并行规则 */
+function objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+  if(!isMerge.value){
+    // 产品类型不显示
+    const _row = spanArrEquity.value[rowIndex];
+    if(_row == 0){
+      return {
+        rowspan: _row,
+        colspan: 0,
+      };
+    }
+  }else{
+    //处理行的合并
+    if (indexArrEquity.value.includes(rowIndex)) {
+      if (columnIndex === 0) {
+        return {
+          rowspan: 1,
+          colspan: 2,
+        };
+      } else if (columnIndex === 1) {
+        return {
+          rowspan: 0,
+          colspan: 0,
+        };
+      }
+    }
+    // 权益行业主客观合并
+    const _row = spanArrEquity.value[rowIndex];
+    if(_row == 2){
+      // 为2 是主客观都有,合并,这时合并行业和产品类型
+      if(columnIndex === 0){
+        return {
+          rowspan: 1,
+          colspan: 2,
+        };
+      }else if(columnIndex === 1){
+        return {
+          rowspan: 0,
+          colspan: 0,
+        };
+      }
+    }else if(_row == 0){
+      // 为0 表示不需要这行,被合并掉了
+      return {
+        rowspan: _row,
+        colspan: 0,
+      };
+    }else if(_row == 1.5){
+      // 为1.5 是主客观都有,但不合并,这时合并行业
+      if(columnIndex === 0){
+        return {
+          rowspan: 2,
+          colspan: 1,
+        };
+      }
+    }else if(_row == 0.5){
+      if(columnIndex === 0){
+        return {
+          rowspan: 0,
+          colspan: 0,
+        };
+      }
+    }
+  }
+}
+
+/* 勾选权限 */
+function handleSelectionChange(val) {
+  let selectArr = val.map((item, index) => {
+    return item.ChartPermissionId;
+  });
+  props.form === 1
+    ? emit('selectAuthHandle', selectArr)
+    : emit('selectAuthHandle2', selectArr);
+}
+
+// 是否可选择
+function canSelect(row) {
+  return row.ChartPermissionId === 1 ? false : true;
+}
+
+
+
+</script>
+<template>
+  <el-table
+		:data="filterAuth"
+		:span-method="objectSpanMethod"
+		@selection-change="handleSelectionChange"
+		ref="authTableRef"
+		border
+		style="margin-top: 20px"
+	>
+		<el-table-column label="行业" align="center" >
+			<template #default="scope">{{ scope.row.PermissionName }}</template>
+		</el-table-column>
+		<el-table-column label="产品类型" align="center" v-if="isMerge" >
+			<template #default="scope">{{ scope.row.PermissionTypeName }}</template>
+		</el-table-column>
+		<el-table-column label="状态" align="center" >
+			<template #default="scope">{{ scope.row.Status }}</template>
+		</el-table-column>
+		<el-table-column label="服务期限" align="center">
+			<template #default="scope">{{
+				scope.row.StartDate + '—' + scope.row.EndDate
+			}}</template>
+		</el-table-column>
+		<el-table-column label="剩余天数" align="center">
+			<template #default="scope">{{ scope.row.ExpireDay }}</template>
+		</el-table-column>
+            <el-table-column 
+            v-if="fromType == 'edit'" 
+            type="selection" 
+            width="70"
+            align="center"
+            label-class-name="DisabledSelection"
+            :selectable="canSelect">
+            </el-table-column>
+	</el-table>
+</template>
+<style scoped lang="scss">
+/*表格表头全选*/
+:deep(.DisabledSelection .cell::after){
+	content:"全选";
+	font-size: 12px;
+	margin-left: 2px;
+}
+</style>

+ 99 - 0
src/views/custom_manage/custom/components/FreezAuthList.vue

@@ -0,0 +1,99 @@
+<script setup>
+import { ref } from "vue";
+
+const props = defineProps({
+  	autharr: {
+			type: Array
+		}
+})
+
+	/* 选择全选或取消全选 */
+function handleCheckAll(item) {
+  // // 取到所有的子菜单id
+  //获取公有的id合集
+  let publicIds=[]
+
+  
+  let ids = item.Items.map(item =>{
+    if(item.IsPublic==1){
+      publicIds.push(item.ChartPermissionId)
+    }
+    return item.ChartPermissionId
+  })
+  item.CheckList = item.checkAll ? ids : publicIds;	
+      item.isIndeterminate = publicIds.length>0&&!item.checkAll?true:false;
+}
+
+
+/* 复选框組选中时 */
+function handleChecked(item) {
+  let len = item.CheckList.length;
+  item.checkAll = len === item.Items.length;
+  item.isIndeterminate = len > 0 && len < item.Items.length;
+}
+
+
+//控制权限设置是否禁用编辑
+function setSelectPerDisabled(data){
+  if(!data) return true
+  const arr=data.Items?data.Items.filter(_e=>_e.IsPublic==1):[]
+  return arr.length==data.Items.length
+}
+</script>
+<template>
+  <!-- 申请解冻/申请领取权限列表 -->
+  <div class="authContainer">
+    <h3>请选择需要开通试用的品种:</h3>
+    <ul class="menu_lists">
+      <li v-for="item in autharr" :key="item.ClassifyName" class="menu_item">
+        <el-checkbox
+          :indeterminate="item.isIndeterminate"
+          v-model="item.checkAll"
+          :disabled="setSelectPerDisabled(item)"
+          style="margin-right: 30px; font-weight: bold; min-width: 90px"
+          @change="handleCheckAll(item)"
+          >{{ item.ClassifyName + ":" }}</el-checkbox
+        >
+        <el-checkbox-group
+          v-model="item.CheckList"
+          @change="handleChecked(item)"
+        >
+          <el-checkbox
+            v-for="list in item.Items"
+            :label="list.ChartPermissionId"
+            :key="list.ChartPermissionId"
+            class="list_item"
+            :disabled="list.IsPublic === 1"
+            >{{ list.PermissionName }}</el-checkbox
+          >
+        </el-checkbox-group>
+      </li>
+    </ul>
+  </div>
+</template>
+<style scoped lang="scss">
+.authContainer {
+	padding-top: 20px;
+	border-top: 1px dashed #DCDCDC;
+	.menu_lists {
+		padding: 20px 0 0;
+		border-radius: 4px;
+		.menu_item {
+			display: flex;
+			// align-items: center;
+			margin-bottom: 15px;
+			&:last-child {
+				margin-bottom: 0;
+			}
+			.list_item {
+				margin-right: 20px;
+				margin-bottom: 10px;
+				&:last-child {
+					margin-right: 0;
+				}
+			}
+		}
+	}
+
+}
+</style>

+ 241 - 0
src/views/custom_manage/custom/components/TotalDayDialog.vue

@@ -0,0 +1,241 @@
+<script setup>
+import { computed, ref, watch } from 'vue'
+import { customInterence } from '@/api/api.js'
+import moment from 'moment'
+
+const props = defineProps({
+  isTotalDayDialogShow: {
+    type: Boolean,
+    default: false,
+  },//控制弹窗展示
+  customInfo: {
+    type: Object,
+    default:()=>{
+      return {
+        CompanyType:''
+      }
+    }
+  },//客户信息
+})
+const emit = defineEmits(['close'])
+
+
+const tabsShow = computed(() =>{
+  const{IsShared} = props.customInfo
+  //是否是共享客户
+  if(!IsShared) return false
+  //是否是管理员
+  const role = localStorage.getItem("Role");
+  if(!role.includes('admin'))return false
+  return true
+})
+
+const tabs = [{label:'FICC',key:'ficc'},{label:'权益',key:'rai'}]
+const tableLabel = [
+    {
+        label:'试用日期',
+        key:'Date',
+        minwidthsty:180
+    },
+    {
+        label:'试用天数',
+        key:'Days',
+        widthsty:80
+    },
+    {
+        label:'状态',
+        key:'Status',
+        minwidthsty:150
+    },
+]
+
+const activeTab = ref('ficc')//默认选中的tab ficc/rai
+const tableData = ref([])
+const pageNo = ref(1)
+const pageSize = ref(5)
+const total = ref(1)
+async function getTabData(){
+  const res = await customInterence.tryOutDeail({
+    CompanyId:props.customInfo.CompanyId,
+    ProductId:activeTab.value==='ficc'?1:2,
+    PageSize:pageSize.value,
+    CurrentIndex:pageNo.value
+  })
+  if(res.Ret!==200) return
+  //console.log('res',res)
+  const {List,Paging} = res.Data
+  total.value = Paging.Totals
+  tableData.value = List
+}
+
+function handleCurrentChange(page){
+  pageNo.value = page
+  getTabData()
+}
+
+const totalDay = ref(props.customInfo.FiccTryOutDay)//累计试用天数
+function changeTab(tab){
+  const {FiccTryOutDay,RaiTryOutDay} = props.customInfo
+  activeTab.value = tab.key
+  totalDay.value = activeTab.value==='ficc'?FiccTryOutDay:RaiTryOutDay
+  pageNo.value = 1
+  getTabData()
+}
+
+function formatDate(startDate,endDate,type,index){
+  if(type==='range'){
+    const startStr = startDate==='0001-01-01T00:00:00Z'?'--':moment(startDate).format('YYYY.MM.DD')
+    //如果是第一页的第一条,判断endDate是否超过当天
+    let realDate = endDate
+    if(index===0&&pageNo.value===1&&moment()<moment(endDate)){
+      realDate = moment()
+    }
+    const endStr = endDate==='0001-01-01T00:00:00Z'?'--':moment(realDate).format('YYYY.MM.DD')
+    return `${startStr} ~ ${endStr}`
+  }
+  if(type==='count'){
+    if(startDate==='0001-01-01T00:00:00Z'||endDate==='0001-01-01T00:00:00Z') return 0
+    const day = moment(endDate).diff(moment(startDate),'day')
+    return Math.max(day+1,1)
+  }
+}
+
+function formatStatus(status){
+    const statusMap = {
+      'add_try_out':'增开试用',
+      'receive':'流失转试用',
+      'thaw':'冻结转试用',
+      'delay':'试用延期',
+      'apply_receive':'流失转试用',
+      'add':'新增试用',
+      'edit':'试用变更',
+      'formal_to_try_out':'正式转试用'
+    }
+    return statusMap[status]||'--'
+}
+
+function closeDia() {
+  tableData.value=[]
+  emit("close");
+}
+
+watch(
+  ()=>props.isTotalDayDialogShow,
+  (val) => {
+      console.log(val)
+      if(val){
+        const {CompanyType,IsShared} = props.customInfo
+        const companyType = (IsShared||CompanyType.includes('ficc'))?'ficc':'rai'
+        changeTab({key:companyType})
+      }
+  }
+)
+
+</script>
+<template>
+  <el-dialog
+    :model-value="isTotalDayDialogShow"
+    :close-on-click-modal="false"
+    :modal-append-to-body="false"
+    @close="closeDia"
+    width="889px"
+    draggable
+    center
+  >
+    <template #header>
+      <div style="display: flex; align-items: center">
+        <span style="fontsize: 16px"
+          >{{ customInfo ? customInfo.CompanyName : "" }}——累计试用天数</span
+        >
+      </div>
+    </template>
+    <div class="dialog-container">
+      <div class="tab-container" v-if="tabsShow">
+        <p class="tab" :class="{active:activeTab===tab.key}" 
+          v-for="tab in tabs" :key="tab.key"
+          @click="changeTab(tab)">{{tab.label}}</p>
+      </div>
+      <p style="margin:20px 0;">
+        <el-tooltip 
+          effect="dark" 
+          placement="top-start"
+          content="累计试用天数:试用日期的并集"
+        >
+          <template #content>
+            <i class="el-icon-question" style="font-size:16px;"/>
+          </template>
+        </el-tooltip>
+        累计试用天数:<span style="color:#409EFF;">{{totalDay}}</span></p>
+      <div class="table-container">
+          <el-table
+              v-if="tableData"
+              :data="tableData"
+              border
+              max-height="600"
+              style="width: 100%; margin-bottom: 20px">
+              <el-table-column
+                type="index"
+                label="序号"
+                align="center"
+                width="50">
+              </el-table-column>
+              <el-table-column align="center"
+                  v-for="item in tableLabel" :key="item.key"
+                  :label="item.label"
+                  :prop="item.prop"
+                  :width="item.widthsty" 
+                  :min-width="item.minwidthsty"
+              >
+              <template #default="{row,$index}">
+                <span v-if="item.key==='Date'">
+                  {{formatDate(row['StartDate'],row['EndDate'],'range',$index)}}
+                </span>
+                <span v-if="item.key==='Days'">
+                  {{formatDate(row['StartDate'],row['RealEndDate'],'count')}}
+                </span>
+                <span v-if="item.key==='Status'">
+                  {{formatStatus(row['Source'])}}
+                </span>
+              </template>
+              </el-table-column>
+          </el-table>
+          <el-pagination 
+            layout="total,prev,pager,next" 
+            background
+            :current-page="pageNo"
+            @current-change="handleCurrentChange"
+            :page-size="pageSize" 
+            :total="total"
+            style="text-align:right;">
+					</el-pagination>
+      </div>
+    </div>
+  </el-dialog>
+</template>
+<style scoped lang="scss">
+.dialog-container{
+  padding:0 50px 15px 50px;
+  .tab-container{
+    display: flex;
+    .tab{
+      cursor: pointer;
+      width:110px;
+      height:40px;
+      text-align: center;
+      line-height: 40px;
+      font-size: 14px;
+      background-color: #ECF5FF;
+      color:#409EFF;
+      border:1px solid #B3D8FF;
+      margin-right: 42px;
+      border-radius: 4px;
+      &.active{
+        border-color: #409EFF;
+        background-color: #409EFF;
+        color: #FFFFFF;
+      }
+    }
+  }
+}
+
+</style>

+ 1 - 1
src/views/custom_manage/components/accumulativeFrequencyDlg.vue → src/views/custom_manage/custom/components/accumulativeFrequencyDlg.vue

@@ -40,7 +40,7 @@ const roadShowList=async()=>{
 
 <template>
   <div class="container-accumulativeFrequency">
-    <el-dialog :model-value="props.accumulativeFrequencyDlg" :close-on-click-modal="false" :modal-append-to-body="false" @close="closeDia" width="800px" v-dialogDrag center>
+    <el-dialog :model-value="props.accumulativeFrequencyDlg" :close-on-click-modal="false" :modal-append-to-body="false" @close="closeDia" width="800px" draggable center>
       <template #header>
         <div style="display: flex; align-items: center">
           <span style="font-size: 16px">{{ props.accumulativeFrequencyItem.CompanyName }}-路演详情</span>

+ 150 - 0
src/views/custom_manage/custom/components/customRemarkDialog.vue

@@ -0,0 +1,150 @@
+<script setup>
+import { ref,computed,watch } from 'vue'
+import { customInterence } from '@/api/api.js'
+import { ElMessage,ElMessageBox } from 'element-plus'
+
+const props = defineProps({
+  isRemarkLook:{
+      type:Boolean,
+      default:false
+  },
+  lookRemarkItem:{
+      type:Object,
+      default:()=>{
+          return {}
+      }
+  },
+  canEdit:{//是否可新增备注
+      type:Boolean,
+      default:true
+  }
+})
+
+const emit = defineEmits(['close'])
+
+
+const Role = computed(() => {
+    return localStorage.getItem('Role') || ''
+})
+
+//获取备注列表
+const lookRemarkList = ref([])//备注列表
+const lookRemarkTextarea = ref('')
+const tableLoading = ref(false)
+function getRemarkList(){
+    tableLoading.value = true
+    customInterence.lookRemarkAuth({
+        CompanyId:props.lookRemarkItem.CompanyId
+    }).then(res=>{
+        if(res.Ret!==200) return 
+        lookRemarkList.value = res.Data||[]
+        tableLoading.value = false
+    })
+}
+
+//新增备注
+function lookRemarkAdd(){
+    if(!lookRemarkTextarea.value.length){
+        return ElMessage.warning("请输入备注内容")
+    }
+    customInterence.addCustomRemark({
+        CompanyId:props.lookRemarkItem.CompanyId,
+        Remark:lookRemarkTextarea.value
+    }).then(res=>{
+        if(res.Ret!==200) return 
+        ElMessage.success('保存成功')
+        lookRemarkTextarea.value=''
+        getRemarkList()
+    })
+}
+
+//删除备注
+function deleteRecord(data){
+    ElMessageBox.confirm('备注删除后不可恢复,确认删除吗?','提示',{
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type:'warning',
+        appendToBody:false
+    }).then(()=>{
+        customInterence.deleteRemark({
+            RemarkId:data.RemarkId
+        }).then(res=>{
+            if(res.Ret!==200) return 
+            ElMessage.success("删除成功")
+            getRemarkList()
+        })
+    })
+}
+
+function closeDia(){
+    emit('close')
+}
+
+watch(
+  () =>props.isRemarkLook,
+  (newval) => {
+    if(newval){
+        lookRemarkTextarea.value=''
+        getRemarkList()
+    }
+  }
+)
+</script>
+<template>
+    <!-- 共享客户列表-备注 -->
+    <!-- 逻辑与客户列表-备注基本相同,将权限判断做成了可配置项 -->
+    <el-dialog 
+        :model-value="isRemarkLook" 
+        :close-on-click-modal="false" 
+        :modal-append-to-body="true"
+        :append-to-body="true"
+        @close="closeDia" width="800px" draggable center>
+        <template #header>
+          <div style="display:flex;alignItems:center;">
+              <img :src="$icons.auth" style="color:#fff;width:16px;height:16px;marginRight:5px;">
+              <span style="fontSize:16px;">备注</span>
+          </div>
+        </template>
+        <div>
+            <div v-if="Role!=='admin'">
+                <el-input type="textarea" :rows="3" placeholder="请输入文字" v-model="lookRemarkTextarea">
+                </el-input>
+                <div class="look-remark-commit" @click="lookRemarkAdd">保存</div>
+            </div>
+            <el-table :data="lookRemarkList" border max-height="300"  v-loading="tableLoading"
+                style="width: 100%; margin-top: 20px;margin-bottom: 20px">
+                <el-table-column label="备注内容" key="Remark" align="center">
+                    <template #default="scope">{{scope.row.Remark}}</template>
+                </el-table-column>
+                <el-table-column label="客户类型" align="center" key="ProductName"
+                    v-if="lookRemarkItem.IsShared">
+                    <template #default="scope">{{scope.row.ProductName}}</template>
+                </el-table-column>
+                <el-table-column label="创建时间" key="CreateTime" align="center">
+                    <template #default="scope">{{scope.row.CreateTime}}</template>
+                </el-table-column>
+                <el-table-column label="操作" align="center" v-if="Role!=='admin'">
+                    <template #default="{row}">
+                        <el-button type="text" size="small" style="color:red;" v-if="row.ButtonDel"
+                            @click="deleteRecord(row)">删除</el-button>
+                    </template>
+                </el-table-column>
+            </el-table>
+        </div>
+        <div style="padding:20px 0;"></div>
+    </el-dialog>
+</template>
+<style scoped lang="scss">
+.look-remark-commit{
+    width: 426px;
+    height: 41px;
+    background: #409EFF;
+    margin:  30px auto;
+    text-align: center;
+    line-height: 41px;
+    color: #fff;
+    box-shadow: 0px 2px 6px 1px rgba(64, 158, 255, 0.05);
+    border-radius: 4px 4px 4px 4px;
+    cursor: pointer;
+}
+</style>

+ 105 - 0
src/views/custom_manage/custom/components/permissionDetail.vue

@@ -0,0 +1,105 @@
+<script setup>
+import { ref,watch } from 'vue'
+import { customInterence, equityContacts, raiInterface } from "@/api/api.js";
+import CpessionTableEquity from "./CpessionTableEquity.vue";
+
+
+const props = defineProps({
+  isPermissionDetailShow: {
+    default: false,
+    type: Boolean,
+  },
+  researchDetailId: {
+    default: 0,
+    type: Number,
+  },
+})
+const emit = defineEmits(['close'])
+
+watch(
+  () => props.isPermissionDetailShow,
+  (newVal) => {
+    newVal && getDetailList();
+  }
+)
+
+// 弹框关闭的事件
+function cancelHandle() {
+  emit('close')
+  tableData.value = [];
+}
+
+
+const tableData = ref([])
+const Points = ref("")
+/* 获取客户详情 */
+async function getDetailList() {
+  tableData.value = [];
+  const res = await customInterence.customDetail({
+    CompanyId: props.researchDetailId,
+  });
+  if (res.Ret !== 200) return;
+  Points.value = res.Data.RaiItem.Points || "";
+  let auth = [];
+  res.Data.RaiItem.PermissionList.forEach((item) => {
+    let obj = {
+      checkAll: item.CheckList && item.CheckList.length === item.Items.length ? true : false,
+      isIndeterminate: item.CheckList && item.CheckList.length > 0 && item.CheckList.length < item.Items.length,
+      ...item,
+    };
+    auth.push(obj);
+  });
+  tableData.value = auth;
+}
+
+
+
+const isShowResearchNumber = ref(false) // 研选服务点数明细 弹框
+const tableListResearch = ref([]) // 严选数据
+// 查看
+function lookNumber() {
+  isShowResearchNumber.value = true;
+  getDataList();
+}
+// 明细弹框关闭
+function handleClose() {
+  isShowResearchNumber.value = false;
+  tableListResearch.value = [];
+}
+// 获取表格数据
+async function getDataList() {
+  const res = await raiInterface.activityPointsBill({
+    CompanyId: props.researchDetailId,
+  });
+  if (res.Ret === 200) {
+    tableListResearch.value = res.Data.List || [];
+  }
+}
+
+</script>
+<template>
+  <el-dialog title="权限详情" draggable :model-value="isPermissionDetailShow" :close-on-click-modal="false" :modal-append-to-body="false" @close="cancelHandle" center width="800px">
+      <CpessionTableEquity v-if="tableData.length" fromType="detail" :authList="tableData" style="margin-bottom: 20px" />
+      <div style="margin: 20px 0" v-if="Points">
+        <span>研选服务点数</span>
+        <span>{{ Points }}</span>
+        <span class="editsty" @click="lookNumber">明细>></span>
+      </div>
+    </el-dialog>
+    <el-dialog title="研选服务点数明细" :model-value="isShowResearchNumber" width="80%" draggable :close-on-click-modal="false" :modal-append-to-body="false" center @close="handleClose">
+      <el-table style="margin-bottom: 30px" :data="tableListResearch" border height="500">
+        <el-table-column align="center" prop="Content" label="事项"></el-table-column>
+        <el-table-column align="center" prop="CreateTime" label="时间"></el-table-column>
+        <el-table-column align="center" prop="RealName" label="参会人" width="150"></el-table-column>
+        <el-table-column align="center" prop="minNumber" label="小计" width="100">
+          <template #default="{ row }">
+            <span :style="{ color: row.BillDetailed > 0 ? '#31c640' : '#ec808d' }"> {{ row.BillDetailed > 0 ? "+" + row.BillDetailed : row.BillDetailed }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column align="center" prop="Points" label="合计" width="100"></el-table-column>
+      </el-table>
+    </el-dialog>
+</template>
+<style scoped lang="scss">
+
+</style>

+ 257 - 0
src/views/custom_manage/custom/components/premissionView.vue

@@ -0,0 +1,257 @@
+<script setup>
+import { ref, watch } from 'vue'
+
+const props = defineProps({
+  isLook:{
+    type:Boolean,
+    required:true
+  },
+  lookTitle:{
+    type:String,
+    default:'未知公司名'
+  },
+  lookAuthList:{
+    type:Array,
+    default:()=> []
+  },
+  lookAuthListEquity:{
+    type:Array,
+    default:()=> []
+  }
+})
+
+const emit = defineEmits(['closeDia'])
+
+
+/* 处理合并数组 */
+const position =  ref(0)
+const rowSpanArr = ref([])//处理合并行数组结构
+function getRowSpan() {
+  rowSpanArr.value = [];
+  /* [2,0,1] */
+  props.lookAuthList.forEach((item, index) => {
+    if (index === 0) {
+      rowSpanArr.value.push(1);
+      position.value = 0;
+    } else {
+      if (props.lookAuthList[index].ClassifyName === props.lookAuthList[index - 1].ClassifyName) {
+        rowSpanArr.value[position] += 1; //项目名称相同,合并到同一个数组中
+        rowSpanArr.value.push(0);
+        props.lookAuthList[index].ClassifyName = props.lookAuthList[index - 1].ClassifyName;
+      } else {
+        rowSpanArr.value.push(1);
+        position.value = index;
+      }
+    }
+  });
+}
+/* 合并行规则 */
+function objectSpanMethod({ row, column, rowIndex, columnIndex }) {
+  if (columnIndex === 0) {
+    const _row = rowSpanArr.value[rowIndex];
+      return {
+        rowspan: _row,
+        colspan: 1
+      };
+  }
+}
+
+/* 权益处理数据 */
+const spanArrEquity = ref([])
+const posEquity = ref(0)
+const isPermissionTypeShow = ref(false)
+const indexArrEquity = ref([])
+function getSpanArr(data) {
+  data.map((v, i, s) => {
+    if (!v.PermissionTypeName) {
+    indexArrEquity.value.push(i);
+    }
+  });
+  for (var i = 0; i < data.length; i++) {
+    let element = data[i]
+    if (i === 0) {
+      spanArrEquity.value.push(1);
+      posEquity.value = 0;
+    } else {
+      // 判断当前元素与上一个元素是否相同(line为标记)
+      if (element.PermissionName === data[i - 1].PermissionName) {
+        if(element.IsMerge){
+          // 主客观都有,需要合并
+          spanArrEquity.value[posEquity.value] += 1;
+          spanArrEquity.value.push(0);
+        }else{
+          // 主客观都有 不需要合并,说明是服务期限或者状态不一样
+          spanArrEquity.value[posEquity.value] += 0.5;
+          spanArrEquity.value.push(0.5);
+        }
+      } else {
+        spanArrEquity.value.push(1);
+        posEquity.value = i;
+      }
+    }
+  }
+}
+/* 权益处理数组合并 */
+function objectSpanMethodEquity({ row, column, rowIndex, columnIndex}){
+  if(!isPermissionTypeShow.value){
+    // 产品类型不显示
+    const _row = spanArrEquity.value[rowIndex];
+    if(_row == 0){
+      return {
+        rowspan: _row,
+        colspan: 0,
+      };
+    }
+  }else{
+    //处理行的合并
+    if (indexArrEquity.value.includes(rowIndex)) {
+      if (columnIndex === 0) {
+        return {
+          rowspan: 1,
+          colspan: 2,
+        };
+      } else if (columnIndex === 1) {
+        return {
+          rowspan: 0,
+          colspan: 0,
+        };
+      }
+    }
+    // 权益行业主客观合并
+    const _row = spanArrEquity.value[rowIndex];
+    if(_row == 2){
+      // 为2 是主客观都有,合并,这时合并行业和产品类型
+      if(columnIndex === 0){
+        return {
+          rowspan: 1,
+          colspan: 2,
+        };
+      }else if(columnIndex === 1){
+        return {
+          rowspan: 0,
+          colspan: 0,
+        };
+      }
+    }else if(_row == 0){
+      // 为0 表示不需要这行,被合并掉了
+      return {
+        rowspan: _row,
+        colspan: 0,
+      };
+    }else if(_row == 1.5){
+      // 为1.5 是主客观都有,但不合并,这时合并行业
+      if(columnIndex === 0){
+        return {
+          rowspan: 2,
+          colspan: 1,
+        };
+      }
+    }else if(_row == 0.5){
+      if(columnIndex === 0){
+        return {
+          rowspan: 0,
+          colspan: 0,
+        };
+      }
+    }
+  }
+}
+
+function closeDia(){
+  spanArrEquity.value = []
+  indexArrEquity.value = []
+  emit('closeDia')
+}
+
+watch(
+  () => props.lookAuthList,
+  (value) => {
+    if(value.length>0){
+      getRowSpan();
+    }
+})
+watch(
+  () => props.lookAuthListEquity,
+  (newvalue) => {
+    if(newvalue.length>0){
+      isPermissionTypeShow.value = newvalue.some(item => !item.IsMerge)
+      getSpanArr(newvalue) //权益
+    }
+})
+
+</script>
+<template>
+		<el-dialog
+		:model-value="isLook"
+		:close-on-click-modal="false"
+		:modal-append-to-body='false'
+		@close="closeDia"
+		width="800px"
+		draggable
+		center>
+      <template #header>
+        <div class="dialog-title">
+          <img :src="$icons.auth" />
+          <span>{{lookTitle}}</span>
+        </div>
+      </template>
+			<template v-if="lookAuthList && lookAuthList.length > 0">
+				<div>
+					FICC权限
+				</div>
+        <el-table
+        :data="lookAuthList"
+        :span-method="objectSpanMethod"
+        border
+        max-height="300"
+        style="width: 100%; margin-top: 20px;margin-bottom: 20px">
+          <el-table-column label="所属类目" align="center">
+            <template #default="scope">{{scope.row.ClassifyName}}</template>
+          </el-table-column>
+          <el-table-column label="品种" align="center">
+            <template #default="scope">{{scope.row.PermissionName}}</template>
+          </el-table-column>
+          <el-table-column label="状态" align="center">
+            <template #default="scope">{{scope.row.Status}}</template>
+          </el-table-column>
+          <el-table-column label="服务期限" align="center" min-width="200">
+            <template #default="scope">{{scope.row.StartDate+'~'+scope.row.EndDate}}</template>
+          </el-table-column>
+          <el-table-column label="剩余天数" align="center">
+            <template #default="scope">{{scope.row.ExpireDay}}</template>
+          </el-table-column>
+        </el-table>
+			</template>
+			<template v-if="lookAuthListEquity && lookAuthListEquity.length > 0">
+				<div>
+					权益权限
+				</div>
+				<el-table
+        :data="lookAuthListEquity"
+        :span-method="objectSpanMethodEquity"
+        border
+        max-height="300"
+        style="width: 100%; margin-top: 20px">
+          <el-table-column label="行业" align="center">
+            <template #default="scope">{{scope.row.PermissionName}}</template>
+          </el-table-column>
+          <el-table-column label="产品类型" v-if="isPermissionTypeShow" align="center">
+            <template #default="scope">{{scope.row.PermissionTypeName}}</template>
+          </el-table-column>
+          <el-table-column label="状态" align="center">
+            <template #default="scope">{{scope.row.Status}}</template>
+          </el-table-column>
+          <el-table-column label="服务期限" align="center" min-width="200">
+            <template #default="scope">{{scope.row.StartDate+'~'+scope.row.EndDate}}</template>
+          </el-table-column>
+          <el-table-column label="剩余天数" align="center">
+            <template #default="scope">{{scope.row.ExpireDay}}</template>
+          </el-table-column>
+			  </el-table>
+			</template>
+			<div style="padding:20px 0;"></div>
+		</el-dialog>
+</template>
+<style scoped lang="scss">
+
+</style>

+ 165 - 0
src/views/custom_manage/custom/customCityList.vue

@@ -0,0 +1,165 @@
+<script setup>
+import { reactive, ref, toRefs } from "vue";
+import {locationOptions} from "./location"
+import { customInterence } from '@/api/api.js'
+
+
+const tableColumns = [
+  {
+      label:'客户名称',
+      key:'CompanyName'
+  },{
+      label:'类型',
+      key:'CompanyType'
+  },{
+      label:'所属行业',
+      key:'IndustryName'
+  },{
+      label:'客户地址',
+      key:'City'
+  },{
+      label:'原销售',
+      key:'SellerName'
+  },{
+      label:'分配销售',
+      key:'ShareSeller'
+  },{
+      label:'状态',
+      key:'Status'
+  }
+]
+const filterState = reactive({
+  searchCitys:[],
+  provinceValue:'',
+  cityValue:'',
+  searchText:'',
+  pageNo: 1,
+  pageSize: 10
+})
+
+const tableData = ref([])
+const tableLoading = ref(false)
+const total = ref(0)
+function getTableList(){
+    tableLoading.value=true
+    customInterence.getCustomCityList({
+        PageSize:filterState.pageSize,
+        CurrentIndex:filterState.pageNo,
+        Keyword:filterState.searchText,
+        Province:filterState.provinceValue,
+        City:filterState.cityValue
+    }).then(res=>{
+        if(res.Ret!==200) return
+        tableData.value = res.Data.List
+        total.value = res.Data.Paging.Totals
+    })
+    
+}
+getTableList()
+
+function currentChange(page){
+    filterState.pageNo=page
+    getTableList()
+}
+
+
+function handleChangeLocation(){
+    const provinceArr = []
+    const cityArr = []
+    filterState.searchCitys.forEach(item=>{
+        // 省
+        provinceArr.push(item[0])
+        // 市
+        cityArr.push(item[1])
+    })
+//provinceArr需要去重
+    filterState.provinceValue = [...new Set(provinceArr)].join(',')
+    filterState.cityValue = cityArr.join(',')
+    filterState.page_no = 1;
+    getTableList();
+}
+
+const { 
+  searchCitys,
+  provinceValue,
+  cityValue,
+  searchText,
+  pageNo,
+  pageSize 
+} = toRefs(filterState)
+
+</script>
+<template>
+  <div class="custom-city-list-wrap">
+    <div class="select-box box-wrap">
+      <el-cascader
+        v-model="searchCitys"
+        :props="{
+          multiple: true,
+          value: 'name',
+          children: 'city',
+          label: 'name',
+        }"
+        :options="locationOptions"
+        clearable
+        collapse-tags
+        placeholder="请选择客户地址"
+        @change="handleChangeLocation"
+      >
+      </el-cascader>
+      <el-input
+        placeholder="客户名称/原销售/分配销售"
+        prefix-icon="el-icon-search"
+        v-model="searchText"
+        clearable
+        @input="getTableList"
+      ></el-input>
+    </div>
+    <div class="table-box box-wrap">
+      <el-table :data="tableData" border>
+        <el-table-column
+          v-for="item in tableColumns"
+          :key="item.key"
+          :label="item.label"
+          align="center"
+        >
+          <template #default="{ row }">
+            {{ row[item.key] }}
+          </template>
+        </el-table-column>
+      </el-table>
+      <el-pagination
+        layout="prev,pager,next,total"
+        background
+        :current-page="pageNo"
+        @current-change="currentChange"
+        :page-size="pageSize"
+        :total="total"
+      >
+      </el-pagination>
+    </div>
+  </div>
+</template>
+<style scoped lang="scss">
+.custom-city-list-wrap{
+    .box-wrap{
+        padding:30px;
+        background-color: #fff;
+        border-radius: 4px;
+    }
+    .select-box{
+        display: flex;
+        justify-content: space-between;
+        .el-input{
+            width:400px;
+        }
+    }
+    .table-box{
+        margin-top: 30px;
+        .el-pagination{
+            margin-top: 30px;
+            justify-content: flex-end;
+        }
+    }
+}
+</style>

+ 925 - 0
src/views/custom_manage/custom/customDetail.vue

@@ -0,0 +1,925 @@
+<script setup>
+import { ref } from 'vue'
+import { useRoute,useRouter } from 'vue-router'
+import { ElMessage,ElMessageBox } from 'element-plus'
+import { customInterence,mychartInterface } from '@/api/api.js'
+// import{ customAllInterence } from '@/api/modules/crmApi.js'
+// import Ctimeline from '../compontents/Ctimeline.vue'
+// import Contactdia from '../compontents/Contactdialog.vue'
+// import Readia from '../compontents/ReadDialog.vue'
+// import ElImageViewer from 'element-ui/packages/image/src/image-viewer'
+// import CpessionTable from '../compontents/CpessionTable.vue'
+// import pdf from 'vue-pdf'
+// import chartAuthDialog from '../compontents/chartAuthDialog.vue'
+// import CpessionTableEquity from '../compontents/CpessionTableEquity.vue'
+// import ExportData from '../compontents/exportData.vue'
+// import ProductReadInfo from '../compontents/ProductReadInfo.vue'
+// import DeductDetailDlg from './components/deductDetailDlg.vue'
+// import HistoryContract from '../compontents/historyContract.vue'
+
+</script>
+<template>
+  <div class="customDetail_box" v-if="showData">
+		<div class="customDetail_container" style="display:flex">
+			
+				<div class="left_form_cont" style="flex:1;margin-right:100px">
+					<p class="page-title">基础信息</p>
+					<ul class="detail_item" v-if="basicform">
+						<li style="width:40%">
+							<label class="label">客户名称</label>
+							<span class="con">
+								<span style="margin-right: 10px;">{{basicform.CompanyName}} </span>
+								<el-tooltip content="此客户存在长期且反复申请试用,但从未签约的情况,请谨慎领取" placement="top" :open-delay="500" 
+								v-if="RaiSellerRole && basicform.IsScrounge==1" >
+									<img width="16" style="cursor: pointer;vertical-align: text-top;" src="../../../assets/img/icons/warning_triangle_yellow.png" />
+								</el-tooltip>
+							</span>
+						</li>
+
+						<li style="width:26%">
+							<label class="label">所属区域</label>
+							<span class="con">{{basicform.RegionType}}</span>
+						</li>
+						<li v-if="basicform.RegionType==='海外'">
+							<label class="label">所属国家</label>
+							<span class="con">{{basicform.Nation}}</span>
+						</li>
+						<li v-else>
+							<label class="label">客户地址</label>
+							<span class="con">{{basicform.Province}}<span v-if="basicform.Province">/</span>{{basicform.City}}</span>
+						</li>
+						<li style="width:40%">
+							<label class="label">社会信用码</label>
+							<span class="con">{{basicform.CreditCode}}</span>
+						</li>
+						<li style="width:26%">
+							<label class="label">客户类型</label>
+							<span class="con">{{raiform&&ficcform?'FICC/权益':basicform.CreateAuth==1?'FICC':"权益"}}</span>
+						</li>
+					</ul>
+					<!-- 权益类型信息 -->
+					<template v-if="raiform">
+						<p class="page-title">权益类型信息</p>
+						<ul class="detail_item" style="margin-bottom:0">
+							<li style="width:40%">
+								<label class="label">客户状态</label>
+								<span class="con">{{raiform.Status}}</span>
+							</li>
+							<li style="width:26%">
+								<label class="label">所属销售</label>
+								<span class="con">{{raiform.SellerName}}</span>
+							</li>
+							<li>
+								<label class="label">所属行业</label>
+								<span class="con">{{raiform.IndustryName}}</span>
+							</li>
+							<li style="width:40%">
+								<label class="label">客户来源</label>
+								<span class="con">{{raiform.Source}}</span>
+							</li>
+							<!-- <li style="width:50%">
+								<label class="label">备注</label>
+								<span class="con">{{raiform.Reasons}}</span>
+							</li> -->
+							<li style="width:23%">
+								<label class="label">管理规模</label>
+								<span class="con">{{raiform.Scale ==1?'50亿以下':raiform.Scale ==2?'50~100亿':raiform.Scale ==3?'100亿以上':''}}</span>
+							</li>
+							<li v-if="raiform.SpecialSurplus">
+								<label class="label-num" >专项调研剩余次数</label>
+								<span class="con">{{raiform.SpecialSurplus}} <span class="editsty" @click="clickDlgNumberHandler('专项调研')">明细>></span></span>
+							</li>
+							<li v-if="RoleType==='admin'" style="width:100%">
+								<label class="label"
+								>客户编码</label>
+								<span class="con" style="word-break: break-word;">{{raiform.OpenCode}}</span>
+							</li>
+							<li  style="width:100%" v-if="raiform.Points">
+								<label class="label-num">研选服务点数</label>
+								<span class="con" style="word-break: break-word;">{{raiform.Points}}</span>
+								<span v-if="raiform.Points" @click="clickDlgNumberHandler('研选服务')" class="con" style="word-break: break-word;color:#409EFF;padding-left:10px;cursor: pointer;">明细>></span>
+							</li>
+						</ul>
+						<el-collapse v-model="raiCollapseOpen" accordion>
+							<el-collapse-item name="1">
+								<template slot="title">
+									<p style="display:inline-block;font-size:15px;padding-left:23px">
+										<span style="font-weight:bold">权限设置</span> 
+										<span style="color:#1989FA;display:inline-block;margin-left:10px">{{raiCollapseOpen=='1'?'收起':'展开'}}</span>
+									</p>
+								</template>
+								<!-- <CpessionTable fromType="detail" :authList="raiform.authList"/> -->
+								<CpessionTableEquity fromType="detail" :authList="raiform.authList"/>
+							</el-collapse-item>
+						</el-collapse>
+					</template>
+					<!-- FICC类型信息 -->
+					<template v-if="ficcform">
+						<p class="page-title">FICC类型信息</p>
+						<ul class="detail_item" style="margin-bottom:0">
+							<li style="width:40%">
+								<label class="label">客户状态</label>
+								<span class="con">{{ficcform.Status}}</span>
+							</li>
+							<li style="width:26%">
+								<label class="label">所属销售</label>
+								<span class="con">{{ficcform.SellerName}}</span>
+							</li>
+							<li>
+								<label class="label">所属行业</label>
+								<span class="con">{{ficcform.IndustryName}}</span>
+							</li>
+							<li style="width:40%">
+								<label class="label">客户来源</label>
+								<span class="con">{{ficcform.Source}}</span>
+							</li>
+							<!-- <li style="width:50%">
+								<label class="label">备注</label>
+								<span class="con">{{ficcform.Reasons}}</span>
+							</li> -->
+							<li v-if="RoleType==='admin'">
+								<label class="label">客户编码</label>
+								<span class="con" style="word-break: break-word;">{{ficcform.OpenCode}}</span>
+							</li>
+						</ul>
+						<el-collapse v-model="ficcCollapseOpen" accordion>
+							<el-collapse-item name="1">
+								<template slot="title">
+									<p style="display:inline-block;font-size:15px;padding-left:23px">
+										<span style="font-weight:bold">权限设置</span> 
+										<span style="color:#1989FA;display:inline-block;margin-left:10px">{{ficcCollapseOpen=='1'?'收起':'展开'}}</span>
+									</p>
+								</template>
+								<CpessionTable fromType="detail" :authList="ficcform.authList"/>
+							</el-collapse-item>
+						</el-collapse>
+					</template>
+
+				</div>
+				<div style="flex-shrink: 0;">
+					<div style="display:flex;justify-content:flex-end;align-items: center;gap:0 20px;margin:0 0 30px;">
+						<span style="color:#409EFF;cursor:pointer;font-size: 14px;margin-right: 20px;" v-if="isBtnShow.BtnHistoryList&&dealList.length" @click="previewHistory">历史签约</span>
+						<el-button type="primary" style="width:100px;" @click="editHandle" v-if="isBtnShow.BtnEdit">编辑</el-button>
+						<el-button type="danger" plain style="width:100px;" @click="delHandle" v-if="isBtnShow.BtnDelete">删除</el-button>
+					</div>
+					<Ctimeline :id="companyId"></Ctimeline>
+				</div>
+		</div>
+		<!-- 联系人 -->
+		<div class="customDetail_container" style="marginTop:20px;padding:30px 40px 80px 60px;">
+			<div class="customList_bot_top">
+				<div >
+					<div v-if="isContractButtonShow">
+						<input type="file" size="small" name="file" @change="fileSelected()" id="fileImport" class="true-file" style="display:none;">
+						<el-button type="primary" @click="addConcat">添加联系人</el-button>
+						<el-button type="primary" @click.native="importHandle">批量导入</el-button>
+						<!-- <span style="fontSize:16px;color:#AAB4CC;">(请至少添加一位联系人)</span> -->
+						<!-- <el-button v-if="RoleType=='admin' || isUserYanXuanButtonShow" style="margin-left:20px" type="primary" @click="exportDataIsShow=true">导出数据</el-button> -->
+						<a :href="downTemplate" download style="fontSize:14px;color:#409eff;margin-left:30px">下载导入模板</a>
+					</div>
+				</div>
+				<div style="display: flex">
+				  <template v-if="!isUserYanXuanButtonShow">
+					<el-select 
+						v-model="IsSubscribe"
+						placeholder="是否关注公众号" 
+						multiple
+						clearable
+						style="margin-right: 10px;width: 300px;" 
+						@change="changeSubscribe"
+					>
+						<el-option 
+							label="已关注弘则研究"
+							value="1"
+							:disabled="IsSubscribe.includes('2')"
+						/>
+						<el-option 
+							label="已关注查研观向小助手"
+							value="3"
+							:disabled="IsSubscribe.includes('4')"
+						/>
+						<el-option 
+							label="未关注弘则研究"
+							value="2"
+							:disabled="IsSubscribe.includes('1')"
+						/>
+						<el-option 
+							label="未关注查研观向小助手"
+							value="4"
+							:disabled="IsSubscribe.includes('3')"
+						/>
+					</el-select>
+
+					<el-select v-model="platform_type" style="margin-right: 10px;width: 250px;" @change="changeSubProductHandle">
+						<el-option
+							v-for="item in platformOption"
+							:key="item.key"
+							:label="item.ProductName"
+							:value="item.key"
+						>
+							{{ item.ProductName }}
+						</el-option>
+					</el-select>
+				  </template>
+					<el-input
+						placeholder="姓名/手机号码/邮箱"
+						v-model="search_txt"
+						style="maxWidth:400px"
+						@input="searchUser"
+						clearable>
+						<i slot="prefix" class="el-input__icon el-icon-search"></i>
+					</el-input>
+				</div>
+			</div>
+			<div class="bot_cont">
+				<el-table
+				ref="userTable"
+				:data="userTable"
+				v-loading="isShowloadding"
+				:row-class-name="setRowClass"
+				element-loading-text="数据加载中..."
+				border>
+					<el-table-column
+					prop="RealName"
+					label="姓名"
+					align="center"
+					min-width="80px"
+					>
+						<template slot-scope="scope"
+							:class="{'isShared':scope.row.IsShared}"
+						>
+							<img :src="$icons.card" alt="" style="width:17px;cursor:pointer;marginRight:5px;"
+							v-if="scope.row.BusinessCardUrl"
+							@click="reviewCard(scope.row.BusinessCardUrl)">
+							<img src="~@/assets/img/icons/like-heart.png" class="name-follow-heart" v-if="scope.row.IsFollow==1">
+							<span :class="{'isShared':scope.row.IsShared}">{{scope.row.RealName}}</span>
+						</template>
+					</el-table-column>
+					<el-table-column prop="Position" label="职位" align="center" min-width="80px"></el-table-column>
+					<el-table-column
+					prop="Mobile"
+					label="手机号"
+					align="center"
+					min-width="100">
+						<template slot-scope="scope"><span v-if="scope.row.Mobile&&scope.row.CountryCode">{{scope.row.CountryCode}}-</span><span>{{scope.row.Mobile+(scope.row.MobileTwo?'/'+scope.row.MobileTwo:'')}}</span> </template>
+					</el-table-column>
+					<el-table-column
+					prop="Email"
+					label="邮箱"
+					min-width="120"
+					align="center">
+						<template slot-scope="scope"> <span>{{scope.row.Email}}</span> </template>
+					</el-table-column>
+					<el-table-column
+					prop="IsMaker"
+					label="是否KP"
+					align="center">
+						<template slot-scope="scope"> <span>{{scope.row.IsMaker==1?'是':'否'}}</span> </template>
+					</el-table-column>
+					<!-- crm 14.7 -->
+					<template v-if="isUserYanXuanButtonShow">
+						<el-table-column
+						prop="IsRegister"
+						label="是否绑定"
+						width="90"
+						align="center">
+							<template slot-scope="scope">
+								<div style="text-align:left; display: flex;align-items: center;">
+									<img v-if="scope.row.MfyxIsBinding" style="width:16px;height:16px;margin-right: 5px;" src="~@/assets/img/icons/icon_1.png" alt="">
+									<img v-else style="width:16px;height:16px;margin-right: 5px;" src="~@/assets/img/icons/icon_2.png" alt="">
+									<span>{{scope.row.MfyxIsBinding?'已绑定':'未绑定'}}</span> 
+								</div>
+							</template>
+						</el-table-column>
+						<el-table-column
+						prop="CreatedTime"
+						label="绑定时间"
+						min-width="150"
+						align="center">
+							<template slot-scope="scope"> <span>{{scope.row.MfyxBindingTime}}</span> </template>
+						</el-table-column>
+					</template>
+					<template v-else>
+						<el-table-column
+						prop="IsRegister"
+						label="是否注册"
+						align="center">
+							<template slot-scope="scope"> <span>{{scope.row.IsRegister?'已注册':'未注册'}}</span> </template>
+						</el-table-column>
+						<el-table-column
+						prop="CreatedTime"
+						label="注册时间"
+						min-width="150"
+						align="center">
+							<template slot-scope="scope"> <span>{{scope.row.RegisterTime|formatTime}}</span> </template>
+						</el-table-column>
+					</template>
+					<el-table-column
+					prop="IsSubscribeHzyj"
+					label="是否关注公众号"
+					min-width="90"
+					align="center">
+						<template slot-scope="scope">
+							<div style="text-align:left" v-if="RoleType !=='权益'">
+								<img v-if="scope.row.IsSubscribeHzyj==1" style="width:16px;height:16px" src="~@/assets/img/icons/icon_1.png" alt="">
+								<img v-else style="width:16px;height:16px" src="~@/assets/img/icons/icon_2.png" alt="">
+								<span>弘则研究</span>
+							</div>
+							<div style="text-align:left">
+								<img v-if="scope.row.IsSubscribeCygx==1" style="width:16px;height:16px" src="~@/assets/img/icons/icon_1.png" alt="">
+								<img v-else style="width:16px;height:16px" src="~@/assets/img/icons/icon_2.png" alt="">
+								<span>查研观向小助手</span>
+							</div>
+						</template>
+					</el-table-column>
+					<!-- crm 14.7 -->
+					<el-table-column
+					v-if="isUserYanXuanButtonShow"
+					prop="IsRegister"
+					label="互动次数"
+					align="center">
+						<template slot-scope="scope"> <span class="editsty" @click="MfyxInteractionNumHandler(scope.row)">{{scope.row.MfyxInteractionNum}}</span> </template>
+					</el-table-column>
+					<!-- crm 14.7 -->
+					<el-table-column
+					v-if="!isUserYanXuanButtonShow"
+					prop="ViewTotal"
+					label="累计阅读次数"
+					align="center">
+						<template slot-scope="scope"> <span>{{scope.row.ViewTotal||'暂无'}}</span> </template>
+					</el-table-column>
+					<el-table-column
+					prop="LastViewTimeStr"
+					label="最近一次阅读时间"
+					min-width="150"
+					align="center">
+						<template slot-scope="scope"> <span>{{scope.row.ViewTotal?scope.row.LastViewTimeStr:''|formatTime}}</span> </template>
+					</el-table-column>
+					<el-table-column
+					v-if="!isUserYanXuanButtonShow"
+					label="研报统计"
+					align="center">
+						<template slot-scope="scope"> <span v-if="scope.row.ViewTotal!=0" class="editsty" @click="lookReport(scope.row)" :disabled="!isContractButtonShow" >点击查看</span></template>
+					</el-table-column>
+					<el-table-column
+						v-if="ficcform && !isUserYanXuanButtonShow"
+						prop="YbProductViewTotal"
+						label="其他统计"
+						min-width="110"
+						align="center">
+						<template slot-scope="scope"> <span :class="scope.row.YbProductViewTotal?'editsty':''" @click="lookReadInfo(scope.row)">{{scope.row.YbProductViewTotal||'0'}}</span> </template>
+					</el-table-column>
+					<!-- crm 14.7 -->
+					<template v-if="isUserYanXuanButtonShow">
+						<el-table-column
+						prop="IsRegister"
+						label="个人研选订阅权限"
+						width="140"
+						align="center">
+							<template slot-scope="scope"> 
+								<div style="text-align:left; display: flex;align-items: center;">
+									<img v-if="scope.row.MfyxStatus=='试用'" style="width:16px;height:16px;margin-right: 5px;" src="~@/assets/img/icons/icon_1.png" alt="">
+									<img v-else style="width:16px;height:16px;margin-right: 5px;" src="~@/assets/img/icons/icon_2.png" alt="">
+									<span>{{scope.row.MfyxStatus}}</span> 
+								</div>
+							</template>
+						</el-table-column>
+						<el-table-column
+						prop="CreatedTime"
+						label="研选服务期限"
+						min-width="150"
+						align="center">
+							<template slot-scope="scope"> <span>{{scope.row.MfyxStartDate}} -- {{scope.row.MfyxEndDate}}</span> </template>
+						</el-table-column>
+					</template>
+					<el-table-column label="操作" align="center" min-width="150">
+						<template slot-scope="scope"  v-if="isContractButtonShow">
+							<div class="contact-opt-box" style="color:#4099ef; font-size:14px;">
+								<span  class="editsty" @click="editContact(scope.row)">编辑</span>
+								<span class="editsty move" style="margin:0 5px;" @click="handleShowMove(scope.row)">移动</span>
+								<span style="margin-right:5px;" :class="scope.row.IsFollow==1?'deletesty':'editsty'"
+								@click="followContact(scope.row)"
+								>{{ scope.row.IsFollow==1?'取消关注':'关注' }}</span>
+								<span class="deletesty" @click.stop="delConcat(scope.row)">删除</span>
+								<!-- <block v-if="RoleType!='权益'&&ficcform&&['正式','试用','永续'].includes(ficcform.Status)">
+								<span 
+									class="chart" 
+									@click.stop="handleShowChartAuth(scope.row)"
+									v-if="scope.row.IsChartPermissionSetting==0"
+									style="color:#4099ef"
+								>图表权限</span>
+								<span 
+									class="chart" 
+									@click.stop="handleShowChartAuth(scope.row)"
+									v-if="scope.row.IsChartPermissionSetting==1"
+									style="color:#13ce66"
+								>图表权限</span>
+								<span 
+									class="chart" 
+									v-if="scope.row.IsChartPermissionSetting==2"
+									style="color:#bbb"
+								>图表权限</span>
+								</block> -->
+								<p v-if="isUserYanXuanButtonShow" class="editsty" @click="isOpenMfyxStatusHandler(scope.row)">{{scope.row.MfyxStatus =='试用'?'关闭研选订阅试用':'开通研选订阅试用'}} </p>
+							</div>
+						</template>
+					</el-table-column>
+					<div slot="empty" style="lineHeight:40px;margin:30px 0;color:#999;">
+						<img src="~@/assets/img/cus_m/nodata.png" alt="" style="display:block;width:160px;height:128px;margin: auto;">
+						<span>暂无联系人</span>
+					</div>
+				</el-table>
+				<el-col :span="24" class="toolbar">
+					<el-pagination 
+					layout="total,prev,pager,next,jumper" 
+					background 
+					:current-page="page_no"
+					@current-change="handleCurrentChange"
+					page-size="10"
+					:total="total"
+					style="float:right;">
+					</el-pagination>
+				</el-col>
+			</div>
+		</div>
+		<!-- 添加联系人弹窗 -->
+		<Contactdia
+		:userId="userId"
+		:name="defaultName"
+		:id="companyId"
+		:title="diatit"
+		:userForm="diaform"
+		:custom_name="diaform.companyName"
+		:isAddContact="isAddContact"
+		:regionType="regionType"
+		:isEditUser="true"
+		@cancel="canceldialog"
+		>
+		</Contactdia>
+		<!-- 阅读报告弹窗 -->
+		<Readia
+		:readId="readId"
+		:lookRead="isRead"
+		:title="readTit"
+		@cancelRead="cancelRead">
+		</Readia>
+		<!-- 图片预览 -->
+		<el-image-viewer 
+		v-if="showViewer" 
+		:on-close="closeViewer" 
+		:url-list="[imgView]" />
+		<!-- 历史签约弹窗 旧版-->
+		<!-- <el-dialog
+		:visible.sync="isPreview"
+		:modal-append-to-body='false'
+		:show-close="false"
+		custom-class="customDetail_contract_dialog"
+		center
+		top="7vh"
+		v-dialogDrag
+		width="60%">
+			<div slot="title" style="display:flex;alignItems:center;">
+				<span style="fontSize:16px;color:#333;fontWeight:bold;">历史签约</span>
+			</div>
+			<template v-if="dealList.length">
+				<div v-for="(item,index) in dealList" :key="index" class="history_item">
+					<el-tag style="margin-bottom:30px;margin-right:10px" size="small">合同编号:{{item.ContractCode}}</el-tag>
+					<div style="display:inline-block">
+						<span style="margin-right:5px;border:1px solid #409eff;padding:4px 8px;font-size:12px;color:#409eff;background:#ecf5ff;border-radius:4px">
+							{{item.ContractType}}
+						</span>
+						<el-tooltip
+							class="item" 
+							effect="dark"
+							v-if="item.ContractType!='补充协议'"
+							placement="top-start">
+								<div slot="content" v-if="item.ContractType=='新签合同'">没有正式转试用记录的客户,在申请转正时提交的合同</div>
+								<div slot="content" v-if="item.ContractType=='续约合同'">
+									1、有正式转试用记录的客户,在申请转正时提交的合同<br>
+									2、所有客户在续约申请时提交的合同
+								</div>
+								<i class="el-icon-info"></i>
+						</el-tooltip>
+					</div>
+					
+					<ul class="detail_item">
+						<li>
+							<span style="min-width:300px;marginRight:200px;display:inline-block;">合同期限:{{item.StartDate+'~'+item.EndDate}}</span>
+							<span>合同金额:{{item.Money}}元</span>
+						</li>
+						<li>
+							<span style="min-width:300px;marginRight:200px;display:inline-block;">付款方式:{{item.PayMethod}}</span>
+							<span>付款渠道:{{item.PayChannel}}</span>
+						</li>
+						<li>
+							<span style="min-width:300px;marginRight:200px;display:inline-block;">审批时间:{{item.ModifyTimeStr|formatTime}}</span>
+						</li>
+						<li class="textarea_item" style="width:97%;">
+							<label style="display:block;marginBottom:20px;fontSize:16px;position:relative;">
+								权限设置
+							</label>	
+							<ul class="menu_lists">
+								<li v-for="auth in item.PermissionList" :key="auth.ClassifyName" class="menu_item">
+									<el-checkbox :indeterminate="auth.CheckList.length>0&&auth.CheckList.length<auth.Items.length" v-model="auth.CheckAll" disabled @change="handleCheckAll(item)" style="marginRight:30px;fontWeight:bold;">{{auth.ClassifyName+':'}}</el-checkbox>
+									<el-checkbox-group v-model="auth.CheckList" @change="handleChecked(item)" disabled>
+										<el-checkbox v-for="list in auth.Items" :label="list.ChartPermissionId" :key="list.ChartPermissionId" class="list_item">{{list.PermissionName}}</el-checkbox>
+									</el-checkbox-group>
+								</li>
+							</ul>	
+						</li>
+						<li class="textarea_item" style="width:97%;display:flex" v-if="item.ImgUrl!=''">
+							<label style="marginRight:17px;fontSize:16px;position:relative;width:112px;">
+								查看合同附件
+							</label>
+							<ul class="img_cont">
+								<li v-for="img in item.constractFiles" :key="img" class="img_item" style="display:inline-block;margin-right:10px">
+									<el-image :src="require('@/assets/img/constract/word-icon.png')" style="width:240px;height:180px;" v-if="img.type=='word'" @click.native="preViewConstractFile(img)"></el-image>
+									<pdf ref="pdf" :src="img.url" style="width:240px;height:180px;overflow:hidden" v-else-if="img.type=='pdf'" @click.native="preViewConstractFile(img)"></pdf>
+									<el-image :src="img.url" :preview-src-list="constractFileImgList" alt="" style="background:#aaa;width:240px;height:180px;" v-else @click.native="preViewConstractFile(item.constractFiles)"/>
+									<i class="el-icon-zoom-in" style="position:absolute;right:12px;top:12px;color:#fff;" @click="preViewConstractFile(img)"></i>
+								</li>
+							</ul>
+						</li>
+					</ul>
+				</div>
+			</template>
+			<span v-else>暂无历史合同</span>
+		</el-dialog> -->
+		<!-- 导入的联系人表格 -->
+		<el-dialog
+		title="批量导入"
+		:visible.sync="isShowImportDia"
+		:close-on-click-modal="false"
+		:modal-append-to-body='false'
+		@close="cancelImport"
+		center
+		width="1000px">
+		
+			<template  v-if="!isImportRepeat">
+				<div style="fontSize:15px;color:#606266;marginBottom:20px;">请确认导入信息(已过滤信息不全的联系人):</div>
+				<el-table :data="importData" border max-height="350">
+					<el-table-column align="center" label="姓名">
+						<template slot-scope="scope">{{scope.row.RealName}}</template>
+					</el-table-column>
+					<el-table-column align="center" label="性别">
+						<template slot-scope="scope">{{scope.row.Sex==1?'男':scope.row.Sex==2?'女':''}}</template>
+					</el-table-column>
+					<el-table-column align="center" label="手机号">
+						<template slot-scope="scope">{{scope.row.CountryCode+'-'+scope.row.Mobile||''}}</template>
+					</el-table-column>
+					<!-- <el-table-column align="center" label="手机号2">
+						<template slot-scope="scope">{{scope.row.MobileTwo||''}}</template>
+					</el-table-column> -->
+					<el-table-column align="center" label="邮箱">
+						<template slot-scope="scope">{{scope.row.Email||''}}</template>
+					</el-table-column>
+					<el-table-column align="center" label="是否KP">
+						<template slot-scope="scope">{{scope.row.IsMaker==1?'是':'否'}}</template>
+					</el-table-column>
+					<el-table-column align="center" label="职位">
+						<template slot-scope="scope">{{scope.row.Position||''}}</template>
+					</el-table-column>
+					<el-table-column align="center" label="部门">
+						<template slot-scope="scope">{{scope.row.DepartmentName||''}}</template>
+					</el-table-column>
+				</el-table>
+			</template>
+			<!-- 重复联系人 -->
+			<template v-else>
+				<div style="font-size:16px;color:#606266;margin-bottom:10px">导入完成。</div>
+				<div style="fontSize:16px;color:#606266;marginBottom:20px;">请单独处理以下系统中已存在的联系人:</div>
+				<el-table :data="repeatData" border max-height="300">
+					<el-table-column align="center" label="联系人">
+						<template slot-scope="scope">{{scope.row.RealName}}</template>
+					</el-table-column>
+					<el-table-column  align="center" label="手机号/邮箱" width="300">
+						<template slot-scope="scope">
+							{{scope.row.Mobile}} 
+							{{(scope.row.Mobile&&scope.row.Email)?'/':''}}
+							{{scope.row.Email}}
+						</template>
+					</el-table-column>
+					<el-table-column align="center" label="销售">
+						<template slot-scope="scope">{{scope.row.SellerRealName}}</template>
+					</el-table-column>
+					<el-table-column align="center" label="关联客户" min-width="150">
+						<template slot-scope="scope">{{scope.row.CompanyName}}</template>
+					</el-table-column>
+					<el-table-column align="center" label="操作">
+						<template slot-scope="scope">
+							<el-button type="text" size="small" @click="handleMoveToCurrentCustom(scope.row,scope.$index)" v-if="scope.row.HasMove">移至当前客户</el-button>
+						</template>
+					</el-table-column>
+				</el-table>
+				<p style="padding:20px 0;font-size:16px;">无法移至当前客户的联系人,请联系对应销售处理。</p>
+			</template>
+			
+			<div style="display:flex;justify-content:center;margin:30px 0">
+				<template  v-if="!isImportRepeat">
+					<el-button type="primary" style="marginRight:24px;" @click="ensureImport">确定</el-button>
+					<el-button  type="primary" plain style="width:80px;" @click="cancelImport">取消</el-button>
+				</template>
+				<el-button type="primary" style="width:100px;" v-else @click="cancelImport(1)">知道了</el-button>
+			</div>
+		</el-dialog>
+
+		<!-- 移动联系人弹窗 -->
+		<el-dialog
+			title="提示"
+			:visible.sync="isMove"
+			:close-on-click-modal="false"
+			:modal-append-to-body="false"
+			@close="cancelMove"
+			center
+			top="25vh"
+			width="500px">
+			<div slot="title" style="display: flex; align-items: center; position: relative">
+				<img
+					src="../../../assets/img/icons/move.png"
+					style="color: #fff; width: 16px; height: 16px; margin-right: 5px"/>
+				<span style="font-size: 16px">移动联系人</span>
+				<i
+					class="el-icon-close"
+					style="
+						font-size: 24px;
+						cursor: pointer;
+						position: absolute;
+						right: 20px;
+						top: 50%;
+						transform: translateY(-50%);
+					"
+					@click="cancelMove"
+				></i>
+			</div>
+			<el-form
+				@submit.native.prevent
+				:model="moveForm"
+				ref="moveFormvalidate"
+				inline
+				:rules="moveRule"
+				label-width="80px"
+				class="demo-ruleForm"
+				style="margin-top: 15px">
+				<el-form-item
+					label="移动到"
+					prop="companyId"
+					style="width: 100%">
+					<el-select
+						v-model="moveForm.companyId"
+						filterable
+						remote
+						:remote-method="getCompany"
+						@focus="focusGetCompany"
+						@change="getCompanySeller"
+						placeholder="请选择公司"
+						style="width: 280px">
+						<el-option
+							v-for="item in typeArr"
+							:key="item.CompanyId"
+							:label="item.CompanyName"
+							:value="item.CompanyId">
+						</el-option>
+					</el-select>
+				</el-form-item>
+				<el-form-item
+					label="所属销售"
+					prop="belongUser"
+					style="width: 100%"
+					v-if="!hideBelongUser">
+					<el-select
+						v-model="moveForm.belongUser"
+						placeholder="请选择对应销售"
+						style="width: 280px">
+						<el-option
+							v-for="item in belongList"
+							:key="item.AdminId"
+							:label="item.RealName"
+							:value="item.AdminId">
+						</el-option>
+					</el-select>
+				</el-form-item>
+				<div v-if="isMoveShowTips&&ficcform&&['正式','试用','永续'].includes(ficcform.Status)" style="text-align:center;color:#999">提示:移动联系人会关闭该联系人的图表权限</div>
+				<div style="display: flex; justify-content: center; margin: 30px 0 55px">
+					<el-button type="primary" @click="submitMove">保存</el-button>
+					<el-button @click="cancelMove">取消</el-button>
+				</div>
+			</el-form>
+		</el-dialog>
+
+		<!-- 设置图库权限弹窗 -->
+		<chartAuthDialog
+			:chartAuthClassifyList="chartAuthClassifyList"
+			:chartAuthUserInfo="chartAuthUserInfo"
+			:showChartAuthPop="showChartAuthPop"
+			@chartAuthClose="showChartAuthPop=false"
+			@chartAuthSave="chartAuthSave"
+		></chartAuthDialog>
+		<export-data  :exportDataIsShow.sync="exportDataIsShow" :companyId="companyId"/>
+    	<!-- 分产品阅读统计弹窗 -->
+		<product-read-info
+		:productReadInfoShow="productReadInfoShow"
+		:productReadId="productReadId"
+		:subProductId="platform_type"
+		:subProductName="subProductName"
+		:clickToal="clickToal"
+		:productReadTitle="productReadTitle"
+		@close="productReadInfoShow=false"
+		></product-read-info>
+		<!-- 研选服务点数明细 弹框 -->
+
+		<DeductDetailDlg :isShowResearchNumber.sync="isShowResearchNumber" :isShowDlgType.sync="isShowDlgType" :dataForm="raiform"/>
+		<!-- 历史签约弹窗 新版 -->
+		<HistoryContract 
+			:isPreview="isPreview"
+			:dealList="dealList"
+			@close="isPreview=false"
+		/>
+	</div>
+</template>
+<style lang='scss' scoped>
+.contact-opt-box{
+	.chart{
+		display: inline-block;
+		cursor: pointer;
+		margin-left: 5px;
+	}
+}
+.el-icon-arrow-right:before{
+	color: #1989FA;
+}
+:deep(.el-message-box__header .el-message-box__title){
+	color: #333 !important;
+}
+.page-title{
+	font-size: 16px;
+	font-weight: bold;
+	color: #333;
+	height: 40px;
+	line-height: 40px;
+	padding-left: 10px;
+	background: #F0F2F5;
+	margin-bottom: 40px;
+}
+
+.customDetail_container {
+	.isShared::after{
+		content: '共享';
+		font-size: 12px;
+		// padding: 0px 0px 0px 2px;
+		width: 30px;
+		color: #3994fb;
+		background-color: #dcecfc;
+		position: absolute;
+		left: 0;
+		bottom: 0;
+		border-top-right-radius: 5px;
+	}
+	padding:30px 40px 60px 60px;
+	background: #fff;
+	position: relative;
+	border: 1px solid #ECECEC;
+	border-radius: 4px;
+	box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+	font-size: 16px;
+	color: #666;
+	/* reset */
+	.el-form-item {
+		margin-bottom: 30px;
+		&:last-child {
+			margin-bottom: 0;
+		}
+	}
+	.el-collapse {
+		border: none;
+	}
+	:deep(.el-collapse-item__header) {
+		display: block;
+		border: none;
+		font-size: 16px;
+		color: #333;
+	}
+	:deep(.el-collapse-item__wrap) {
+		border: none;
+	}
+	:deep(.textarea_item .el-form-item__content) {
+		width: 100%;
+	}
+	:deep(.el-form-item .el-checkbox-group) {
+		height: 40px;
+		line-height: 40px;
+	}
+	:deep(.distpicker-address-wrapper select) {
+		width: 198px;
+	}
+	/*  */
+	.detail_item {
+		display: flex;
+		align-items: center;
+		flex-wrap: wrap;
+		margin-bottom: 40px;
+		li {
+			width: 33%;
+			color: #666;
+			margin-bottom: 30px;
+			font-size: 15px;
+			display: flex;
+			.label{
+				display: inline-block;
+				width: 80px;
+				text-align: right;
+				margin-right: 30px;
+				flex-shrink: 0;
+			}
+			.label-num {
+				flex-shrink: 0;
+				margin-right: 30px;
+			}
+			.con{
+				display: inline-block;
+				color: #333;
+				// font-weight: bold;
+			}
+		}
+	}
+	.menu_lists {
+		padding: 40px 18px;
+		border: 1px dashed #AAB4CC;
+		border-radius: 4px;
+		.menu_item {
+			display: flex;
+			// align-items: center;
+			margin-bottom: 30px;
+			&:last-child {
+				margin-bottom: 0;
+			}
+			.list_item {
+				margin-right: 30px;
+				margin-bottom: 10px;
+				&:last-child {
+					margin-right: 0;
+				}
+			}
+		}
+	}
+	.customList_bot_top {
+		display: flex;
+		justify-content: space-between;
+		align-items: center;
+		margin-bottom: 28px;
+	}
+	.name-follow-heart{
+		width:25px;
+		height: 15px;
+		position: absolute;
+		left: 0;
+    top: 0;
+	}
+	.not-read-seven-days{
+		background-color: #FFF8F8;
+	}
+}
+.customDetail_contract_dialog {
+	max-height: 810px;
+	min-height: 200px;
+	overflow-y: auto;
+	.el-dialog__header {
+		background: #fff;
+	}
+	.el-dialog__body {
+		padding: 30px 50px !important;
+	}
+	.history_item {
+		margin-bottom: 60px;
+		.detail_item {
+			font-size: 16px;
+			color: #666;
+			li {
+				margin-bottom: 30px;
+				&:last-child {
+					margin-bottom: 0;
+				}
+			}
+		}
+	}
+	.menu_lists {
+		padding: 20px 18px;
+		border: 1px dashed #AAB4CC;
+		border-radius: 4px;
+		.menu_item {
+			display: flex;
+			// align-items: center;
+			margin-bottom: 20px;
+			&:last-child {
+				margin-bottom: 0;
+			}
+			.list_item {
+				margin-right: 30px;
+				margin-bottom: 5px;
+				&:last-child {
+					margin-right: 0;
+				}
+			}
+		}
+	}
+}
+</style>

+ 392 - 489
src/views/custom_manage/custom/customSearch.vue

@@ -1,32 +1,101 @@
+<script>
+import { defineComponent, } from 'vue'
+export default defineComponent({
+  //进入前是否清除参数
+  beforeRouteEnter(to, from, next) {
+    if(!['/editCustom','/turnCustom','/updateCustom','/pickCustom','/customDetail'].includes(from.path)) {
+      sessionStorage.removeItem('customSearchBack')
+    }
+    
+		next()
+  }
+})
+</script>
+
 <script setup>
 import { ref,computed,reactive,onBeforeMount } from "vue";
 import { customInterence } from '@/api/api.js'
-import { useRouter } from 'vue-router'
+import { useRouter,onBeforeRouteLeave, useRoute } from 'vue-router'
 import { Search,MoreFilled } from '@element-plus/icons-vue'
 import { ElMessageBox,ElMessage } from 'element-plus'
+import { useViewPermissionDia,useLookTrialDia,useCommunicaRecordDia,useChooseContractDia,useList,useAddTrialDia,useViewRemarkCustomDia,useCompleteInfoDia,useFreezeReasonDia } from "./hooks/customlistHook";
 import mPage from '@/components/mPage.vue'
+import permissionView from './components/premissionView.vue'
+import Capplydia from './components/Capplydialog.vue'
+import Contactdia from './components/Contactdialog.vue'
+import Cauthlist from './components/CauthList.vue'
+import CompleteInfo from './components/CompleteInfo.vue'
+import ContractInfo from './components/ContractInfo.vue'
+import PermissionDetail from './components/permissionDetail.vue'
+
+onBeforeRouteLeave(() => {
+  let backData = {
+    keyword:search_txt.value,
+    page:pageinfo.page_no
+  }
+  sessionStorage.setItem('customSearchBack',JSON.stringify(backData))
+})
 
 const $router = useRouter()
+const $route = useRoute()
 
-const Role = computed(() => {
-  let role = localStorage.getItem('Role') || '';
-  return role;
-})
-const RaiSellerRole = computed(() => {
-  return ['rai_seller','rai_admin','admin'].includes(Role)
-})
-const RoleType = computed(() => {
-  let type = localStorage.getItem('RoleType') || '';
-  return type;
-})
-const RoleIdentity = computed(() => {
-  let role = localStorage.getItem('RoleIdentity') || '';
-  return role;
-})
-const SellerAdminId = computed(() => {
-  let type = localStorage.getItem('AdminId') || '';
-  return type;
-})
+
+const { 
+  suspendHandle,
+  editHandle,
+  Role,
+  RaiSellerRole,
+  RoleType,
+  RoleIdentity,
+  SellerAdminId,
+} = useList();
+
+const { 
+  isLook,
+  lookTitle,
+  lookAuthList,
+  lookAuthListEquity,
+  lookHandle,
+  closeDia
+} = useViewPermissionDia();//查看权限弹窗
+
+
+const {
+  isAddTrial,
+  addTryId,
+  addTrialHandle,
+  closeAddTrial
+} = useAddTrialDia();//增开试用弹窗
+
+const {
+  lookRemarkTitle,
+  lookRemarkList,
+  lookRemarkTextarea,
+  isRemarkLook,
+  lookRemarkItem,
+  lookRemarkDelete,
+  closeRemark,
+  lookRemarkHandle
+} = useViewRemarkCustomDia();//查看备注弹窗
+
+
+function init() {
+  /* 返回保持上次的状态 */
+  if(sessionStorage.getItem('customSearchBack')) {
+    let backData = JSON.parse(sessionStorage.getItem('customSearchBack'));
+    search_txt.value = backData.keyword;
+    pageinfo.page_no=backData.page
+    getTableData()
+  }
+  getSale();
+
+
+  search_txt.value= $route.query.name ? $route.query.name:  $route.query.code?$route.query.code : ''
+		if(search_txt.value){
+			getTableData()
+		}
+}
+init()
 
 
 /* 获取表格数据 */
@@ -209,111 +278,35 @@ function itemclickHandle(query) {
 }
 
 
-const completeForm = ref({
-  show:false,
-})//补全信息弹窗
-//获取客户详情判断基本信息是否完整 id 客户id type 1 跨部门 0 不是跨部门
-async function getCustomerDetail(id,type){
-  
-  let res=await customInterence.customDetail({
-    CompanyId:id
-  })
-  if(res.Ret!=200) return
-
-  // 跨部门领取
-  if(type===1){
-    if((res.Data.Item.RegionType!='海外'&&!res.Data.Item.Province&&!res.Data.Item.City)||!res.Data.Item.CreditCode){
-
-      completeForm.value={
-        CompanyId:id,
-        name:res.Data.Item.CompanyName,
-        nameDisable:res.Data.Item.CompanyName!='',
-        Province:res.Data.Item.Province,
-        City:res.Data.Item.City,
-        CityDisable:res.Data.Item.City!='',
-        CreditCode:res.Data.Item.CreditCode,
-        CreditCodeDisable:res.Data.Item.CreditCode!='',
-        RegionType:res.Data.Item.RegionType,
-        
-        flag:true,//是否为跨部门
-        show:true
-      }
-    }else{
-      completeForm.value.show=false
-    }
-  }else{
-    let RoleType=RoleType.value
-    let IndustryId='',Source=';'
-    if(RoleType=='ficc'){
-      IndustryId=res.Data.FiccItem.IndustryId
-      Source=res.Data.FiccItem.Source
-    }else if(RoleType=='权益'){
-      IndustryId=res.Data.RaiItem.IndustryId
-      Source=res.Data.RaiItem.Source
-    }
-    // let IndustryId=res.Data.CreateAuth == 1?res.Data.FiccItem.IndustryId:res.Data.RaiItem.IndustryId
-    // let Source=res.Data.CreateAuth == 1?res.Data.FiccItem.Source:res.Data.RaiItem.Source
-    if((res.Data.Item.RegionType!='海外'&&!res.Data.Item.Province&&!res.Data.Item.City)||!res.Data.Item.CreditCode||!IndustryId||!Source){
-      completeForm.value={
-        nameDisable:res.Data.Item.CompanyName!='',
-        CityDisable:res.Data.Item.City!='',
-        CreditCodeDisable:res.Data.Item.CreditCode!='',
-        IndustryIdDisable:IndustryId!=' ',
-        SourceDisable:Source!='',
-        CompanyId:id,
-        name:res.Data.Item.CompanyName,
-        Province:res.Data.Item.Province,
-        City:res.Data.Item.City,
-        CreditCode:res.Data.Item.CreditCode,
-        IndustryId:IndustryId?IndustryId:'',
-        Source:Source,
-        RegionType:res.Data.Item.RegionType,
-        flag:false,//是否为跨部门
-        show:true
-      }
-    }else{
-      completeForm.value.show=false
-    }
+const {
+  completeForm,
+  getCustomerDetail,
+  closeCompleteInfo
+} = useCompleteInfoDia();//补全信息弹窗
+//关闭补全信息弹窗
+function cancelCompleteInfo(refresh){
+  // 刷新列表
+  if(refresh){
+    getTableData()
   }
-
-  return new Promise((resolve,reject)=>{
-    resolve(completeForm.value.show)
-  })
-    
+  closeCompleteInfo()
 }
 
 
-/* 申请转正 */
-const contractModel = reactive({
-  show:true,
-  data:null,//客户信息(列表用户数据)
-	type:'',//类型 申请转正、续约申请、补充协议
-})
-async function applyTurn(item) {
-  //判断是否需要补全信息
-  let flag=await getCustomerDetail(item.CompanyId,0) 
-  if(flag) return
-  contractModel.show=true
-  contractModel.data=item
-  contractModel.type='申请转正'
-}
-/* 续约申请操作 */
-async function updateHandle(item) {
-  //判断是否需要补全信息
-  let flag = await getCustomerDetail(item.CompanyId)
-  if(flag) return
-  contractModel.show=true
-  contractModel.data=item
-  contractModel.type='续约申请'
-}
-// 补充协议
-async function addAgreement(item) {
-  //判断是否需要补全信息
-  let flag = await getCustomerDetail(item.CompanyId)
-  if(flag) return
-  contractModel.show=true
-  contractModel.data=item
-  contractModel.type='补充协议'
+const { 
+  contractModel,
+	applyTurn,
+	updateHandle,
+	addAgreement,
+	handleContractModel,
+	contractDialog,
+  closeContractInfoDia
+} = useChooseContractDia();//选择合同弹窗
+function contractInfoDialogClose(e){
+  closeContractInfoDia()
+  if(e==='updateList'){
+    getTableData();
+  }
 }
 
 
@@ -322,6 +315,7 @@ async function addAgreement(item) {
 const isApply = ref(false)//申请弹窗
 const applyForm = ref({})//客户信息
 const applyTit = ref('')
+const isShowclose = ref(false)//联系人弹窗时记录是否是领取流失客户
 const isPickLoss = ref(false)//联系人弹窗时记录是否是领取流失客户
 const	isPickSelf = ref(false)//是否为领取自己的流失客户
 const regionType = ref("")
@@ -400,6 +394,37 @@ async function receiveHandle(item) {
       isAddContact.value = true;
   }).catch(() => {});
 }
+/* 领取流失客户添加联系人后再领取 */
+function cancelConcatdia(type) {
+  isAddContact.value = false;
+  isPickSelf.value=false
+  if(type == 1) {
+    customInterence.Pick({
+      CompanyId:addCompanyId.value,
+    }).then(res => {
+      if(res.Ret === 200) {
+        ElMessage.success(res.Msg);
+        getTableData();
+      }
+    })
+  }else {
+    ElMessage.warning('领取失败')
+  }
+}
+function cancelHandle(type) {
+  isApply.value = false;
+  applyForm.value = {}
+  if(type == 1) {
+    getTableData();
+  }
+}
+// 领取自己的流失客户下一步申请操作
+const contactFormData = ref({})
+function addContactNext({formData}){
+  contactFormData.value=formData
+  isAddContact.value=false
+  isApply.value=true
+}
 
 
 /* 修改销售操作 */
@@ -415,6 +440,7 @@ const moveRule = {
     { required: true, message: '所属销售不能为空', trigger: 'blur' },
   ]
 }
+const moveformRef = ref(null)
 function updateSale(item) {
   moveform.value = {
     companyType:item.CompanyType,
@@ -425,6 +451,30 @@ function updateSale(item) {
   handleModifysalesArr(item.SellerId)
   isMove.value = true;
 }
+/* 移动客户所属销售 */
+function saveMove() {
+  moveform.value.validate((valid) => {
+    if (valid) {
+      customInterence.moveSale({
+        CompanyType:moveform.companyType,
+        CompanyId:moveform.companyId,
+        SellsId:Number(moveform.sale[1])||Number(moveform.sale[2])
+      }).then(res => {
+        if(res.Ret === 200) {
+          ElMessage.success(res.Msg);
+          getTableData();
+          isMove.value = false;
+        }
+      })
+    }
+  })		
+}
+/* 取消移动客户 */
+function cancelMove() {
+  moveformRef.value.resetFields();
+  isMove.value = false;
+}
+
 const salesArr = ref([])//修改销售时可选择的数据
 // 处理修改销售数据 不可以修改到已存在销售
 function handleModifysalesArr(id){
@@ -450,34 +500,31 @@ function getSale() {
     }
   })
 }
-getSale();
 
 
-/* 启用/暂停 */
-function suspendHandle(item) {
-  customInterence.Suspend({
-    CompanyId:item.CompanyId
-  }).then(res => {
-    if(res.Ret === 200) {
-      ElMessage.success(res.Msg);
-      item.IsSuspend = item.IsSuspend === 1 ? 0 : 1;
-    }
-  })
-}
-
 
 /* 冻结客户 */
-const isFreezeReason = ref(false)//冻结理由弹窗
-const freezeData = ref({
-  reason:"",//冻结理由
-  CompanyId:'',
-  CompanyType:""
-})
-function freezHandle(item) {
-  isFreezeReason.value = true
-  freezeData.value.CompanyId=item.CompanyId
-  let RoleType=localStorage.getItem('RoleType')
-  freezeData.value.CompanyType=RoleType
+const {
+  isFreezeReason,
+  freezeData,
+  freezHandle,
+  closeFreezeReason
+} = useFreezeReasonDia();//冻结客户理由弹窗
+async function  handleConfirmFreeze(){
+  if(!freezeData.value.reason){
+    ElMessage.error('请填写冻结理由')
+    return
+  }
+  let res=await customInterence.Freez({
+    CompanyId:Number(freezeData.value.CompanyId),
+    CompanyType:freezeData.value.CompanyType,
+    Remark:freezeData.value.reason
+  })
+  if(res.Ret===200){
+    ElMessage.success('冻结成功');
+    closeFreezeReason()
+    getTableData();
+  }
 }
 
 
@@ -496,217 +543,6 @@ async function receiveOtherHandle(item) {
 }
 
 
-/* 增加试用 */
-const isAddTrial = ref(false)//增加试用弹窗
-const addTryId = ref('')//增开试用的id
-function addTrialHandle(item) {
-  authList.value = [];
-  customInterence.lookauth({
-    CompanyId:item.CompanyId,
-    LookType:1
-  }).then(res => {
-    if(res.Ret === 200) {
-      let auth = [];
-      // res.Data.List 有值为 ficc
-      // res.Data.ListRai 有值为 权益
-      if(res.Data.List) {
-        res.Data.List.forEach(item=> {
-          let obj = {
-            checkAll:item.CheckList&&item.CheckList.length===item.Items.length?true:false,
-            isIndeterminate:item.CheckList&&item.CheckList.length>0 && item.CheckList.length<item.Items.length,
-            defaultAuth:item.CheckList,
-            customType:'ficc',
-            ...item,
-          }
-          auth.push(obj)
-        })
-      }else if(res.Data.ListRai) {
-        auth = filterRaiAuth(res.Data.ListRai,auth)
-
-      }
-     
-      authList = auth;
-    }
-  })
-  addTryId.value = item.CompanyId;
-  isAddTrial.value = true;
-}
-function filterRaiAuth(data,auth) {
-     // 权益 RaiMerge 0不管 1合并 2拆分 所传入的数据结构不一样
-    data[0].RaiMerge==1
-      ? data.forEach(item=> { // 合并
-          let obj = {
-            checkAll:item.CheckList&&item.CheckList.length===item.Items.length?true:false,
-            isIndeterminate:item.CheckList&&item.CheckList.length>0 && item.CheckList.length<item.Items.length,
-            defaultAuth:item.CheckList,
-            ...item,
-          }
-          auth.push(obj)
-        })
-      : data.forEach(item=> { // 拆分
-          let obj = {
-            defaultAuth:item.CheckList,
-            customType:'权益',
-            ...item,
-          }	
-          // 组合所需的数据格式
-          obj.dataList=[
-            {
-              PermissionTypeName:'',
-              medicine:{
-                value:'医药',
-                isIndeterminate:item.CheckList.filter(id => [obj.Items[0].ChartPermissionId,obj.Items[1].ChartPermissionId].includes(id)).length ==1,
-                isCheckAll:item.CheckList.filter(id => [obj.Items[0].ChartPermissionId,obj.Items[1].ChartPermissionId].includes(id)).length == 2,
-                isDisabled:item.CheckList.filter(id => [obj.Items[0].ChartPermissionId,obj.Items[1].ChartPermissionId].includes(id)).length ==2
-              },
-              consumption:{
-                value:'消费',
-                isIndeterminate:item.CheckList.filter(id => [obj.Items[2].ChartPermissionId,obj.Items[3].ChartPermissionId].includes(id)).length ==1,
-                isCheckAll:item.CheckList.filter(id => [obj.Items[2].ChartPermissionId,obj.Items[3].ChartPermissionId].includes(id)).length == 2,
-                isDisabled:item.CheckList.filter(id => [obj.Items[2].ChartPermissionId,obj.Items[3].ChartPermissionId].includes(id)).length ==2
-              },
-              technology:{
-                value:'科技',
-                isIndeterminate:item.CheckList.filter(id => [obj.Items[4].ChartPermissionId,obj.Items[5].ChartPermissionId].includes(id)).length ==1,
-                isCheckAll:item.CheckList.filter(id => [obj.Items[4].ChartPermissionId,obj.Items[5].ChartPermissionId].includes(id)).length == 2,
-                isDisabled:item.CheckList.filter(id => [obj.Items[4].ChartPermissionId,obj.Items[5].ChartPermissionId].includes(id)).length ==2
-              },
-              smart:{
-                value:'智造',
-                isIndeterminate:item.CheckList.filter(id => [obj.Items[6].ChartPermissionId,obj.Items[7].ChartPermissionId].includes(id)).length ==1,
-                isCheckAll:item.CheckList.filter(id => [obj.Items[6].ChartPermissionId,obj.Items[7].ChartPermissionId].includes(id)).length == 2,
-                isDisabled:item.CheckList.filter(id => [obj.Items[6].ChartPermissionId,obj.Items[7].ChartPermissionId].includes(id)).length ==2
-              },
-              strategy:{
-                value:'策略'
-              },
-              experts:{
-                value:'专家'
-              },
-              roadshow:{
-                value:'路演服务'
-              },
-              choose:{
-                value:'研选订阅'
-              },
-              points:{
-                value:'研选扣点包'
-              },
-            },
-            {
-              PermissionTypeName:{
-                value:'主观',
-                isIndeterminate:[1,2,3].includes(item.CheckList.filter(id => [obj.Items[0].ChartPermissionId,obj.Items[2].ChartPermissionId,
-                  obj.Items[4].ChartPermissionId,obj.Items[6].ChartPermissionId].includes(id)).length),
-                isCheckAll:item.CheckList.filter(id => [obj.Items[0].ChartPermissionId,obj.Items[2].ChartPermissionId,
-                  obj.Items[4].ChartPermissionId,obj.Items[6].ChartPermissionId].includes(id)).length == 4,
-                isDisabled:item.CheckList.filter(id => [obj.Items[0].ChartPermissionId,obj.Items[2].ChartPermissionId,
-                  obj.Items[4].ChartPermissionId,obj.Items[6].ChartPermissionId].includes(id)).length ==4
-              },
-              medicine:{
-                value:obj.Items[0].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[0].ChartPermissionId)
-              },
-              consumption:{
-                value:obj.Items[2].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[2].ChartPermissionId)
-              },
-              technology:{
-                value:obj.Items[4].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[4].ChartPermissionId)
-              },
-              smart:{
-                value:obj.Items[6].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[6].ChartPermissionId)
-              },
-              strategy:{
-                value:obj.Items[8].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[8].ChartPermissionId)
-              },
-              experts:{
-                value:obj.Items[9].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[9].ChartPermissionId)
-              },
-              roadshow:{
-                value:obj.Items[10].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[10].ChartPermissionId)
-              },
-              choose:{
-                value:obj.Items[11].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[11].ChartPermissionId)
-              },
-              points:{
-                value:obj.Items[12].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[12].ChartPermissionId)
-              }
-            },
-            {
-              PermissionTypeName:{
-                value:'客观',
-                isIndeterminate:[1,2,3].includes(item.CheckList.filter(id => [obj.Items[1].ChartPermissionId,obj.Items[3].ChartPermissionId,
-                  obj.Items[5].ChartPermissionId,obj.Items[7].ChartPermissionId].includes(id)).length),
-                isCheckAll:item.CheckList.filter(id => [obj.Items[1].ChartPermissionId,obj.Items[3].ChartPermissionId,
-                  obj.Items[5].ChartPermissionId,obj.Items[7].ChartPermissionId].includes(id)).length == 4,
-                isDisabled:item.CheckList.filter(id => [obj.Items[1].ChartPermissionId,obj.Items[3].ChartPermissionId,
-                  obj.Items[5].ChartPermissionId,obj.Items[7].ChartPermissionId].includes(id)).length ==4
-              },
-              medicine:{
-                value:obj.Items[1].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[1].ChartPermissionId)
-              },
-              consumption:{
-                value:obj.Items[3].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[3].ChartPermissionId)
-              },
-              technology:{
-                value:obj.Items[5].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[5].ChartPermissionId)
-              },
-              smart:{
-                value:obj.Items[7].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[7].ChartPermissionId)
-              },
-              strategy:{
-                value:obj.Items[8].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[8].ChartPermissionId)
-              },
-              experts:{
-                value:obj.Items[9].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[9].ChartPermissionId)
-              },
-              roadshow:{
-                value:obj.Items[10].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[10].ChartPermissionId)
-              },
-              choose:{
-                value:obj.Items[11].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[11].ChartPermissionId)
-              },
-              points:{
-                value:obj.Items[12].ChartPermissionId,
-                isDisabled:item.CheckList.includes(obj.Items[12].ChartPermissionId)
-              }
-            }
-          ]
-
-          auth.push(obj)
-        })
-        
-    return auth
-}
-
-
-/* 编辑客户 */
-function editHandle(item) {
-  $router.push({
-    path:'/editCustom',
-    query:{
-      id:item.CompanyId
-    }
-  })
-}
-
-
 /* 删除 */
 function delHandle(item) {
   ElMessageBox.confirm('删除后客户将不能查阅报告,确定删除吗?','提示',{
@@ -725,133 +561,6 @@ function delHandle(item) {
 }
 
 
-/* 查看权限 */
-const isLook = ref(false)//权限弹窗
-const authList = ref([])
-const lookAuthList = ref([])//查看的权限
-const lookAuthListEquity = ref([])
-const isPermissionTypeShow = ref(false)
-function lookHandle(item) {
-  authList.value = [];
-  lookAuthList.value = [];
-  customInterence.lookauth({
-    CompanyId:item.CompanyId
-  }).then(res => {
-    if(res.Ret === 200) {
-    let auth = [];			
-      res.Data.List ?	res.Data.List.forEach(item=> { 
-        auth.push(item.Items)
-      }):''
-      lookAuthList.value = auth.flat(Infinity);
-      getRowSpan();
-      let authEquity =[] //权益
-      res.Data.ListRai ?	res.Data.ListRai.forEach(item=> {//权益
-        // 过滤没有权限的套餐
-        authEquity.push(item.Items.filter(it => item.CheckList.includes(it.ChartPermissionId)))
-      }):''
-      lookAuthListEquity.value = authEquity.flat(Infinity) //权益
-      isPermissionTypeShow.value = lookAuthListEquity.value.some(item => !item.IsMerge)
-      
-      getSpanArr(lookAuthListEquity.value) //权益
-    }
-  })
-  isLook.value = true;
-}
-
-/* 权益处理数据 */
-const indexArrEquity = ref([])//权益
-const spanArrEquity = ref([]);
-const posEquity = ref(0)
-function getSpanArr(data) {
-  data.map((v, i, s) => {
-    if (!v.PermissionTypeName) {
-      indexArrEquity.value.push(i);
-    }
-  });
-  for (var i = 0; i < data.length; i++) {
-    let element = data[i]
-    if (i === 0) {
-      spanArrEquity.value.push(1);
-      posEquity.value = 0;
-    } else {
-      // 判断当前元素与上一个元素是否相同(line为标记)
-      if (element.PermissionName === data[i - 1].PermissionName) {
-        if(element.IsMerge){
-          // 主客观都有,需要合并
-          spanArrEquity.value[posEquity.value] += 1;
-          spanArrEquity.value.push(0);
-        }else{
-          // 主客观都有 不需要合并,说明是服务期限或者状态不一样
-          spanArrEquity.value[posEquity.value] += 0.5;
-          spanArrEquity.value.push(0.5);
-        }
-      } else {
-        spanArrEquity.value.push(1);
-        posEquity.value = i;
-      }
-    }
-  }
-  // console.log(this.indexArrEquity,this.spanArrEquity);
-}
-
-/* 处理合并数组 */
-const rowSpanArr = ref([])
-const position = ref(0)
-function getRowSpan() {
-  rowSpanArr.value = [];
-  /* [2,0,1] */
-  lookAuthList.value.forEach((item, index) => {
-    if (index === 0) {
-      rowSpanArr.value.push(1);
-      position.value = 0;
-    } else {
-      if (lookAuthList.value[index].ClassifyName === lookAuthList.value[index - 1].ClassifyName) {
-        rowSpanArr.value[position.value] += 1; //项目名称相同,合并到同一个数组中
-        rowSpanArr.value.push(0);
-        lookAuthList.value[index].ClassifyName = lookAuthList.value[index - 1].ClassifyName;
-      } else {
-        rowSpanArr.value.push(1);
-        position.value = index;
-      }
-    }
-  });
-}
-/* 合并行规则 */
-function objectSpanMethod({ row, column, rowIndex, columnIndex }) {
-  if (columnIndex === 0) {
-    const _row = this.rowSpanArr[rowIndex];
-      return {
-        rowspan: _row,
-        colspan: 1
-      };
-  }
-}
-
-
-/* 查看备注 */
-const lookRemarkTitle = ref('')//查看备注标题
-const	lookRemarkList = ref([])//查看备注列表
-const	lookRemarkTextarea = ref('')//备注的文本框
-const	isRemarkLook = ref(false)////查看备注弹窗
-const	lookRemarkItem = ref({})////查看备注的item项
-function lookRemarkHandle(item) {
-  /*
-  lookRemarkTitle:'',//查看备注标题
-  lookRemarkList:[],//查看备注列表
-  */
-  lookRemarkTitle.value = "备注";
-  lookAuthList.value = [];
-  lookRemarkItem.value = item;
-  customInterence.lookRemarkAuth({
-    CompanyId:item.CompanyId
-  }).then(res => {
-    if(res.Ret === 200) {
-      lookRemarkList.value=res.Data;
-    }
-  })
-  isRemarkLook.value = true;
-}
-
 const isPermissionDetailShow = ref(false)// 权限详情 弹框
 const	researchDetailId = ref(0)
 function researchDetailHandle(item) {
@@ -859,12 +568,6 @@ function researchDetailHandle(item) {
   researchDetailId.value = item.CompanyId
 }
 
-
-
-function handleContractModel() {
-
-}
-
 </script>
 <template>
   <div class="customSearch_container">
@@ -1062,6 +765,206 @@ function handleContractModel() {
         />
       </el-col>
     </div>
+
+    <!-- 申请弹窗 -->
+		<Capplydia 
+		:isApply="isApply"
+		:title="applyTit"
+		:formdata="applyForm"
+		:contactFormData="contactFormData"
+		@cancelHandle="cancelHandle">
+		</Capplydia>
+
+    <!-- 查看权限弹窗 -->
+    <permissionView
+      :isLook="isLook"
+      :lookTitle="lookTitle"
+      :lookAuthList="lookAuthList"
+      :lookAuthListEquity="lookAuthListEquity"
+      @closeDia="closeDia"
+    ></permissionView>
+
+    <!-- 增开试用弹窗 -->
+		<el-dialog
+		v-model="isAddTrial"
+		:close-on-click-modal="false"
+		:modal-append-to-body='false'
+		@close="closeAddTrial"
+		width="800px"
+		center>
+      <template #header>
+        <div style="display:flex;alignItems:center;">
+          <span style="fontSize:16px;">增开试用</span>
+        </div>
+      </template>
+			<Cauthlist
+			:autharr="authList"
+			:id="addTryId"
+			@addOver="addTryOver"
+			@close="closeAddTrial"/>
+		</el-dialog>
+
+    <!-- 移动客户弹窗 -->
+		<el-dialog
+		v-model="isMove"
+		:close-on-click-modal="false"
+		:modal-append-to-body='false'
+		@close="cancelMove"
+		center
+		width="30%">
+      <template #header>
+        <div style="display:flex;align-items:center;">
+          <img :src="$icons.edit" style="color:#fff;width:16px;height:16px;margin-right:5px;">
+          <span style="fontSize:16px;">修改销售</span>
+        </div>
+      </template>
+
+			<el-form :model="moveform" :rules="moveRule" ref="moveform" label-width="100px" style="marginTop:15px;">
+				<el-form-item label="客户名称" prop="name">
+					<span style="fontSize:16px;">{{moveform.companyName}}</span>
+				</el-form-item>
+				<el-form-item label="所属销售" prop="sale">
+					<el-cascader
+						v-model="moveform.sale"
+						placeholder="请选择修改的销售"
+						style="width: 70%"
+						:options="salesArr"
+						:props="{multiple: false,label:'RealName',children:'ChildrenList',value:'AdminId'}"
+						:show-all-levels="false"
+						clearable
+						filterable>
+					</el-cascader>
+				</el-form-item>
+			</el-form>	
+			<div style="display:flex;justify-content:center;margin:75px 0 26px;">
+				<el-button type="primary" style="width:80px;marginRight:24px;" @click="saveMove">保存</el-button>
+				<el-button  style="width:80px;" @click="cancelMove">取消</el-button>
+			</div>
+		</el-dialog>
+
+    <!-- 添加联系人弹窗 -->
+		<Contactdia
+		:id="addCompanyId"
+		:title="'新增联系人'"
+		:userForm="diaform"
+		:needCard="true"
+		:isShowclose="isShowclose"
+		:isPickLoss="isPickLoss"
+		:isPickSelf="isPickSelf"
+		:regionType="regionType"
+		:isAddContact="isAddContact"
+		@cancel="cancelConcatdia"
+		@addContactNext="addContactNext">
+		</Contactdia>
+
+    <!-- 冻结理由弹窗 -->
+		<el-dialog
+		v-model="isFreezeReason"
+		:close-on-click-modal="false"
+		:modal-append-to-body='false'
+		@close="closeFreezeReason"
+		width="800px"
+		center>
+      <template #header>
+        <div style="display:flex;align-items:center;">
+          <img src="../../assets/img/freeze-icon.png" alt="" width="16" style="margin-right:10px">
+          <span style="font-size:16px;">冻结</span>
+        </div>
+      </template>
+			<el-input
+				type="textarea"
+				:rows="6"
+				placeholder="请输入冻结理由"
+				v-model="freezeData.reason">
+			</el-input>
+			<div style="text-align:center;margin:30px 0;">
+				<el-button type="primary" @click="handleConfirmFreeze">确定</el-button>
+				<el-button type="primary" plain @click="closeFreezeReason">取消</el-button>
+			</div>
+		</el-dialog>
+
+    <!-- 补全信息弹窗 -->
+		<CompleteInfo
+			:form="completeForm"
+			@cancel="cancelCompleteInfo($event)"
+		></CompleteInfo>
+
+    <!-- 申请转正、续约申请、补充协议选择申请合同模式弹窗 -->
+		<el-dialog
+			v-model="contractModel.show"
+			:modal-append-to-body='false'
+			width="800px"
+			class="self-dialog"
+		>
+			<div style="text-align:center;margin:30px 0 100px 0">
+				<img width="191" src="../../assets/img/cus_m/bzht.png" @click="handleContractModel('标准')" style="margin-right:80px;cursor: pointer;">
+				<img width="191" src="../../assets/img/cus_m/fbzht.png" @click="handleContractModel('非标准')" style="cursor: pointer;">
+				<p style="font-size:15px;color:#333;text-align:left;padding-left:100px;margin-top:30px">
+					注:<br>
+					系统生成合同请选择标准合同入口<br>
+					非系统生成合同请选择非标准合同入口(包含已走完邮件流程的标准合同)</p>
+			</div>
+		</el-dialog>
+
+		<!-- 申请转正、续约申请、补充协议标准合同模式下 合同信息弹窗 -->
+		<ContractInfo 
+			:initData="contractDialog" 
+			@contractInfoDialogClose="contractInfoDialogClose"
+		></ContractInfo>
+
+		<!-- 查看备注弹窗 -->
+		<el-dialog
+		v-model="isRemarkLook"
+		:close-on-click-modal="false"
+		:modal-append-to-body="true"
+		:append-to-body="true"
+		@close="closeDia"
+		width="800px"
+		v-dialogDrag
+		center>
+      <template #header>
+        <div style="display:flex;alignItems:center;">
+          <img :src="$icons.auth" style="color:#fff;width:16px;height:16px;marginRight:5px;">
+          <span style="fontSize:16px;">{{lookRemarkTitle}}</span>
+        </div>
+      </template>
+			<template>
+				<div v-if="(RoleIdentity == 'rai_seller' || RoleIdentity == 'ficc_seller') || (SellerAdminId == lookRemarkItem.SellerId)">
+					<el-input
+						type="textarea"
+						:rows="3"
+						placeholder="请输入文字"
+						v-model="lookRemarkTextarea">
+					</el-input>
+					<div class="look-remark-commit" @click="lookRemarkAdd">保存</div>
+				</div>
+				<el-table
+			:data="lookRemarkList"
+			border
+			max-height="300"
+			style="width: 100%; margin-top: 20px;margin-bottom: 20px">
+				<el-table-column label="备注内容"  key="Remark"  align="center">
+					<template #default="scope">{{scope.row.Remark}}</template>
+				</el-table-column>
+				<el-table-column label="客户类型" align="center" key="ProductName" v-if="lookRemarkItem.IsShared && (RoleIdentity != 'rai_seller' && RoleIdentity != 'ficc_seller')">
+					<template #default="scope">{{scope.row.ProductName}}</template>
+				</el-table-column>
+				<el-table-column label="创建时间"  key="CreateTime" align="center">
+					<template #default="scope">{{scope.row.CreateTime}}</template>
+				</el-table-column>
+				<el-table-column label="操作" align="center">
+					<template #default="{row}">
+						<el-button type="text" size="small" style="color:red;" v-if="row.ButtonDel"
+							@click="lookRemarkDelete(row)">删除</el-button>
+					</template>
+				</el-table-column>
+			</el-table>
+			</template>
+			<div style="padding:20px 0;"></div>
+		</el-dialog>
+
+    <!-- 权限详情弹框 -->
+		<permission-detail :isPermissionDetailShow="isPermissionDetailShow" :researchDetailId="researchDetailId" @close="isPermissionDetailShow=false"/>
     
   </div>
 </template>

+ 1347 - 0
src/views/custom_manage/custom/customShareList.vue

@@ -0,0 +1,1347 @@
+<script setup>
+import { computed, reactive, ref, toRefs } from "vue";
+import { useRouter } from 'vue-router';
+import { customInterence } from "@/api/api.js";
+import { ElMessage } from "element-plus";
+import { Search } from '@element-plus/icons-vue';
+import moment from 'moment';
+import { useList,useViewPermissionDia,useViewRoadShowDia,useViewRemarkDia,useLookTrialDia,useCommunicaRecordDia } from "./hooks/customlistHook";
+import AccumulativeFrequencyDlg from './components/accumulativeFrequencyDlg.vue'
+import permissionView from './components/premissionView.vue'
+import TotalDayDialog from './components/TotalDayDialog.vue'
+import ShareListDialog from './components/shareListDialog.vue';
+import CustomRemarkDialog from './components/customRemarkDialog.vue';
+import ContractInfo from './components/ContractInfo.vue';
+import CompleteInfo from './components/CompleteInfo.vue';
+import Cauthlist from './components/CauthList.vue';
+
+const router = useRouter()
+
+const { btnCommandList, btnName, goDetail,defaultSalesProps,statusList } = useList(); //列表操作按钮
+
+const { isLook,lookTitle,lookAuthList,lookAuthListEquity,lookHandle,closeDia } = useViewPermissionDia();//查看权限弹窗
+
+const { accumulativeFrequencyClick,accumulativeFrequencyDlg,accumulativeFrequencyItem,closeAccumulativeDlg } = useViewRoadShowDia();//路演详情弹窗
+
+const { customInfo,isRemarkLook,handleShowRemark,closeRemarkDia } = useViewRemarkDia();//查看备注弹窗
+
+const { isTotalDayDialogShow,customItem,handleTotalDayClick,closeLookTrial } = useLookTrialDia();//查看累计试用天数弹窗
+
+const { shareCustomInfo,isShareRecodeDialogShow,allowEdit,
+handleShowShareRecode } = useCommunicaRecordDia();//服务记录弹窗
+
+const adminId = localStorage.getItem('AdminId')
+const isPWang = computed(() => {
+  return adminId == 66;
+});
+const isYDLou = computed(() => {
+  // 不同环境下 楼颖丹账号的adminId 不一样
+  if (process.env.NODE_ENV == "development" || process.env.NODE_ENV == "test") {
+    return adminId == 476;
+  } else if (process.env.NODE_ENV == "production") {
+    return adminId == 15;
+  }
+});
+const Role = computed(() => {
+  let role = localStorage.getItem("Role") || "";
+  if (role == "admin" || isPWang.value || isYDLou.value) {
+    // 只有王沛、楼颖丹和所有admin账号才有分配销售的权利
+    return "thisAdmin";
+  } else {
+    return "thisSeller";
+  }
+});
+const roleType = computed(() => {
+  return localStorage.getItem("Role") || "";
+});
+
+/* 获取表格 */
+const isShowloadding = ref();
+const filterState = reactive({
+  sort_type: "", //自定义排序方式
+  sort_param: "", //自定义排序方式的哪一个
+  sales: [],
+  originalSales: [],
+  page_no: 1,
+  pageSize: 10,
+  status: "",
+  search_txt: "",
+});
+const total = ref(0);
+const tableData = ref([]);
+const IsShareGroup = ref(false); //是否为咨询组销售
+function getTableData() {
+  isShowloadding.value = true;
+  // 处理销售筛选
+  let salesArr = [];
+  if (filterState.originalSales.length) {
+    salesArr = filterState.originalSales.map((item) => {
+      return item[item.length - 1];
+    });
+  }
+
+  let params = {
+    SortParam: filterState.sort_param, //自定义排序字段
+    SortType: filterState.sort_type, //排序方式
+    PageSize: filterState.pageSize,
+    CurrentIndex: filterState.page_no,
+    Keyword: filterState.search_txt,
+    ListParam: filterState.status,
+    SellerId: filterState.sales.join(","),
+    OriginalSellerId: salesArr.join(","),
+  };
+  customInterence.getShareCustomList(params).then((res) => {
+    if (res.Ret === 200) {
+      total.value = res.Data.Paging.Totals || 0;
+      tableData.value = res.Data.List || [];
+      isShowloadding.value = false;
+      IsShareGroup.value = res.Data.IsShareGroup || false;
+      filterState.status = res.Data.Status;
+    }
+  });
+}
+getTableData()
+
+/* 页码改变 */
+function handleCurrentChange(page) {
+  filterState.page_no = page;
+  getTableData();
+}
+
+/* 到期天数排序发生变化 全局排序 */
+function sortChangeHandle(item) {
+  filterState.sort_type =
+    item.order === "ascending"
+      ? "asc"
+      : item.order === "descending"
+      ? "desc"
+      : "";
+  filterState.sort_param = item.prop;
+  getTableData();
+}
+
+/* 获取可分配销售 */
+const salesArr = ref([]);
+function getSale() {
+  customInterence.getShareSaleList().then((res) => {
+    if (res.Ret === 200) {
+      salesArr.value = res.Data || [];
+      //无子级的组无法选择
+      const filterNodes = (arr) => {
+        arr.length &&
+          arr.forEach((item) => {
+            item.ChildrenList && filterNodes(item.ChildrenList);
+
+            if (!Number(item.AdminId) && !item.ChildrenList) {
+              item.disabled = true;
+            }
+          });
+      };
+      filterNodes(salesArr.value);
+      console.log("salesArr", salesArr.value);
+    }
+  });
+}
+getSale()
+
+/* 获取销售 */
+const originalSalesArr = ref([]);
+function getoriginalSale() {
+  customInterence.getShareSale().then((res) => {
+    if (res.Ret === 200) {
+      originalSalesArr.value = res.Data.List || [];
+    }
+  });
+}
+getoriginalSale()
+
+
+function getToolBtnList(data) {
+  let toolList = [];
+  const { BtnItem } = data;
+  for (const i in btnCommandList) {
+    if (BtnItem[i]) {
+      toolList.push({ type: btnCommandList[i], code: i + "" });
+    }
+  }
+  return toolList;
+}
+
+/* 操作-按钮 */
+async function itemclickHandle(query) {
+  if (query.type == "分配销售" || query.type == "修改销售") {
+    assignedSellerFun(query.data);
+  } else if (query.type == "查看权限") {
+    lookHandle(query.data);
+  } else if (query.type == "沟通记录") {
+    handleShowShareRecode(query.data);
+  } else if (query.type == "备注") {
+    handleShowRemark(query.data);
+  } else if (["续约申请", "补充协议"].includes(query.type)) {
+    handleOpenContractChoose(query.type, query.data);
+  } else if (query.type == "增开试用") {
+    addTrialHandle(query.data);
+  } else if (query.type == "设置共享" || query.type == "取消共享") {
+    shareSetting(query.data);
+  }
+}
+
+/* 分配销售 */
+const assignedSellerShow = ref(false); //分配销售弹窗
+const assignedSellerTitle = ref("分配销售");
+const assignform = reactive({
+  CompanyId: "",
+  CompanyName: "",
+  SellsId: "", //选择的销售
+});
+const assignformRef = ref(null);
+function assignedSellerFun(row) {
+  assignform.CompanyName = row.CompanyName;
+  assignform.CompanyId = row.CompanyId;
+  assignform.SellsId = row.ShareSellerId == 0 ? "" : row.ShareSellerId + "";
+  //根据当前角色 获取salesArr
+  //若是ficc角色 取咨询组销售(一级)
+  //若是rai角色 去权益销售组(多级)
+  assignedSellerShow.value = true;
+}
+function saveAssign() {
+  assignformRef.validate((valid) => {
+    if (valid) {
+      if (!Number(assignform.SellsId)) {
+        ElMessage.warning("请选择销售而不是分组!");
+        return;
+      }
+      let param = {
+        CompanyId: assignform.CompanyId,
+        SellsId: assignform.SellsId,
+      };
+      customInterence.assignShareSeller(param).then((res) => {
+        if (res.Ret == 200) {
+          ElMessage.success(assignedSellerTitle.value + "成功");
+          getTableData();
+          assignedSellerShow.value = false;
+        }
+      });
+    }
+  });
+}
+/* 取消分配销售 */
+function cancelAssign() {
+  assignform.CompanyName = "";
+  assignform.CompanyId = "";
+  assignform.SellsId = "";
+
+  assignformRef.value.resetFields();
+  assignedSellerShow.value = false;
+}
+
+// 设置/取消 共享
+function shareSetting(row) {
+  customInterence
+    .setCustomShare({
+      CompanyId: row.CompanyId,
+      IsShare: row.IsShare == 0 ? 1 : 0,
+    })
+    .then((res) => {
+      if (res.Ret == 200) {
+        ElMessage.success(row.IsShare == 0 ? "设置共享成功" : "取消共享成功");
+        getTableData();
+      }
+    });
+}
+
+/* 增开试用 */
+const isAddTrial = ref(false)
+const authList = ref([])
+const addTryId = ref(0)
+//增加试用完成
+function addTryOver(){
+	isAddTrial.value = false;
+	getTableData();
+}
+//增开试用
+function addTrialHandle(item) {
+	authList.value = [];
+	customInterence.lookauth({
+		CompanyId:item.CompanyId,
+		LookType:1
+	}).then(res => {
+		if(res.Ret === 200) {
+			let auth = [];
+			// res.Data.List 有值为 ficc
+			// res.Data.ListRai 有值为 权益
+			res.Data.List ? res.Data.List.forEach(item=> {
+				let obj = {
+					checkAll:item.CheckList&&item.CheckList.length===item.Items.length?true:false,
+					isIndeterminate:item.CheckList&&item.CheckList.length>0 && item.CheckList.length<item.Items.length,
+					defaultAuth:item.CheckList,
+					customType:'ficc',
+					...item,
+				}
+				auth.push(obj)
+			}):
+			// 权益 RaiMerge 0不管 1合并 2拆分 所传入的数据结构不一样
+			/**权益权限ID
+			 * 科技-主观(20)-客观(37)
+			 * 消费-主观(21)-客观(38)
+			 * 医药-主观(22)-客观(39)
+			 * 智造-主观(19)-客观(36)
+			 * 策略(23)
+			 * 专家(29)
+			 * 固收(53)
+			 * 调研(54)
+			 * 路演服务(30)
+			 * 研选订阅(31)
+			 * 研选扣点包(52)
+			 */
+			res.Data.ListRai[0].RaiMerge==1?res.Data.ListRai.forEach(item=> { // 合并
+				let checkedLen = item.Items.filter(it => item.CheckList && item.CheckList.includes(it.ChartPermissionId)).length
+				let obj = {
+					checkAll:checkedLen === item.Items.length,
+					isIndeterminate:checkedLen > 0 && checkedLen < item.Items.length,
+					defaultAuth:item.CheckList,
+					...item,
+				}
+				auth.push(obj)
+			}): res.Data.ListRai.forEach(item=> { // 拆分
+				let obj = {
+					defaultAuth:item.CheckList,
+					customType:'权益',
+					...item,
+				}	
+				// 组合所需的数据格式
+				let subjectivityIds=item.Items.filter(it => it.PermissionType==1).map(it => it.ChartPermissionId)//主观的ids
+				let subjectivityLength=subjectivityIds.length//有几个主观的id
+				let subjectivityCheckedLen = item.CheckList.filter(id => subjectivityIds.includes(id)).length//选中的有几个主观的id
+				let objectivityIds=item.Items.filter(it => it.PermissionType==2).map(it => it.ChartPermissionId)//客观的ids
+				let objectivityCheckedLen = item.CheckList.filter(id => objectivityIds.includes(id)).length//有几个客观的id
+				let objectivityLength=objectivityIds.length//选中的有几个客观的id
+				let arr = [{PermissionTypeName:''},
+									{PermissionTypeName:{
+										value:'主观',
+										isIndeterminate:subjectivityCheckedLen>0 && subjectivityCheckedLen<subjectivityLength,
+										isCheckAll:subjectivityCheckedLen == subjectivityLength,
+										isDisabled:subjectivityCheckedLen == subjectivityLength,
+										ids:subjectivityIds
+									}},
+									{PermissionTypeName:{
+										value:'客观',
+										isIndeterminate:objectivityCheckedLen > 0 && objectivityCheckedLen < objectivityLength,
+										isCheckAll:objectivityCheckedLen == objectivityLength,
+										isDisabled:objectivityCheckedLen == objectivityLength,
+										ids:objectivityIds
+									}}]
+				item.Items.map(cp =>{
+					if(cp.PermissionType==0){
+						// 没有主客观的权限
+						arr[0][cp.PermissionName]={
+							value:cp.PermissionName,
+							width:cp.PermissionName=='研选扣点包'?'100px':'',
+							merge:true
+						}
+						arr[1][cp.PermissionName]={
+							value:cp.ChartPermissionId,
+							isDisabled:item.CheckList.includes(cp.ChartPermissionId),
+							merge:true
+						}
+						arr[2][cp.PermissionName]={
+							value:cp.ChartPermissionId,
+							isDisabled:item.CheckList.includes(cp.ChartPermissionId),
+							merge:true
+						}
+					}else if(cp.PermissionType==1){
+						// 找出对应的客观Id
+						let objectivity = item.Items.find(it => it.PermissionName == cp.PermissionName && it.PermissionType==2)
+						arr[0][cp.PermissionName]={
+							value:cp.PermissionName,
+							isIndeterminate:item.CheckList.filter(id => [cp.ChartPermissionId,objectivity?objectivity.ChartPermissionId:0].includes(id)).length ==1,
+							isCheckAll:item.CheckList.filter(id => [cp.ChartPermissionId,objectivity?objectivity.ChartPermissionId:0].includes(id)).length == 2,
+							isDisabled:item.CheckList.filter(id => [cp.ChartPermissionId,objectivity?objectivity.ChartPermissionId:0].includes(id)).length ==2,
+							bothIds:[cp.ChartPermissionId,objectivity?objectivity.ChartPermissionId:0]
+						}
+						arr[1][cp.PermissionName]={
+							value:cp.ChartPermissionId,
+							isDisabled:item.CheckList.includes(cp.ChartPermissionId)
+						}
+					}else{
+						// 分主客观的客观
+						arr[2][cp.PermissionName]={
+							value:cp.ChartPermissionId,
+							isDisabled:item.CheckList.includes(cp.ChartPermissionId)
+						}
+					}
+				})
+				obj.dataList=arr
+				auth.push(obj)
+			})
+			authList.value = auth;
+		}
+	})
+	addTryId.value = item.CompanyId;
+	isAddTrial.value = true;
+}
+
+
+//关闭合同信息弹窗
+const contractDialog = ref({
+	show:false,
+	type:'',//类型 续约申请、补充协议
+	cusdata:null,//客户信息(列表用户数据)
+})//续约申请、补充协议 合同信息弹窗
+const contractModel = ref({
+	show:false,
+	data:null,//客户信息(列表用户数据)
+	type:'',//类型 续约申请、补充协议
+})//续约申请、补充协议 选择合同类型弹窗 
+const completeForm = ref({})
+function contractInfoDialogClose(e){
+	contractDialog.value={
+		show:false,
+		type:'',
+		cusdata:null,
+	}
+	if(e==='updateList'){
+		getTableData();
+	}
+}
+//验证客户信息完整性
+async function getCustomerDetail(id){
+	let res=await customInterence.customDetail({
+		CompanyId:id
+	})
+	if(res.Ret!=200) return
+
+	let RoleType=localStorage.getItem('RoleType')
+	let IndustryId='',Source=';'
+	if(RoleType=='ficc'){
+		IndustryId=res.Data.FiccItem.IndustryId
+		Source=res.Data.FiccItem.Source
+	}else if(RoleType=='权益'){
+		IndustryId=res.Data.RaiItem.IndustryId
+		Source=res.Data.RaiItem.Source
+	}
+	if((res.Data.Item.RegionType!='海外'&&!res.Data.Item.Province&&!res.Data.Item.City)||!res.Data.Item.CreditCode||!IndustryId||!Source){
+		completeForm.value={
+			nameDisable:res.Data.Item.CompanyName!='',
+			CityDisable:res.Data.Item.City!='',
+			CreditCodeDisable:res.Data.Item.CreditCode!='',
+			IndustryIdDisable:IndustryId!=' ',
+			SourceDisable:Source!='',		
+			CompanyId:id,
+			name:res.Data.Item.CompanyName,
+			Province:res.Data.Item.Province,
+			RegionType:res.Data.Item.RegionType,
+			City:res.Data.Item.City,
+			CreditCode:res.Data.Item.CreditCode,
+			IndustryId:IndustryId?IndustryId:'',
+			Source:Source,
+			flag:false,//是否为跨部门
+			show:true
+		}
+	}else{
+		completeForm.value.show=false
+	}
+	return new Promise((resolve,reject)=>{
+		resolve(completeForm.value.show)
+	})
+}
+//关闭补全信息弹窗
+function cancelCompleteInfo(refresh){
+	// 刷新列表
+	if(refresh){
+		getTableData()
+	}
+	completeForm.value={
+		show:false
+	}
+}
+//打开合同选择弹窗
+async function handleOpenContractChoose(type,data){
+	
+	let flag=await getCustomerDetail(data.CompanyId)
+	if(flag) return
+	contractModel.value = {
+		type,data,show:true
+	}
+}
+//选择标准/非标合同
+function handleContractModel(model){
+	if(model==='标准'){
+		contractDialog.value.type = contractModel.value.type
+		contractDialog.value.cusdata = contractModel.value.data
+		contractDialog.value.show = true
+	}else{
+		sessionStorage.setItem('companyInfo',JSON.stringify(contractModel.value.data))
+		const routeMap = {
+			'续约申请':'/updateCustom',
+			'补充协议':'/addAgreement'
+		}
+		const { href } = router.resolve({path:routeMap[contractModel.value.type],})||{href:''}
+		href&&window.open(href, '_blank');
+	}
+	contractModel.value={
+		type:'',data:null,show:false
+	}
+}
+
+
+const {
+  sales,
+  originalSales,
+  page_no,
+  pageSize,
+  status,
+  search_txt,
+} = toRefs(filterState)
+
+</script>
+<!-- 页面在客户列表上进行的二次修改,若后续有和客户列表相似的功能,请查看客户列表页面 -->
+<template>
+  <div
+    class="customList_container"
+    id="customList_container"
+    ref="cusContainer"
+  >
+    <div class="customList_bot">
+      <div class="customList_bot_search">
+        <div style="margin-bottom: 8px" v-if="!IsShareGroup">
+          <el-select
+            v-model="status"
+            placeholder="请选择状态"
+            @change="getTableData"
+            style="width: 214px; margin-right: 20px"
+          >
+            <el-option
+              :label="item.label"
+              :value="item.value"
+              v-for="(item, index) in statusList"
+              :key="index"
+            ></el-option>
+          </el-select>
+          <el-cascader
+            v-model="originalSales"
+            placeholder="请选择原销售"
+            style="width: 240px; margin-right: 10px;"
+            :options="originalSalesArr"
+            :props="defaultSalesProps"
+            :show-all-levels="false"
+            collapse-tags
+            clearable
+            filterable
+            @change="getTableData"
+            v-if="roleType !== 'ficc_seller'"
+          />
+          <!-- <el-select v-model="sales" placeholder="请选择分配销售" style="width: 214px; margin-right: 20px;" 
+          clearable filterable multiple collapse-tags @change="getTableData">
+            <el-option :label="item.RealName" :value="item.AdminId" v-for="item in salesArr" :key="item.AdminId" ></el-option>
+          </el-select> -->
+          <el-cascader
+            v-model="sales"
+            :options="salesArr"
+            :show-all-levels="false"
+            placeholder="请选择分配销售"
+            :props="{
+              multiple: true,
+              emitPath: false,
+              value: 'AdminId',
+              label: 'RealName',
+              children: 'ChildrenList',
+            }"
+            @change="getTableData"
+          >
+          </el-cascader>
+        </div>
+        <div v-else>
+          <el-button type="primary" @click="$router.push('/customCityList')"
+            >查看同城客户</el-button
+          >
+          <el-cascader
+            v-model="originalSales"
+            placeholder="请选择原销售"
+            style="width: 200px; margin-right: 10px;"
+            :options="originalSalesArr"
+            :props="defaultSalesProps"
+            :show-all-levels="false"
+            collapse-tags
+            clearable
+            filterable
+            @change="getTableData"
+          />
+        </div>
+        <el-input
+          placeholder="客户名称/社会信用码/手机号码/邮箱"
+          v-model="search_txt"
+          style="max-width: 531px; margin-bottom: 8px"
+          @input="handleCurrentChange(1)"
+          clearable
+        >
+					<template #prefix>
+						<el-icon><Search /></el-icon>
+					</template>
+        </el-input>
+      </div>
+      <div class="bot_cont">
+        <el-table
+          ref="userTable"
+          :data="tableData"
+          v-loading="isShowloadding"
+          element-loading-text="数据加载中..."
+          @sort-change="sortChangeHandle"
+          border
+        >
+          <el-table-column
+            prop="CompanyName"
+            label="客户名称"
+            align="center"
+            min-width="7.14%"
+          >
+            <template #default="scope">
+              <span
+                v-if="scope.row.IsSuspend === 1 || scope.row.Status == '潜在'"
+                @click="goDetail(scope.row)"
+                class="mouse-enter"
+                :class="{
+                  'color-red':
+                    scope.row.Status.includes('正式') &&
+                    scope.row.WeekViewActive === 0,
+                }"
+                :style="
+                  scope.row.Status == '潜在' ? '' : 'color:#bbb;cursor:pointer'
+                "
+              >
+                {{ scope.row.CompanyName }}
+              </span>
+              <span
+                v-else
+                style="color: #409eff; cursor: pointer"
+                @click="goDetail(scope.row)"
+                class="customName"
+                :class="{
+                  isShared: scope.row.IsShared,
+                  'color-red':
+                    scope.row.Status.includes('正式') &&
+                    scope.row.WeekViewActive === 0,
+                }"
+                >{{ scope.row.CompanyName }}</span
+              >
+              <img
+                width="15"
+                src="../../../assets/img/icons/remark.png"
+                alt=""
+                v-if="
+                  scope.row.RenewalReason ||
+                  (scope.row.Status === '冻结' && scope.row.FreezeReason)
+                "
+              />
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="CompanyType"
+            label="类型"
+            align="center"
+            min-width="4.14%"
+          >
+            <template #default="{ row }">
+              <template v-if="row.CompanyType.indexOf('/') !== -1">
+                <span :style="row.IsSuspend === 1 ? 'color:#bbb' : ''">{{
+                  row.CompanyType.split("/")[0]
+                }}</span
+                ><br />
+                <span v-if="row.FiccPackageType" class="ficc-package">{{
+                  row.FiccPackageType == 1 ? "大套餐" : "小套餐"
+                }}</span>
+                <br v-if="row.FiccPackageType" />
+                <span :style="row.IsSuspend === 1 ? 'color:#bbb' : ''">{{
+                  row.CompanyType.split("/")[1]
+                }}</span>
+              </template>
+              <template v-else>
+                <span :style="row.IsSuspend === 1 ? 'color:#bbb' : ''">{{
+                  row.CompanyType
+                }}</span>
+                <span
+                  v-if="row.FiccPackageType && row.CompanyType.includes('ficc')"
+                  class="ficc-package"
+                  >{{ row.FiccPackageType == 1 ? "大套餐" : "小套餐" }}</span
+                >
+              </template>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="IndustryName"
+            label="所属行业"
+            min-width="6.14%"
+            align="center"
+          >
+            <template #default="scope">
+              <div :style="scope.row.IsSuspend === 1 ? 'color:#bbb' : ''">
+                <p
+                  :style="scope.row.IsSuspend === 1 ? 'color:#bbb' : ''"
+                  v-for="item in scope.row.IndustryName.split('/')"
+                  :key="item"
+                >
+                  {{ item }}
+                </p>
+              </div>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="City"
+            label="客户地址"
+            min-width="6.14%"
+            align="center"
+          >
+            <template #default="scope">
+              <span
+                v-if="scope.row.Province && scope.row.City"
+                :style="scope.row.IsSuspend === 1 ? 'color:#bbb' : ''"
+                >{{ scope.row.Province }}<br />{{ scope.row.City }}</span
+              >
+              <span
+                v-else
+                :style="scope.row.IsSuspend === 1 ? 'color:#bbb' : ''"
+                >{{ scope.row.RegionType }}</span
+              >
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="SellerName"
+            label="原销售"
+            min-width="6.14%"
+            align="center"
+          >
+            <template #default="scope">
+              <p
+                :style="scope.row.IsSuspend === 1 ? 'color:#bbb' : ''"
+                v-for="item in scope.row.SellerName.split('/')"
+                :key="item"
+              >
+                {{ item }}
+              </p>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="ShareSeller"
+            label="分配销售"
+            min-width="6.14%"
+            align="center"
+          >
+          </el-table-column>
+          <el-table-column
+            prop="Status"
+            label="状态"
+            min-width="7.14%"
+            align="center"
+          >
+            <template #default="scope">
+              <p
+                :style="
+                  scope.row.IsSuspend === 1
+                    ? 'color:#bbb;margin:3px 0'
+                    : 'margin:3px 0'
+                "
+                v-for="(item, index) in scope.row.Status.split('/')"
+                :key="item"
+              >
+                {{ item }}
+                <template v-if="item === '试用' && scope.row.TryStageSlice">
+                  <el-select
+                    v-model="scope.row.TryStageSlice[index].TryStage"
+                    v-if="scope.row.Status === '试用/试用'"
+                    :disabled="!scope.row.TryStageSlice[index].HasPermission"
+                    size="mini"
+                    style="width: 50px"
+                    placeholder=""
+                    @change="
+                      changeTrialHandle(
+                        scope.row,
+                        scope.row.TryStageSlice[index]
+                      )
+                    "
+                  >
+                    <el-option
+                      v-for="item in trialTags"
+                      :key="item.value"
+                      :label="item.label"
+                      :value="item.value"
+                    >
+                    </el-option>
+                  </el-select>
+                  <el-select
+                    v-model="scope.row.TryStageSlice[0].TryStage"
+                    :disabled="!scope.row.TryStageSlice[0].HasPermission"
+                    v-else
+                    size="mini"
+                    style="width: 50px"
+                    placeholder=""
+                    @change="
+                      changeTrialHandle(scope.row, scope.row.TryStageSlice[0])
+                    "
+                  >
+                    <el-option
+                      v-for="item in trialTags"
+                      :key="item.value"
+                      :label="item.label"
+                      :value="item.value"
+                    >
+                    </el-option>
+                  </el-select>
+                </template>
+              </p>
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="累计试用天数"
+            align="center"
+            min-width="5.14%"
+            prop="tryOutDay"
+            sortable="custom"
+          >
+            <template #default="{ row }">
+              <el-tooltip
+                :disabled="
+                  row.IsSuspend === 1 ||
+                  row.FiccTryOutDay + row.RaiTryOutDay === 0
+                "
+              >
+								<template #content>
+									<div>
+										<p v-if="row.FiccTryOutDay">
+											FICC累计试用天数:{{ row.FiccTryOutDay }}
+										</p>
+										<p v-if="row.RaiTryOutDay">
+											权益累计试用天数:{{ row.RaiTryOutDay }}
+										</p>
+									</div>
+								</template>
+                <span
+                  :style="
+                    row.IsSuspend === 1
+                      ? 'color:#bbb'
+                      : 'color:#409EFF;cursor:pointer;'
+                  "
+                  @click="handleTotalDayClick(row)"
+                >
+                  {{ row.FiccTryOutDay + row.RaiTryOutDay }}
+                </span>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="阅读"
+            align="center"
+            min-width="5.14%"
+            prop="viewTotal"
+            sortable="custom"
+          >
+            <template #default="{ row }">
+              <el-tooltip
+                :disabled="
+                  row.IsSuspend === 1 || row.FiccView + row.RaiView === 0
+                "
+              >
+								<template #content>
+									<div>
+										<p v-if="row.FiccView">
+											FICC报告阅读次数:{{ row.FiccView }}
+										</p>
+										<p v-if="row.RaiView">权益报告阅读次数:{{ row.RaiView }}</p>
+									</div>
+								</template>
+                <span
+                  :style="
+                    row.IsSuspend === 1
+                      ? 'color:#bbb'
+                      : 'color:#409EFF;cursor:pointer;'
+                  "
+                >
+                  <!-- 阅读次数拆分 -->
+                  {{ row.AllViewTotal }}
+                </span>
+              </el-tooltip>
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="路演"
+            align="center"
+            min-width="5.14%"
+            prop="roadShowTotal"
+            sortable="custom"
+          >
+            <template #default="scope">
+              <span
+                :style="scope.row.IsSuspend === 1 ? 'color:#bbb' : ''"
+                @click="accumulativeFrequencyClick(scope)"
+                class="editsty"
+                v-if="scope.row.RoadShowTotal > 0"
+                >{{ scope.row.RoadShowTotal }}</span
+              >
+              <span
+                :style="scope.row.IsSuspend === 1 ? 'color:#bbb' : ''"
+                v-else
+                >{{ scope.row.RoadShowTotal }}</span
+              >
+            </template>
+          </el-table-column>
+          <el-table-column
+            label="最近阅读"
+            min-width="8.14%"
+            align="center"
+            prop="viewTime"
+            sortable="custom"
+          >
+            <template #default="scope">
+              <p
+                v-if="scope.row.FiccLastViewTime"
+                :style="scope.row.IsSuspend === 1 ? 'color:#bbb' : ''"
+              >
+                ficc:
+                {{ moment(scope.row.FiccLastViewTime).format("YYYY.MM.DD") }}
+              </p>
+              <p
+                v-else-if="scope.row.RaiLastViewTime"
+                :style="scope.row.IsSuspend === 1 ? 'color:#bbb' : ''"
+              >
+                权益:
+                {{ moment(scope.row.RaiLastViewTime).format("YYYY.MM.DD") }}
+              </p>
+              <p v-else :style="scope.row.IsSuspend === 1 ? 'color:#bbb' : ''">
+                --
+              </p>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="EndDate"
+            :label="'服务期限'"
+            align="center"
+            min-width="6.14%"
+          >
+            <template #default="scope">
+              <span :style="scope.row.IsSuspend === 1 ? 'color:#bbb' : ''">
+                <!-- 正常的时间显示 -->
+                <template v-if="scope.row.StartDate.indexOf('/') == -1">
+                  {{ scope.row.StartDate }}~{{ scope.row.EndDate }}
+                </template>
+                <!-- 公用客户的时间显示 -->
+                <template v-else>
+                  {{ scope.row.StartDate.substr(0, 10) }}~{{
+                    scope.row.EndDate.substr(0, 10)
+                  }}/{{ scope.row.StartDate.substr(11) }}~{{
+                    scope.row.EndDate.substr(11)
+                  }}
+                </template>
+              </span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="expireDay"
+            :label="'到期'"
+            align="center"
+            min-width="5.14%"
+            sortable="custom"
+          >
+            <template #default="scope">
+              <span :style="scope.row.IsSuspend === 1 ? 'color:#bbb' : ''">
+                {{ scope.row.ExpireDay || "--" }}
+              </span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="createTime"
+            :label="'创建时间'"
+            sortable="custom"
+            align="center"
+            min-width="6.14%"
+          >
+            <template #default="scope">
+              <span :style="scope.row.IsSuspend === 1 ? 'color:#bbb' : ''">
+                {{ moment(scope.row.CreatedTime).format("YYYY.MM.DD") }}
+              </span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="lastServiceTime"
+            :label="'最新服务时间'"
+            sortable="custom"
+            align="center"
+            min-width="6.14%"
+          >
+            <template #default="scope">
+              <span :style="scope.row.IsSuspend === 1 ? 'color:#bbb' : ''">
+                {{
+                  scope.row.LastServiceTime.substr(0, 10).replaceAll(
+                    "-",
+                    "."
+                  ) || "--"
+                }}
+              </span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            prop="serviceTimes"
+            :label="'服务次数'"
+            sortable="custom"
+            align="center"
+            min-width="6.14%"
+          >
+            <template #default="scope">
+              <span
+                :style="
+                  scope.row.ServiceTimes > 0
+                    ? 'color:#409eff;cursor: pointer;'
+                    : ''
+                "
+                @click="handleShowShareRecode(scope.row, 'list')"
+              >
+                {{ scope.row.ServiceTimes }}
+              </span>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" align="center" min-width="7.14%">
+            <template #default="scope">
+              <div
+                class="tool"
+                style="
+                  display: flex;
+                  align-items: center;
+                  justify-content: center;
+                "
+                v-if="scope.row.ApproveStatus != '待审批'"
+              >
+                <!-- <span class="editsty" style="white-space: nowrap;" @click="itemclickHandle({type:'查看权限',data:scope.row})">
+									查看权限
+								</span>
+								<span @click="itemclickHandle({type:'分配销售',data:scope.row})" v-if="Role=='thisAdmin'" class="editsty"
+									style="white-space: nowrap;">
+									{{scope.row.ShareSellerId?'修改销售':'分配销售'}}
+								</span>
+								<span class="editsty" @click="itemclickHandle({type:'服务记录',data:scope.row})">
+									服务记录
+								</span>
+								<span class="editsty" @click="itemclickHandle({type:'备注',data:scope.row})">
+									备注
+								</span> -->
+                <div
+                  class="font-tool"
+                  style="display: flex; flex-direction: column"
+                >
+                  <span
+                    class="editsty"
+                    v-for="item in getToolBtnList(scope.row).slice(0, 3)"
+                    :key="item.type"
+                    @click="
+                      itemclickHandle({ type: item.type, data: scope.row })
+                    "
+                  >
+                    <!-- {{item.type==='分配销售'?scope.row.ShareSellerId?'修改销售':'分配销售':item.type}} -->
+                    {{ btnName(item, scope.row) }}
+                  </span>
+                </div>
+                <el-dropdown
+                  size="medium"
+                  placement="bottom-start"
+                  @command="itemclickHandle"
+                  style="height: 16px; margin-left: 5px"
+                  v-if="getToolBtnList(scope.row).length > 3"
+                >
+                  <span class="el-dropdown-link">
+                    <i class="el-icon-more el-icon--right"></i>
+									</span>
+
+									<template #dropdown>
+										<el-dropdown-menu>
+											<el-dropdown-item
+												:command="{ type: item.type, data: scope.row }"
+												v-for="item in getToolBtnList(scope.row).slice(3)"
+												:key="item.type"
+											>
+												<span>{{ btnName(item, scope.row) }}</span>
+											</el-dropdown-item>
+										</el-dropdown-menu>
+									</template>
+                </el-dropdown>
+              </div>
+            </template>
+          </el-table-column>
+					<template #empty>
+						<div
+							style="line-height: 44px; margin: 60px 0; color: #999"
+						>
+							<img
+								src="~@/assets/img/cus_m/nodata.png"
+								alt=""
+								style="display: block; width: 160px; height: 128px; margin: auto"
+							/>
+							<span>暂无信息</span>
+						</div>
+					</template>
+        </el-table>
+        <div class="toolbar fixedbar">
+          <el-pagination
+            layout="prev,pager,next,total"
+            background
+            :current-page="page_no"
+            @current-change="handleCurrentChange"
+            :page-size="pageSize"
+            :total="total"
+            style="float: right"
+          >
+          </el-pagination>
+        </div>
+      </div>
+    </div>
+
+    <!-- 修改销售弹窗 -->
+    <el-dialog
+      draggable
+      v-model="assignedSellerShow"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      :title="assignedSellerTitle"
+      class="changeSaleDia"
+      @close="cancelAssign"
+      center
+      width="444px"
+    >
+      <el-form
+        :model="assignform"
+        :rules="rule"
+        ref="assignform"
+        label-width="110px"
+      >
+        <el-form-item label="客户名称" prop="name">
+          <span style="fontsize: 16px">{{ assignform.CompanyName }}</span>
+        </el-form-item>
+        <el-form-item label="分配销售" prop="SellsId">
+          <el-cascader
+            v-model="assignform.SellsId"
+            :options="salesArr"
+            :show-all-levels="false"
+            placeholder="请选择分配销售"
+            style="width: 240px"
+            :props="{
+              multiple: false,
+              emitPath: false,
+              value: 'AdminId',
+              label: 'RealName',
+              children: 'ChildrenList',
+            }"
+          >
+          </el-cascader>
+        </el-form-item>
+      </el-form>
+      <div style="display: flex; justify-content: center; margin: 60px 0 35px">
+        <el-button
+          type="primary"
+          style="width: 80px; margin-right: 24px"
+          @click="saveAssign"
+          >保存</el-button
+        >
+        <el-button style="width: 80px" @click="cancelAssign">取消</el-button>
+      </div>
+    </el-dialog>
+    <!-- 查看权限弹窗 -->
+    <permissionView
+      :isLook="isLook"
+      :lookTitle="lookTitle"
+      :lookAuthList="lookAuthList"
+      :lookAuthListEquity="lookAuthListEquity"
+      @closeDia="closeDia"
+    ></permissionView>
+    <!-- 累计试用天数弹窗 -->
+    <total-day-dialog
+      :isTotalDayDialogShow="isTotalDayDialogShow"
+      :customInfo="customItem"
+      @close="closeLookTrial"
+    />
+    <!-- 路演业阅读的弹框 -->
+    <accumulative-frequency-dlg
+      :accumulativeFrequencyDlg="accumulativeFrequencyDlg"
+      :accumulativeFrequencyItem="accumulativeFrequencyItem"
+			@close="closeAccumulativeDlg"
+    />
+    <!-- 服务记录弹窗 -->
+    <share-list-dialog
+      :isShareRecodeDialogShow="isShareRecodeDialogShow"
+      :customInfo="shareCustomInfo"
+      :allowEdit="allowEdit"
+      @close="
+        () => {
+          isShareRecodeDialogShow && getTableData();
+          isShareRecodeDialogShow = false;
+        }
+      "
+    />
+    <!-- 备注弹窗 -->
+    <custom-remark-dialog
+      :isRemarkLook="isRemarkLook"
+      :lookRemarkItem="customInfo"
+      @close="closeRemarkDia"
+    />
+    <!-- 补全客户信息弹窗 -->
+    <CompleteInfo
+      :form="completeForm"
+      @cancel="cancelCompleteInfo($event)"
+    ></CompleteInfo>
+
+    <!-- 合同  -->
+    <el-dialog
+      v-model="contractModel.show"
+      :modal-append-to-body="false"
+      width="800px"
+      class="self-dialog"
+      draggable
+    >
+      <div style="text-align: center; margin: 30px 0 100px 0">
+        <img
+          width="191"
+          src="../../../assets/img/cus_m/bzht.png"
+          @click="handleContractModel('标准')"
+          style="margin-right: 80px; cursor: pointer"
+        />
+        <img
+          width="191"
+          src="../../../assets/img/cus_m/fbzht.png"
+          @click="handleContractModel('非标准')"
+          style="cursor: pointer"
+        />
+        <p
+          style="
+            font-size: 15px;
+            color: #333;
+            text-align: left;
+            padding-left: 100px;
+            margin-top: 30px;
+          "
+        >
+          注:<br />
+          系统生成合同请选择标准合同入口<br />
+          非系统生成合同请选择非标准合同入口(包含已走完邮件流程的标准合同)
+        </p>
+      </div>
+    </el-dialog>
+    <!-- 合同信息 -->
+    <ContractInfo
+      :initData="contractDialog"
+      @contractInfoDialogClose="contractInfoDialogClose"
+    ></ContractInfo>
+
+    <!-- 增开试用弹窗 -->
+    <el-dialog
+      v-model="isAddTrial"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      @close="isAddTrial = false"
+      width="800px"
+      draggable
+      center
+    >
+      <template #header>
+        <div style="display: flex; alignitems: center">
+          <span style="fontsize: 16px">增开试用(默认两个月)</span>
+        </div>
+      </template>
+      <Cauthlist
+        :autharr="authList"
+        :id="addTryId"
+        @addOver="addTryOver"
+        @close="isAddTrial = false"
+      />
+    </el-dialog>
+  </div>
+</template>
+<style lang="scss" scoped>
+.ficc-package {
+  display: inline-block;
+  font-size: 12px;
+  padding: 0 5px;
+  border-radius: 5px;
+  color: #3994fb;
+  background-color: #dcecfc;
+}
+.color-red {
+  color: red !important;
+}
+.isShared::after {
+  content: "共享";
+  font-size: 12px;
+  // padding: 0px 0px 0px 2px;
+  width: 30px;
+  color: #3994fb;
+  background-color: #dcecfc;
+  position: absolute;
+  left: 0;
+  bottom: 0;
+  border-top-right-radius: 5px;
+}
+.customList_container {
+  .customList_bot {
+    min-height: calc(100vh - 324px);
+    padding: 30px 30px 80px;
+    background: #fff;
+    position: relative;
+    border: 1px solid #ececec;
+    border-radius: 4px;
+    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+    .customList_bot_search {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      flex-wrap: wrap;
+      margin-bottom: 12px;
+    }
+    .bot_cont {
+      //padding-bottom: 20px;
+      .fixedbar {
+        position: fixed;
+        right: 45px;
+        bottom: 20px;
+        background-color: transparent;
+        z-index: 2;
+      }
+    }
+  }
+  .mouse-enter {
+    &:hover {
+      text-decoration: underline;
+    }
+  }
+
+  :deep(.el-input--mini) {
+    .el-input__inner {
+      padding: 0 6px !important;
+      height: 24px;
+      line-height: 24px;
+      color: #409eff;
+      background: #ecf5ff;
+      border-color: #409eff;
+      text-align: center;
+    }
+    .el-input__suffix {
+      right: -22px;
+    }
+    &.is-disabled {
+      .el-input__inner {
+        border-color: #e4e7ed;
+      }
+      .el-input__suffix {
+        display: none;
+      }
+    }
+  }
+
+  :deep(.self-dialog) {
+    .el-dialog__header {
+      background-color: #fff !important;
+      .el-dialog__close.el-icon.el-icon-close {
+        color: #666;
+      }
+    }
+  }
+  :deep(.changeSaleDia) {
+    .el-cascader .el-input {
+      width: 100%;
+    }
+  }
+}
+</style>

+ 779 - 30
src/views/custom_manage/custom/hooks/customlistHook.js

@@ -1,38 +1,14 @@
-/* 拓展客户列表额外需求 原页面太长 逻辑不好找 */
-import { ref,reactive } from "vue";
-import {ElMessage,ElMessageBox} from "element-plus"
 
+import { ref,reactive,computed } from "vue";
+import { router } from "@/router";
+import {ElMessage,ElMessageBox} from "element-plus"
 import { customInterence } from '@/api/api.js'
 
+
 export function customListHook(){
-	const act_trialTag=ref(0)//默认的标签状态
-	const trialTagArr=ref([])
-	const trialTags=reactive([ 
-		{
-			label: '推进',
-			value: 2
-		},
-		{
-			label: '跟踪',
-			value: 3
-		},
-		{
-			label: '预备',
-			value: 4
-		},
-		{
-			label: '未分类',
-			value: 1
-		},
-	])// 试用的标签状态
-	const isTotalDayDialogShow=ref(false)//控制累计试用天数弹窗
 	const customInfo=ref({})
 	const isShareRecodeDialogShow=ref(false)//控制服务记录弹窗
 	const allowEdit=ref(true)//是否允许编辑服务记录
-	const isCloseCustomDialogShow=ref(false)
-	const closeReason=ref('')
-	const fromArea=ref('')
-	const areaArr=reactive([{name:'国内'},{name:'海外'}])
 
 	//打开服务记录弹窗
 	const handleShowShareRecode=(data,type='')=>{
@@ -49,6 +25,107 @@ export function customListHook(){
 }
 
 
+export function useList() {
+	const btnCommandList = {// 按钮命令列表
+		BtnView: '查看权限',
+		BtnModifySeller: '分配销售',
+		BtnUpdate: '续约申请',
+		BtnAddAgreement: '补充协议',
+		BtnTryOut: '增开试用',
+		BtnServiceRecord:'沟通记录',
+		BtnRemarkView:'备注',
+		BtnShare:'设置共享',
+	}
+
+	const statusList = [{label:'未共享',value:3},{label:'已分配',value:1},{label:'待分配',value:2}]
+
+	const defaultSalesProps = {
+		multiple: true,
+		label:'RealName',
+		children:'ChildrenList',
+		value:'AdminId'
+	}//销售级联配置
+
+	// 用于返回按钮名称
+	function btnName(btnItem,row){
+		if(btnItem.code=='BtnShare') return row.IsShare===1?'取消共享':'设置共享'
+		if(btnItem.code=='BtnModifySeller') return row.ShareSellerId?'修改销售':'分配销售'
+		return btnItem.type
+	}
+
+
+	/* 前往详情页 */
+	function goDetail(item) {
+		const { href } = router.resolve({
+			path:'/customDetail',
+			query:{
+				id:item.CompanyId,
+			}});
+		window.open(href, '_blank');
+	}
+
+	/* 启用/暂停 */
+	function suspendHandle(item) {
+		customInterence.Suspend({
+			CompanyId:item.CompanyId
+		}).then(res => {
+			if(res.Ret === 200) {
+				ElMessage.success(res.Msg);
+				item.IsSuspend = item.IsSuspend === 1 ? 0 : 1;
+			}
+		})
+	}
+
+
+	/* 编辑客户 */
+	function editHandle(item) {
+		router.push({
+			path:'/editCustom',
+			query:{
+				id:item.CompanyId
+			}
+		})
+	}
+
+	const Role = computed(() => {
+		let role = localStorage.getItem('Role') || '';
+		return role;
+	})
+	const RaiSellerRole = computed(() => {
+		return ['rai_seller','rai_admin','admin'].includes(Role.value)
+	})
+	const RoleType = computed(() => {
+		let type = localStorage.getItem('RoleType') || '';
+		return type;
+	})
+	const RoleIdentity = computed(() => {
+		let role = localStorage.getItem('RoleIdentity') || '';
+		return role;
+	})
+	const SellerAdminId = computed(() => {
+		let type = localStorage.getItem('AdminId') || '';
+		return type;
+	})
+
+
+	return {
+		btnCommandList,
+		defaultSalesProps,
+		statusList,
+		btnName,
+		goDetail,
+		suspendHandle,
+
+		Role,
+		RaiSellerRole,
+		RoleType,
+		RoleIdentity,
+		SellerAdminId,
+
+	}
+}
+
+
 /* 阅读记录弹窗 */
 export function useReadia() {
 
@@ -126,13 +203,685 @@ export function useCommunicaRecordDia() {
 	}
 
 	return {
-		customInfo,
+		shareCustomInfo: customInfo,
 		isShareRecodeDialogShow,
 		allowEdit,
 		handleShowShareRecode
 	}
 }
 
+
+/* 查看权限弹窗 */
 export function useViewPermissionDia() {
+		const isLook = ref(false)//权限弹窗
+		const	lookTitle = ref('')//权限弹窗标题
+		const	lookAuthList = ref([])//查看的权限
+		const	lookAuthListEquity = ref([])//权益
+
+		// 打开弹窗
+		function lookHandle(item) {
+			lookTitle.value = item.CompanyName;
+			customInterence.lookauth({
+				CompanyId:item.CompanyId
+			}).then(res => {
+				if(res.Ret === 200) {
+					isLook.value = true;
+					let auth = [];			
+					res.Data.List ?	res.Data.List.forEach(item=> { 
+						auth.push(item.Items)
+					}):''
+					lookAuthList.value = auth.flat(Infinity);
+
+					let authEquity =[] //权益
+					res.Data.ListRai ?	res.Data.ListRai.forEach(item=> {//权益
+						// 过滤没有权限的套餐
+						let check_Auth = item.Items.filter(it => item.CheckList.includes(it.ChartPermissionId))
+						check_Auth.map(item =>{
+						// 排序 以防合并问题
+							if(item.PermissionType==1){
+								//主观 找客观
+								authEquity.push(item)
+								let ob = check_Auth.find(it => it.PermissionName == item.PermissionName && it.PermissionType!==1)
+								ob && authEquity.push(ob)
+							}else if(item.PermissionType==0){
+								authEquity.push(item)
+							}else{
+								// 客观
+								if(!authEquity.find(t => t.ChartPermissionId == item.ChartPermissionId)){
+									authEquity.push(item)
+								}
+							}
+						})
+					}):''
+					lookAuthListEquity.value = authEquity.flat(Infinity) //权益
+				}
+			})
+		}
+
+		/* 关闭查看权限弹窗 */
+		function closeDia() {
+			lookTitle.value = '';
+			lookAuthList.value = [];
+			lookAuthListEquity.value = []
+			isLook.value = false;
+		}
+
+		return {
+			isLook,
+			lookTitle,
+			lookAuthList,
+			lookAuthListEquity,
+			lookHandle,
+			closeDia
+		}
+}
+
+/* 备注弹窗 */
+export function useViewRemarkDia() {
+	const customInfo = ref({})
+	const isRemarkLook = ref(false)
+
+	function handleShowRemark(item){
+		customInfo.value = item
+		isRemarkLook.value = true
+	}
+
+	function closeRemarkDia() {
+		isRemarkLook.value = false
+		customInfo.value = {}
+	}
+
+	return {
+		customInfo,
+		isRemarkLook,
+		handleShowRemark,
+		closeRemarkDia
+	}
+}
+
+/* 生成合同弹窗 */
+export function useCreateContractDia() {
+
+}
+
+/* 增开试用弹窗 */
+export function useAddTrialDia() {
+	/* 增加试用 */
+	const isAddTrial = ref(false)//增加试用弹窗
+	const addTryId = ref('')//增开试用的id
+
+	function addTrialHandle(item) {
+		authList.value = [];
+		customInterence.lookauth({
+			CompanyId:item.CompanyId,
+			LookType:1
+		}).then(res => {
+			if(res.Ret === 200) {
+				let auth = [];
+				// res.Data.List 有值为 ficc
+				// res.Data.ListRai 有值为 权益
+				if(res.Data.List) {
+					res.Data.List.forEach(item=> {
+						let obj = {
+							checkAll:item.CheckList&&item.CheckList.length===item.Items.length?true:false,
+							isIndeterminate:item.CheckList&&item.CheckList.length>0 && item.CheckList.length<item.Items.length,
+							defaultAuth:item.CheckList,
+							customType:'ficc',
+							...item,
+						}
+						auth.push(obj)
+					})
+				}else if(res.Data.ListRai) {
+					auth = filterRaiAuth(res.Data.ListRai,auth)
+
+				}
+			
+				authList = auth;
+			}
+		})
+		addTryId.value = item.CompanyId;
+		isAddTrial.value = true;
+	}
+
+	function filterRaiAuth(data,auth) {
+			// 权益 RaiMerge 0不管 1合并 2拆分 所传入的数据结构不一样
+			data[0].RaiMerge==1
+				? data.forEach(item=> { // 合并
+						let obj = {
+							checkAll:item.CheckList&&item.CheckList.length===item.Items.length?true:false,
+							isIndeterminate:item.CheckList&&item.CheckList.length>0 && item.CheckList.length<item.Items.length,
+							defaultAuth:item.CheckList,
+							...item,
+						}
+						auth.push(obj)
+					})
+				: data.forEach(item=> { // 拆分
+						let obj = {
+							defaultAuth:item.CheckList,
+							customType:'权益',
+							...item,
+						}	
+						// 组合所需的数据格式
+						obj.dataList=[
+							{
+								PermissionTypeName:'',
+								medicine:{
+									value:'医药',
+									isIndeterminate:item.CheckList.filter(id => [obj.Items[0].ChartPermissionId,obj.Items[1].ChartPermissionId].includes(id)).length ==1,
+									isCheckAll:item.CheckList.filter(id => [obj.Items[0].ChartPermissionId,obj.Items[1].ChartPermissionId].includes(id)).length == 2,
+									isDisabled:item.CheckList.filter(id => [obj.Items[0].ChartPermissionId,obj.Items[1].ChartPermissionId].includes(id)).length ==2
+								},
+								consumption:{
+									value:'消费',
+									isIndeterminate:item.CheckList.filter(id => [obj.Items[2].ChartPermissionId,obj.Items[3].ChartPermissionId].includes(id)).length ==1,
+									isCheckAll:item.CheckList.filter(id => [obj.Items[2].ChartPermissionId,obj.Items[3].ChartPermissionId].includes(id)).length == 2,
+									isDisabled:item.CheckList.filter(id => [obj.Items[2].ChartPermissionId,obj.Items[3].ChartPermissionId].includes(id)).length ==2
+								},
+								technology:{
+									value:'科技',
+									isIndeterminate:item.CheckList.filter(id => [obj.Items[4].ChartPermissionId,obj.Items[5].ChartPermissionId].includes(id)).length ==1,
+									isCheckAll:item.CheckList.filter(id => [obj.Items[4].ChartPermissionId,obj.Items[5].ChartPermissionId].includes(id)).length == 2,
+									isDisabled:item.CheckList.filter(id => [obj.Items[4].ChartPermissionId,obj.Items[5].ChartPermissionId].includes(id)).length ==2
+								},
+								smart:{
+									value:'智造',
+									isIndeterminate:item.CheckList.filter(id => [obj.Items[6].ChartPermissionId,obj.Items[7].ChartPermissionId].includes(id)).length ==1,
+									isCheckAll:item.CheckList.filter(id => [obj.Items[6].ChartPermissionId,obj.Items[7].ChartPermissionId].includes(id)).length == 2,
+									isDisabled:item.CheckList.filter(id => [obj.Items[6].ChartPermissionId,obj.Items[7].ChartPermissionId].includes(id)).length ==2
+								},
+								strategy:{
+									value:'策略'
+								},
+								experts:{
+									value:'专家'
+								},
+								roadshow:{
+									value:'路演服务'
+								},
+								choose:{
+									value:'研选订阅'
+								},
+								points:{
+									value:'研选扣点包'
+								},
+							},
+							{
+								PermissionTypeName:{
+									value:'主观',
+									isIndeterminate:[1,2,3].includes(item.CheckList.filter(id => [obj.Items[0].ChartPermissionId,obj.Items[2].ChartPermissionId,
+										obj.Items[4].ChartPermissionId,obj.Items[6].ChartPermissionId].includes(id)).length),
+									isCheckAll:item.CheckList.filter(id => [obj.Items[0].ChartPermissionId,obj.Items[2].ChartPermissionId,
+										obj.Items[4].ChartPermissionId,obj.Items[6].ChartPermissionId].includes(id)).length == 4,
+									isDisabled:item.CheckList.filter(id => [obj.Items[0].ChartPermissionId,obj.Items[2].ChartPermissionId,
+										obj.Items[4].ChartPermissionId,obj.Items[6].ChartPermissionId].includes(id)).length ==4
+								},
+								medicine:{
+									value:obj.Items[0].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[0].ChartPermissionId)
+								},
+								consumption:{
+									value:obj.Items[2].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[2].ChartPermissionId)
+								},
+								technology:{
+									value:obj.Items[4].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[4].ChartPermissionId)
+								},
+								smart:{
+									value:obj.Items[6].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[6].ChartPermissionId)
+								},
+								strategy:{
+									value:obj.Items[8].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[8].ChartPermissionId)
+								},
+								experts:{
+									value:obj.Items[9].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[9].ChartPermissionId)
+								},
+								roadshow:{
+									value:obj.Items[10].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[10].ChartPermissionId)
+								},
+								choose:{
+									value:obj.Items[11].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[11].ChartPermissionId)
+								},
+								points:{
+									value:obj.Items[12].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[12].ChartPermissionId)
+								}
+							},
+							{
+								PermissionTypeName:{
+									value:'客观',
+									isIndeterminate:[1,2,3].includes(item.CheckList.filter(id => [obj.Items[1].ChartPermissionId,obj.Items[3].ChartPermissionId,
+										obj.Items[5].ChartPermissionId,obj.Items[7].ChartPermissionId].includes(id)).length),
+									isCheckAll:item.CheckList.filter(id => [obj.Items[1].ChartPermissionId,obj.Items[3].ChartPermissionId,
+										obj.Items[5].ChartPermissionId,obj.Items[7].ChartPermissionId].includes(id)).length == 4,
+									isDisabled:item.CheckList.filter(id => [obj.Items[1].ChartPermissionId,obj.Items[3].ChartPermissionId,
+										obj.Items[5].ChartPermissionId,obj.Items[7].ChartPermissionId].includes(id)).length ==4
+								},
+								medicine:{
+									value:obj.Items[1].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[1].ChartPermissionId)
+								},
+								consumption:{
+									value:obj.Items[3].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[3].ChartPermissionId)
+								},
+								technology:{
+									value:obj.Items[5].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[5].ChartPermissionId)
+								},
+								smart:{
+									value:obj.Items[7].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[7].ChartPermissionId)
+								},
+								strategy:{
+									value:obj.Items[8].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[8].ChartPermissionId)
+								},
+								experts:{
+									value:obj.Items[9].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[9].ChartPermissionId)
+								},
+								roadshow:{
+									value:obj.Items[10].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[10].ChartPermissionId)
+								},
+								choose:{
+									value:obj.Items[11].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[11].ChartPermissionId)
+								},
+								points:{
+									value:obj.Items[12].ChartPermissionId,
+									isDisabled:item.CheckList.includes(obj.Items[12].ChartPermissionId)
+								}
+							}
+						]
+
+						auth.push(obj)
+					})
+					
+			return auth
+	}
+
+	function closeAddTrial() {
+		isAddTrial.value = false
+	}
+
+	return {
+		isAddTrial,
+		addTryId,
+		addTrialHandle,
+		closeAddTrial
+	}
+}
+
+/* 查看路演详情弹窗 */
+export function useViewRoadShowDia() {
+	const accumulativeFrequencyItem = ref({})
+	const accumulativeFrequencyDlg = ref(false)
+
+	function accumulativeFrequencyClick(item){
+	 	accumulativeFrequencyDlg.value = true
+		accumulativeFrequencyItem.value = item.row
+	}
+
+	function closeAccumulativeDlg() {
+		accumulativeFrequencyDlg.value = false
+	}
 	
-}
+	return {
+		accumulativeFrequencyClick,
+		accumulativeFrequencyDlg,
+		accumulativeFrequencyItem,
+		closeAccumulativeDlg
+	}
+}
+
+
+/* 查看累计试用天数弹窗 */
+export function useLookTrialDia() {
+	const isTotalDayDialogShow = ref(false)
+	const customItem = ref({})
+
+	function handleTotalDayClick(data){
+		isTotalDayDialogShow.value = true
+		customItem.value = data
+	}
+
+	function closeLookTrial() {
+		isTotalDayDialogShow.value = false
+		customItem.value = {}
+	}
+
+	return {
+		isTotalDayDialogShow,
+		customItem,
+		handleTotalDayClick,
+		closeLookTrial
+	}
+}
+
+
+export function useMoveSaleDia() {
+	const isMove = ref(false)//修改销售
+	const moveform = ref({
+		companyType:'',
+		companyId:'',//客户id
+		companyName:'',
+		sale:'',//修改的销售
+	})
+	const moveRule = {
+		sale:[
+			{ required: true, message: '所属销售不能为空', trigger: 'blur' },
+		]
+	}
+
+	function updateSale(item) {
+		moveform.value = {
+			companyType:item.CompanyType,
+			companyName:item.CompanyName,
+			companyId:item.CompanyId,
+			sale:''
+		}
+		handleModifysalesArr(item.SellerId)
+		isMove.value = true;
+	}
+
+	/* 取消移动客户 */
+	function cancelMove() {
+		moveformRef.value.resetFields();
+		isMove.value = false;
+	} 
+
+	return {
+
+	}
+}
+
+
+/* 申请转正,续约申请,补充协议 */
+export function useChooseContractDia() {
+
+	const contractModel = reactive({
+		show:false,
+		data:null,//客户信息(列表用户数据)
+		type:'',//类型 申请转正、续约申请、补充协议
+	})
+	const { getCustomerDetail } = useCompleteInfoDia();
+
+	async function applyTurn(item) {
+		//判断是否需要补全信息
+		let flag=await getCustomerDetail(item.CompanyId,0) 
+		if(flag) return
+		contractModel.show=true
+		contractModel.data=item
+		contractModel.type='申请转正'
+	}
+
+	/* 续约申请操作 */
+	async function updateHandle(item) {
+		//判断是否需要补全信息
+		let flag = await getCustomerDetail(item.CompanyId)
+		if(flag) return
+		contractModel.show=true
+		contractModel.data=item
+		contractModel.type='续约申请'
+	}
+
+	// 补充协议
+	async function addAgreement(item) {
+		//判断是否需要补全信息
+		let flag = await getCustomerDetail(item.CompanyId)
+		if(flag) return
+		contractModel.show=true
+		contractModel.data=item
+		contractModel.type='补充协议'
+	}
+
+
+	const contractDialog = reactive({
+		show:false,
+		type:'',//类型 申请转正、续约申请、补充协议
+		cusdata:null,//客户信息(列表用户数据)
+	})//申请转正、续约申请、补充协议 合同信息弹窗
+
+	// 申请转正、续约申请、补充协议点击合同类型
+	function handleContractModel(e){
+		contractModel.show=false
+		if(e==='非标准'){
+			if(contractModel.type==='申请转正'){
+				sessionStorage.setItem('companyInfo',JSON.stringify(contractModel.data))
+				router.push({
+					path:'/turnCustom',
+				})
+			}else if(contractModel.type==='续约申请'){
+				sessionStorage.setItem('companyInfo',JSON.stringify(contractModel.data))
+				router.push({
+					path:'/updateCustom',
+				})
+			}else if(contractModel.type==='补充协议'){
+				sessionStorage.setItem('companyInfo',JSON.stringify(contractModel.data))
+				router.push({
+					path:'/addAgreement',
+				})
+			}
+			return
+		}
+		// 标准合同
+		contractDialog.show=true
+		contractDialog.type=contractModel.type
+		contractDialog.cusdata=contractModel.data
+	}
+
+	function closeContractInfoDia() {
+			contractDialog.show = false;
+			contractDialog.type = '';//类型 申请转正、续约申请、补充协议
+			contractDialog.cusdata = null;//客户信息(列表用户数据)
+	}
+
+	return {
+		contractModel,
+		applyTurn,
+		updateHandle,
+		addAgreement,
+		handleContractModel,
+		contractDialog,
+		closeContractInfoDia
+	}
+}
+
+
+/* 查看备注弹窗 客户列表 */
+export function useViewRemarkCustomDia() {
+	/* 查看备注 */
+	const lookRemarkTitle = ref('')//查看备注标题
+	const	lookRemarkList = ref([])//查看备注列表
+	const	lookRemarkTextarea = ref('')//备注的文本框
+	const	isRemarkLook = ref(false)////查看备注弹窗
+	const	lookRemarkItem = ref({})////查看备注的item项
+
+
+	function lookRemarkHandle(item) {
+		/*
+		lookRemarkTitle:'',//查看备注标题
+		lookRemarkList:[],//查看备注列表
+		*/
+		lookRemarkTitle.value = "备注";
+		lookAuthList.value = [];
+		lookRemarkItem.value = item;
+		customInterence.lookRemarkAuth({
+			CompanyId:item.CompanyId
+		}).then(res => {
+			if(res.Ret === 200) {
+				lookRemarkList.value=res.Data;
+			}
+		})
+		isRemarkLook.value = true;
+	}
+
+	//删除备注
+	async function lookRemarkDelete(data){
+		ElMessage('备注删除后不可恢复,确认删除吗?','提示',{
+			confirmButtonText: '确定',
+			cancelButtonText: '取消',
+			type:'warning',
+			appendToBody:false
+		}).then(async()=>{
+			const res = await customInterence.deleteRemark({
+				RemarkId:data.RemarkId
+			})
+			if(res.Ret!==200) return 
+			ElMessage.success("删除成功")
+			customInterence.lookRemarkAuth({
+				CompanyId:lookRemarkItem.value.CompanyId
+			}).then(res => {
+				if(res.Ret === 200) {
+					lookRemarkList.value=res.Data;
+				}
+			})
+		})
+	}
+
+	function closeRemark() {
+		isRemarkLook.value = false
+	}
+
+	return {
+		lookRemarkTitle,
+		lookRemarkList,
+		lookRemarkTextarea,
+		isRemarkLook,
+		lookRemarkItem,
+		lookRemarkDelete,
+		closeRemark,
+		lookRemarkHandle
+	}
+}
+
+
+/* 补全客户信息弹窗 */
+export function useCompleteInfoDia() {
+	const completeForm = ref({
+		show:false,
+	})//补全信息弹窗
+	
+	//获取客户详情判断基本信息是否完整 id 客户id type 1 跨部门 0 不是跨部门
+	async function getCustomerDetail(id,type){
+		
+		let res=await customInterence.customDetail({
+			CompanyId:id
+		})
+		if(res.Ret!=200) return
+	
+		// 跨部门领取
+		if(type===1){
+			if((res.Data.Item.RegionType!='海外'&&!res.Data.Item.Province&&!res.Data.Item.City)||!res.Data.Item.CreditCode){
+	
+				completeForm.value={
+					CompanyId:id,
+					name:res.Data.Item.CompanyName,
+					nameDisable:res.Data.Item.CompanyName!='',
+					Province:res.Data.Item.Province,
+					City:res.Data.Item.City,
+					CityDisable:res.Data.Item.City!='',
+					CreditCode:res.Data.Item.CreditCode,
+					CreditCodeDisable:res.Data.Item.CreditCode!='',
+					RegionType:res.Data.Item.RegionType,
+					
+					flag:true,//是否为跨部门
+					show:true
+				}
+			}else{
+				completeForm.value.show=false
+			}
+		}else{
+			let RoleType=RoleType.value
+			let IndustryId='',Source=';'
+			if(RoleType=='ficc'){
+				IndustryId=res.Data.FiccItem.IndustryId
+				Source=res.Data.FiccItem.Source
+			}else if(RoleType=='权益'){
+				IndustryId=res.Data.RaiItem.IndustryId
+				Source=res.Data.RaiItem.Source
+			}
+			// let IndustryId=res.Data.CreateAuth == 1?res.Data.FiccItem.IndustryId:res.Data.RaiItem.IndustryId
+			// let Source=res.Data.CreateAuth == 1?res.Data.FiccItem.Source:res.Data.RaiItem.Source
+			if((res.Data.Item.RegionType!='海外'&&!res.Data.Item.Province&&!res.Data.Item.City)||!res.Data.Item.CreditCode||!IndustryId||!Source){
+				completeForm.value={
+					nameDisable:res.Data.Item.CompanyName!='',
+					CityDisable:res.Data.Item.City!='',
+					CreditCodeDisable:res.Data.Item.CreditCode!='',
+					IndustryIdDisable:IndustryId!=' ',
+					SourceDisable:Source!='',
+					CompanyId:id,
+					name:res.Data.Item.CompanyName,
+					Province:res.Data.Item.Province,
+					City:res.Data.Item.City,
+					CreditCode:res.Data.Item.CreditCode,
+					IndustryId:IndustryId?IndustryId:'',
+					Source:Source,
+					RegionType:res.Data.Item.RegionType,
+					flag:false,//是否为跨部门
+					show:true
+				}
+			}else{
+				completeForm.value.show=false
+			}
+		}
+	
+		return new Promise((resolve,reject)=>{
+			resolve(completeForm.value.show)
+		})
+			
+	}
+
+	function closeCompleteInfo() {
+		completeForm.value.show = false
+	}
+
+	return {
+		completeForm,
+		getCustomerDetail,
+		closeCompleteInfo
+	}
+}
+
+/* 冻结客户理由弹窗 */
+export function useFreezeReasonDia() {
+	const isFreezeReason = ref(false)//冻结理由弹窗
+	const freezeData = ref({
+		reason:"",//冻结理由
+		CompanyId:'',
+		CompanyType:""
+	})
+
+
+	function freezHandle(item) {
+		isFreezeReason.value = true
+		freezeData.value.CompanyId=item.CompanyId
+		let RoleType=localStorage.getItem('RoleType')
+		freezeData.value.CompanyType=RoleType
+	}
+
+	//关闭冻结理由弹窗
+	function closeFreezeReason(){
+		isFreezeReason.value=false
+		freezeData.value={
+			reason:"",
+			CompanyId:'',
+			CompanyType:""
+		}
+	}
+
+	return {
+		isFreezeReason,
+		freezeData,
+		freezHandle,
+		closeFreezeReason
+	}
+
+}

+ 4 - 6
src/views/custom_manage/custom/components/ContactSaveEnDia.vue → src/views/custom_manage/customEn/components/ContactSaveEnDia.vue

@@ -1,5 +1,6 @@
 <script setup>
 import { reactive, ref,watch } from "vue";
+import $ from 'jquery'
 import { ElMessage } from 'element-plus'
 import { customInterence } from '@/api/api.js';
 
@@ -204,7 +205,6 @@ function moveContact(){
             v-model="submitForm.Name"
             style="width: 337px"
             placeholder="请输入联系人姓名"
-            size="medium"
           ></el-input>
         </el-form-item>
         <el-form-item
@@ -219,7 +219,6 @@ function moveContact(){
             v-model="submitForm.Email"
             style="width: 337px"
             placeholder="请输入邮箱地址"
-            size="medium"
           ></el-input>
         </el-form-item>
         <el-form-item label="手机号" prop="Phone">
@@ -253,7 +252,6 @@ function moveContact(){
           />
           <el-button
             type="primary"
-            size="medium"
             @click="clickinput"
             v-if="!submitForm.carte"
             >点击上传</el-button
@@ -295,12 +293,11 @@ function moveContact(){
       <div style="text-align: center; margin-top: 60px">
         <el-button
           type="primary"
-          size="medium"
           style="width: 120px; margin-right: 6px"
           @click="submit"
           >确定</el-button
         >
-        <el-button size="medium" style="width: 120px" @click="closeAddDia"
+        <el-button style="width: 120px" @click="closeAddDia"
           >取消</el-button
         >
       </div>
@@ -380,4 +377,5 @@ function moveContact(){
     </div>
   </el-dialog>
 </template>
-<style scoped lang="scss"></style>
+<style scoped lang="scss">
+</style>

+ 195 - 0
src/views/custom_manage/customEn/components/ToDoTotalEdit.vue

@@ -0,0 +1,195 @@
+<script setup>
+import { ref, watch } from 'vue'
+import { ElMessage } from 'element-plus'
+import { customInterence } from '@/api/api.js'
+import Editor from '@tinymce/tinymce-vue'
+import tinymce from "tinymce";//即使没有引用也不能删,Editor依赖tinymce
+import "tinymce/models/dom"
+import "tinymce/themes/silver";
+import "tinymce/plugins/lists"; //列表插件
+import "tinymce/plugins/quickbars"; //快速栏插件
+import "tinymce/plugins/fullscreen"; //全屏插件
+// import "tinymce/plugins/paste"; //黏贴插件
+import "tinymce/icons/default/icons";
+import 'tinymce/themes/silver/theme.min'
+
+const props = defineProps({
+  visible:{
+    type:Boolean,
+    default:false
+  }
+})
+const emit = defineEmits(['close'])
+
+const setting = {
+  // language: "zh_CN",
+  // language_url: './utils/tinymce_zh_CN.js',
+  menubar: false,
+  toolbar: [
+    "indent outdent alignleft aligncenter alignright alignjustify numlist bullist bold italic underline strikethrough",
+    "fontselect fontsizeselect forecolor backcolor",
+  ],
+  quickbars_selection_toolbar:false,  
+  quickbars_insert_toolbar: false,
+  // plugins: "lists quickbars paste",
+  inline: true,
+  selector:'#editorDom',
+  paste_as_text: true,
+  paste_block_drop: true,
+  fontsize_formats:'12px 14px 16px 18px 20px 22px 24px 36px 48px',
+  font_formats:`微软雅黑='微软雅黑';宋体='宋体';黑体='黑体';仿宋='仿宋';
+                楷体='楷体';隶书='隶书';幼圆='幼圆';Andale Mono=andale mono,times;
+                Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;
+                Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;
+                Courier New=courier new,courier;Georgia=georgia,palatino;
+                Helvetica=helvetica;`,
+  toolbar_persist:true,
+  fixed_toolbar_container: ".editor-tool",
+  skin_url: "/static/css",
+  content_url: "/static/css",
+  placeholder:"点击输入任务描述"
+}
+
+
+const updateTime = ref('')//更新时间
+const athor = ref('')//更新人
+const content = ref('')//最新内容 
+function getToDoDetail(){
+  customInterence.getToDoEditData().then(res=>{
+    if(res.Ret!==200) return 
+    const {Content,CreateUserName,ModifyTime} = res.Data
+    content.value = Content
+    updateTime.value = ModifyTime
+    athor.value = CreateUserName
+  })
+}
+
+function closeDia(){
+  updateTime.value = ''
+  athor.value = ''
+  content.value = ''
+  emit("close")
+}
+
+function saveContent(){
+  customInterence.saveToDoEditData({
+    Description:content.value
+  }).then(res=>{
+    if(res.Ret!==200) return 
+    ElMessage.success('保存成功')
+    closeDia()
+  })
+}
+
+watch(
+  () => props.visible,
+  (newVal) => {
+     if(newVal){
+        getToDoDetail()
+      }
+  }
+)
+
+</script>
+<template>
+  <el-dialog
+      :model-value="visible"
+      :close-on-click-modal="false"
+      :modal-append-to-body="false"
+      @close="closeDia"
+      width="889px"
+      draggable
+      center
+    >
+      <template #header>
+        <div style="display: flex; alignitems: center">
+          <span style="fontsize: 16px"
+            >To-Do编辑框</span
+          >
+        </div>
+      </template>
+      <div class="dialog-container">
+        <div class="label-box">
+          <p style="width:120px;color:#333333;">任务描述</p>
+          <p style="width:300px;color:#999999;">上次更新时间:{{updateTime}}</p>
+          <p>更新人:{{athor}}</p>
+        </div>
+        <div class="editor-box" >
+          <div class="editor-tool"></div>
+          <div class="editor" id="editorDom">
+            <Editor 
+              v-model="content" 
+              :init="setting" 
+            ></Editor>
+          </div>
+            
+        </div>
+        <div class="footer">
+          <el-button type="primary"  @click="saveContent">保存</el-button>
+          <el-button @click="closeDia">取消</el-button>
+        </div>
+      </div>
+    </el-dialog>
+</template>
+<style scoped lang="scss">
+.dialog-container{
+  padding:0 50px 15px 50px;
+  .label-box{
+    display: flex;
+    margin-bottom: 20px;
+  }
+  .editor-box{
+    .editor{
+      height:500px;
+      color: #333;
+      ul{
+        margin-left: 1em !important;
+        list-style-type: disc !important;
+      }
+      ol{
+        margin-left: 1em !important;
+        list-style-type: decimal !important;
+      }
+    }
+  }
+  .mce-content-body {
+    width: 100%;
+    height: 100%;
+    padding: 10px;
+    box-sizing: border-box;
+    border: 1px solid #ccc;
+    font-size: 16px;
+    &:focus-visible{
+      outline: 0;
+    }
+    ul{
+      margin-left: 1em !important;
+      list-style-type: disc !important;
+    }
+    ol{
+      margin-left: 1em !important;
+      list-style-type: decimal !important;
+    }
+  }
+  .mce-edit-focus{
+    outline: 0;
+  }
+  .mce-content-body:not([dir=rtl])[data-mce-placeholder]:not(.mce-visualblocks)::before {
+    left:10px !important;
+  }
+  .footer{
+    margin-top:20px;
+    text-align: center;
+  }
+}
+:deep(.to-do-total-edit-wrap){
+  ul{
+    margin-left: 1em;
+    list-style-type: disc;
+  }
+  ol{
+    margin-left: 1em;
+    list-style-type: decimal;
+  }
+}
+</style>

+ 128 - 0
src/views/custom_manage/customEn/components/UnDoStatistic.vue

@@ -0,0 +1,128 @@
+<script setup>
+import { ref, watch } from 'vue'
+import { customInterence } from '@/api/api.js'
+
+const props = defineProps({
+  visible:{
+    type:Boolean,
+    default:false
+  }
+})
+const emit = defineEmits(['close'])
+
+const tableLabel = [{
+  key:'CompanyName',
+  label:'客户名称'
+},
+{
+  key:'Content',
+  label:'任务描述'
+},
+{
+  key:'EndTime',
+  label:'截止时间',
+  sortable:'custom'
+}]
+
+const tableData = ref([])
+const pageNo = ref(1)
+const pageSize = ref(10)
+const total = ref(0)
+const sortType = ref(0)
+
+function getTableData(){
+  customInterence.getUnDoList({
+    PageSize:pageSize.value,
+    CurrentIndex:pageNo.value,
+    SortType:sortType.value
+  }).then(res=>{
+    if(res.Ret!==200) return 
+    tableData.value = res.Data.List
+    total.value = res.Data.Paging.Totals
+  })
+}
+
+function handleCurrentChange(page){
+  pageNo.value = page
+  getTableData()
+}
+
+function closeDia(){
+  tableData.value=[]
+  sortType.value=0
+  pageNo.value = 1
+  emit("close")
+}
+
+function sortChange({order}){
+  sortType.value = order?order==='ascending'?1:2:0
+  getTableData()
+}
+
+
+watch(() =>props.visible,
+  (newVal) => {
+    if(newVal){
+        getTableData()
+    }
+  }
+)
+</script>
+<template>
+<div class="un-do-statistic-wrap">
+  <el-dialog
+    :model-value="visible"
+    :close-on-click-modal="false"
+    :modal-append-to-body="false"
+    @close="closeDia"
+    width="889px"
+    draggable
+    center
+  >
+    <template #header>
+      <div style="display: flex; align-items: center">
+        <span style="font-size: 16px"
+          >未完成To-Do</span
+        >
+      </div>
+    </template>
+    <div class="dialog-container">
+      <div class="table-container">
+          <el-table
+            v-if="tableData&&visible"
+            :data="tableData"
+            border
+            @sort-change="sortChange"
+            max-height="600"
+            style="width: 100%; margin-bottom: 20px">
+            <el-table-column align="center"
+                v-for="item in tableLabel" :key="item.key"
+                :label="item.label"
+                :width="item.widthsty" 
+                :min-width="item.minwidthsty"
+                :sortable="item.sortable"
+            >
+            <template #default="{row}">
+              <span>{{row[item.key]}}</span>
+            </template>
+            </el-table-column>
+          </el-table>
+          <el-pagination 
+            layout="total,prev,pager,next" 
+            background
+            :current-page="pageNo"
+            @current-change="handleCurrentChange"
+            :page-size="pageSize" 
+            :total="total"
+            style="text-align:right;">
+          </el-pagination>
+      </div>
+    </div>
+  </el-dialog>
+</div>
+</template>
+<style scoped lang="scss">
+.dialog-container{
+  padding:0 50px 15px 50px;
+}
+</style>

+ 0 - 0
src/views/custom_manage/custom/components/clickNumberDetailDia.vue → src/views/custom_manage/customEn/components/clickNumberDetailDia.vue


+ 134 - 0
src/views/custom_manage/customEn/components/historyToDoDiaEn.vue

@@ -0,0 +1,134 @@
+<script setup>
+import { reactive, ref,computed,watch } from 'vue'
+import mPage from '@/components/mPage.vue';
+import { customInterence } from '@/api/api.js'
+
+const props = defineProps({
+  visible:{
+    type:Boolean,
+    required:true
+  },
+  // todo数据
+  todoInfo:{
+    type:Object,
+    required:true
+  }
+})
+const emit = defineEmits(['close'])
+
+const dialogTitle = computed(()=>{
+  return props.todoInfo.CompanyName+"——任务历史记录"
+})
+
+
+const historyList = ref([])
+const params = reactive({
+  CurrentIndex:1,
+  PageSize:10,
+  CompanyId:0,
+  SortType:""
+})
+const total = ref(0)
+const firstLoading = ref(false)
+function getList(){
+  customInterence.getTodoListEn(params).then(res=>{
+    firstLoading.value = false
+    historyList.value = res.Data.List || []
+    total.value = res.Data.Paging.Totals
+  })
+}
+
+//切换页码
+function pageChange(page_no){
+  params.CurrentIndex=page_no
+  getList()
+}
+// 排序
+function createtimeSortChange({order}){
+  params.SortType=order=="ascending"?'2':order=="descending"?'1':'0'
+  getList()
+}
+
+function closeDia(){
+  emit("close")
+}
+
+
+watch(
+  () => props.visible,
+  (newVal) =>{
+    if(!newVal) return 
+    firstLoading.value = true
+    params.CompanyId = props.todoInfo.CompanyId
+    getList()
+  }
+)
+
+</script>
+<template>
+  <el-dialog :title="dialogTitle" append-to-body width="1042px" top="10vh"
+  :model-value="visible" @closed="closeDia" :close-on-click-modal="false">
+    <div  style="padding:10px 20px 35px 20px;">
+      <el-table :data="historyList" border @sort-change="createtimeSortChange" 
+      v-loading="firstLoading" element-loading-text="加载中">
+        <el-table-column label="任务描述" align="center" prop="Content">
+          <template #default="{row}">
+            {{row.Content}}
+          </template>
+        </el-table-column>
+        <el-table-column label="创建人" align="center" prop="CreateUserName" width="100">
+          <template #default="{row}">
+            {{row.CreateUserName}}
+          </template>
+        </el-table-column>
+        <el-table-column label="创建时间" align="center" width="160" sortable="custom"
+        prop="CreateTime">
+          <template #default="{row}">
+            {{row.CreateTime}}
+          </template>
+        </el-table-column>
+        <el-table-column label="截止日期" align="center" width="120"
+        prop="EndTimeStr">
+          <template #default="{row}">
+            {{row.EndTimeStr}}
+          </template>
+        </el-table-column>
+        <el-table-column label="备注" align="center" width="150"
+        prop="Remark">
+          <template #default="{row}">
+            {{row.Remark}}
+          </template>
+        </el-table-column>
+        <el-table-column label="审核人" align="center" width="100"
+        prop="ApproveUserName">
+          <template #default="{row}">
+            {{row.ApproveUserName || '--'}}
+          </template>
+        </el-table-column>
+        <el-table-column label="审核时间" align="center" width="160"
+        prop="ApproveTime">
+          <template #default="{row}">
+            {{row.ApproveTime || '--'}}
+          </template>
+        </el-table-column>
+      </el-table>
+      <!-- 页数选择器 -->
+      <m-page
+        v-show="total!=0"
+        style="float: none;text-align: right;margin-top: 70px;"
+        :page_no="params.CurrentIndex"
+        :pageSize="params.PageSize"
+        :total="total"
+        @handleCurrentChange="pageChange"
+      />
+    </div>
+  </el-dialog>
+</template>
+<style scoped lang="scss">
+  .custom-title{
+    margin-bottom: 20px;
+    font-size: 14px;
+    font-weight: 400;
+    color: #000000;
+  }
+</style>

+ 85 - 0
src/views/custom_manage/customEn/components/reportVarietyEnSet.vue

@@ -0,0 +1,85 @@
+<script setup>
+import { computed, ref } from 'vue'
+import { reportVarietyENInterence } from '@/api/api.js'
+
+const props = defineProps({
+  checked:{
+    type: Array
+  },
+  disabled:{
+    type: Boolean
+  }
+})
+
+// 计算是否全选
+const isCheckedAll = computed(()=>{
+    return itemGroup=>itemGroup.Child.every(item=>checkedItems.value.includes(item.EnPermissionId))
+})
+// 计算是否模糊
+const isIndeterminate = computed(()=>{
+    return itemGroup=>!itemGroup.Child.every(item=>checkedItems.value.includes(item.EnPermissionId)) && itemGroup.Child.some(item=>checkedItems.value.includes(item.EnPermissionId))
+})
+
+
+const opts = ref([])
+const checkedItems = ref(props.checked||[])
+function getOpts(){
+    reportVarietyENInterence.filterVarietyOpts({}).then(res=>{
+        opts.value=res
+    })
+}
+getOpts()
+
+// 大项复选框改变
+function groupChange(itemGroup,val){
+    if(val){
+        // 大项选中,将组中所有小项选中
+        itemGroup.Child.forEach(item=>{
+            if(!checkedItems.value.includes(item.EnPermissionId)) checkedItems.value.push(item.EnPermissionId)
+        })
+    }else{
+        // 大项取消,将组中所有小项取消
+        checkedItems.value=checkedItems.value.filter(item=>!itemGroup.Child.map(item=>item.EnPermissionId).includes(item))
+    }
+}
+
+defineExpose({
+  checkedItems
+})
+
+</script>
+<template>
+  <div class="report-variety">
+      <div v-for="itemGroup,index in opts" :key="index" class="group-list">
+          <div style="flex-shrink: 0;margin-right:30px;width:100px">
+              <el-checkbox 
+                  class="item-group" 
+                  :model-value="isCheckedAll(itemGroup)" 
+                  :indeterminate="isIndeterminate(itemGroup)" 
+                  @change="groupChange(itemGroup,$event)"
+                  :disabled="disabled"
+              >{{itemGroup.EnPermissionName}}:</el-checkbox>
+          </div>
+          <div style="flex:1">
+              <el-checkbox 
+                  style="margin-bottom:15px" 
+                  v-model="checkedItems" 
+                  v-for="item in itemGroup.Child" 
+                  :key="item.EnPermissionId" 
+                  :label="item.EnPermissionId"
+                  :disabled="disabled"
+              >{{item.EnPermissionName}}</el-checkbox>
+          </div>
+      </div>
+  </div>
+</template>
+<style scoped lang="scss">
+.group-list{
+    // line-height: 80px;
+    margin-bottom: 20px;
+    display: flex;
+    .item-group{
+        font-weight: 600;
+    }
+}
+</style>

+ 161 - 0
src/views/custom_manage/customEn/components/todoDialogEn.vue

@@ -0,0 +1,161 @@
+<script setup>
+import { reactive, ref,nextTick,computed,watch } from "vue";
+import { customInterence } from '@/api/modules/crmApi';
+
+const props = defineProps({
+  visible:{
+    type:Boolean,
+    required:true
+  },
+  // todo数据
+  todoInfo:{
+    type:Object,
+    required:true
+  },
+  // 新建、编辑、完成
+  optionType:{
+    type:String,
+    default:'新建'
+  }
+})
+const emit = defineEmits(['todoFormRef','close'])
+
+const dialogTitle = computed(() =>{
+  return props.todoInfo.CompanyName+"——任务详情"
+})
+
+const todoForm = reactive({
+  CompanyId:0,
+  Id:0,
+  Description:"",
+  EndTime:"",
+  Createtime:"",
+  Remark:""
+})
+const todoFormRef = ref(null)
+// 确认提交
+function todoConfirm(){
+  
+  todoFormRef.value.validate(valid=>{
+    if(valid){
+      emit("todoConfirm",todoForm)
+      closeDia()
+    }
+  })
+}
+
+// 关闭弹窗
+function closeDia(){
+  emit("close")
+
+  todoForm.CompanyId=0,
+  todoForm.Description="",
+  todoForm.EndTime="",
+  todoForm.Createtime="",
+  todoForm.Remark=""
+
+  nextTick(()=>{
+    todoFormRef.value.clearValidate()
+  })
+}
+
+watch(
+  () => props.visible,
+  (newVal)=>{
+    if(!newVal) return 
+    todoForm.CompanyId=props.todoInfo.CompanyId
+    if(props.optionType!='新建'){
+      customInterence.todoEditListEn({CompanyId:props.todoInfo.CompanyId}).then(res=>{
+        todoForm.Description = res.Data[0].Content
+        todoForm.Createtime = res.Data[0].CreateTime
+        todoForm.EndTime = res.Data[0].EndTimeStr
+        todoForm.Id = res.Data[0].Id
+      })
+    }
+  }
+)
+
+</script>
+<template>
+  <el-dialog
+    :title="dialogTitle"
+    append-to-body
+    width="800px"
+    :model-value="visible"
+    @closed="closeDia"
+    :close-on-click-modal="false"
+  >
+    <div style="padding: 10px 20px 35px 20px">
+      <el-form :model="todoForm" label-width="100px" ref="todoFormRef">
+        <el-form-item
+          label="任务描述:"
+          prop="Description"
+          :rules="{
+            required: true,
+            message: '任务描述不能为空',
+            trigger: 'blur',
+          }"
+        >
+          <el-input
+            v-model="todoForm.Description"
+            resize="none"
+            :rows="10"
+            placeholder="请输入任务描述"
+            type="textarea"
+            :disabled="optionType == '完成'"
+          ></el-input>
+        </el-form-item>
+        <el-form-item
+          label="创建时间:"
+          prop="Createtime"
+          v-if="optionType == '完成'"
+          :rules="{
+            required: true,
+            message: '创建时间不能为空',
+            trigger: 'blur',
+          }"
+        >
+          <span>{{ todoForm.Createtime }}</span>
+        </el-form-item>
+        <el-form-item
+          label="截止日期:"
+          prop="EndTime"
+          :rules="{
+            required: true,
+            message: '截止日期不能为空',
+            trigger: 'change',
+          }"
+        >
+          <el-date-picker
+            v-model="todoForm.EndTime"
+            placeholder="请选择日期"
+            value-format="yyyy-MM-dd"
+            :clearable="false"
+            style="width: 329px"
+            v-if="optionType != '完成'"
+          ></el-date-picker>
+          <span v-else>{{ todoForm.EndTime }}</span>
+        </el-form-item>
+        <el-form-item label="备注:" prop="Remark" v-if="optionType == '完成'">
+          <el-input
+            v-model="todoForm.Remark"
+            resize="none"
+            :rows="2"
+            placeholder="请输入备注"
+            type="textarea"
+          ></el-input>
+        </el-form-item>
+      </el-form>
+      <div style="margin-top: 40px; text-align: center">
+        <el-button
+          type="primary"
+          style="width: 120px; margin-right: 10px"
+          @click="todoConfirm"
+          >确定</el-button
+        >
+        <el-button style="width: 120px" @click="closeDia">取消</el-button>
+      </div>
+    </div>
+  </el-dialog>
+</template>
+<style scoped lang="scss"></style>

+ 569 - 0
src/views/custom_manage/customEn/customListEn.vue

@@ -0,0 +1,569 @@
+<script setup>
+import { reactive, ref } from 'vue'
+import { useRouter } from 'vue-router'
+import { ElMessage,ElMessageBox } from 'element-plus'
+import { Search } from '@element-plus/icons-vue'
+import { customInterence,reportVarietyENInterence } from '@/api/api.js'
+import _ from 'lodash'
+import mPage from '@/components/mPage.vue';
+import clickNumberDetail from "./components/clickNumberDetailDia.vue"
+import todoDialogEn from "./components/todoDialogEn.vue"
+import historyToDoDiaEn from './components/historyToDoDiaEn.vue';
+import country from "@/utils/countryData"
+import UnDoStatistic from './components/UnDoStatistic.vue';
+import ToDoTotalEdit from './components/ToDoTotalEdit.vue';
+import reportVarietyEnSet from './components/reportVarietyEnSet.vue'
+
+const router = useRouter()
+
+const countryData=country
+
+// 获取销售列表
+const sellerList = ref([])
+function getSellerList(){
+  customInterence.saleslist({SellerType:1}).then(res=>{
+    if(res.Ret == 200){
+      sellerList.value = res.Data.List || []
+    }
+  })
+}
+getSellerList()
+
+
+/* 获取销售 */
+//销售筛选
+const sales = ref([])
+const salesArr = ref([])
+function getSale() {
+  customInterence.getSale({Status:0}).then(res => {
+      if(res.Ret === 200) {
+          salesArr.value = res.Data.List||[];
+      }
+  })
+}
+getSale()
+
+
+
+// 获取列表
+const searchParams = reactive({
+  Keywords:"",
+  CurrentIndex:1,
+  PageSize:10,
+  SortType:"",
+  SortParam:""
+})
+const dataList = ref([])
+const total = ref(0)
+const varietyVal = ref([])
+function getList(type=''){
+  if(type=='search'){
+    searchParams.CurrentIndex=1
+  }
+  const arr=[]
+  varietyVal.value&&varietyVal.value.forEach(_e => {
+    arr.push(_e[1])
+  });
+  customInterence.getCustomListEn({
+      ...searchParams,
+      EnPermissionIds:arr.join(','),
+      Sellers:sales.value.join(',')
+  }).then(res=>{
+    // console.log(res);
+    if(res.Ret == 200){
+      dataList.value = res.Data.List || []
+      total.value = res.Data.Paging.Totals
+    }
+  })
+}
+getList()
+
+
+ //切换页码
+function pageChange(page_no){
+  searchParams.CurrentIndex=page_no
+  getList()
+}
+function refreshList(){
+  searchParams.Keywords="",
+  searchParams.CurrentIndex=1,
+  searchParams.PageSize=8,
+  searchParams.SortType="",
+  searchParams.SortParam=""
+
+  varietyVal.value=[]
+  getList()
+}
+// 累计点击量排序
+function sortChange({order,prop}){
+  console.log('order',order)
+  const sortParamMap = {
+    "todoStatus":"todoStatusStr",
+    "dlDay":"deadLine"
+  }
+  if(sortParamMap[prop]){
+    const {SortParam} = searchParams
+    searchParams.SortParam = SortParam === sortParamMap[prop]?'':sortParamMap[prop]
+    searchParams.SortType=''
+  }else{
+    searchParams.SortParam = ''
+    searchParams.SortType=order=="descending"?'1':order=="ascending"?'2':'0'
+  }
+  getList()
+}
+
+
+
+// 获取英文品种权限数据
+const varietyOpt = ref([])
+function getENReportVarietyOpts(){
+  reportVarietyENInterence.filterVarietyOpts({}).then(res=>{
+    varietyOpt.value=res
+  })
+}
+getENReportVarietyOpts()
+
+
+
+ // ----------------------------------TODO
+ const todoInfo = ref({}) // todo数据项
+const todoDialogShow = ref(false)// 是否打开新建/编辑 TODO的弹窗
+const todoOptionType = ref("")// todo操作类型 新建、编辑、完成
+const todoHistoryDialogShow = ref(false)
+const isToDoTotalEditShow = ref(false)
+const isUnDoStatisticShow = ref(false)
+const todoFormRef = ref(null)
+// 打开TODO弹窗
+function openTodoEditDia(row,type){
+  //打开新建/编辑/审核弹窗
+  // console.log(row,type);
+  todoInfo.value=row
+  if(['新建','编辑',"完成"].includes(type)){
+    todoOptionType.value = type
+    todoDialogShow.value = true
+  }else{
+    todoHistoryDialogShow.value=true
+  }
+}
+// 新建/编辑/审核确认提交
+function todoSubmit(todo){
+  let apiName;
+  let param={}
+  if(todoOptionType.value=='新建'){
+    apiName = "addCustomToDoEn"
+    param={
+      CompanyId:todo.CompanyId,
+      Description:todo.Description,
+      EndTime:todo.EndTime
+    }
+  }else if(todoOptionType.value=='编辑'){
+    apiName = "editCustomToDoEn"
+    param={
+      Id:todo.Id,
+      CompanyId:todo.CompanyId,
+      Description:todo.Description,
+      EndTime:todo.EndTime
+    }
+  }else if(todoOptionType.value=='完成'){
+    apiName = "finishCustomToDoEn"
+    param={
+      Id:todo.Id,
+      Remark:todo.Remark
+    }
+  }
+  customInterence[apiName](param).then(res=>{
+    if(res.Ret==200){
+      ElMessage.success(todoOptionType.value+'任务成功')
+      if(todoOptionType.value!='编辑'){
+        getList()
+      }
+    }
+  })
+}
+function changeEnabled(data){
+  const {CompanyId,Enabled} = data
+  const enabled = Enabled===1?0:1
+  customInterence.editEnabledAll({
+    CompanyId,Enabled:enabled
+  }).then(res=>{
+    if(res.Ret!==200) return 
+    ElMessage.success(`${Enabled===1?'禁用':'启用'}成功`)
+    getList()
+  })
+}
+// 根据todo的状态选择颜色
+function selectTodoColor(TodoButtonColor){
+  return TodoButtonColor=='gray'?"#D9D9D9":TodoButtonColor=='red'?"#D1433A":"#4EC225"
+}
+// 根据todo的状态选择操作按钮
+function selectTodoOption(TodoInfo){
+  if(TodoInfo.TodoStatus){
+    if(!TodoInfo.HiddenConfirm){
+      return ["编辑","完成","历史"]
+    }else{
+      return ["编辑","历史"]
+    }
+  }else{
+    return ["新建","历史"]
+  }
+}
+
+
+
+// -------------------------------------------添加客户
+function openAddUserDia(){
+  const { href } = router.resolve({
+    path:'/addCustomEn',
+  });
+  window.open(href, '_blank');
+}
+
+ //查看客户看详情
+function customDetail(row){
+  const { href } = router.resolve({
+  path:'/detailCustomEn',
+  query:{
+    companyId:row.CompanyId,
+  }});
+  window.open(href, '_blank');
+}
+
+ // 编辑客户
+function editCustom(row){
+  const { href } = router.resolve({
+  path:'/editCustomEn',
+  query:{
+    companyId:row.CompanyId,
+  }});
+  window.open(href, '_blank');
+}
+
+
+ // 删除客户
+function delCustom(row){
+  ElMessageBox.confirm(`是否确认删除客户<span style="color:#409EFF">${row.CompanyName}</span>,并删除该客户下所有的联系人?`,"操作提示",
+  {
+    type:"warning",
+    dangerouslyUseHTMLString:true,
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+  }).then(res=>{
+    customInterence.delCustomEn({CompanyId:row.CompanyId}).then(res=>{
+      if(res.Ret == 200){
+        ElMessage.success("删除客户成功")
+        getList()
+      }
+    })
+  }).catch(() => {});
+}
+
+
+  // -----------------------------点击量详情
+const showClickNumberDia = ref(false)
+const clickNumberDetailItem = reactive({
+  customerName:"",
+  customerId:0
+})
+function clickNumberDetailHandle(row){
+  clickNumberDetailItem.customerName = row.CompanyName
+  clickNumberDetailItem.customerId = row.CompanyId
+  showClickNumberDia.value=true
+}
+
+
+
+const showSetVariety = ref(false)
+const checkedVariety = ref([])
+const activeItem = ref({})//当前编辑权限的客户信息
+const varietyInsRef = ref(null)
+function handleSaveVariety(){
+  let params={
+    CompanyId:activeItem.value.CompanyId,
+    EnPermissions:varietyInsRef.value.checkedItems||[]
+  }
+  // console.log(params);
+  customInterence.setENCustomReportVariety(params).then(res=>{
+    if(res.Ret===200){
+      ElMessage.success('设置成功')
+      refreshList()
+      showSetVariety=false
+    }
+  })
+}
+function handleShowSetVariety(item){
+  activeItem.value=item
+  checkedVariety.value=_.cloneDeep(item.EnPermissions||[]) 
+  showSetVariety.value=true
+}
+
+function handleChangeVariety(){
+
+  searchParams.Keywords="",
+  searchParams.CurrentIndex=1,
+  searchParams.PageSize=8,
+  searchParams.SortType="",
+  searchParams.SortParam=""
+
+  getList()
+}
+
+
+
+</script>
+<template>
+  <div id="custom-listEn-container">
+    <!-- 顶部区域 -->
+    <div class="top-zone">
+      <div class="btn-box">
+        <el-button type="primary" @click="openAddUserDia" style="height: 40px;width: 110px;">添加客户</el-button>
+        <el-button type="primary" @click="isToDoTotalEditShow=true" style="height: 40px;width: 110px;padding:0;text-align:center;line-height:40px;">TO-DO编辑框</el-button>
+        <el-button type="primary" @click="isUnDoStatisticShow=true" style="height: 40px;width: 110px;padding:0;text-align:center;line-height:40px;">未完成TO-DO</el-button>
+      </div>
+      <div>
+        <el-cascader
+            v-model="sales"
+            placeholder="请选择销售"
+            :options="salesArr"
+            :props="{
+                emitPath:false,
+                multiple: true,
+                label:'RealName',
+                children:'ChildrenList',
+                value:'AdminId'
+            }"
+            :show-all-levels="false"
+            collapse-tags
+            clearable
+            filterable
+            @change="getList('search')">
+        </el-cascader>
+        <el-cascader
+          v-model="varietyVal"
+          :options="varietyOpt"
+          collapse-tags
+          clearable
+          :props="{
+            multiple:true,
+            value:'EnPermissionId',
+            label:'EnPermissionName',
+            children:'Child'
+          }"
+          placeholder="请选择阅读权限"
+          @change="handleChangeVariety"
+          style="margin-left:20px"
+        />
+        <el-input 
+          v-model="searchParams.Keywords" 
+          placeholder="请输入客户名称/邮箱/手机号" 
+          @input="getList('search')"
+          style="width: 520px;margin-left:20px"
+        >
+          <template #prefix>
+						<el-icon><Search /></el-icon>
+					</template>
+        </el-input>
+      </div>
+      
+    </div>
+    <!-- 表格区域 -->
+    <div class="table-zone">
+        <el-table :data="dataList" border @sort-change="sortChange">
+          <el-table-column label="客户名称" align="center" prop="CompanyName">
+            <template #default="{row}">
+              <span class="table-options" @click="customDetail(row)" >{{row.CompanyName}}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="To-Do" align="center" prop="todoStatus" sortable="custom">
+            <template #header>
+							<div class="todolabel" :class="{sort:searchParams.SortParam=='todoStatusStr'}" style="display:inline-block;">
+								<span>To-Do</span>
+							</div>
+						</template>
+            <template #default="{row}">
+              <div class="todo-status-box">
+                <div class="todo-status-flag" :style="'background-color:'+selectTodoColor(row.TodoInfo.TodoButtonColor)"></div>
+                <div>
+                  <div class="table-options" 
+                  v-for="item in selectTodoOption(row.TodoInfo)" :key="item"
+                  @click="openTodoEditDia(row,item)">
+                    {{item}}
+                  </div>
+                </div>
+              </div>
+              <!-- {{row.todoStatus}} -->
+            </template>
+          </el-table-column>
+          <el-table-column align="center" prop="dlDay" sortable="custom">
+            <template #header>
+              <el-tooltip content="未完成To Do任务的截止日期-当前日期" placement="top-start">
+                <div class="todolabel" :class="{sort:searchParams.SortParam=='deadLine'}" style="display:inline-block;">
+                  <span>DL</span>
+                  <i class="el-icon-warning-outline"></i>
+                </div>
+              </el-tooltip>
+            </template>
+            <template #default="{row}">
+              {{row.TodoInfo.Deadline || '--'}}
+            </template>
+          </el-table-column>
+          <el-table-column label="所属国家" align="center" prop="Country">
+            <template #default="{row}">
+              {{row.Country}}
+            </template>
+          </el-table-column>
+          <el-table-column label="所属销售" align="center" prop="SellerName">
+            <template #default="{row}">
+              {{row.SellerName}}
+            </template>
+          </el-table-column>
+          <el-table-column label="累计点击量" align="center" 
+          width="140" prop="ViewTotal" sortable="custom">
+            <template #default="{row}">
+              <span class="table-options" @click="clickNumberDetailHandle(row)" v-if="row.ViewTotal!=0">{{row.ViewTotal}}</span>
+              <span v-else>{{row.ViewTotal}}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="创建时间" align="center" show-overflow-tooltip prop="CreateTime">
+            <template #default="{row}">
+              {{row.CreateTime}}
+            </template>
+          </el-table-column>
+          <el-table-column label="状态" align="center" show-overflow-tooltip prop="CreateTime">
+            <template #default="{row}">
+              <span :style="`color:${row.Enabled!==1?'red':''}`">{{row.Enabled===0?'禁用':row.Enabled===1?'启用':'部分禁用'}}</span>
+            </template>
+          </el-table-column>
+          <el-table-column label="操作" align="center">
+            <template #default="{row}">
+              <span class="table-options option-button" @click="handleShowSetVariety(row)">权限配置</span>
+              <span class="table-options option-button" @click="editCustom(row)">编辑</span>
+              <span class="table-options option-button" @click="changeEnabled(row)">{{row.Enabled===1?'禁用':'启用'}}</span>
+              <span class="table-options option-button" @click="delCustom(row)" style="color:#D1433A;">删除</span>
+            </template>
+          </el-table-column>
+          <template #empty>
+            <div class="table-noData">
+              <img src="~@/assets/img/cus_m/nodata.png">
+              <span>暂无数据</span>
+            </div>
+          </template>
+      </el-table>
+    </div>
+    <!-- 页数选择器 -->
+    <m-page
+      :page_no="searchParams.CurrentIndex"
+      :pageSize="searchParams.PageSize"
+      :total="total"
+      style="position: absolute;right: 50px;bottom: 50px;"
+      @handleCurrentChange="pageChange"
+    />
+
+    <!-- 详情弹窗 -->
+    <click-number-detail :visible="showClickNumberDia" 
+    :name="clickNumberDetailItem.customerName" 
+    :id="clickNumberDetailItem.customerId"></click-number-detail>
+    <!-- to do新建/编辑/完成弹窗 -->
+    <todo-dialog-en :visible="todoDialogShow" :todoInfo="todoInfo" 
+     @todoConfirm="todoSubmit" :option-type="todoOptionType" @close="todoDialogShow=false"></todo-dialog-en>
+     <!-- to do历史弹窗 -->
+     <history-to-do-dia-en :visible="todoHistoryDialogShow" :todoInfo="todoInfo" @close="todoHistoryDialogShow=false"></history-to-do-dia-en>
+     <!-- 未完成to-do统计弹窗 -->
+     <un-do-statistic :visible="isUnDoStatisticShow" @close="isUnDoStatisticShow=false"></un-do-statistic>
+     <!-- To-Do编辑框弹窗 -->
+     <to-do-total-edit :visible="isToDoTotalEditShow" @close="isToDoTotalEditShow=false"></to-do-total-edit>
+    <!-- 配置权限 -->
+    <el-dialog 
+      title="权限配置" 
+      v-model="showSetVariety" 
+      width="705px"
+      append-to-body 
+      :close-on-click-modal="false"
+    >
+      <div style="padding:10px 40px">
+        <reportVarietyEnSet ref="varietyInsRef" :checked="checkedVariety" v-if="showSetVariety" />
+      </div>
+      <div style="text-align:center;padding:10px 0 30px 0">
+        <el-button type="primary" plain @click="showSetVariety=false">取消</el-button>
+        <el-button type="primary" style="margin-left:20px" @click="handleSaveVariety">保存</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+<style scoped lang="scss">
+#custom-listEn-container{
+    display: flex;
+    flex-direction: column;
+    height:calc(100vh - 110px);
+    background-color: white;
+    border: 1px solid #ECECEC;
+    border-radius: 2px;
+    box-sizing: border-box;
+    padding: 20px 30px 30px 30px;
+    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+    .top-zone{
+      display: flex;
+      justify-content: space-between;
+      margin-bottom: 20px;
+    }
+    .table-zone{
+      overflow: auto;
+      flex-grow: 1;
+      margin-top: 10px;
+      margin-bottom: 50px;
+      .todo-status-box{
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        .todo-status-flag{
+          width: 10px;
+          height: 10px;
+          border-radius: 50%;
+          margin-right: 20px;
+        }
+      }
+      .table-options{
+        cursor: pointer;
+        font-size: 14px;
+        color: #409EFF;
+      }
+      .option-button{
+        white-space:nowrap;
+        margin: 0 6px;
+      }
+      .table-noData{
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+        margin: 18vh 0;
+        img{
+          height: 110px;
+          width: 136px;
+        }
+        span{
+          font-weight: 400;
+          font-size: 16px;
+          color: #999999;
+        }
+      }
+    }
+
+    :deep(.todolabel){
+			&+span.caret-wrapper{
+				.sort-caret.ascending{
+					border-bottom-color: #C0C4CC;
+				}
+				.sort-caret.descending{
+					border-top-color: #C0C4CC
+				}
+			}
+		}
+		:deep(.todolabel.sort){
+			&+span.caret-wrapper{
+				.sort-caret.ascending{
+					border-bottom-color: #409EFF;
+				}
+			}
+		}
+  }
+</style>

+ 488 - 0
src/views/custom_manage/customEn/editCustomEn.vue

@@ -0,0 +1,488 @@
+<script setup>
+import { reactive, ref,onMounted } from 'vue'
+import { useRoute, useRouter } from 'vue-router';
+import { customInterence } from '@/api/api.js'
+import { ElImageViewer,ElMessage,ElMessageBox } from 'element-plus'
+import { Search } from '@element-plus/icons-vue'
+import { useClickNumDia } from "../custom/hooks/customlistHook";
+import mPage from '@/components/mPage.vue';
+import clickNumberDetail from "./components/clickNumberDetailDia.vue"
+import country from "@/utils/countryData"
+import ContactSaveEnDia from './components/ContactSaveEnDia.vue';
+import reportVarietyEnSet from './components/reportVarietyEnSet.vue'
+
+const $router = useRouter()
+const $route = useRoute()
+
+const countryData=country
+
+const {showClickTimesDia,clickTimesDetailItem,clickTimesDetail,closeNumDia,} = useClickNumDia(); //点击量详情弹窗
+
+onMounted(()=> {
+  if($route.path == '/addCustomEn'){
+    getSellerList()
+    return
+  } 
+  if(!$route.query.companyId){
+    // 无客户信息
+    $router.replace('/customListEn')
+    return 
+  }
+
+  getSellerList()
+  customDetail()
+  getList()
+})
+
+// 获取销售列表
+const sellerList = ref([])
+function getSellerList(){
+  customInterence.saleslist({SellerType:1}).then(res=>{
+    if(res.Ret == 200){
+      sellerList.value = res.Data.List || []
+    }
+  })
+}
+
+
+// edit 编辑英文客户 英文客户详情
+const viewType = ref($route.path == '/detailCustomEn'?'detail':'edit')
+const editForm = reactive({
+  CompanyId:$route.query.companyId||0,
+  CompanyName:"",
+  CountryCode:"",
+  Country:"",
+  SellerId:""
+})
+
+const varietyOpts = ref([])
+// 客户详情
+function customDetail(){
+  customInterence.customDetailEn({CompanyId:editForm.CompanyId}).then(res=>{
+    if(res.Ret == 200){
+      editForm.CompanyName=res.Data.CompanyName
+      editForm.Country=res.Data.Country
+      editForm.CountryCode=res.Data.CountryCode
+      editForm.SellerId=res.Data.SellerId
+      varietyOpts.value=res.Data.EnPermissions
+    }else{
+      $router.replace('/customListEn')
+    }
+  })
+}
+
+
+// 联系人列表搜索参数
+const searchParams = reactive({
+  CompanyId:$route.query.companyId||0,
+  CurrentIndex:1,
+  PageSize:8,
+  SortType:"",
+  Keywords:""
+})
+const total = ref(0)
+  // 联系人列表
+const contactsList = ref([])
+function getList(type=''){
+  if(type=="search"){
+    searchParams.CurrentIndex=1
+  }
+  customInterence.getContactsListEn(searchParams).then(res=>{
+    if(res.Ret == 200){
+      contactsList.value = res.Data.List || []
+      total.value = res.Data.Paging.Totals
+    }
+  })
+}
+// 累计点击量排序
+function clickTimesSortChange({order}){
+  searchParams.SortType=order=="ascending"?'2':order=="descending"?'1':''
+  getList()
+}
+// 重置列表和搜索项
+function refreshList(){
+  searchParams.SortType=""
+  searchParams.Keywords=""
+  searchParams.CurrentIndex=1
+  getList()
+}
+function pageChange(page_no){
+  searchParams.CurrentIndex=page_no
+  getList()
+}
+function updateList(type){
+  type=='refresh'?getList():refreshList()
+}
+
+
+
+ // 修改提交
+const editFormRef = ref(null)
+const varietyInsRef = ref(null)
+function editSubmit(){
+  editFormRef.value.validate(valid=>{
+    if(valid){
+      customInterence.addCustomEn({
+          ...editForm,
+          EnPermissions:varietyInsRef.value.checkedItems||[],
+          Nation:editForm.Country
+      }).then(res=>{
+        if(res.Ret == 200){
+          let messageEle=ElMessage.success($route.path == '/addCustomEn'?'添加客户成功':'编辑客户成功')
+          setTimeout(()=>{
+            messageEle.close()
+            editCancel()
+          },1000)
+        }
+      })
+    }
+  })
+}
+// 取消修改
+function editCancel(){
+  //this.$router.back()
+  $router.push({path:'/customListEn'})
+}
+
+
+
+// -----------------------英文客户详情独有方法
+// 去编辑用户
+function toEdit(){
+  $router.replace({path:'/editCustomEn',query:{companyId:editForm.CompanyId}})
+  viewType.value="edit"
+}
+// 删除客户
+function customDelete(){
+  ElMessageBox.confirm(`是否确认删除客户<span style="color:#409EFF">${editForm.CompanyName}</span>,并删除该客户下所有的联系人?`,"操作提示",
+  {
+    type:"warning",
+    dangerouslyUseHTMLString:true,
+    confirmButtonText: "确定",
+    cancelButtonText: "取消"
+  }).then(res=>{
+    customInterence.delCustomEn({CompanyId:editForm.CompanyId}).then(res=>{
+      if(res.Ret == 200){
+        ElMessage.success("删除客户成功")
+
+        setTimeout(()=>{
+
+          $router.push({path:'/customListEn'})
+        },1000)
+      }
+    })
+  }).catch(() => {});
+}
+
+
+// -------------------------------------添加/编辑联系人
+const dialogTitle = ref("添加联系人")
+const showAddDia = ref(false)
+const contactsSubmitForm = ref({})
+//添加联系人
+function addContacts(){
+  contactsSubmitForm.value={}
+  dialogTitle.value="添加联系人"
+  showAddDia.value=true
+}
+// 编辑联系人
+function editContacts(row){
+  contactsSubmitForm.value=row
+  dialogTitle.value="编辑联系人"
+  showAddDia.value=true
+}
+// -----------------------------上传批量导入模板
+function templateUpload(file){
+  let formData = new FormData()
+  formData.append('File',file.file)
+  formData.append('CompanyId',editForm.CompanyId)
+  customInterence.importContactsEn(formData).then(res=>{
+    if(res.Ret == 200){
+      ElMessage.success('批量导入成功')
+      refreshList()
+    }
+  })
+}
+// 删除联系人
+function delContacts(row){
+  ElMessageBox.confirm(`是否确认删除联系人<span style="color:#409EFF">${row.Name}</span>?`,"操作提示",
+  {
+    type:"warning",
+    dangerouslyUseHTMLString:true,
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+  }).then(res=>{
+    customInterence.delContactsEn({EmailId:row.Id}).then(res=>{
+      if(res.Ret == 200){
+        ElMessage.success("删除联系人成功")
+        getList()
+      }
+    })
+
+  }).catch(() => {});
+} 
+//启用禁用联系人
+function changeStatus(row){
+  customInterence.editEnabledEn({
+    EmailId:row.Id,
+    Enabled:row.Enabled===1?0:1
+  }).then(res=>{
+    if(res.Ret!==200) return 
+    ElMessage.success('操作成功')
+    getList()
+  })
+}
+
+
+/* 预览名片 */
+const imgView = ref('')
+const showViewer = ref(false)
+function reviewCard(card) {
+
+  showViewer.value = true;
+  imgView.value = card;
+}
+/* 关闭预览 */
+function closeViewer() {
+  imgView.value = '';
+  showViewer.value = false;
+}
+
+
+
+</script>
+<template>
+  <div id="edit-custom-container">
+    <!-- 编辑客户区域 -->
+    <div class="edit-custom-zone">
+      <el-form :model="editForm" inline ref="editFormRef" style="flex:1">
+        <el-form-item label="客户名称" prop="CompanyName" :rules="{required:true,message:'客户名称不能为空',trigger:'blur'}">
+          <el-input v-model="editForm.CompanyName" placeholder="请输入客户名称" style="width: 337px;" :disabled="viewType=='detail'"></el-input>
+        </el-form-item>
+        <el-form-item label="所属国家" prop="CountryCode" :rules="{required:true,message:'所属国家不能为空',trigger:'change'}">
+          <el-select v-model="editForm.CountryCode" placeholder="请选择" filterable style="width: 337px;" :disabled="viewType=='detail'">
+            <el-option :label="item.cnName" :value="item.code" v-for="item in countryData" :key="item.code" >
+              <div style="display: flex;justify-content: space-between;">
+                <span>{{ item.cnName }}</span>
+                <span style="color: #8492a6; font-size: 13px">{{ item.code }}</span>
+              </div>
+            </el-option>
+          </el-select>
+        </el-form-item>
+        <br/>
+        <el-form-item label="所属销售" prop="SellerId" :rules="{required:true,message:'所属销售不能为空',trigger:'change'}">
+          <el-select v-model="editForm.SellerId" placeholder="请选择" style="width: 337px;" filterable :disabled="viewType=='detail'">
+            <el-option :label="item.RealName" :value="item.AdminId" v-for="item in sellerList" :key="item.AdminId"></el-option>
+          </el-select>
+        </el-form-item>
+        <div class="variety-set-wrap">
+          <el-form-item label="权限配置" :rules="{required:true,message:'请选择权限',trigger:'change'}">
+            <div class="con">
+              <reportVarietyEnSet ref="varietyInsRef" v-if="editForm.CompanyName||$route.path == '/addCustomEn'" :checked="varietyOpts" :disabled="viewType=='edit'?false:true"/>
+            </div>
+          </el-form-item>
+        </div>
+      </el-form>
+      <div class="edit-zone-options">
+        <template v-if="viewType=='edit'">
+          <el-button type="primary" style="width:120px;margin-right: 6px;"  @click="editSubmit">保存</el-button>
+          <el-button  style="width:120px;"  @click="editCancel">取消</el-button>
+        </template>
+        <template v-else>
+          <el-button type="primary" style="width:120px;margin-right: 6px;"  @click="toEdit">编辑</el-button>
+          <el-button  style="width:120px;" @click="customDelete">删除</el-button>
+        </template>
+      </div>
+    </div>
+    <!-- 联系人区域 -->
+    <div class="contacts-zone" v-if="$route.path != '/addCustomEn'">
+      <div class="contacts-options-zone">
+        <!-- 联系人操作区域 -->
+        <div class="options-zone-buttons">
+          <el-button type="primary" style="margin-right: 16px;" @click="addContacts">添加联系人</el-button>
+          <el-upload action="#" :show-file-list="false" style="display: inline;" :http-request="templateUpload"
+          accept=".xls,.xlsx">
+            <el-button type="primary" style="width: 112px;margin-right: 26px;">批量导入</el-button>
+          </el-upload>
+          <a href="https://hzstatic.hzinsights.com/static/admin/excel/英文联系人批量导入模板.xlsx" download>批量导入模板</a>
+        </div>
+        <div>
+          <el-input v-model="searchParams.Keywords" placeholder="请输入联系人姓名/邮箱" @input="getList('search')"
+          style="width: 520px;" clearable >
+            <template #prefix>
+              <el-icon><Search/></el-icon>
+            </template>
+          </el-input>
+        </div>
+      </div>
+      <!-- 联系人列表区域 -->
+      <div class="contacts-table-zone">
+        <div style="overflow: auto;flex-grow: 1;">
+          <el-table :data="contactsList" border @sort-change="clickTimesSortChange">
+            <el-table-column label="联系人姓名" align="center" prop="Name">
+              <template #default="{row}">
+                <img 
+                  :src="$icons.card"
+                  alt="" 
+                  style="width:17px;cursor:pointer;marginRight:5px;"
+                  v-if="row.BusinessCardUrl"
+                  @click="reviewCard(row.BusinessCardUrl)"
+                />
+                <span>{{row.Name}}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="注册公司" align="center" prop="CompanyName">
+              <template #default="{row}">
+                {{row.CompanyName || '-'}}
+              </template>
+            </el-table-column>
+            <el-table-column label="手机号" align="center" prop="Mobile">
+              <template #default="{row}">
+                {{row.CountryCode}}-{{row.Mobile}}
+              </template>
+            </el-table-column>
+            <el-table-column label="注册时间" align="center" prop="RegisterTime">
+              <template #default="{row}">
+                {{row.RegisterTime || '-'}}
+              </template>
+            </el-table-column>
+            <el-table-column label="邮箱地址" align="center" prop="Email">
+              <template #default="{row}">
+                {{row.Email}}
+              </template>
+            </el-table-column>
+            <el-table-column label="累计点击量" align="center" sortable="custom" width="120"
+            prop="ViewTotal">
+              <template #default="{row}">
+                <span class="table-options" @click="clickTimesDetail(row)" v-if="row.ViewTotal!=0">{{row.ViewTotal}}</span>
+                <span v-else>{{row.ViewTotal}}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="添加时间" align="center" prop="CreateTime" >
+              <template #default="{row}">
+                {{row.CreateTime}}
+              </template>
+            </el-table-column>
+            <el-table-column label="状态" align="center" prop="Enabled" >
+              <template #default="{row}">
+                <span :class="[row.Enabled===0?'hint':'']">{{row.Enabled?'启用':'禁用'}}</span>
+              </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" width="120">
+              <template #default="{row}">
+                <span class="table-options" style="margin-right: 12px;" @click="editContacts(row)">编辑</span>
+                <span class="table-options" style="margin-right: 12px;" @click="changeStatus(row)">{{row.Enabled?'禁用':'启用'}}</span>
+                <span class="table-options" @click="delContacts(row)" style="color:#D1433A;">删除</span>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+        
+        <!-- 页数选择器 -->
+        <m-page
+          v-show="total!=0"
+          style="float: none;text-align: right;margin-top: 20px;"
+          :page_no="searchParams.CurrentIndex"
+          :pageSize="searchParams.PageSize"
+          :total="total"
+          @handleCurrentChange="pageChange"
+        />
+      </div>
+    </div>
+    <!-- 累计点击量详情弹窗 -->
+    <click-number-detail :visible="showClickTimesDia" 
+    :name="clickTimesDetailItem.contactsName" type="contacts"
+    :id="clickTimesDetailItem.contactsId" @close="closeNumDia"></click-number-detail>
+    <!-- 添加/编辑联系人 -->
+    <contact-save-en-dia :contactsSubmitForm="contactsSubmitForm" :title="dialogTitle" :showAddDia="showAddDia"
+     :companyId="searchParams.CompanyId" @updateList="updateList" @close="showAddDia=false"></contact-save-en-dia>
+
+    <!-- 图片预览 -->
+		<el-image-viewer 
+		v-if="showViewer" 
+		@close="closeViewer" 
+		:urlList="[imgView]" />
+  </div>
+</template>
+<style scoped lang="scss">
+#edit-custom-container{
+  .edit-custom-zone{
+    padding: 30px 30px 10px 30px;
+    display: flex;
+    justify-content: space-between;
+    border: 1px solid #ECECEC;
+    background-color: white;
+    border-radius: 2px;
+    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+    margin-bottom: 20px;
+    .edit-zone-options{
+      min-width: 260px;
+    }
+  }
+  .contacts-zone{
+    border: 1px solid #ECECEC;
+    background-color: white;
+    border-radius: 2px;
+    box-shadow: 0 3px 6px rgba(0, 0, 0, 0.05);
+    padding: 30px;
+    box-sizing: border-box;
+    display: flex;
+    flex-direction: column;
+    .contacts-options-zone{
+      display: flex;
+      justify-content: space-between;
+      flex-wrap: wrap;
+      margin-bottom: 20px;
+      .options-zone-buttons{
+        margin-bottom: 10px;
+        a{
+          cursor: pointer;
+          font-size: 16px;
+          color: #409EFF;
+          line-height: 40px;
+        }
+      }
+    }
+    .contacts-table-zone{
+      .table-options{
+        cursor: pointer;
+        font-size: 14px;
+        color: #409EFF;
+      }
+    }
+
+  }
+  .hint{
+    color: red;
+  }
+
+  :deep(.el-form-item){
+    margin-right: 100px;
+  }
+  :deep(.el-form-item:nth-child(2)){
+    margin-right: 50px;
+  }
+  :deep(.el-form-item__label){
+    color: black;
+  }
+  .img_item {
+    position: relative;
+    width: 280px;
+    height: 180px;
+    border-radius: 4px;
+  }
+  :deep(.variety-set-wrap){
+      .el-form-item{
+        width: 100%;
+        .el-form-item__content{
+          display: block;
+          .con{
+            border: 1px dashed #DCDFE6;
+            border-radius: 4px;
+            padding: 20px;
+          }
+        }
+      }
+    }
+}
+</style>

+ 2 - 1
src/views/custom_manage/custom/limitContactListEn.vue → src/views/custom_manage/customEn/limitContactListEn.vue

@@ -7,7 +7,7 @@ import { customInterence } from "@/api/api.js";
 import clickNumberDetail from "./components/clickNumberDetailDia.vue";
 import ContactSaveEnDia from "./components/ContactSaveEnDia.vue";
 import mPage from "@/components/mPage.vue";
-import { useClickNumDia } from "./hooks/customlistHook";
+import { useClickNumDia } from "../custom/hooks/customlistHook";
 
 const route = useRoute();
 
@@ -282,6 +282,7 @@ const {
       :showAddDia="showAddDia"
       :companyId="0"
       @updateList="getList"
+      @close="showAddDia=false"
     ></contact-save-en-dia>
 
     <el-image-viewer

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 6 - 0
static/css/skin.min.css


Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно