| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814 |
- <template>
- <a-card>
- <a-form class="smart-query-form" ref="stepFormRef" labelWrap :label-col="labelCol" :model="formState"
- :rules="formRules">
- <div class="approval-steps">
- <div>
- <div class="basic-title">
- <div class="basic-title-left">
- <div class="basic-title-line"></div>
- <span class="basic-title-text">线索登记</span>
- </div>
- <div class="basic-title-right">
- <a-button type="primary" @click="reset">重置</a-button>
- <a-button type="primary" @click="submit">提交</a-button>
- </div>
- </div>
- <div class="steps-content">
- <a-row :gutter="16">
- <a-col :span="8">
- <a-form-item label="项目类型" name="projectType">
- <a-select
- v-model:value="formState.projectType"
- placeholder="请选择"
- :options="serviceProviderOptions"
- />
- </a-form-item>
- </a-col>
- <a-col :span="16">
- <a-form-item label="线索名称">
- <a-input
- v-model:value="formState.clueName"
- placeholder="请输入线索名称"
- />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="24">
- <a-form-item label="项目名称" name="projectName">
- <a-input
- v-model:value="formState.projectName"
- placeholder="自动生成(甲方-分厂-几期-机组-工程属性)"
- />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="8">
- <a-form-item label="线索来源" name="clueSource">
- <a-select
- v-model:value="formState.clueSource"
- placeholder="请选择线索来源"
- :options="clueSourceOptions"
- @change="handleClueSourceChange"
- />
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item :label="dynamicField.label" :name="dynamicField.name">
- <a-select
- v-if="formState.clueSource === 'serviceProvider'"
- v-model:value="formState.providerName"
- :placeholder="dynamicField.placeholder"
- :options="serviceProviderOptions"
- />
- <a-select
- v-else-if="formState.clueSource === 'marketActivity'"
- v-model:value="formState.providerName"
- :placeholder="dynamicField.placeholder"
- :options="activityOptions"
- />
- <a-input
- v-else-if="formState.clueSource === 'referral'"
- v-model:value="formState.providerName"
- :placeholder="dynamicField.placeholder"
- />
- <a-select
- v-else
- disabled
- placeholder="请先选择线索来源"
- />
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item label="工程属性" name="engineeringAttribute">
- <a-select
- v-model:value="formState.engineeringAttribute"
- placeholder="请选择"
- :options="ownerUnitOptions1"
- />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="8">
- <a-form-item label="地区" name="countryRegion">
- <a-cascader
- v-model:value="formState.countryRegion"
- :options="regionOptions"
- placeholder="请选择"
- />
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item label="省市区" name="province">
- <a-cascader
- v-model:value="formState.province"
- :options="regionOptions"
- placeholder="请选择"
- />
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item label="项目地址">
- <a-input
- v-model:value="formState.projectAddress"
- placeholder="请输入"
- />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="业主单位">
- <div class="flex-container">
- <a-select
- v-model:value="formState.ownerUnit"
- placeholder="请选择"
- style="flex: 1; margin-right: 8px"
- :options="ownerUnitOptions"
- :disabled="isAnyPartyASelected && !formState.isOwnerPartyA"
- @change="handleOwnerUnitChange"
- />
- <a-radio-group
- v-model:value="formState.isOwnerPartyA"
- button-style="solid"
- @change="() => handlePartyAChange('owner')"
- >
- <a-radio-button value="yes">甲方</a-radio-button>
- </a-radio-group>
- </div>
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="设计单位">
- <div class="flex-container">
- <a-select
- v-model:value="formState.designFlats"
- placeholder="请选择"
- style="flex: 1; margin-right: 8px"
- :options="ownerUnitOptions"
- :disabled="isAnyPartyASelected && !formState.isDesignPartyA"
- />
- <a-radio-group
- v-model:value="formState.isDesignPartyA"
- button-style="solid"
- @change="() => handlePartyAChange('design')"
- >
- <a-radio-button value="yes">甲方</a-radio-button>
- </a-radio-group>
- </div>
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="12">
- <a-form-item label="总承包单位">
- <div class="flex-container">
- <a-select
- v-model:value="formState.generalContractingFlats"
- placeholder="请选择"
- style="flex: 1; margin-right: 8px"
- :options="ownerUnitOptions"
- :disabled="isAnyPartyASelected && !formState.isTrustPartyA"
- />
- <a-radio-group
- v-model:value="formState.isTrustPartyA"
- button-style="solid"
- @change="() => handlePartyAChange('trust')"
- >
- <a-radio-button value="yes">甲方</a-radio-button>
- </a-radio-group>
- </div>
- </a-form-item>
- </a-col>
- <a-col :span="12">
- <a-form-item label="招标代理单位">
- <div class="flex-container">
- <a-select
- v-model:value="formState.investmentAgentFlats"
- placeholder="请选择"
- style="flex: 1; margin-right: 8px"
- :options="ownerUnitOptions"
- :disabled="isAnyPartyASelected && !formState.isBiddingAgentPartyA"
- />
- <a-radio-group
- v-model:value="formState.isBiddingAgentPartyA"
- button-style="solid"
- @change="() => handlePartyAChange('biddingAgent')"
- >
- <a-radio-button value="yes">甲方</a-radio-button>
- </a-radio-group>
- </div>
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="8">
- <a-form-item label="是否联合体" name="complex">
- <a-select
- v-model:value="formState.complex"
- placeholder="请选择"
- :options="serviceProviderOptions"
- />
- </a-form-item>
- </a-col>
- <a-col :span="16">
- <a-form-item label="联合体情况" name="complexDescription">
- <a-input
- v-model:value="formState.complexDescription"
- placeholder="请输入"
- />
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="8">
- <a-form-item label="项目所属行业" name="projectBelongIndustry">
- <a-select
- v-model:value="formState.projectBelongIndustry"
- placeholder="请选择"
- :options="ownerUnitOptions5"
- />
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item label="业务类型" name="businessType">
- <a-select
- v-model:value="formState.businessType"
- placeholder="请选择"
- :options="ownerUnitOptions4"
- />
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item label="招标平台" name="tenderPlatform">
- <a-input v-model:value="formState.tenderPlatform" placeholder="请输入"/>
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="8">
- <a-form-item label="项目总概算" name="projectBudget">
- <a-input v-model:value="formState.projectBudget" placeholder="自动生成(各标段概算之和)"/>
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item label="项目资金来源" name="projectMoneySource">
- <a-select
- v-model:value="formState.projectMoneySource"
- placeholder="请选择"
- :options="ownerUnitOptions3"
- />
- </a-form-item>
- </a-col>
- <a-col :span="8">
- <a-form-item label="分厂/几期/机组" name="factory">
- <a-input v-model:value="formState.factory" placeholder="请输入"/>
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="24">
- <a-form-item label="项目背景" name="projectBackground" class="smart-query-form-item">
- <a-input v-model:value="formState.projectBackground" placeholder="请输入"/>
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="24">
- <a-form-item label="项目阶段" name="projectStage" class="smart-query-form-item">
- <a-input v-model:value="formState.projectStage" placeholder="请输入"/>
- </a-form-item>
- </a-col>
- </a-row>
- <a-row :gutter="16">
- <a-col :span="8">
- <a-form-item label="归属营销人员" class="smart-query-form-item">
- <a-select
- v-model:value="formState.belongMarketer"
- placeholder="请选择"
- :options="ownerUnitOptions5"
- />
- </a-form-item>
- </a-col>
- </a-row>
- </div>
- </div>
- <div>
- <div class="basic-title">
- <div class="basic-title-left">
- <div class="basic-title-line"></div>
- <span class="basic-title-text">协作团队</span>
- </div>
- </div>
- <div class="steps-content">
- <bs-table v-bind="tableOptions">
- </bs-table>
- <a-button type="dashed" @click="showModal" block>
- <plus-outlined/>
- 添加成员
- </a-button>
- <a-modal
- v-model:visible="visible"
- title="添加团队成员"
- @ok="handleOk"
- @cancel="handleCancel"
- >
- <a-form layout="vertical">
- <a-form-item label="营销经理">
- <a-input v-model:value="formStates.manager" />
- </a-form-item>
- <a-form-item label="营销团队">
- <a-input v-model:value="formStates.team" />
- </a-form-item>
- <a-form-item label="支持说明">
- <a-textarea v-model:value="formStates.description" />
- </a-form-item>
- </a-form>
- </a-modal>
- <!-- <bs-table></bs-table>-->
- <!-- <a-table-->
- <!-- :columns="teamColumns"-->
- <!-- :data-source="teamData"-->
- <!-- :pagination="false"-->
- <!-- bordered-->
- <!-- >-->
- <!-- <template #bodyCell="{ column, record }">-->
- <!-- <template v-if="column.key === 'action'">-->
- <!-- <a-button type="link" danger @click="removeTeam(record.key)">删除</a-button>-->
- <!-- </template>-->
- <!-- </template>-->
- <!-- </a-table>-->
- </div>
- </div>
- <div>
- <div class="basic-title">
- <div class="basic-title-left">
- <div class="basic-title-line"></div>
- <span class="basic-title-text">其他信息</span>
- </div>
- </div>
- <div class="steps-content">
- <a-row :gutter="16" class="smart-query-form-row">
- <a-col :span="24">
- <a-form-item label="附件">
- <a-upload-dragger
- v-model:file-list="fileList"
- name="file"
- :multiple="true"
- :before-upload="beforeUpload"
- @change="handleUploadChange"
- :accept="'.png,.jpg,.doc,.pdf,.mp4,.avi'"
- >
- <p class="ant-upload-drag-icon">
- <inbox-outlined/>
- </p>
- <p class="ant-upload-text">点击或将文件拖拽到这里上传</p>
- <p class="ant-upload-hint">支持:png、jpg、doc、pdf、mp4、avi...</p>
- </a-upload-dragger>
- </a-form-item>
- </a-col>
- </a-row>
- </div>
- </div>
- </div>
- </a-form>
- </a-card>
- </template>
- <script setup lang="jsx">
- import {reactive, ref, computed} from 'vue';
- const visible = ref(false);
- import {
- PlusOutlined,
- InboxOutlined,
- } from '@ant-design/icons-vue';
- import {useRouter} from 'vue-router';
- import {message} from 'ant-design-vue';
- import _ from 'lodash';
- import BsTable, {useBsTable} from '/@/components/BsUi/Table/index.js';
- const stepFormRef = ref(null);
- const router = useRouter();
- const formStates = reactive({
- manager: '',
- team: '',
- description: ''
- });
- // --------------------- 数据 ---------------------
- // 表单数据
- const formState = reactive({
- projectType: '',
- clueName: '',
- projectName: '',
- providerName: '',
- engineeringAttribute: '',
- countryRegion: '',
- province: '',
- designFlats: '',
- generalContractingFlats: '',
- investmentAgentFlats: '',
- complex: '',
- complexDescription: '',
- projectBelongIndustry: '',
- businessType: '',
- tenderPlatform: '',
- projectBudget: '',
- projectMoneySource: '',
- factory: '',
- projectBackground: '',
- projectStage: '',
- belongMarketer: '',
- attachment: '',
- projectAddress: '',
- clueSource: 'serviceProvider',
- isOwnerPartyA: undefined,
- isDesignPartyA: undefined,
- isTrustPartyA: undefined,
- isBiddingAgentPartyA: undefined,
- serviceProvider: undefined,
- region: undefined,
- teamDTOList: []
- });
- // --------------------- 校验规则 ---------------------
- const formRules = {
- // customerName: [{ required: true, message: '请输入客户名称', trigger: 'change' }],
- };
- const {
- tableOptions,
- setTablePropsValue: setValue,
- getTablePropsValue: getValue,
- } = useBsTable({
- tableOptions: {
- // url:''
- gridOptions: {
- loading: false,
- displayToolbar:'123',
- data: [],
- columns: [
- {
- field: 'key',
- title: '序号',
- },
- {
- field: 'manager',
- title: '营销经理',
- },
- {
- field: 'team',
- title: '营销团队',
- },
- {
- field: 'description',
- title: '支持说明',
- },
- {
- field: 'opt',
- title: '操作',
- width: '120px',
- fixed: 'right',
- align: 'center',
- slots: {
- default({row, column}) {
- return (
- <a-button
- type='text'
- size='small'
- onClick={() => {
- deleteRow(row.key);
- }}
- >
- 删除
- </a-button>
- );
- },
- },
- },
- ],
- },
- toolbarConfig: {
- enable: false,
- },
- pagerConfig: {
- enabled: true,
- isFixed: false,
- pageSize: 10,
- pageNum: 1,
- total: 0,
- },
- },
- });
- const showModal = () => {
- formStates.manager = '';
- formStates.team = '';
- formStates.description = '';
- visible.value = true;
- };
- // 确认添加
- const handleOk = () => {
- const currentData = getValue('gridOptions.data') || [];
- const newRow = {
- key: Date.now().toString(), // 生成唯一key
- manager: formStates.manager,
- team: formStates.team,
- description: formStates.description
- };
- setValue('gridOptions.data', [...currentData, newRow]);
- console.log(setValue('gridOptions.data', [...currentData, newRow]))
- resetForm();
- visible.value = false;
- };
- // 取消
- const handleCancel = () => {
- resetForm();
- visible.value = false;
- };
- // 重置表单
- const resetForm = () => {
- formState.manager = '';
- formState.team = '';
- formState.description = '';
- };
- // 删除行
- const deleteRow = (key) => {
- const currentData = getValue('gridOptions.data') || [];
- const newData = currentData.filter(item => item.key !== key);
- setValue('gridOptions.data', newData);
- };
- const addTeam = () => {
- const newKey = String(teamData.value.length + 1);
- teamData.value.push({
- key: newKey,
- manager: '',
- team: '',
- support: '',
- });
- };
- const dynamicField = computed(() => {
- switch (formState.clueSource) {
- case 'serviceProvider':
- return {
- label: '服务商名称',
- name: 'serviceProvider',
- placeholder: '请选择服务商'
- };
- case 'marketActivity':
- return {
- label: '活动名称',
- name: 'activityName',
- placeholder: '请选择活动'
- };
- case 'referral':
- return {
- label: '介绍备注',
- name: 'referralNote',
- placeholder: '请输入介绍备注'
- };
- default:
- return {
- label: '请选择',
- name: '',
- placeholder: '请先选择线索来源'
- };
- }
- });
- const handleClueSourceChange = () => {
- // 清空相关字段的值
- formState.serviceProvider = undefined;
- formState.activityName = undefined;
- formState.referralNote = undefined;
- };
- const isAnyPartyASelected = computed(() => {
- return (
- formState.isOwnerPartyA === 'yes' ||
- formState.isDesignPartyA === 'yes' ||
- formState.isTrustPartyA === 'yes' ||
- formState.isBiddingAgentPartyA === 'yes'
- );
- });
- // 处理单位选择变化
- const handleOwnerUnitChange = (value) => {
- if (value) {
- formState.isOwnerPartyA = 'yes';
- resetOtherPartyAs('owner');
- }
- };
- // 处理甲方选择变化
- const handlePartyAChange = (currentType) => {
- console.log(currentType, 'currentType')
- if (formState[`is${capitalizeFirstLetter(currentType)}PartyA`] === 'yes') {
- resetOtherPartyAs(currentType);
- }
- };
- const resetOtherPartyAs = (currentType) => {
- const types = ['owner', 'design', 'trust', 'biddingAgent'];
- types.forEach(type => {
- if (type !== currentType) {
- formState[`is${capitalizeFirstLetter(type)}PartyA`] = undefined;
- formState[`${type}Unit`] = undefined;
- }
- });
- };
- // 首字母大写辅助函数
- const capitalizeFirstLetter = (string) => {
- return string.charAt(0).toUpperCase() + string.slice(1);
- };
- const removeTeam = (key) => {
- teamData.value = teamData.value.filter(item => item.key !== key);
- };
- const labelCol = {style: {width: '110px'}};
- // ----------------------- 上传附件 ----------------------------
- // 已上传的附件列表
- const defaultFileList = ref([]);
- function changeAttachment(fileList) {
- defaultFileList.value = fileList;
- formState.attachment = _.isEmpty(fileList) ? [] : fileList;
- }
- // ----------------------- 步骤相关 ---------------------------
- const submit = () => {
- router.push('/market-manage/external-manage/clue-management/clue-list');
- // stepFormRef.value
- // .validateFields()
- // .then((values) => {
- // Modal.confirm({
- // title: '提示',
- // content: '确定要提交吗?',
- // okText: '确认',
- // onOk() {
- // postFormData();
- // },
- // cancelText: '取消',
- // onCancel() {
- // },
- // });
- // })
- // .catch((error) => {
- // console.log('step1_error', error);
- // });
- };
- const postFormData = () => {
- // customerApi.CustomerAddition(formModel).then((res) => {
- // message.success('提交成功');
- // router.push({path: '/teamwork/customer-manage/customer-list'});
- // });
- };
- //------------------------地区-------------------------------------
- // 文件上传
- const fileList = ref([]);
- const handleUploadChange = (info) => {
- let fileList = [...info.fileList];
- fileList = fileList.slice(-5); // 限制上传数量
- fileList.value = fileList;
- };
- const beforeUpload = (file) => {
- const isLt10M = file.size / 1024 / 1024 < 10;
- if (!isLt10M) {
- message.error('文件大小不能超过10MB!');
- return false;
- }
- return true;
- };
- const clueSourceOptions = ref([
- {value: 'serviceProvider', label: '服务商提供'},
- {value: 'marketActivity', label: '市场活动'},
- {value: 'referral', label: '转介绍'}
- ]);
- const serviceProviderOptions = ref([
- {value: 'provider1', label: '项目类'},
- {value: 'provider2', label: '贸易类'},
- ]);
- // 活动选项
- const activityOptions = ref([
- {value: 'activity1', label: '国内客户'},
- {value: 'activity2', label: '国外客户'}
- ]);
- const ownerUnitOptions = ref([
- {value: 'owner1', label: '国内客户'},
- {value: 'owner2', label: '国外客户'},
- ]);
- const ownerUnitOptions1 = ref([
- {value: 'owner1', label: '新建'},
- {value: 'owner2', label: '旧改'},
- ]);
- const ownerUnitOptions3 = ref([
- {value: 'owner1', label: '客户提供'},
- ]);
- const ownerUnitOptions4 = ref([
- {value: 'owner1', label: '业务一部'},
- {value: 'owner2', label: '业务二部'},
- {value: 'owner3', label: '业务三部'},
- ]);
- const ownerUnitOptions5 = ref([
- {value: 'owner1', label: '政府机构'},
- {value: 'owner2', label: '民营企业'},
- ]);
- const regionOptions = ref([
- {
- value: 'zhejiang',
- label: '浙江省',
- children: [
- {
- value: 'hangzhou',
- label: '杭州市',
- children: [
- {value: 'xihu', label: '西湖区'},
- ],
- },
- ],
- },
- // 其他省份...
- ]);
- </script>
- <style scoped lang="less">
- .flex-container {
- display: flex;
- align-items: center;
- }
- .approval-steps {
- display: flex;
- flex-direction: column;
- gap: 20px;
- // width: 1350px;
- margin: 0 auto;
- .basic-title {
- display: flex;
- justify-content: space-between;
- align-items: center;
- width: 100%;
- height: 40px;
- padding: 0 16px 4px 16px;
- border-bottom: 2px solid #f6f6f6;
- background: #ffffff;
- border-top-left-radius: 8px;
- border-top-right-radius: 8px;
- .basic-title-left {
- height: 100%;
- display: flex;
- align-items: center;
- .basic-title-line {
- width: 4px;
- height: 20px;
- border-radius: 4px;
- background: #267ef8;
- margin-right: 5px;
- }
- .basic-title-text {
- font-size: 16px;
- font-style: normal;
- font-weight: 600;
- line-height: 20px;
- }
- }
- .basic-title-right {
- display: flex;
- gap: 10px;
- }
- }
- .steps-content {
- margin-top: 14px;
- }
- .steps-action {
- display: flex;
- justify-content: center;
- margin-top: 18px;
- }
- }
- </style>
|