|
@@ -0,0 +1,587 @@
|
|
|
+import React from 'react';
|
|
|
+import {
|
|
|
+ Tooltip,
|
|
|
+ Button,
|
|
|
+ AutoComplete,
|
|
|
+ Input,
|
|
|
+ Select,
|
|
|
+ Spin,
|
|
|
+ Table,
|
|
|
+ message,
|
|
|
+ Form,
|
|
|
+ Tabs,
|
|
|
+} from 'antd';
|
|
|
+import $ from 'jquery/src/ajax';
|
|
|
+import { ShowModal, } from "@/tools.js";
|
|
|
+import { industry } from "@/dataDic.js"
|
|
|
+import ShowModalDiv from "@/showModal.jsx";
|
|
|
+import { ChooseList } from "../../../order/orderNew/chooseList";
|
|
|
+import MainBusinessLog from './mainBusinessLog';
|
|
|
+
|
|
|
+import './customer.less';
|
|
|
+
|
|
|
+const TabPane = Tabs.TabPane;
|
|
|
+
|
|
|
+const IntentionCustomer = Form.create()(React.createClass({
|
|
|
+
|
|
|
+ getInitialState() {
|
|
|
+ return {
|
|
|
+ searchInfor: {},
|
|
|
+ fjlist: [],
|
|
|
+ loading: false,
|
|
|
+ visible: false,
|
|
|
+ changeList: undefined,
|
|
|
+ uid: '',
|
|
|
+ dataSource: [],
|
|
|
+ pagination: {
|
|
|
+ defaultCurrent: 1,
|
|
|
+ defaultPageSize: 10,
|
|
|
+ showQuickJumper: true,
|
|
|
+ pageSize: 10,
|
|
|
+ onChange: function (page) {
|
|
|
+ this.loadData(page);
|
|
|
+ }.bind(this),
|
|
|
+ showTotal: function (total) {
|
|
|
+ return '共' + total + '条数据';
|
|
|
+ }
|
|
|
+ },
|
|
|
+ columns: [{
|
|
|
+ title: '客户名称',
|
|
|
+ dataIndex: 'nickname',
|
|
|
+ key: 'nickname',
|
|
|
+ fixed: 'left',
|
|
|
+ width: 200,
|
|
|
+ render: text => {
|
|
|
+ return (
|
|
|
+ <Tooltip title={text}>
|
|
|
+ <div>{text}</div>
|
|
|
+ </Tooltip>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '地区',
|
|
|
+ dataIndex: 'area',
|
|
|
+ key: 'area',
|
|
|
+ width: 150,
|
|
|
+ render: (text, record) => {
|
|
|
+ return (record.province || "") + (!record.city ? "" : "-") + (record.city || "") + (!record.area ? "" : "-") + (record.area || "");
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '客户类型',
|
|
|
+ dataIndex: 'shareType',
|
|
|
+ key: 'shareType',
|
|
|
+ render: text => {
|
|
|
+ return (
|
|
|
+ <div>{["私有客户", "公共客户", "签单客户", "外联客户"][text]}</div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '主营产品',
|
|
|
+ dataIndex: 'businessScope',
|
|
|
+ key: 'businessScope',
|
|
|
+ width: 200,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '行业',
|
|
|
+ dataIndex: 'industry',
|
|
|
+ key: 'industry',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '联系人',
|
|
|
+ dataIndex: 'contactName',
|
|
|
+ key: 'contactName',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '所属人',
|
|
|
+ dataIndex: 'adminName',
|
|
|
+ key: 'adminName',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '意向合作项目',
|
|
|
+ dataIndex: 'intendedProject',
|
|
|
+ key: 'intendedProject'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '知产情况',
|
|
|
+ dataIndex: 'patentCount',
|
|
|
+ key: 'patentCount',
|
|
|
+ width: 220,
|
|
|
+ render: (text, record) => {
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ 专利 {text || 0}
|
|
|
+ 其中发明专利 {record.inventionPatentCount || 0}
|
|
|
+ 实用新型 {record.utilityModelCount || 0}
|
|
|
+ 外观设计 {record.appearancePatentCount || 0}
|
|
|
+ 软著 {record.softwareWorksCount || 0}
|
|
|
+ 其他类型 {record.otherCount || 0}
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '财务数据',
|
|
|
+ dataIndex: 'financialData',
|
|
|
+ key: 'financialData',
|
|
|
+ width: 200,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '前期沟通',
|
|
|
+ dataIndex: 'earlyCommunication',
|
|
|
+ key: 'earlyCommunication',
|
|
|
+ width: 200,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '面谈思路及目的',
|
|
|
+ dataIndex: 'interviewIdeas',
|
|
|
+ key: 'interviewIdeas',
|
|
|
+ width: 200,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '所属部门',
|
|
|
+ dataIndex: 'depName',
|
|
|
+ key: 'depName',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '操作',
|
|
|
+ dataIndex: 'id',
|
|
|
+ key: 'id',
|
|
|
+ render: text => {
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ <Button
|
|
|
+ onClick={(e) => {
|
|
|
+ e.stopPropagation();
|
|
|
+ this.setState({
|
|
|
+ visible: true,
|
|
|
+ uid: text
|
|
|
+ })
|
|
|
+ }} type="primary" style={{ marginLeft: '10px' }}>主营日志</Button>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ columnsX: [
|
|
|
+ {
|
|
|
+ title: '客户名称',
|
|
|
+ dataIndex: 'nickname',
|
|
|
+ key: 'nickname',
|
|
|
+ fixed: 'left',
|
|
|
+ width: 200,
|
|
|
+ render: text => {
|
|
|
+ return (
|
|
|
+ <Tooltip title={text}>
|
|
|
+ <div>{text}</div>
|
|
|
+ </Tooltip>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '地区',
|
|
|
+ dataIndex: 'area',
|
|
|
+ key: 'area',
|
|
|
+ width: 150,
|
|
|
+ render: (text, record) => {
|
|
|
+ return (record.province || "") + (!record.city ? "" : "-") + (record.city || "") + (!record.area ? "" : "-") + (record.area || "");
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '客户类型',
|
|
|
+ dataIndex: 'shareType',
|
|
|
+ key: 'shareType',
|
|
|
+ render: text => {
|
|
|
+ return (
|
|
|
+ <div>{["私有客户", "公共客户", "签单客户", "外联客户"][text]}</div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '渠道类别',
|
|
|
+ dataIndex: 'channelType',
|
|
|
+ key: 'channelType',
|
|
|
+ render: text => {
|
|
|
+ return (
|
|
|
+ <div>{["", "其他", "民主党派", "园区", "民间组织", "战略合作单位"][text]}</div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '企业数',
|
|
|
+ dataIndex: 'enterpriseCount',
|
|
|
+ key: 'enterpriseCount',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '联系人',
|
|
|
+ dataIndex: 'contactName',
|
|
|
+ key: 'contactName',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '所属人',
|
|
|
+ dataIndex: 'adminName',
|
|
|
+ key: 'adminName',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '面谈项目',
|
|
|
+ dataIndex: 'intendedProject',
|
|
|
+ key: 'intendedProject',
|
|
|
+ width: 200,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '考核指标',
|
|
|
+ dataIndex: 'channelIndicators',
|
|
|
+ key: 'channelIndicators',
|
|
|
+ width: 200,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '面谈思路及目的',
|
|
|
+ dataIndex: 'interviewIdeas',
|
|
|
+ key: 'interviewIdeas',
|
|
|
+ width: 200,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '面谈人及分工',
|
|
|
+ dataIndex: 'interviewDistribution',
|
|
|
+ key: 'interviewDistribution',
|
|
|
+ width: 200,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '所属部门',
|
|
|
+ dataIndex: 'depName',
|
|
|
+ key: 'depName',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '操作',
|
|
|
+ dataIndex: 'id',
|
|
|
+ key: 'id',
|
|
|
+ render: text => {
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ <Button
|
|
|
+ onClick={(e) => {
|
|
|
+ e.stopPropagation();
|
|
|
+ this.setState({
|
|
|
+ visible: true,
|
|
|
+ uid: text
|
|
|
+ })
|
|
|
+ }} type="primary" style={{ marginLeft: '10px' }}>主营日志</Button>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ dataSource: [],
|
|
|
+ };
|
|
|
+ },
|
|
|
+
|
|
|
+ componentWillMount() {
|
|
|
+ this.loadData();
|
|
|
+ },
|
|
|
+
|
|
|
+ componentWillReceiveProps(nextProps) {
|
|
|
+ if (nextProps.newChannel !== this.props.newChannel) {
|
|
|
+ this.setState({
|
|
|
+ changeList: undefined
|
|
|
+ })
|
|
|
+ this.reset();
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ loadData(pageNo) {
|
|
|
+ const { searchInfor, pagination } = this.state;
|
|
|
+ this.setState({
|
|
|
+ loading: true,
|
|
|
+ });
|
|
|
+ let datas = Object.assign(searchInfor, {
|
|
|
+ newChannel: this.props.newChannel,
|
|
|
+ pageNo: pageNo || 1,
|
|
|
+ pageSize: pagination.pageSize,
|
|
|
+ });
|
|
|
+ $.ajax({
|
|
|
+ method: "get",
|
|
|
+ dataType: "json",
|
|
|
+ crossDomain: false,
|
|
|
+ url: globalConfig.context + "/api/admin/userArchives/selectUserArchives",
|
|
|
+ data: datas,
|
|
|
+ success: function (data) {
|
|
|
+ ShowModal(this);
|
|
|
+ this.setState({
|
|
|
+ loading: false,
|
|
|
+ });
|
|
|
+ if (data.error && data.error.length === 0) {
|
|
|
+ if (data.data.list) {
|
|
|
+ pagination.current = data.data.pageNo;
|
|
|
+ pagination.total = data.data.totalCount;
|
|
|
+ if (data.data && data.data.list && !data.data.list.length) {
|
|
|
+ pagination.current = 0;
|
|
|
+ pagination.total = 0;
|
|
|
+ }
|
|
|
+ this.setState({
|
|
|
+ dataSource: data.data.list,
|
|
|
+ pagination: this.state.pagination,
|
|
|
+ pageNo: data.data.pageNo,
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ this.setState({
|
|
|
+ dataSource: data.data,
|
|
|
+ pagination: false,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ message.warning(data.error[0].message);
|
|
|
+ }
|
|
|
+ }.bind(this),
|
|
|
+ }).always(
|
|
|
+ function () {
|
|
|
+ this.setState({
|
|
|
+ loading: false,
|
|
|
+ });
|
|
|
+ }.bind(this)
|
|
|
+ );
|
|
|
+ },
|
|
|
+
|
|
|
+ followUp(e) {
|
|
|
+ const { searchInfor } = this.state;
|
|
|
+ this.setState({
|
|
|
+ searchInfor: Object.assign(searchInfor, {
|
|
|
+ aname: e,
|
|
|
+ }),
|
|
|
+ });
|
|
|
+ $.ajax({
|
|
|
+ method: "get",
|
|
|
+ dataType: "json",
|
|
|
+ crossDomain: false,
|
|
|
+ url: globalConfig.context + "/api/admin/customer/listAdminByName",
|
|
|
+ data: {
|
|
|
+ adminName: e,
|
|
|
+ },
|
|
|
+ success: function (data) {
|
|
|
+ let thedata = data.data;
|
|
|
+ if (!thedata) {
|
|
|
+ if (data.error && data.error.length) {
|
|
|
+ message.warning(data.error[0].message);
|
|
|
+ }
|
|
|
+ thedata = {};
|
|
|
+ }
|
|
|
+ this.setState({
|
|
|
+ fjlist: thedata,
|
|
|
+ });
|
|
|
+ }.bind(this),
|
|
|
+ }).always(
|
|
|
+ function () {
|
|
|
+ this.setState({
|
|
|
+ loading: false,
|
|
|
+ });
|
|
|
+ }.bind(this)
|
|
|
+ );
|
|
|
+ },
|
|
|
+
|
|
|
+ selectF(value) {
|
|
|
+ const { searchInfor, fjlist } = this.state;
|
|
|
+ const newdataSources = JSON.stringify(fjlist) == "{}" ? [] : fjlist;
|
|
|
+ this.setState({
|
|
|
+ searchInfor: Object.assign(searchInfor, {
|
|
|
+ aid: newdataSources.find((item) => item.name == value).id,
|
|
|
+ }),
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ changeList(arr) {
|
|
|
+ const newArr = [];
|
|
|
+ let list = this.props.newChannel == 1
|
|
|
+ ? this.state.columnsX
|
|
|
+ : this.state.columns
|
|
|
+ list.forEach((item) => {
|
|
|
+ arr.forEach((val) => {
|
|
|
+ if (val === item.title) {
|
|
|
+ newArr.push(item);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ this.setState({
|
|
|
+ changeList: newArr,
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ search() {
|
|
|
+ this.loadData();
|
|
|
+ },
|
|
|
+
|
|
|
+ reset() {
|
|
|
+ this.setState({
|
|
|
+ searchInfor: JSON.parse(JSON.stringify({})),
|
|
|
+ }, () => {
|
|
|
+ this.loadData();
|
|
|
+ })
|
|
|
+ },
|
|
|
+
|
|
|
+ render() {
|
|
|
+ const { searchInfor } = this.state
|
|
|
+ const { newChannel } = this.props
|
|
|
+ const newdataSources =
|
|
|
+ JSON.stringify(this.state.fjlist) == "{}" ? [] : this.state.fjlist;
|
|
|
+ const newoptions = newdataSources.map((group) => (
|
|
|
+ <Select.Option key={group.id} value={group.name}>
|
|
|
+ {group.name}
|
|
|
+ </Select.Option>
|
|
|
+ ));
|
|
|
+ return (
|
|
|
+ <div className="user-content">
|
|
|
+ <ShowModalDiv ShowModal={this.state.showModal} onClose={() => { this.setState({ showModal: false }) }} />
|
|
|
+ <div className="content-title" style={{ marginBottom: 10 }}>
|
|
|
+ <span style={{ fontWeight: 900, fontSize: 16 }}>{newChannel == 1 ? "渠道档案汇总" : "客户档案汇总"}</span>
|
|
|
+ </div>
|
|
|
+ <div className="user-search">
|
|
|
+ <Tabs
|
|
|
+ defaultActiveKey="1"
|
|
|
+ className="test">
|
|
|
+ <TabPane tab="搜索" key="1" style={{ paddingTop: '10px' }}>
|
|
|
+ <Input
|
|
|
+ placeholder={newChannel == 1 ? "渠道名称" : "客户名称"}
|
|
|
+ value={searchInfor.name || undefined}
|
|
|
+ style={{ width: 150, marginRight: 10 }}
|
|
|
+ onChange={e => {
|
|
|
+ this.setState({
|
|
|
+ searchInfor: Object.assign(searchInfor, {
|
|
|
+ name: e.target.value,
|
|
|
+ }),
|
|
|
+ });
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <AutoComplete
|
|
|
+ className="certain-category-search"
|
|
|
+ dropdownClassName="certain-category-search-dropdown"
|
|
|
+ dropdownMatchSelectWidth={false}
|
|
|
+ style={{ width: "150px" }}
|
|
|
+ dataSource={newoptions}
|
|
|
+ placeholder="所属人"
|
|
|
+ value={searchInfor.aname || undefined}
|
|
|
+ onChange={this.followUp.bind(this)}
|
|
|
+ filterOption={true}
|
|
|
+ onSelect={this.selectF.bind(this)}
|
|
|
+ >
|
|
|
+ <Input />
|
|
|
+ </AutoComplete>
|
|
|
+ {newChannel == 1 &&
|
|
|
+ <Select
|
|
|
+ mode="multiple"
|
|
|
+ placeholder={"请选择渠道类别"}
|
|
|
+ style={{ width: 200 }}
|
|
|
+ value={searchInfor.channelType ? searchInfor.channelType.split(",") : undefined}
|
|
|
+ onChange={(e) => {
|
|
|
+ this.setState({
|
|
|
+ searchInfor: Object.assign(searchInfor, {
|
|
|
+ channelType: e.toString(),
|
|
|
+ }),
|
|
|
+ });
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {[
|
|
|
+ { name: "民主党派", val: 2 },
|
|
|
+ { name: "园区", val: 3 },
|
|
|
+ { name: "民间组织", val: 4 },
|
|
|
+ { name: "战略合作单位", val: 5 },
|
|
|
+ { name: "其他", val: 1 },].map((it, ins) => (
|
|
|
+ <Option key={it.val}>{it.name}</Option>
|
|
|
+ ))}
|
|
|
+ </Select>}
|
|
|
+ {newChannel == 0 && <Input
|
|
|
+ placeholder="产品关键字"
|
|
|
+ value={searchInfor.businessScope || undefined}
|
|
|
+ style={{ width: 150, marginRight: 10 }}
|
|
|
+ onChange={e => {
|
|
|
+ this.setState({
|
|
|
+ searchInfor: Object.assign(searchInfor, {
|
|
|
+ businessScope: e.target.value,
|
|
|
+ }),
|
|
|
+ });
|
|
|
+ }}
|
|
|
+ />}
|
|
|
+ {newChannel == 0 &&
|
|
|
+ <Select
|
|
|
+ mode="multiple"
|
|
|
+ placeholder={"请选择行业"}
|
|
|
+ style={{ width: 200 }}
|
|
|
+ value={searchInfor.industry ? searchInfor.industry.split(",") : undefined}
|
|
|
+ onChange={(e) => {
|
|
|
+ this.setState({
|
|
|
+ searchInfor: Object.assign(searchInfor, {
|
|
|
+ industry: e.toString(),
|
|
|
+ }),
|
|
|
+ });
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {industry.map((it, ins) => (
|
|
|
+ <Option key={it.value}>{it.key}</Option>
|
|
|
+ ))}
|
|
|
+ </Select>}
|
|
|
+ <Select
|
|
|
+ placeholder={"请选择客户类型"}
|
|
|
+ style={{ width: 150 }}
|
|
|
+ value={searchInfor.shareType}
|
|
|
+ onChange={(e) => {
|
|
|
+ this.setState({
|
|
|
+ searchInfor: Object.assign(searchInfor, {
|
|
|
+ shareType: e,
|
|
|
+ }),
|
|
|
+ });
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Option value="">全部客户</Option>
|
|
|
+ <Option value="0">私有客户</Option>
|
|
|
+ <Option value="1">公共客户</Option>
|
|
|
+ <Option value="2">签单客户</Option>
|
|
|
+ <Option value="3">外联客户</Option>
|
|
|
+ </Select>
|
|
|
+ <Button type="primary" onClick={this.search} style={{ marginRight: 10 }}>
|
|
|
+ 搜索
|
|
|
+ </Button>
|
|
|
+ <Button onClick={this.reset}>重置</Button>
|
|
|
+ </TabPane>
|
|
|
+ <TabPane tab="更改表格显示数据" key="2">
|
|
|
+ <div style={{ marginLeft: 10 }}>
|
|
|
+ <ChooseList
|
|
|
+ columns={newChannel == 1 ? this.state.columnsX : this.state.columns}
|
|
|
+ changeFn={this.changeList}
|
|
|
+ changeList={this.state.changeList}
|
|
|
+ top={55}
|
|
|
+ margin={11}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </TabPane>
|
|
|
+ </Tabs>
|
|
|
+ </div>
|
|
|
+ <div className="patent-table">
|
|
|
+ <Spin spinning={this.state.loading}>
|
|
|
+ <Table
|
|
|
+ columns={this.state.changeList
|
|
|
+ ? this.state.changeList
|
|
|
+ : newChannel == 1
|
|
|
+ ? this.state.columnsX
|
|
|
+ : this.state.columns}
|
|
|
+ dataSource={this.state.dataSource}
|
|
|
+ pagination={this.state.pagination}
|
|
|
+ bordered
|
|
|
+ scroll={{ x: newChannel == 0 ? "130%" : "120%" }}
|
|
|
+ />
|
|
|
+ </Spin>
|
|
|
+ </div>
|
|
|
+ {this.state.visible &&
|
|
|
+ <MainBusinessLog
|
|
|
+ visible={this.state.visible}
|
|
|
+ uid={this.state.uid}
|
|
|
+ onCancel={() => {
|
|
|
+ this.setState({
|
|
|
+ visible: false,
|
|
|
+ uid: ''
|
|
|
+ })
|
|
|
+ }}
|
|
|
+ />}
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+}));
|
|
|
+export default IntentionCustomer;
|