Prechádzať zdrojové kódy

feat: tab新增标段管理、项目决策链、风险管理 及上传逻辑修改

liyang 4 mesiacov pred
rodič
commit
29127cbfe2

+ 26 - 32
src/views/market-manage/external-manage/clue-management/clue-registration/index.vue

@@ -343,20 +343,19 @@
             <a-row :gutter="16" class="smart-query-form-row">
               <a-col :span="24">
                 <p style="margin-left: 45px">附件:支持png、jpg、doc、ppt、pdf、mp4、avi等常见附件格式</p>
-                <a-upload
-                    v-model:file-list="fileList"
-                    :before-upload="beforeUpload"
-                    :customRequest="customRequest"
-                    multiple
-                >
-                  <a-button style="margin-left: 85px" type="dashed">
-                    <upload-outlined></upload-outlined>
-                    点击上传
-                  </a-button>
-                </a-upload>
+                <Upload
+                    style="margin-left: 90px"
+                    ref="UploadRef"
+                    :defaultFileList="defaultFileList"
+                    :maxUploadSize="10"
+                    :folder="FILE_FOLDER_TYPE_ENUM.COMMON.value"
+                    buttonText="上传文件"
+                    listType="text"
+                    extraMsg="最多上传10个附件"
+                    @change="changeAttachment"
+                />
                 <div class="attachment-list">
-                  <div v-for="(file, index) in fileList" :key="file.uid" class="attachment-item">
-                    <a-checkbox v-model:checked="file.checked" class="attachment-checkbox"></a-checkbox>
+                  <div v-for="(file, index) in defaultFileList" :key="file.uid" class="attachment-item">
                     <span class="attachment-name">{{ file.name }}</span>
                     <div class="attachment-actions">
                       <a-button type="link" @click="handlePreview(file)">预览</a-button>
@@ -392,6 +391,8 @@ import AreaCascader from "/@/components/framework/area-cascader/index.vue";
 import {SELECT_MULTIPLE} from "/@/components/BsUi/constant.js";
 import OrgUserSelector from "/@/components/BsUi/OrgUserSelector/index.vue";
 import styles from "./index.module.scss";
+import {FILE_FOLDER_TYPE_ENUM} from "/@/constants/support/file-const.js";
+import Upload from "/@/components/support/file-upload/index.vue";
 const stepFormRef = ref(null);
 const router = useRouter();
 const formStates = reactive({
@@ -427,7 +428,7 @@ const formState = reactive({
   projectBackground: '',
   projectStage: '',
   belongMarketer: '',
-  attachment: '',
+  attachment: undefined,
   projectAddress: '',
   clueSource: 'serviceProvider',
   isOwnerPartyA: undefined,
@@ -514,22 +515,13 @@ const {
     },
   },
 });
-const fileList = ref([
-  {
-    uid: '1',
-    name: '附件名称信息占位在这里附件信息.avi',
-    status: 'done',
-    checked: false,
-    uploadTime: '2024-03-07 14:28:22'
-  },
-  {
-    uid: '2',
-    name: '附件名称信息占位在这里附件信息.avi',
-    status: 'done',
-    checked: false,
-    uploadTime: '2024-03-07 14:28:22'
-  }
-]);
+const defaultFileList = ref([]);
+function changeAttachment(fileList) {
+  defaultFileList.value = fileList;
+  formState.attachment = _.isEmpty(fileList) ? [] : fileList;
+}
+
+const fileList = ref([]);
 const beforeUpload = (file) => {
   const isAllowedType = [
     'image/png',
@@ -730,8 +722,10 @@ const submit = () => {
 const postFileData = () => {
   let params = {
     ...formState,
-    teams: getValue('gridOptions.data')
+    teams: getValue('gridOptions.data'),
+    attachment:formState.attachment.map(item => item.fileUrl).join(',')
   }
+  console.log(params,'fileListfileList')
   clientManageApi.inteListAdd(params).then((res) => {
     message.success('提交成功');
     router.push({
@@ -808,7 +802,7 @@ const ownerUnitOptions5 = useBsDict.getDictList('BLINK_MARKET_PROJECT_INDUSTRY')
 
 .attachment-list {
   margin-top: 16px;
-  margin-left: 80px;
+  margin-left: 90px;
 }
 
 .attachment-item {

+ 250 - 0
src/views/market-manage/external-manage/clue-management/view-details/components/CooperativeProject.vue

@@ -0,0 +1,250 @@
+<template>
+  <a-layout class="management-container">
+    <!-- 左侧单位树形结构 -->
+<!--    <a-layout-sider width="300" class="left-sider">-->
+<!--      <div class="decision-framework">-->
+<!--        <h3 class="section-title">决策框架构</h3>-->
+
+<!--        &lt;!&ndash; 业主单位 &ndash;&gt;-->
+<!--        <div class="company-section">-->
+<!--          <h4 class="company-title">业主单位</h4>-->
+<!--          <div class="group-section">-->
+<!--            <h5 class="group-title">集团公司名称信息展示位置</h5>-->
+<!--            <a-list :data-source="ownerSubsidiaries" :bordered="false" size="small">-->
+<!--              <template #renderItem="{ item }">-->
+<!--                <a-list-item class="subsidiary-item">{{ item }}</a-list-item>-->
+<!--              </template>-->
+<!--            </a-list>-->
+<!--          </div>-->
+<!--        </div>-->
+
+<!--        &lt;!&ndash; 总承包单位 &ndash;&gt;-->
+<!--        <div class="company-section">-->
+<!--          <h4 class="company-title">总承包单位</h4>-->
+<!--          <div class="group-section">-->
+<!--            <h5 class="group-title">集团公司名称信息展示位置</h5>-->
+<!--            <a-list :data-source="contractorSubsidiaries" :bordered="false" size="small">-->
+<!--              <template #renderItem="{ item }">-->
+<!--                <a-list-item class="subsidiary-item">{{ item }}</a-list-item>-->
+<!--              </template>-->
+<!--            </a-list>-->
+<!--          </div>-->
+<!--        </div>-->
+<!--      </div>-->
+<!--    </a-layout-sider>-->
+
+    <!-- 右侧人员表格 -->
+    <a-layout-content class="right-content">
+      <div class="association-chain">
+        <h3 class="section-title">关联链列表</h3>
+        <a-table
+            :columns="columns"
+            :data-source="dataSource"
+            :pagination="false"
+            size="middle"
+            bordered
+        >
+          <template #bodyCell="{ column, record }">
+            <template v-if="column.key === 'operation'">
+              <a-space>
+                <a-button type="link" size="small" @click="handleEdit(record)">编辑</a-button>
+                <a-button type="link" size="small" danger @click="handleDelete(record)">删除</a-button>
+              </a-space>
+            </template>
+          </template>
+        </a-table>
+      </div>
+    </a-layout-content>
+  </a-layout>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import {
+  Layout,
+  LayoutSider,
+  LayoutContent,
+  List,
+  ListItem,
+  Table,
+  Button,
+  Space,
+  message
+} from 'ant-design-vue';
+
+const ownerSubsidiaries = [
+  '下属公司名称信息展示',
+  '下属公司名称信息展示位置',
+  '下属公司名称信息展示位置',
+  '下属公司名称信息展示位置',
+  '下属公司名称信息展示位置',
+  '下属公司名称信息展示位置',
+  '下属公司名称信息展示位置',
+  '下属公司名称信息展示位置'
+];
+
+const contractorSubsidiaries = [
+  '下属公司名称信息展示位置',
+  '下属公司名称信息展示位置'
+];
+
+const columns = [
+  {
+    title: '姓名',
+    dataIndex: 'name',
+    key: 'name',
+    width: 100
+  },
+  {
+    title: '性别',
+    dataIndex: 'gender',
+    key: 'gender',
+    width: 80
+  },
+  {
+    title: '年龄',
+    dataIndex: 'age',
+    key: 'age',
+    width: 80
+  },
+  {
+    title: '联系电话',
+    dataIndex: 'phone',
+    key: 'phone',
+    width: 120
+  },
+  {
+    title: '类型',
+    dataIndex: 'type',
+    key: 'type',
+    width: 120
+  },
+  {
+    title: '职务',
+    dataIndex: 'position',
+    key: 'position',
+    width: 120
+  },
+  {
+    title: '操作',
+    key: 'operation',
+    width: 120
+  }
+];
+
+const dataSource = ref([
+  {
+    key: '1',
+    name: '唐敏',
+    gender: '男',
+    age: 43,
+    phone: '13245674567',
+    type: '总承包单位',
+    position: '总经理'
+  },
+  {
+    key: '2',
+    name: '吴胜',
+    gender: '女',
+    age: 43,
+    phone: '13245674567',
+    type: '业主单位',
+    position: '总监'
+  },
+  {
+    key: '3',
+    name: '胡思宁',
+    gender: '男',
+    age: 43,
+    phone: '13245674567',
+    type: '设计院',
+    position: '副总经理'
+  },
+  {
+    key: '4',
+    name: '江民泰',
+    gender: '女',
+    age: 43,
+    phone: '13245674567',
+    type: '业主单位',
+    position: '副总经理'
+  }
+]);
+
+const handleEdit = (record) => {
+  message.info(`编辑 ${record.name}`);
+  // 这里添加实际的编辑逻辑
+};
+
+const handleDelete = (record) => {
+  dataSource.value = dataSource.value.filter(item => item.key !== record.key);
+  message.success(`已删除 ${record.name}`);
+};
+</script>
+
+<style scoped>
+.management-container {
+  height: 100vh;
+  background: #fff;
+}
+
+.left-sider {
+  background: #fff;
+  border-right: 1px solid #f0f0f0;
+  padding: 16px;
+  overflow-y: auto;
+}
+
+.right-content {
+  padding: 16px;
+  overflow-y: auto;
+}
+
+.section-title {
+  font-size: 16px;
+  font-weight: bold;
+  margin-bottom: 16px;
+  color: #333;
+}
+
+.company-section {
+  margin-bottom: 24px;
+}
+
+.company-title {
+  font-size: 15px;
+  font-weight: bold;
+  margin: 12px 0 8px 0;
+  color: #333;
+}
+
+.group-title {
+  font-size: 14px;
+  font-weight: normal;
+  margin: 8px 0;
+  color: #666;
+  padding-left: 8px;
+}
+
+.subsidiary-item {
+  padding: 4px 0 4px 16px;
+  font-size: 13px;
+  color: #666;
+}
+
+/* 调整列表项样式 */
+:deep(.ant-list-item) {
+  padding: 0 !important;
+  border: none !important;
+}
+
+/* 表格样式调整 */
+:deep(.ant-table) {
+  background: #fff;
+}
+
+:deep(.ant-table-thead > tr > th) {
+  background: #fafafa;
+  font-weight: bold;
+}
+</style>

+ 107 - 0
src/views/market-manage/external-manage/clue-management/view-details/components/InfoMaterial.vue

@@ -0,0 +1,107 @@
+<template>
+  <div class="retention-transformation">
+    <bs-table v-bind="tableOptions">
+      <template #toolbarLeft>
+        <a-space>
+          <span>累计留资客户 283人</span>
+        </a-space>
+      </template>
+    </bs-table>
+  </div>
+</template>
+<script setup lang="jsx">
+import {ref, reactive} from "vue"
+import BsTable, {useBsTable} from '/@/components/BsUi/Table/index.js';
+import {DISPLAY_STATE} from '/@/components/BsUi/constant.js';
+import {useRouter} from "vue-router";
+
+const {id} = defineProps(['id'])
+const router = useRouter()
+const {
+  tableOptions,
+  setTablePropsValue: setValue,
+  getTablePropsValue: getValue,
+} = useBsTable({
+  tableOptions: {
+    url: '',
+    gridOptions: {
+      loading: false,
+      columns: [
+        {
+          type: 'seq',
+          width: 80,
+        },
+        {
+          field: 'knowRunyang',
+          title: '风险条例库',
+        },
+        {
+          field: 'companyName',
+          title: '判定条件',
+
+        },
+        {
+          field: 'address',
+          title: '风险类型',
+        },
+        {
+          field: 'contact',
+          title: '分值',
+        },
+        {
+          field: 'contactPhone',
+          title: '权重系数',
+        },
+        {
+          field: 'post',
+          title: '分析情况',
+        },
+        {
+          field: 'needDescription',
+          title: '匹配结果',
+        },
+        {
+          field: 'communicativeProject',
+          title: '得分',
+        },
+        {
+          field: 'projectDescription',
+          title: '操作人',
+        },
+        {
+          field: 'follow',
+          title: '添加时间',
+        },
+      ],
+    },
+    pagerConfig: {
+      enabled: true,
+      pageSize: 10,
+      pageNum: 1,
+      id: id,
+      total: 0,
+      isFixed: false
+    },
+    toolbarConfig: {
+      enable: false,
+    },
+    tableSearchBeforeBiz() {
+      const searchParams = getValue('searchConfig.data');
+      setValue('searchConfig.data', {...searchParams, id: id});
+    },
+  },
+});
+
+function fetchTableData() {
+
+}
+</script>
+<style lang="scss" scoped>
+.retention-transformation {
+  .toolbarTop {
+    display: flex;
+    flex-direction: row;
+    //justify-content: space-between;
+  }
+}
+</style>

+ 157 - 0
src/views/market-manage/external-manage/clue-management/view-details/components/SectionManagement.vue

@@ -0,0 +1,157 @@
+<template>
+  <div class="retention-transformation">
+    <bs-table v-bind="tableOptions">
+      <template #toolbarTop>
+        <div class="toolbarTop">
+          <div></div>
+          <a-button type="primary">
+            <span>创建标段</span>
+          </a-button>
+          <a-button type="primary" style="margin-left: 10px">
+            <span>标段转商机</span>
+          </a-button>
+        </div>
+      </template>
+      <template #toolbarLeft>
+        <a-space>
+<!--          <span>累计留资客户 283人</span>-->
+        </a-space>
+      </template>
+    </bs-table>
+  </div>
+</template>
+<script setup lang="jsx">
+import { ref, reactive } from "vue"
+import BsTable, { useBsTable } from '/@/components/BsUi/Table/index.js';
+import { DISPLAY_STATE } from '/@/components/BsUi/constant.js';
+import { useRouter } from "vue-router";
+const { id } = defineProps(['id'])
+const router = useRouter()
+const {
+  tableOptions,
+  setTablePropsValue: setValue,
+  getTablePropsValue: getValue,
+} = useBsTable({
+  tableOptions: {
+    url: '',
+    gridOptions: {
+      loading: false,
+      columns: [
+  
+        {
+          field: 'knowRunyang',
+          title: '标段名称',
+        },
+        {
+          field: 'companyName',
+          title: '标段状态',
+
+        },
+        {
+          field: 'address',
+          title: '标段ID',
+        },
+        {
+          field: 'contact',
+          title: '概算金额(元)',
+        },
+        {
+          field: 'contactPhone',
+          title: '预计招标日期',
+        },
+        {
+          field: 'post',
+          title: '竞争对手',
+        },
+        {
+          field: 'needDescription',
+          title: '备注',
+        },
+        {
+          field: 'communicativeProject',
+          title: '归属营销人员',
+        },
+        {
+          field: 'projectDescription',
+          title: '归属营销部门',
+        },
+        {
+          field: 'follow',
+          title: '创建人',
+        },
+        {
+          field: 'followLog',
+          title: '创建时间',
+        },
+        {
+          // fixed: 'right',
+          title: '操作',
+          cellRender: {
+            name: 'CellOption',
+            extraProps: {
+              buttons: [
+                {
+                  title: '编辑',
+                  code: 'add',
+                  display: ({ row }) => {
+                    return row.name !== 'hanxiaohui0' ? DISPLAY_STATE.VISIBLE : DISPLAY_STATE.HIDDEN;
+                  },
+                  disabled({ row }) {
+                    return false;
+                  },
+                  onClick({ row }) {
+                    console.log("row", row);
+                    // message.success(row.name)
+                  },
+                  extraProps: {},
+                },
+                {
+                  title: '详情',
+                  code: 'view',
+                  display: ({ row }) => {
+                    return DISPLAY_STATE.VISIBLE;
+                  },
+                  disabled({ row }) {
+                    return false;
+                  },
+                  onClick({ row }) {
+                    // router.push('/market-manage/activity-manage/activity-management/detail')
+                  },
+                  extraProps: {},
+                },
+              ],
+            },
+          },
+        },
+      ],
+    },
+    pagerConfig: {
+      enabled: true,
+      pageSize: 10,
+      pageNum: 1,
+      id: id,
+      total: 0,
+      isFixed: false
+    },
+    toolbarConfig: {
+      enable: false,
+    },
+    tableSearchBeforeBiz() {
+      const searchParams = getValue('searchConfig.data');
+      setValue('searchConfig.data', { ...searchParams, id: id });
+    },
+  },
+});
+function fetchTableData() {
+
+}
+</script>
+<style lang="scss" scoped>
+.retention-transformation {
+  .toolbarTop {
+    display: flex;
+    flex-direction: row;
+    //justify-content: space-between;
+  }
+}
+</style>

+ 33 - 29
src/views/market-manage/external-manage/clue-management/view-details/index.vue

@@ -1,14 +1,13 @@
 <template>
   <div class="page-detail">
-    <page-detail-layout :tabs="tabs" v-model:tab-active-key="tabActiveKey" :index-config="indexConfig" :steps-data="stepsData"
+    <page-detail-layout :tabs="tabs" v-model:tab-active-key="tabActiveKey" :index-config="indexConfig"
+                        :steps-data="stepsData"
                         title="华东电力二期治理项目">
       <template #titleRight>
-<!--        <img src="/@/assets/images/page-detail-layout/customer/SS_user.png" alt=""/>-->
+        <!--        <img src="/@/assets/images/page-detail-layout/customer/SS_user.png" alt=""/>-->
         <a-tag color="blue">转介绍</a-tag>
       </template>
-
       <template #toolBtn>
-
         <a-button ghost type="primary" size="small">转移</a-button>
         <a-button type="primary" size="small">预进场</a-button>
         <a-button danger ghost type="primary" size="small">释放公海</a-button>
@@ -23,7 +22,7 @@
           </div>
         </a-tag>
       </template>
-      <template #tab1>
+      <template #BasicInformation>
         <bs-contents-wrapper>
           <!-- 客户信息(动态列数) -->
           <bs-descriptions
@@ -40,14 +39,23 @@
           </bs-descriptions>
 
           <!-- 管理信息(表格) -->
-          <bs-descriptions title="协作团队">
+          <bs-descriptions v-if="tableList&&tableList.length>0" title="协作团队">
             <bs-table v-bind="tableOptions" v-if="tableList&&tableList.length>0"/>
           </bs-descriptions>
         </bs-contents-wrapper>
       </template>
 
-      <template #tab2>tab2</template>
-      <template #tab3>tab3</template>
+      <template #sectionManagement>
+        <SectionManagement :id="id"/>
+      </template>
+
+      <template #infoMaterial>
+        <InfoMaterial :id="id"/>
+      </template>
+
+      <template #cooperativeProject>
+        <CooperativeProject />
+      </template>
     </page-detail-layout>
   </div>
 </template>
@@ -60,9 +68,13 @@ import BsTable, {useBsTable} from '/@/components/BsUi/Table/index.js';
 import {clientManageApi} from '/@/api/market-manage/clue-management/index.js';
 import {onMounted,} from 'vue';
 import {useRoute} from 'vue-router';
+import SectionManagement from './components/SectionManagement.vue'
+import CooperativeProject from './components/CooperativeProject.vue'
+import InfoMaterial from './components/InfoMaterial.vue'
 
 const route = useRoute();
-const tabActiveKey = ref('tab1');
+const {id} = route.query
+const tabActiveKey = ref('BasicInformation');
 const bsDescriptionItems = ref([]);
 const tableList = ref([]);
 const fetchData = (id) => {
@@ -72,7 +84,7 @@ const fetchData = (id) => {
     setValue('gridOptions.data', res.data.teamDTOList)
     const customerData = res.data;
     bsDescriptionItems.value = [
-      {label: '项目类型', value: customerData.projectType?.[0].valueName|| '--'},
+      {label: '项目类型', value: customerData.projectType?.[0].valueName || '--'},
       {label: '线索名称', value: customerData.clueName || '--'},
       {label: '线索来源', value: customerData.clueSource || '--'},
       {label: '服务商名称', value: customerData.providerName || '--'},
@@ -95,8 +107,8 @@ const fetchData = (id) => {
       {label: '分厂/几期/机组', value: customerData.shortDescription || '--'},
     ];
   })
-  clientManageApi.getQueryHeaderList(id).then((res)=>{
-    console.log(res,8885555)
+  clientManageApi.getQueryHeaderList(id).then((res) => {
+    console.log(res, 8885555)
   })
 }
 const getImgUrl = (name) => {
@@ -217,26 +229,18 @@ watch(
       }
     }
 );
-const customerData = ref({
-  returnTo: "政府机构",
-  level: "A级",
-  industry: "行业名称信息展示",
-  type: "投资单位",
-  region: "归属区域信息展示位置",
-  salesPerson: "任颖"
-});
 const tabs = ref([
   {
     title: '基本信息',
-    key: 'tab1',
-    slotName: 'tab1',
+    key: 'BasicInformation',
+    slotName: 'BasicInformation',
     selectedIcon: getImgUrl('icon-jibenxinxi-all'),
     unSelectedIcon: getImgUrl('icon-jibenxinxi'),
   },
   {
-    title: '跟进情况',
-    key: 'FollowUp',
-    slotName: 'FollowUp',
+    title: '标段管理',
+    key: 'sectionManagement',
+    slotName: 'sectionManagement',
     selectedIcon: getImgUrl('icon-genjinqingkuang-all'),
     unSelectedIcon: getImgUrl('icon-genjinqingkuang'),
   },
@@ -257,8 +261,8 @@ const tabs = ref([
 
   {
     title: '项目决策链',
-    key: 'CooperativeProject',
-    slotName: 'CooperativeProject',
+    key: 'cooperativeProject',
+    slotName: 'cooperativeProject',
     selectedIcon: getImgUrl('icon-hezuoxiangmu-all'),
     unSelectedIcon: getImgUrl('icon-hezuoxiangmu'),
   },
@@ -299,8 +303,8 @@ const tabs = ref([
   },
   {
     title: '风险管理',
-    key: 'InfoMaterial',
-    slotName: 'InfoMaterial',
+    key: 'infoMaterial',
+    slotName: 'infoMaterial',
     selectedIcon: getImgUrl('icon-xinxiziliao-all'),
     unSelectedIcon: getImgUrl('icon-xinxiziliao'),
   },