|
|
@@ -0,0 +1,441 @@
|
|
|
+<template>
|
|
|
+ <div
|
|
|
+
|
|
|
+ >
|
|
|
+ <headerTitle title="基本信息"></headerTitle>
|
|
|
+ <el-form
|
|
|
+ label-width="120px"
|
|
|
+ ref="form"
|
|
|
+ :model="form"
|
|
|
+ :rules="rules"
|
|
|
+ style="margin-top: 30px"
|
|
|
+ >
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="选择客户" prop="contactName">
|
|
|
+ <el-input
|
|
|
+ placeholder="请选择"
|
|
|
+ v-model="form.contactName"
|
|
|
+ @click.native="handParent"
|
|
|
+ maxlength="50"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label=" 商机名称" prop="name">
|
|
|
+ <el-input
|
|
|
+ placeholder="请输入"
|
|
|
+ v-model="form.name"
|
|
|
+ maxlength="50"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="选择负责人" prop="responsibleName">
|
|
|
+ <el-input
|
|
|
+ placeholder="请选择"
|
|
|
+ v-model="userInfo.name"
|
|
|
+ disabled
|
|
|
+ maxlength="50"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="商机来源" prop="sourceCode">
|
|
|
+ <DictSelection
|
|
|
+ dictName="商机来源"
|
|
|
+ clearable
|
|
|
+ v-model="form.sourceCode"
|
|
|
+ >
|
|
|
+ </DictSelection>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="赢单率" prop="winRate">
|
|
|
+ <el-input placeholder="请输入内容" v-model="form.winRate">
|
|
|
+ <template slot="append">%</template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="预算" prop="budget">
|
|
|
+ <el-input placeholder="请输入内容" v-model="form.budget">
|
|
|
+ <template slot="append">万元</template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="预计结单日期" prop="expectedClosingDate">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="form.expectedClosingDate"
|
|
|
+ value-format="yyyy-MM-dd"
|
|
|
+ placeholder="请选择"
|
|
|
+ type="date"
|
|
|
+ style="width: 200px"
|
|
|
+ class="filter-item"
|
|
|
+ ></el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="商机阶段" prop="stageCode">
|
|
|
+ <DictSelection
|
|
|
+ dictName="商机阶段"
|
|
|
+ clearable
|
|
|
+ v-model="form.stageCode"
|
|
|
+ >
|
|
|
+ </DictSelection>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item prop="files" label="附件">
|
|
|
+ <fileUpload
|
|
|
+ v-model="form.files"
|
|
|
+ module="main"
|
|
|
+ :showLib="false"
|
|
|
+ :limit="5"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="16">
|
|
|
+ <el-form-item label="备注" prop="remark">
|
|
|
+ <el-input
|
|
|
+ placeholder="请输入"
|
|
|
+ v-model="form.remark"
|
|
|
+ type="textarea"
|
|
|
+ maxlength="300"
|
|
|
+ ></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
+ <headerTitle title="产品清单"></headerTitle>
|
|
|
+ <inventoryTable ref="inventoryTable"></inventoryTable>
|
|
|
+ <headerTitle title="竞品"></headerTitle>
|
|
|
+ <businessAddTable
|
|
|
+ ref="businessAddTable"
|
|
|
+ @timeAll="getDetailTable"
|
|
|
+ :delDetailIds="delDetailIds"
|
|
|
+ ></businessAddTable>
|
|
|
+
|
|
|
+ <headerTitle title="关键人信息"></headerTitle>
|
|
|
+ <personnelAddTable
|
|
|
+ ref="personnelAddTable"
|
|
|
+ :contactId="form.contactId"
|
|
|
+ @timeAll="getPersonnelAddTable"
|
|
|
+ :delDetailIds="PersonnelDetailIds"
|
|
|
+ ></personnelAddTable>
|
|
|
+
|
|
|
+ <head-list ref="headRef" @changeParent="changeHead"></head-list>
|
|
|
+ <parentList
|
|
|
+ ref="parentRef"
|
|
|
+ classType="1"
|
|
|
+ @changeParent="changeParent"
|
|
|
+ ></parentList>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ import store from '@/store';
|
|
|
+ import dictMixins from '@/mixins/dictMixins';
|
|
|
+ import businessAddTable from './businessAddTable.vue';
|
|
|
+ import personnelAddTable from './personnelAddTable.vue';
|
|
|
+ import headList from '@/components/headList';
|
|
|
+ import parentList from '@/views/bpm/handleTask/components/saleOrder/parentList.vue';
|
|
|
+ import {
|
|
|
+ getDetail
|
|
|
+ } from '@/api/bpm/components/saleManage/businessOpportunity';
|
|
|
+
|
|
|
+ import { copyObj } from '@/utils/util';
|
|
|
+ import inventoryTable from '@/views/bpm/handleTask/components/saleOrder/inventoryTable.vue';
|
|
|
+ import fileUpload from '@/components/upload/fileUpload';
|
|
|
+
|
|
|
+ export default {
|
|
|
+ props: {
|
|
|
+ businessId: {
|
|
|
+ default: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mixins: [dictMixins],
|
|
|
+ components: {
|
|
|
+ fileUpload,
|
|
|
+ businessAddTable,
|
|
|
+ personnelAddTable,
|
|
|
+ headList,
|
|
|
+ parentList,
|
|
|
+ inventoryTable
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ let formDef = {
|
|
|
+ id: '',
|
|
|
+ contactName: '',
|
|
|
+ contactId: '',
|
|
|
+ budget: null,
|
|
|
+ expectedClosingDate: '',
|
|
|
+ sourceCode: '',
|
|
|
+ sourceName: '',
|
|
|
+ stageCode: '',
|
|
|
+ stageName: '',
|
|
|
+ winRate: null,
|
|
|
+ name: '',
|
|
|
+ remark: '',
|
|
|
+ responsibleName: '',
|
|
|
+ responsibleId: '',
|
|
|
+ source: '',
|
|
|
+ status: 1,
|
|
|
+ files: []
|
|
|
+ };
|
|
|
+
|
|
|
+ return {
|
|
|
+ delDetailIds: [],
|
|
|
+ PersonnelDetailIds: [],
|
|
|
+ visible: false,
|
|
|
+ title: '',
|
|
|
+ row: {},
|
|
|
+ userInfo: {},
|
|
|
+ activeName: 'base',
|
|
|
+ formDef,
|
|
|
+ form: copyObj(formDef),
|
|
|
+ // removeBankList: [],
|
|
|
+ // removeLinkList: [],
|
|
|
+ tableBankData: [],
|
|
|
+ tableLinkData: [],
|
|
|
+
|
|
|
+ rules: {
|
|
|
+ contactName: [
|
|
|
+ { required: true, message: '请选择客户', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ name: [
|
|
|
+ { required: true, message: '请输入商机名称', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ expectedClosingDate: [
|
|
|
+ { required: true, message: '请选择预计结单日期', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ sourceCode: [
|
|
|
+ { required: true, message: '请选择商机来源名称', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ stageCode: [
|
|
|
+ { required: true, message: '请选择商机阶段名称', trigger: 'change' }
|
|
|
+ ],
|
|
|
+ winRate: [
|
|
|
+ {
|
|
|
+ required: false,
|
|
|
+ trigger: 'blur',
|
|
|
+ validator: (_rule, value, callback) => {
|
|
|
+ console.log(_rule);
|
|
|
+ const reg = /^\d+(\.\d{1,2})?$/; // 限制为最多两位小数的正数
|
|
|
+ if (!value) {
|
|
|
+ callback(); // 验证通过
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (reg.test(value) && parseFloat(value) <= 100) {
|
|
|
+ callback(); // 验证通过
|
|
|
+ } else {
|
|
|
+ value = value && value.replace(/[^0-9.]/g, ''); // 只保留数字和小数点
|
|
|
+ const [integerPart, decimalPart] = value && value.split('.');
|
|
|
+ if (decimalPart && decimalPart.length > 2) {
|
|
|
+ callback(new Error('小数位数不能超过两位'));
|
|
|
+ } else {
|
|
|
+ callback(new Error('只能输入小于100的数字'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ budget: [
|
|
|
+ {
|
|
|
+ required: false,
|
|
|
+ trigger: 'blur',
|
|
|
+ validator: (_rule, value, callback) => {
|
|
|
+ const reg = /^\d{1,13}(\.\d{1,2})?$/; // 限制为最多两位小数的13位以内的正数
|
|
|
+ if (!value) {
|
|
|
+ callback(); // 验证通过
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (reg.test(value)) {
|
|
|
+ callback(); // 验证通过
|
|
|
+ } else {
|
|
|
+ value = value && value.replace(/[^0-9.]/g, ''); // 只保留数字和小数点
|
|
|
+ const [integerPart, decimalPart] = value && value.split('.');
|
|
|
+ if (decimalPart && decimalPart.length > 2) {
|
|
|
+ callback(new Error('小数位数不能超过两位'));
|
|
|
+ } else if (integerPart.length > 13) {
|
|
|
+ callback(new Error('整数位数不能超过13位'));
|
|
|
+ } else {
|
|
|
+ callback(new Error('只能输入数字'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+
|
|
|
+ // 提交状态
|
|
|
+ loading: false,
|
|
|
+ // 是否是修改
|
|
|
+ isUpdate: false,
|
|
|
+
|
|
|
+ // 组织机构树形结构数据
|
|
|
+ groupTreeData: [],
|
|
|
+ // 组织机构平铺数据
|
|
|
+ groupData: []
|
|
|
+ };
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.userInfo = store.state.user.info;
|
|
|
+ });
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.getDetailData(this.businessId);
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ //获取竞品
|
|
|
+ getDetailTable(val) {
|
|
|
+ this.form.competAnalysisList = val;
|
|
|
+ },
|
|
|
+ //获取关键人信息
|
|
|
+ getPersonnelAddTable(val) {
|
|
|
+ this.form.partyList = val;
|
|
|
+ },
|
|
|
+ //选择客户回调
|
|
|
+ changeParent(obj) {
|
|
|
+ this.$set(this.form, 'contactId', obj.id);
|
|
|
+ this.$set(this.form, 'contactName', obj.name);
|
|
|
+ },
|
|
|
+ //选择负责人回调
|
|
|
+ changeHead(obj) {
|
|
|
+ this.$set(this.form, 'responsibleId', obj.id);
|
|
|
+ this.$set(this.form, 'responsibleName', obj.name);
|
|
|
+ },
|
|
|
+ handParent() {
|
|
|
+ let item = {
|
|
|
+ id: this.form.contactId
|
|
|
+ };
|
|
|
+ this.$refs.parentRef.open(item);
|
|
|
+ },
|
|
|
+ handHead() {
|
|
|
+ let item = {
|
|
|
+ id: this.form.responsibleId
|
|
|
+ };
|
|
|
+ this.$refs.headRef.open(item);
|
|
|
+ },
|
|
|
+
|
|
|
+ //获取详情
|
|
|
+ async getDetailData(id) {
|
|
|
+ this.loading = true;
|
|
|
+ const data = await getDetail(id);
|
|
|
+ this.loading = false;
|
|
|
+ if (data) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.form = data;
|
|
|
+ this.$refs.businessAddTable &&
|
|
|
+ this.$refs.businessAddTable.putTableValue(
|
|
|
+ data.competAnalysisList
|
|
|
+ );
|
|
|
+ this.$refs.personnelAddTable &&
|
|
|
+ this.$refs.personnelAddTable.putTableValue(data.partyList);
|
|
|
+ this.$refs.inventoryTable &&
|
|
|
+ this.$refs.inventoryTable.putTableValue(data.productList);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ salesmanChange(val, info) {
|
|
|
+ this.otherForm.salesmanName = info.name;
|
|
|
+ },
|
|
|
+ settlementModeChange(info) {
|
|
|
+ this.otherForm.settlementModeName = info.dictValue;
|
|
|
+ },
|
|
|
+ ifChiefChange(value, idx) {
|
|
|
+ if (value === 1) {
|
|
|
+ this.tableLinkData.forEach((e) => (e.ifChief = 0));
|
|
|
+ this.tableLinkData[idx].ifChief = 1;
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ getValidate() {
|
|
|
+ return Promise.all([
|
|
|
+ new Promise((resolve, reject) => {
|
|
|
+ this.$refs.form.validate((valid) => {
|
|
|
+ if (!valid) {
|
|
|
+ reject(false);
|
|
|
+ } else {
|
|
|
+ resolve(true);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }),
|
|
|
+ new Promise((resolve, reject) => {
|
|
|
+ this.$refs.inventoryTable.validateForm((valid) => {
|
|
|
+ if (!valid) {
|
|
|
+ reject(false);
|
|
|
+ } else {
|
|
|
+ resolve(true);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }),
|
|
|
+ new Promise((resolve, reject) => {
|
|
|
+ this.$refs.businessAddTable.validateForm((valid) => {
|
|
|
+ if (!valid) {
|
|
|
+ reject(false);
|
|
|
+ } else {
|
|
|
+ resolve(true);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }),
|
|
|
+ new Promise((resolve, reject) => {
|
|
|
+ this.$refs.personnelAddTable.validateForm((valid) => {
|
|
|
+ if (!valid) {
|
|
|
+ reject(false);
|
|
|
+ } else {
|
|
|
+ resolve(true);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ })
|
|
|
+ ]);
|
|
|
+ },
|
|
|
+ async getTableValue() {
|
|
|
+ try {
|
|
|
+ await this.getValidate();
|
|
|
+ // 表单验证通过,执行保存操作
|
|
|
+
|
|
|
+
|
|
|
+ let _sourceName = this.getDictValue('商机来源', this.form.sourceCode),
|
|
|
+ _stageName = this.getDictValue('商机阶段', this.form.stageCode);
|
|
|
+ this.form = Object.assign({}, this.form, {
|
|
|
+ responsibleId: this.userInfo.userId,
|
|
|
+ responsibleName: this.userInfo.name,
|
|
|
+ sourceName: _sourceName,
|
|
|
+ stageName: _stageName,
|
|
|
+ files: this.form.files||[]
|
|
|
+ });
|
|
|
+
|
|
|
+ if (this.$refs.inventoryTable.getTableValue().length == 0) {
|
|
|
+ this.$message.warning('产品清单不能为空');
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const commitData = {
|
|
|
+ opportunity: this.form,
|
|
|
+ competAnalysisList: this.$refs.businessAddTable.getTableValue(),
|
|
|
+ partyList: this.$refs.personnelAddTable.getTableValue(),
|
|
|
+ productList: this.$refs.inventoryTable.getTableValue()
|
|
|
+ };
|
|
|
+ return commitData;
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ // 表单验证未通过,不执行保存操作
|
|
|
+ }
|
|
|
+ },
|
|
|
+ cancel() {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.activeName = 'base';
|
|
|
+ // 关闭后,销毁所有的表单数据
|
|
|
+ this.$refs['otherForm'] && this.$refs['otherForm'].resetFields();
|
|
|
+ this.$refs['formRef'] && this.$refs['formRef'].resetFields();
|
|
|
+ this.form = copyObj(this.formDef);
|
|
|
+ this.visible = false;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+</script>
|