index.jsx 79 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009
  1. import React, { Component } from "react";
  2. import { View, Input, Button, Text, Picker, RadioGroup, Label, Radio } from "@tarojs/components";
  3. import Taro, { getCurrentInstance } from "@tarojs/taro";
  4. import { getProvince } from '../../utils/tools/index'
  5. import {
  6. AtSearchBar,
  7. AtTextarea,
  8. AtModal,
  9. AtModalHeader,
  10. AtModalContent,
  11. AtModalAction,
  12. AtInput,
  13. AtIcon,
  14. AtButton,
  15. AtInputNumber
  16. } from "taro-ui";
  17. import Skeleton from "taro-skeleton";
  18. import {
  19. queryByUidAll,
  20. updateUser,
  21. addOneContact,
  22. findCustomerContacts,
  23. updateMainContact,
  24. limitUser,
  25. getBusinessProjectByName,
  26. addProject,
  27. queryProjectList,
  28. delProject
  29. } from "../../utils/servers/servers";
  30. import "./index.less";
  31. import "taro-ui/dist/style/components/icon.scss";
  32. import "taro-ui/dist/style/components/textarea.scss";
  33. import "taro-ui/dist/style/components/modal.scss";
  34. import "taro-ui/dist/style/components/timeline.scss";
  35. import "taro-ui/dist/style/components/calendar.scss";
  36. import "taro-ui/dist/style/components/input.scss";
  37. import "taro-ui/dist/style/components/search-bar.scss";
  38. import MessageNoticebar from "../../components/common/messageNoticebar";
  39. import { industry, channelTypeList, yearList } from '../../utils/tools/config';
  40. import { getChannel } from "../../utils/tools";
  41. import Superior from "../../components/common/superior";
  42. import CheckboxPicker from "../../components/common/CheckboxPicker";
  43. import AddressPicker from "../../components/common/addressPicker"
  44. import InteractList from "./components/InteractList";
  45. class CustomerProfile extends Component {
  46. $instance = getCurrentInstance();
  47. constructor(props) {
  48. super(props);
  49. this.state = {
  50. upType: -1,
  51. isOpened: false,
  52. dtails: {},
  53. projectList: [],
  54. info: {},
  55. sector: {},
  56. isAdd: false,
  57. obj: {},
  58. userList: [],
  59. allProjectList: [],
  60. options: [],
  61. checkProject: [],
  62. checkOptions: [],
  63. isSuperior: false,
  64. channe: {},
  65. isMask: false,
  66. addressPickerShow: false,
  67. region: [],
  68. customItem: [],
  69. multiplePickerShow: false,
  70. multiplePickerTitle: '',
  71. multiplePickerType: '',
  72. multiplePickerOptions: [],
  73. multiplePickerCheckedList: [],
  74. addItemShow: false,
  75. addItemType: '',
  76. addItemTitle: '',
  77. addItemInputVal: '',
  78. interactShow: false,
  79. interactShowType: '',
  80. interactTitle: '',
  81. interactList: []
  82. };
  83. this.queryByUidAll = this.queryByUidAll.bind(this);
  84. this.update = this.update.bind(this);
  85. this.add = this.add.bind(this);
  86. this.getUserList = this.getUserList.bind(this);
  87. this.getBusinessProjectByName = this.getBusinessProjectByName.bind(this);
  88. this.onSearchChange = this.onSearchChange.bind(this);
  89. this.handleOpenMultiplePicker = this.handleOpenMultiplePicker.bind(this);
  90. this.handleMultipleConfirm = this.handleMultipleConfirm.bind(this);
  91. this.handleAddItemSave = this.handleAddItemSave.bind(this);
  92. this.handleCloseAddItemDialog = this.handleCloseAddItemDialog.bind(this);
  93. }
  94. componentDidMount() {
  95. this.setState({
  96. isMask: false
  97. })
  98. this.queryByUidAll();
  99. this.getProjectList();
  100. }
  101. componentDidUpdate(prevProps) {
  102. const { interviewIdx, customerList } = this.props;
  103. if (interviewIdx != prevProps.interviewIdx && interviewIdx >= 0 && interviewIdx < customerList.length) {
  104. this.queryByUidAll();
  105. this.getProjectList();
  106. }
  107. }
  108. handlePrevClick() {
  109. this.props.onPrevClick();
  110. }
  111. handleNextClick() {
  112. this.onSaveAllData((resData) => {
  113. this.props.onNextClick(resData);
  114. })
  115. }
  116. toggleAddressPicker(e) {
  117. if (!e.province) {
  118. this.setState({ addressPickerShow: false });
  119. return;
  120. }
  121. const addressIds = getProvince(e.province, e.city, e.area);
  122. const { dtails } = this.state;
  123. dtails.locationProvince = addressIds[0];
  124. dtails.locationProvinceName = e.province;
  125. dtails.locationCity = addressIds[1];
  126. dtails.locationCityName = e.city;
  127. dtails.locationArea = addressIds[2];
  128. dtails.locationAreaName = e.area;
  129. this.setState({ dtails, addressPickerShow: false });
  130. }
  131. handleOpenMultiplePicker(type) {
  132. let multiplePickerOptions = [];
  133. let multiplePickerTitle = '';
  134. let multiplePickerCheckedList = [];
  135. const { dtails, info } = this.state;
  136. switch (type) {
  137. case 'industry':
  138. // 企业所属行业
  139. multiplePickerOptions = industry;
  140. multiplePickerCheckedList = !!dtails.industry ? dtails.industry.toString().split(',') : [];
  141. multiplePickerTitle = '请选择企业所属行业';
  142. break;
  143. case 'externalInvestIndustry':
  144. // 对外投资控股的行业
  145. multiplePickerOptions = industry;
  146. multiplePickerCheckedList = !!dtails.externalInvestIndustry ? dtails.externalInvestIndustry.toString().split(',') : [];
  147. multiplePickerTitle = '请选择对外投资控股的行业';
  148. break;
  149. case 'examineStatusOther':
  150. // 复审年份
  151. multiplePickerOptions = yearList;
  152. multiplePickerCheckedList = info.examineStatusOther ? info.examineStatusOther.split(',') : [];
  153. multiplePickerTitle = '请选择年份';
  154. break;
  155. case 'buyStatusOther':
  156. // 复购/复审年份
  157. multiplePickerOptions = yearList;
  158. multiplePickerCheckedList = info.buyStatusOther ? info.buyStatusOther.split(',') : [];
  159. multiplePickerTitle = '请选择年份';
  160. break;
  161. default:
  162. break;
  163. }
  164. this.setState({
  165. multiplePickerShow: true,
  166. multiplePickerType: type,
  167. multiplePickerTitle,
  168. multiplePickerOptions,
  169. multiplePickerCheckedList: multiplePickerCheckedList.map(item => Number(item))
  170. })
  171. }
  172. handleMultipleConfirm(selectedIds, selectedLabels) {
  173. const { multiplePickerType, dtails, info } = this.state;
  174. switch (multiplePickerType) {
  175. case "industry":
  176. // 企业所属行业
  177. dtails.industry = selectedIds.join(',');
  178. dtails.industryName = selectedLabels.join(',');
  179. this.setState({ dtails })
  180. break;
  181. case "externalInvestIndustry":
  182. // 对外投资控股的行业
  183. dtails.externalInvestIndustry = selectedIds.join(',');
  184. dtails.externalInvestIndustryName = selectedLabels.join(',');
  185. this.setState({ dtails })
  186. break;
  187. case 'examineStatusOther':
  188. info.examineStatusOther = selectedIds.join(',');
  189. this.setState({ info });
  190. break;
  191. case 'buyStatusOther':
  192. info.buyStatusOther = selectedIds.join(',');
  193. this.setState({ info });
  194. break;
  195. default:
  196. break;
  197. }
  198. }
  199. bindRegionChange (e) {
  200. this.setState({
  201. region: e.detail.value
  202. })
  203. }
  204. isLogin() {
  205. return !!Taro.getStorageSync('userInfor');
  206. }
  207. onShareAppMessage() {
  208. this.limitUser();
  209. return {
  210. title: "客户档案",
  211. path: "/pages/customerProfile/index?id=" + this.$instance.router.params.id,
  212. };
  213. }
  214. // 客户档案详情
  215. queryByUidAll() {
  216. const id = this.props.customerList[this.props.interviewIdx].id;
  217. queryByUidAll(
  218. false,
  219. { id }
  220. )
  221. .then((v) => {
  222. if (v.error.length === 0) {
  223. this.setState({
  224. dtails: {
  225. ...v.data,
  226. companyCount: v.data.companyCount || 0,
  227. socialSecurityCount: v.data.socialSecurityCount || 0,
  228. externalInvestCount: v.data.externalInvestCount || 0,
  229. financialRevenue: v.data.financialRevenue || 0,
  230. financialTax: v.data.financialTax || 0,
  231. financialProperty: v.data.financialProperty || 0,
  232. financialRd: v.data.financialRd || 0,
  233. earlyCommunication: '',
  234. customerDemand: '',
  235. interviewIdeas: '',
  236. interviewPurpose: '',
  237. interviewRecommend: '',
  238. interviewFeedback: '',
  239. followUpPlan: ''
  240. }
  241. })
  242. } else {
  243. setTimeout(() => {
  244. Taro.navigateBack({
  245. delta: 1
  246. })
  247. }, 1800);
  248. Taro.showToast({
  249. title: v.error[0].message,
  250. icon: "none",
  251. duration: 1800,
  252. });
  253. }
  254. })
  255. .catch((err) => {
  256. Taro.showToast({ title: "系统错误,请稍后再试", icon: "none" });
  257. });
  258. }
  259. validParams(params) {
  260. const { dtails } = this.state;
  261. let flag = true;
  262. let message = '';
  263. if (dtails.newChannel == 1) {
  264. // 渠道客户
  265. if (!params.channelType) {
  266. flag = false;
  267. message = '请选择渠道性质';
  268. } else if (!params.enterpriseCount) {
  269. flag = false;
  270. message = '请输入渠道所覆盖企业数';
  271. } else if (!params.channelIndicators) {
  272. flag = false;
  273. message = '请输入渠道考核指标';
  274. } else if (!params.interviewIdeas || (params.interviewIdeas && params.interviewIdeas.length < 20)) {
  275. message = '请输入面谈思路,并且在20字以上';
  276. flag = false;
  277. } else if (!params.interviewPurpose || (params.interviewPurpose && params.interviewPurpose.length < 20)) {
  278. message = '请输入面谈达成的目的,并且在20字以上';
  279. flag = false;
  280. } else {
  281. if (this.state.dtails.interviewList.length) {
  282. if (!params.interviewFeedback || (params.interviewFeedback && params.interviewFeedback.length < 20)) {
  283. message = '请输入面谈后的反馈,并且在20字以上';
  284. flag = false;
  285. } else if (!params.followUpPlan || (params.followUpPlan && params.followUpPlan.length < 20)) {
  286. message = '请输入后续跟进计划,并且在20字以上';
  287. flag = false;
  288. }
  289. }
  290. }
  291. } else {
  292. if (!params.locationProvince) {
  293. message = '请选择企业所在地省市区';
  294. flag = false;
  295. } else if (!params.industry) {
  296. message = '请选择企业所属行业';
  297. flag = false;
  298. } else if (!params.businessScope) {
  299. message = '主营产品不能为空';
  300. flag = false;
  301. } else if (params.companyCount === '' || params.companyCount === undefined || params.companyCount === null) {
  302. message = '请输入母/子公司数';
  303. flag = false;
  304. } else if (params.socialSecurityCount === '' || params.socialSecurityCount === undefined || params.socialSecurityCount === null) {
  305. message = '请输入社保人数';
  306. flag = false;
  307. } else if (params.externalInvestCount === '' || params.externalInvestCount === undefined || params.externalInvestCount === null) {
  308. message = '请输入对外投资控股的企业数';
  309. flag = false;
  310. } else if (params.financialRevenue === '' || params.financialRevenue === undefined || params.financialRevenue === null) {
  311. message = '请输入营收数据';
  312. flag = false;
  313. } else if (params.financialTax === '' || params.financialTax === undefined || params.financialTax === null) {
  314. message = '请输入税收数据';
  315. flag = false;
  316. } else if (params.financialProperty === '' || params.financialProperty === undefined || params.financialProperty === null) {
  317. message = '请输入资产数据';
  318. flag = false;
  319. } else if (params.financialRd === '' || params.financialRd === undefined || params.financialRd === null) {
  320. message = '请输入研发费用';
  321. flag = false;
  322. } else if (!params.externalInvestIndustry) {
  323. message = '请选择对外投资控股的行业';
  324. flag = false;
  325. } else if (!params.externalInvestName) {
  326. message = '请选择对外投资控股的企业';
  327. flag = false;
  328. } else if (!params.earlyCommunication || (params.earlyCommunication && params.earlyCommunication.length < 20)) {
  329. message = '请输入客户的难处,并且在20字以上';
  330. flag = false;
  331. } else if (!params.customerDemand || (params.customerDemand && params.customerDemand.length < 20)) {
  332. message = '请输入客户的需求,并且在20字以上';
  333. flag = false;
  334. } else if (!params.interviewIdeas || (params.interviewIdeas && params.interviewIdeas.length < 20)) {
  335. message = '请输入面谈思路,并且在20字以上';
  336. flag = false;
  337. } else if (!params.interviewPurpose || (params.interviewPurpose && params.interviewPurpose.length < 20)) {
  338. message = '请输入面谈达成的目的,并且在20字以上';
  339. flag = false;
  340. } else if (!params.interviewRecommend || (params.interviewRecommend && params.interviewRecommend.length < 20)) {
  341. message = '请输入经理/上级面谈建议,并且在20字以上';
  342. flag = false;
  343. } else {
  344. if (this.state.dtails.interviewList.length) {
  345. if (!params.interviewFeedback || (params.interviewFeedback && params.interviewFeedback.length < 20)) {
  346. message = '请输入面谈后的反馈,并且在20字以上';
  347. flag = false;
  348. } else if (!params.followUpPlan || (params.followUpPlan && params.followUpPlan.length < 20)) {
  349. message = '请输入后续跟进计划,并且在20字以上';
  350. flag = false;
  351. }
  352. }
  353. }
  354. }
  355. return { flag, message };
  356. }
  357. onSaveAllData(callback) {
  358. const { dtails } = this.state;
  359. let params = {
  360. id: dtails.id,
  361. uid: dtails.uid,
  362. locationProvince: dtails.locationProvince,
  363. locationProvinceName: dtails.locationProvinceName,
  364. locationCity: dtails.locationCity,
  365. locationCityName: dtails.locationCityName,
  366. locationArea: dtails.locationArea,
  367. locationAreaName: dtails.locationAreaName,
  368. type: 1, // 1、更新档案和面谈,0、只更新档案
  369. };
  370. if (dtails.newChannel == 1) {
  371. // 渠道客户
  372. params = {
  373. ...params,
  374. channelType: dtails.channelType,
  375. enterpriseCount: dtails.enterpriseCount,
  376. channelIndicators: dtails.channelIndicators,
  377. interviewIdeas: dtails.interviewIdeas,
  378.     interviewPurpose: dtails.interviewPurpose,
  379. interviewFeedback: dtails.interviewFeedback,
  380.     followUpPlan: dtails.followUpPlan,
  381. };
  382. } else {
  383. let externalInvestIdArr = [];
  384. if (!!dtails.externalInvestName) {
  385. externalInvestIdArr = dtails.externalInvestName.split('、').map(() => {
  386. return '0';
  387. })
  388. }
  389. params = {
  390. ...params,
  391. industry: dtails.industry,
  392. industryName: dtails.industryName,
  393. earlyCommunication: dtails.earlyCommunication,
  394.     customerDemand: dtails.customerDemand,
  395.     interviewIdeas: dtails.interviewIdeas,
  396.     interviewPurpose: dtails.interviewPurpose,
  397.     interviewRecommend: dtails.interviewRecommend,
  398.     interviewFeedback: dtails.interviewFeedback,
  399.     followUpPlan: dtails.followUpPlan,
  400.     patentCount: dtails.patentCount,
  401.     inventionPatentCount: dtails.inventionPatentCount,
  402.     utilityModelCount: dtails.utilityModelCount,
  403.     appearancePatentCount: dtails.appearancePatentCount,
  404.     softwareWorksCount: dtails.softwareWorksCount,
  405.     otherCount: dtails.otherCount,
  406.     financialData: dtails.financialData,
  407.     companyCount: dtails.companyCount,
  408.     socialSecurityCount: dtails.socialSecurityCount,
  409.     externalInvestCount: dtails.externalInvestCount,
  410.     externalInvestIndustry: dtails.externalInvestIndustry,
  411. externalInvestIndustryName: dtails.externalInvestIndustryName,
  412. externalInvestId: externalInvestIdArr.join(','),
  413.     externalInvestName: dtails.externalInvestName,
  414.     financialRevenue: dtails.financialRevenue,
  415.     financialTax: dtails.financialTax,
  416.     financialProperty: dtails.financialProperty,
  417.     financialRd: dtails.financialRd,
  418. standard: dtails.standard,
  419. businessScope: dtails.businessScope,
  420. };
  421. }
  422. for (let key in params) {
  423. if (params[key] === undefined || params[key] === 'undefined' || params[key] === null || params[key] === 'null') {
  424. delete params[key];
  425. }
  426. }
  427. const { flag, message } = this.validParams(params);
  428. if (!flag) {
  429. Taro.showToast({
  430. title: message,
  431. icon: "none",
  432. });
  433. return;
  434. }
  435. updateUser(params).then((v) => {
  436. if (v.error.length === 0) {
  437. Taro.showToast({
  438. title: "修改成功",
  439. });
  440. callback && callback(v.data);
  441. } else {
  442. Taro.showToast({
  443. title: v.error[0].message,
  444. icon: "none",
  445. });
  446. }
  447. })
  448. }
  449. // 修改客户档案
  450. update() {
  451. // const { upType, info } = this.state
  452. // console.log(info)
  453. // let tipList = [
  454. // { key: "inventionPatentCount", value: "请填写发明专利数" },
  455. // { key: "utilityModelCount", value: "请填写实用新型数" },
  456. // { key: "appearancePatentCount", value: "请填写外观专利数" },
  457. // { key: "softwareWorksCount", value: "请填写软著数" },
  458. // { key: "otherCount", value: "请填写其他数量" },
  459. // { key: "financialData", value: "请填写财务数据" },
  460. // { key: "earlyCommunication", value: "请填写前期沟通" },
  461. // { key: "interviewIdeas", value: "请填写面谈思路及目的" },
  462. // { key: "interviewDistribution", value: "请填写主要面谈人及分工" },
  463. // { key: "enterpriseCount", value: "请填写覆盖企业数" },
  464. // { key: "channelIndicators", value: "请填写渠道考核指标" },
  465. // ]
  466. // if (!info.id) {
  467. // delete info.id
  468. // }
  469. // for (let i in info) {
  470. // if (!info[i] && info[i] !== 0) {
  471. // for (var j = 0; j < tipList.length; j++) {
  472. // if (tipList[j].key == i) {
  473. // Taro.showToast({
  474. // title: tipList[j].value,
  475. // icon: "none",
  476. // });
  477. // }
  478. // }
  479. // return
  480. // } else if (info[i] == 0) {
  481. // if (i == "channelType") {
  482. // Taro.showToast({
  483. // title: "请选择渠道类型",
  484. // icon: "none",
  485. // });
  486. // return
  487. // }
  488. // }
  489. // if ((i == "financialData" || i == "earlyCommunication" || i == "interviewIdeas" || i == "interviewDistribution")
  490. // && info[i].length < 20) {
  491. // Taro.showToast({
  492. // title: "至少20字以上",
  493. // icon: "none",
  494. // });
  495. // return
  496. // }
  497. // }
  498. // updateUserDate(upType, info).then((v) => {
  499. // if (v.error.length === 0) {
  500. // Taro.showToast({
  501. // title: "修改成功",
  502. // });
  503. // this.setState({
  504. // isOpened: false
  505. // })
  506. // this.queryByUidAll()
  507. // } else {
  508. // Taro.showToast({
  509. // title: v.error[0].message,
  510. // icon: "none",
  511. // });
  512. // }
  513. // }).catch(() => {
  514. // })
  515. if (this.state.upType == 5) {
  516. this.postAddProject();
  517. } else {
  518. this.setState({ isOpened: false, dtails: { ...this.state.dtails, ...this.state.info } })
  519. }
  520. }
  521. postAddProject() {
  522. const { checkProject, dtails, info } = this.state;
  523. const params = { uid: dtails.id };
  524. if (!checkProject.length) {
  525. Taro.showToast({
  526. title: "请选择要添加的项目",
  527. icon: "none",
  528. });
  529. return;
  530. } else {
  531. params.pid = checkProject[0].id;
  532. if (checkProject[0].cSort == 9) {
  533. if (!info.examineStatus) {
  534. Taro.showToast({
  535. title: "请选择审核状态",
  536. icon: "none",
  537. });
  538. return;
  539. } else if (info.examineStatus == 2 && !info.examineStatusOther) {
  540. Taro.showToast({
  541. title: "请选择复审年份",
  542. icon: "none",
  543. });
  544. return;
  545. } else if (info.examineStatus == 2 && info.examineStatusOther.split(',').length > 1) {
  546. Taro.showToast({
  547. title: "复审年份只能选择一个",
  548. icon: "none",
  549. });
  550. return;
  551. } else {
  552. params.examineStatus = info.examineStatus;
  553. params.examineStatusOther = info.examineStatus == 2 ? info.examineStatusOther : '';
  554. }
  555. } else if (checkProject[0].cSort == 6) {
  556. if (!info.buyStatus) {
  557. Taro.showToast({
  558. title: "请选择复购状态",
  559. icon: "none",
  560. });
  561. return;
  562. } else if (info.buyStatus == 2 && !info.buyStatusOther) {
  563. Taro.showToast({
  564. title: "请选择复购/复审年份",
  565. icon: "none",
  566. });
  567. return;
  568. } else {
  569. params.buyStatus = info.buyStatus;
  570. params.buyStatusOther = info.buyStatus == 2 ? info.buyStatusOther : '';
  571. }
  572. }
  573. }
  574. addProject(params).then(res => {
  575. if (res.error.length == 0) {
  576. Taro.showToast({
  577. title: "项目新增成功!",
  578. });
  579. this.setState({ isOpened: false, checkProject: [] })
  580. this.getProjectList();
  581. } else {
  582. Taro.showToast({
  583. title: v.error[0].message,
  584. icon: "none"
  585. });
  586. }
  587. })
  588. }
  589. /**
  590. * 获取项目列表
  591. */
  592. getProjectList() {
  593. let uid = this.props.customerList[this.props.interviewIdx].id;
  594. const params = { uid, pageNo: 1, pageSize: 9999 }
  595. queryProjectList(params).then(res => {
  596. if (!res.error.length) {
  597. this.setState({ projectList: res.data.list });
  598. }
  599. })
  600. }
  601. handleDelProject(data) {
  602. delProject(data.id, data).then(res => {
  603. if (!res.error.length) {
  604. Taro.showToast({
  605. title: "删除成功!",
  606. });
  607. this.getProjectList();
  608. } else {
  609. Taro.showToast({
  610. title: v.error[0].message,
  611. icon: "none"
  612. });
  613. }
  614. })
  615. }
  616. // 新建联系人
  617. add() {
  618. let data = this.state.obj
  619. for (let i in data) {
  620. if (!data[i] && data[i] !== 0) {
  621. Taro.showToast({
  622. title: "请完善信息",
  623. icon: "none",
  624. });
  625. return
  626. } else if (i == "mobile") {
  627. if (!(/^1[3-9]\d{9}$/.test(data[i]))) {
  628. Taro.showToast({
  629. title: "请输入正确地手机号",
  630. icon: "none",
  631. });
  632. return
  633. }
  634. }
  635. }
  636. data.major = 1
  637. addOneContact(data).then((v) => {
  638. if (v.error.length === 0) {
  639. Taro.showToast({
  640. title: "添加成功",
  641. });
  642. this.setState({
  643. isAdd: false
  644. })
  645. this.queryByUidAll()
  646. } else {
  647. Taro.showToast({
  648. title: v.error[0].message,
  649. icon: "none",
  650. });
  651. }
  652. }).catch(() => {
  653. })
  654. }
  655. // 项目列表
  656. getBusinessProjectByName(val) {
  657. getBusinessProjectByName({
  658. businessName: val || "",
  659. })
  660. .then((v) => {
  661. if (v.error.length === 0) {
  662. let theArr = [];
  663. if (v.data.length > 0) {
  664. for (let i = 0; i < v.data.length; i++) {
  665. let thisdata = v.data[i];
  666. theArr.push({
  667. value: thisdata.id,
  668. label: thisdata.bname,
  669. });
  670. };
  671. }
  672. this.setState({
  673. allProjectList: v.data,
  674. options: theArr
  675. })
  676. } else {
  677. Taro.showToast({ title: v.error[0].message, icon: "none" });
  678. }
  679. })
  680. .catch((err) => {
  681. Taro.showToast({ title: "系统错误,请稍后再试", icon: "none" });
  682. });
  683. }
  684. onSearchChange(value) {
  685. this.setState({
  686. value,
  687. });
  688. }
  689. getUserList() {
  690. findCustomerContacts({
  691. uid: this.$instance.router.params.id,
  692. })
  693. .then((v) => {
  694. if (v.error.length === 0) {
  695. this.setState({
  696. userList: v.data || []
  697. })
  698. } else {
  699. Taro.showToast({ title: v.error[0].message, icon: "none" });
  700. }
  701. })
  702. .catch((err) => {
  703. Taro.showToast({ title: "系统错误,请稍后再试", icon: "none" });
  704. });
  705. }
  706. updateMainContact(id) {
  707. updateMainContact({
  708. uid: this.$instance.router.params.id,
  709. ocbId: id,
  710. }).then((v) => {
  711. if (v.error.length === 0) {
  712. Taro.showToast({
  713. title: "设置成功",
  714. });
  715. this.getUserList()
  716. } else {
  717. Taro.showToast({
  718. title: v.error[0].message,
  719. icon: "none",
  720. });
  721. }
  722. }).catch(() => {
  723. })
  724. }
  725. limitUser() {
  726. limitUser({
  727. uid: this.$instance.router.params.id,
  728. // hours: 1,
  729. }).then((v) => {
  730. if (v.error.length === 0) {
  731. } else {
  732. Taro.showToast({
  733. title: v.error[0].message,
  734. icon: "none",
  735. });
  736. }
  737. }).catch(() => {
  738. })
  739. }
  740. addItemDialog(type) {
  741. let title;
  742. switch (type) {
  743. case 'externalInvestName':
  744. // 对外投资控股的企业名称
  745. title = '添加对外投资控股的企业名称';
  746. break;
  747. default:
  748. break;
  749. }
  750. this.setState({ addItemShow: true, addItemType: type, addItemTitle: title });
  751. }
  752. handleCloseAddItemDialog() {
  753. this.setState({ addItemShow: false, addItemType: '', addItemInputVal: '' });
  754. }
  755. handleAddItemSave() {
  756. switch (this.state.addItemType) {
  757. case 'externalInvestName':
  758. const { dtails } = this.state;
  759. let externalInvestName = this.state.dtails.externalInvestName || '';
  760. let externalInvestNameArr = externalInvestName.split(',').filter(item => !!item);
  761. externalInvestNameArr.push(this.state.addItemInputVal);
  762. dtails.externalInvestName = externalInvestNameArr.join(',');
  763. this.setState({ dtails }, () => {
  764. this.handleCloseAddItemDialog();
  765. });
  766. break;
  767. default:
  768. break;
  769. }
  770. }
  771. openInteractHis(type) {
  772. let interactTitle;
  773. let interactList = this.state.dtails.interviewList;
  774. switch (type) {
  775. case 'earlyCommunication':
  776. interactTitle = '客户的难处历史记录';
  777. break;
  778. case 'customerDemand':
  779. interactTitle = '客户的需求历史记录';
  780. break;
  781. case 'interviewIdeas':
  782. interactTitle = '面谈思路历史记录';
  783. break;
  784. case 'interviewPurpose':
  785. interactTitle = '面谈达成的目的历史记录';
  786. break;
  787. case 'interviewRecommend':
  788. interactTitle = '经理/上级面谈建议历史记录';
  789. break;
  790. case 'interviewFeedback':
  791. interactTitle = '面谈后反馈历史记录';
  792. interactList = interactList.slice(1, interactList.length);
  793. break;
  794. case 'followUpPlan':
  795. interactTitle = '后续跟进计划历史记录';
  796. interactList = interactList.slice(1, interactList.length);
  797. break;
  798. default:
  799. break;
  800. }
  801. this.setState({
  802. interactShow: true,
  803. interactShowType: type,
  804. interactTitle,
  805. interactList
  806. });
  807. }
  808. renderProjectItemName(data) {
  809. let name = data.name;
  810. if (!!data.buyStatus) {
  811. // 会员项目
  812. if (data.buyStatus == 1) {
  813. name = name + `(新购)`;
  814. } else if (data.buyStatus == 2) {} {
  815. name = name + `(复购${data.buyStatusOther})`;
  816. }
  817. } else if (!!data.examineStatus) {
  818. // 高新项目
  819. if (data.examineStatus == 1) {
  820. name = name + `(初次审核)`;
  821. } else if (data.examineStatus == 2) {
  822. name = name + `(${data.examineStatusOther}年复审)`;
  823. }
  824. }
  825. return name;
  826. }
  827. render() {
  828. const { dtails, upType, info, obj, userList } = this.state;
  829. return (
  830. <View className="customerProfile">
  831. <MessageNoticebar />
  832. <View
  833. className="titleContent"
  834. >
  835. {Object.keys(dtails).length === 0 ? (
  836. <Skeleton
  837. title
  838. row={3}
  839. animateName="elastic"
  840. avatarShape="square"
  841. loading
  842. />
  843. ) : (
  844. <View className="content">
  845. <View className="name">
  846. <Text style={{ width: "80%" }}>
  847. <Text className="bod">{dtails.nickname}&nbsp;&nbsp;</Text>
  848. <Text style={{ fontSize: "12px", color: ["red", "green"][dtails.signBills] }}>{["未签单", "已签单"][dtails.signBills]}</Text>
  849. </Text>
  850. {dtails.myUser == 1 && <Button className="share" plain type='primary' open-type="share">分享</Button>}
  851. {/* <View className="share">分享</View> */}
  852. </View>
  853. <View className="button">
  854. <View className="but"
  855. onClick={e => {
  856. e.stopPropagation()
  857. this.setState({
  858. isSuperior: true
  859. })
  860. }}
  861. >上级指导</View>
  862. {
  863. this.state.isSuperior &&
  864. <Superior
  865. id={dtails.uid}
  866. userNames={dtails.nickname}
  867. isOpinion={this.state.isSuperior}
  868. isFill={dtails.myUser == 0}
  869. onClose={() => {
  870. this.setState({
  871. isSuperior: false
  872. })
  873. }}
  874. />
  875. }
  876. <View className="but"
  877. onClick={e => {
  878. e.stopPropagation()
  879. Taro.navigateTo({
  880. url: "/pages/situation/index?id=" + this.$instance.router.params.id + "&notRequired=" + this.$instance.router.params.notRequired,
  881. });
  882. }}
  883. >公出记录</View>
  884. </View>
  885. <View className="row">
  886. <View className="code">{dtails.orgCode}</View>
  887. <View className="time">{dtails.createTime}</View>
  888. </View>
  889. {
  890. dtails.newChannel == 1
  891. ?
  892. <View className="first">
  893. <View className="title">渠道面谈思路表</View>
  894. <View className="val" style={{ display: 'flex' }}>
  895. 企业所在地省市区:
  896. <View className="link" onClick={() => {this.setState({ addressPickerShow: true })}}>
  897. { dtails.locationProvince ? `${dtails.locationProvinceName}-${dtails.locationCityName}-${dtails.locationAreaName}` : '请选择' }
  898. </View>
  899. </View>
  900. <View className="val" style={{ display: 'flex', alignItems: 'center' }}>
  901. 渠道类别:
  902. <Picker
  903. value={dtails.channelType}
  904. range={channelTypeList}
  905. rangeKey='title'
  906. mode='selector'
  907. onChange={(e) => {
  908. const { dtails } = this.state;
  909. dtails.channelType = e.detail.value;
  910. console.log(dtails.channelType)
  911. this.setState({ dtails })
  912. }}>
  913. <View className="link">
  914. {!getChannel(dtails.channelType) ? "请选择" : getChannel(dtails.channelType)}
  915. </View>
  916. </Picker>
  917. </View>
  918. <View className="val" style={{ display: 'flex', alignItems: 'center' }}>
  919. 渠道企业数:
  920. <View style={{width: '120rpx'}}>
  921. <AtInputNumber
  922. min={0}
  923. max={99999}
  924. value={dtails.enterpriseCount}
  925. name='companyCount'
  926. type='number'
  927. placeholder='请输入数量'
  928. size='mini'
  929. onChange={value => {
  930. dtails.enterpriseCount = value;
  931. this.setState({ dtails })
  932. }}
  933. />
  934. </View>
  935. </View>
  936. <View className="val" style={{display: 'flex'}}>
  937. 渠道考核指标:
  938. <AtTextarea
  939. value={dtails.channelIndicators || ''}
  940. onChange={e => {
  941. this.setState({
  942. dtails: Object.assign(dtails, {
  943. channelIndicators: e,
  944. }),
  945. })
  946. }}
  947. maxLength={200}
  948. placeholder='请填写渠道考核指标~'
  949. />
  950. </View>
  951. <View className="tit" style={{ marginTop: '60rpx' }}>
  952. <Text>
  953. 联系人
  954. <Text className="txt">(面谈人)</Text>
  955. </Text>
  956. {
  957. dtails.myUser == 1 &&
  958. <View className="up"
  959. onClick={e => {
  960. e.stopPropagation()
  961. this.getUserList();
  962. this.setState({
  963. isAdd: true,
  964. obj: {
  965. uid: this.$instance.router.params.id,
  966. name: "",
  967. position: "",
  968. department: "",
  969. mobile: "",
  970. }
  971. })
  972. }}
  973. >新增</View>
  974. }
  975. </View>
  976. {
  977. !!dtails.contactList && dtails.contactList.map((v, k) =>
  978. <View className="val" key={k}>{v.name}&nbsp;&nbsp;{v.position}&nbsp;&nbsp;{v.department}&nbsp;&nbsp;{v.mobile}</View>
  979. )
  980. }
  981. <View className="tit" style={{marginTop: '60rpx'}}>
  982. 本次面谈项目
  983. {
  984. dtails.myUser == 1 &&
  985. <View className="up"
  986. onClick={e => {
  987. e.stopPropagation()
  988. this.getBusinessProjectByName("")
  989. this.setState({
  990. upType: 5,
  991. isOpened: true,
  992. info: {
  993. uid: this.$instance.router.params.id,
  994. intendedProject: dtails.intendedProject,
  995. },
  996. checkOptions: []
  997. })
  998. }}
  999. >新增</View>
  1000. }
  1001. </View>
  1002. <View className="val">{
  1003. this.state.projectList.map(item => {
  1004. return <View style={{ display: 'flex', alignItems: 'center' }}>
  1005. <Text style={{ fontSize: '30rpx' }} style={{marginRight: '10rpx'}}>
  1006. { this.renderProjectItemName(item) }
  1007. </Text>
  1008. <AtIcon value="close" size='15' color="#f00" onClick={() => {this.handleDelProject(item)}} />
  1009. </View>
  1010. })
  1011. }</View>
  1012. <View className="tit">
  1013. <Text>
  1014. 面谈思路
  1015. <Text className="txt">(20字以上)</Text>
  1016. </Text>
  1017. { dtails.interviewList.length ? (
  1018. <AtIcon value='clock' size='20' color='#1E90FF' onClick={() => this.openInteractHis('interviewIdeas')}></AtIcon>
  1019. ) : null }
  1020. </View>
  1021. <View className="val">
  1022. <AtTextarea
  1023. value={dtails.interviewIdeas}
  1024. maxLength={200}
  1025. placeholder='请编写本次面谈客户思路~'
  1026. height={70}
  1027. onChange={value => {
  1028. dtails.interviewIdeas = value;
  1029. this.setState({ dtails });
  1030. }}
  1031. />
  1032. </View>
  1033. <View className="tit">
  1034. <Text>
  1035. 面谈达成的目的
  1036. <Text className="txt">(20字以上)</Text>
  1037. </Text>
  1038. { dtails.interviewList.length ? (
  1039. <AtIcon value='clock' size='20' color='#1E90FF' onClick={() => this.openInteractHis('interviewPurpose')}></AtIcon>
  1040. ) : null }
  1041. </View>
  1042. <View className="val">
  1043. <AtTextarea
  1044. value={dtails.interviewPurpose}
  1045. maxLength={200}
  1046. placeholder='请编写本次面谈达成的目的~'
  1047. height={70}
  1048. onChange={value => {
  1049. dtails.interviewPurpose = value;
  1050. this.setState({ dtails });
  1051. }}
  1052. />
  1053. </View>
  1054. <View className="tit">
  1055. <Text>
  1056. 经理/上级面谈建议
  1057. <Text className="txt">(由经理/上级口述,本人整理,20字以上)</Text>
  1058. </Text>
  1059. { dtails.interviewList.length ? (
  1060. <AtIcon value='clock' size='20' color='#1E90FF' onClick={() => this.openInteractHis('interviewRecommend')}></AtIcon>
  1061. ) : null }
  1062. </View>
  1063. <View className="val">
  1064. <AtTextarea
  1065. value={dtails.interviewRecommend}
  1066. maxLength={200}
  1067. placeholder='请编写本次面谈建议~'
  1068. height={70}
  1069. onChange={value => {
  1070. dtails.interviewRecommend = value;
  1071. this.setState({ dtails });
  1072. }}
  1073. />
  1074. </View>
  1075. { dtails.interviewList && dtails.interviewList.length ? (
  1076. <>
  1077. <View className="tit">
  1078. <Text>
  1079. 面谈后的反馈
  1080. <Text className="txt">(20字以上)</Text>
  1081. </Text>
  1082. <AtIcon value='clock' size='20' color='#1E90FF' onClick={() => this.openInteractHis('interviewFeedback')}></AtIcon>
  1083. </View>
  1084. <View className="val">
  1085. <AtTextarea
  1086. value={dtails.interviewFeedback}
  1087. maxLength={200}
  1088. placeholder='请编写本次面谈后的反馈~'
  1089. height={70}
  1090. onChange={value => {
  1091. dtails.interviewFeedback = value;
  1092. this.setState({ dtails });
  1093. }}
  1094. />
  1095. </View>
  1096. <View className="tit">
  1097. <Text>
  1098. 后续跟进计划
  1099. <Text className="txt">(20字以上)</Text>
  1100. </Text>
  1101. <AtIcon value='clock' size='20' color='#1E90FF' onClick={() => this.openInteractHis('followUpPlan')}></AtIcon>
  1102. </View>
  1103. <View className="val">
  1104. <AtTextarea
  1105. value={dtails.followUpPlan}
  1106. maxLength={200}
  1107. placeholder='请编写后续跟进计划~'
  1108. height={70}
  1109. onChange={value => {
  1110. dtails.followUpPlan = value;
  1111. this.setState({ dtails });
  1112. }}
  1113. />
  1114. </View>
  1115. </>
  1116. ) : null }
  1117. </View>
  1118. :
  1119. <View className="first">
  1120. <View className="title">企业面谈思路表</View>
  1121. <View className="val" style={{ display: 'flex' }}>
  1122. 企业所在地省市区:
  1123. {/* <Picker
  1124. mode='region'
  1125. value={this.state.region}
  1126. customItem={this.state.customItem}
  1127. onChange={this.bindRegionChange.bind(this)}
  1128. >
  1129. <View className='picker'>
  1130. { this.state.region.length ? this.state.region.join('-') : '请选择' }
  1131. </View>
  1132. </Picker> */}
  1133. <View className="link" onClick={() => {this.setState({ addressPickerShow: true })}}>
  1134. { dtails.locationProvince ? `${dtails.locationProvinceName}-${dtails.locationCityName}-${dtails.locationAreaName}` : '请选择' }
  1135. </View>
  1136. </View>
  1137. {/* <View className="tit">
  1138. 企业面谈思路表
  1139. {
  1140. dtails.myUser == 1 &&
  1141. <View className="up"
  1142. onClick={e => {
  1143. e.stopPropagation()
  1144. this.setState({
  1145. upType: 0,
  1146. isOpened: true,
  1147. info: {
  1148. uid: this.$instance.router.params.id,
  1149. industry: dtails.industry,
  1150. businessScope: dtails.businessScope,
  1151. },
  1152. sector: {
  1153. id: dtails.industry,
  1154. title: dtails.industryName
  1155. }
  1156. })
  1157. }}
  1158. >修改</View>
  1159. }
  1160. </View> */}
  1161. <View className="val" style={{display: 'flex'}}>
  1162. 企业所属行业:
  1163. <View className="link" onClick={() => this.handleOpenMultiplePicker('industry')}>
  1164. { this.state.dtails.industryName || '请选择' }
  1165. </View>
  1166. </View>
  1167. <View className="val" style={{display: 'flex', alignItems: 'center'}}>
  1168. 主营产品:
  1169. <View style={{flex: 1}}>
  1170. <AtInput
  1171. value={dtails.businessScope}
  1172. name='businessScope'
  1173. placeholder='请用,符号隔开关键字'
  1174. size='mini'
  1175. onChange={value => {
  1176. dtails.businessScope = value;
  1177. this.setState({ dtails })
  1178. }}
  1179. cursor={-1}
  1180. />
  1181. </View>
  1182. </View>
  1183. <View className="val" style={{ display: 'flex', alignItems: 'center' }}>
  1184. 母/子公司数:
  1185. <View style={{width: '120rpx'}}>
  1186. <AtInputNumber
  1187. min={0}
  1188. max={99999}
  1189. value={dtails.companyCount}
  1190. name='companyCount'
  1191. type='number'
  1192. placeholder='请输入数量'
  1193. size='mini'
  1194. onChange={value => {
  1195. dtails.companyCount = value;
  1196. this.setState({ dtails })
  1197. }}
  1198. />
  1199. </View>
  1200. </View>
  1201. <View className="val" style={{ display: 'flex', alignItems: 'center' }}>
  1202. 社保人数:
  1203. <View style={{width: '120rpx'}}>
  1204. <AtInputNumber
  1205. min={0}
  1206. max={99999}
  1207. value={dtails.socialSecurityCount}
  1208. name='socialSecurityCount'
  1209. type='number'
  1210. placeholder='请输入数量'
  1211. size='mini'
  1212. onChange={value => {
  1213. dtails.socialSecurityCount = value;
  1214. this.setState({ dtails })
  1215. }}
  1216. />
  1217. </View>
  1218. </View>
  1219. <View className="val" style={{ display: 'flex', alignItems: 'center' }}>
  1220. 对外投资控股的企业数:
  1221. <View style={{width: '120rpx'}}>
  1222. <AtInputNumber
  1223. min={0}
  1224. max={99999}
  1225. value={dtails.externalInvestCount}
  1226. name='externalInvestCount'
  1227. type='number'
  1228. placeholder='请输入数量'
  1229. size='mini'
  1230. onChange={value => {
  1231. dtails.externalInvestCount = value;
  1232. this.setState({ dtails })
  1233. }}
  1234. />
  1235. </View>
  1236. </View>
  1237. <View className="val" style={{display: 'flex'}}>
  1238. 对外投资控股的行业:
  1239. <View className="link" onClick={() => this.handleOpenMultiplePicker('externalInvestIndustry')}>
  1240. { this.state.dtails.externalInvestIndustryName || '请选择' }
  1241. </View>
  1242. </View>
  1243. <View className="val" style={{display: 'flex'}}>
  1244. 对外投资控股的企业名称:
  1245. <View className="link" onClick={() => this.addItemDialog('externalInvestName')}>
  1246. { this.state.dtails.externalInvestName || '点击新增' }
  1247. </View>
  1248. </View>
  1249. <View className="tit">
  1250. <Text>
  1251. 主要面谈联系信息
  1252. {/* <Text className="txt">(面谈人)</Text> */}
  1253. </Text>
  1254. {
  1255. dtails.myUser == 1 &&
  1256. <View className="up"
  1257. onClick={e => {
  1258. e.stopPropagation()
  1259. this.getUserList();
  1260. this.setState({
  1261. isAdd: true,
  1262. obj: {
  1263. uid: this.$instance.router.params.id,
  1264. name: "",
  1265. position: "",
  1266. department: "",
  1267. mobile: "",
  1268. }
  1269. })
  1270. }}
  1271. >新增</View>
  1272. }
  1273. </View>
  1274. {
  1275. !!dtails.contactList && dtails.contactList.map((v, k) =>
  1276. <View className="val" key={k}>
  1277. {v.name}&nbsp;&nbsp;{v.position}&nbsp;&nbsp;{v.department}&nbsp;&nbsp;{v.mobile}
  1278. {this.state.isMask && <View className="mask"></View>}
  1279. </View>
  1280. )
  1281. }
  1282. <View className="tit">
  1283. 本次面谈项目
  1284. {
  1285. dtails.myUser == 1 &&
  1286. <View className="up"
  1287. onClick={e => {
  1288. e.stopPropagation()
  1289. this.getBusinessProjectByName("")
  1290. this.setState({
  1291. upType: 5,
  1292. isOpened: true,
  1293. info: {
  1294. uid: this.$instance.router.params.id,
  1295. intendedProject: dtails.intendedProject,
  1296. },
  1297. checkOptions: []
  1298. })
  1299. }}
  1300. >新增</View>
  1301. }
  1302. </View>
  1303. <View className="val">{
  1304. this.state.projectList.map(item => {
  1305. return <View style={{ display: 'flex', alignItems: 'center' }}>
  1306. <Text style={{ fontSize: '30rpx' }} style={{marginRight: '10rpx'}}>
  1307. { this.renderProjectItemName(item) }
  1308. </Text>
  1309. <AtIcon value="close" size='15' color="#f00" onClick={() => {this.handleDelProject(item)}} />
  1310. </View>
  1311. })
  1312. }</View>
  1313. <View style={{marginTop: '60rpx'}}>
  1314. <View className="title">面谈已知企业情况</View>
  1315. <View className="tit">
  1316. <Text>
  1317. 1.知识产权情况
  1318. <Text className="txt">(专利信息、标准、专利、软著)</Text>
  1319. </Text>
  1320. {
  1321. dtails.myUser == 1 &&
  1322. <View className="up"
  1323. onClick={e => {
  1324. e.stopPropagation()
  1325. this.setState({
  1326. upType: 1,
  1327. isOpened: true,
  1328. info: {
  1329. uid: this.$instance.router.params.id,
  1330. id: dtails.id,
  1331. inventionPatentCount: dtails.inventionPatentCount || 0,
  1332. utilityModelCount: dtails.utilityModelCount || 0,
  1333. appearancePatentCount: dtails.appearancePatentCount || 0,
  1334. softwareWorksCount: dtails.softwareWorksCount || 0,
  1335. otherCount: dtails.otherCount || 0,
  1336. }
  1337. })
  1338. }}
  1339. >修改</View>
  1340. }
  1341. </View>
  1342. <View className="val">
  1343. 专利&nbsp;<Text className="num">{dtails.patentCount || 0}</Text>&nbsp;&nbsp;&nbsp;
  1344. 其中发明专利&nbsp;<Text className="num">{dtails.inventionPatentCount || 0}</Text>&nbsp;&nbsp;&nbsp;
  1345. 实用新型&nbsp;<Text className="num">{dtails.utilityModelCount || 0}</Text>&nbsp;&nbsp;&nbsp;
  1346. 外观设计&nbsp;<Text className="num">{dtails.appearancePatentCount || 0}</Text>&nbsp;&nbsp;&nbsp;
  1347. 软著&nbsp;<Text className="num">{dtails.softwareWorksCount || 0}</Text>&nbsp;&nbsp;&nbsp;
  1348. 标准&nbsp;<Text className="num">{dtails.standard == 1 ? '有' : '无'}</Text>&nbsp;&nbsp;&nbsp;
  1349. 其他类型&nbsp;<Text className="num">{dtails.otherCount || 0}</Text>&nbsp;&nbsp;&nbsp;
  1350. </View>
  1351. <View className="tit">2.财务数据</View>
  1352. <View className="val" style={{display: 'flex', alignItems: 'center'}}>
  1353. 营收(万元):
  1354. <View style={{width: '120rpx'}}>
  1355. <AtInputNumber
  1356. min={0}
  1357. max={99999}
  1358. value={dtails.financialRevenue}
  1359. name='financialRevenue'
  1360. type='number'
  1361. placeholder='请输入数量'
  1362. size='mini'
  1363. onChange={value => {
  1364. dtails.financialRevenue = value;
  1365. this.setState({ dtails })
  1366. }}
  1367. />
  1368. </View>
  1369. </View>
  1370. <View className="val" style={{display: 'flex', alignItems: 'center'}}>
  1371. 税收(万元):
  1372. <View style={{width: '120rpx'}}>
  1373. <AtInputNumber
  1374. min={0}
  1375. max={99999}
  1376. value={dtails.financialTax}
  1377. name='financialTax'
  1378. type='number'
  1379. placeholder='请输入数量'
  1380. size='mini'
  1381. onChange={value => {
  1382. dtails.financialTax = value;
  1383. this.setState({ dtails })
  1384. }}
  1385. />
  1386. </View>
  1387. </View>
  1388. <View className="val" style={{display: 'flex', alignItems: 'center'}}>
  1389. 资产(万元):
  1390. <View style={{width: '120rpx'}}>
  1391. <AtInputNumber
  1392. min={0}
  1393. max={99999}
  1394. value={dtails.financialProperty}
  1395. name='financialProperty'
  1396. type='number'
  1397. placeholder='请输入数量'
  1398. size='mini'
  1399. onChange={value => {
  1400. dtails.financialProperty = value;
  1401. this.setState({ dtails })
  1402. }}
  1403. />
  1404. </View>
  1405. </View>
  1406. <View className="val" style={{display: 'flex', alignItems: 'center'}}>
  1407. 研发费用(万元):
  1408. <View style={{width: '120rpx'}}>
  1409. <AtInputNumber
  1410. min={0}
  1411. max={99999}
  1412. value={dtails.financialRd}
  1413. name='financialRd'
  1414. type='number'
  1415. placeholder='请输入数量'
  1416. size='mini'
  1417. onChange={value => {
  1418. dtails.financialRd = value;
  1419. this.setState({ dtails })
  1420. }}
  1421. />
  1422. </View>
  1423. </View>
  1424. <View className="tit">3.前期沟通情况</View>
  1425. <View className="tit">
  1426. <Text>
  1427. 客户的难处
  1428. <Text className="txt">(20字以上)</Text>
  1429. </Text>
  1430. { dtails.interviewList.length ? (
  1431. <AtIcon value='clock' size='20' color='#1E90FF' onClick={() => this.openInteractHis('earlyCommunication')}></AtIcon>
  1432. ) : null }
  1433. </View>
  1434. <View className="val">
  1435. <AtTextarea
  1436. value={dtails.earlyCommunication}
  1437. maxLength={200}
  1438. placeholder='请编写本次面谈客户难处~'
  1439. height={70}
  1440. onChange={value => {
  1441. dtails.earlyCommunication = value;
  1442. this.setState({ dtails });
  1443. }}
  1444. />
  1445. </View>
  1446. <View className="tit">
  1447. <Text>
  1448. 客户的需求
  1449. <Text className="txt">(20字以上)</Text>
  1450. </Text>
  1451. { dtails.interviewList.length ? (
  1452. <AtIcon value='clock' size='20' color='#1E90FF' onClick={() => this.openInteractHis('customerDemand')}></AtIcon>
  1453. ) : null }
  1454. </View>
  1455. <View className="val">
  1456. <AtTextarea
  1457. value={dtails.customerDemand}
  1458. maxLength={200}
  1459. placeholder='请编写本次面谈客户需求~'
  1460. height={70}
  1461. onChange={value => {
  1462. dtails.customerDemand = value;
  1463. this.setState({ dtails });
  1464. }}
  1465. />
  1466. </View>
  1467. <View className="tit">
  1468. <Text>
  1469. 面谈思路
  1470. <Text className="txt">(20字以上)</Text>
  1471. </Text>
  1472. { dtails.interviewList.length ? (
  1473. <AtIcon value='clock' size='20' color='#1E90FF' onClick={() => this.openInteractHis('interviewIdeas')}></AtIcon>
  1474. ) : null }
  1475. </View>
  1476. <View className="val">
  1477. <AtTextarea
  1478. value={dtails.interviewIdeas}
  1479. maxLength={200}
  1480. placeholder='请编写本次面谈客户思路~'
  1481. height={70}
  1482. onChange={value => {
  1483. dtails.interviewIdeas = value;
  1484. this.setState({ dtails });
  1485. }}
  1486. />
  1487. </View>
  1488. <View className="tit">
  1489. <Text>
  1490. 面谈达成的目的
  1491. <Text className="txt">(20字以上)</Text>
  1492. </Text>
  1493. { dtails.interviewList.length ? (
  1494. <AtIcon value='clock' size='20' color='#1E90FF' onClick={() => this.openInteractHis('interviewPurpose')}></AtIcon>
  1495. ) : null }
  1496. </View>
  1497. <View className="val">
  1498. <AtTextarea
  1499. value={dtails.interviewPurpose}
  1500. maxLength={200}
  1501. placeholder='请编写本次面谈达成的目的~'
  1502. height={70}
  1503. onChange={value => {
  1504. dtails.interviewPurpose = value;
  1505. this.setState({ dtails });
  1506. }}
  1507. />
  1508. </View>
  1509. <View className="tit">
  1510. <Text>
  1511. 经理/上级面谈建议
  1512. <Text className="txt">(由经理/上级口述,本人整理,20字以上)</Text>
  1513. </Text>
  1514. { dtails.interviewList.length ? (
  1515. <AtIcon value='clock' size='20' color='#1E90FF' onClick={() => this.openInteractHis('interviewRecommend')}></AtIcon>
  1516. ) : null }
  1517. </View>
  1518. <View className="val">
  1519. <AtTextarea
  1520. value={dtails.interviewRecommend}
  1521. maxLength={200}
  1522. placeholder='请编写本次面谈建议~'
  1523. height={70}
  1524. onChange={value => {
  1525. dtails.interviewRecommend = value;
  1526. this.setState({ dtails });
  1527. }}
  1528. />
  1529. </View>
  1530. { dtails.interviewList && dtails.interviewList.length ? (
  1531. <>
  1532. <View className="tit">
  1533. <Text>
  1534. 面谈后的反馈
  1535. <Text className="txt">(20字以上)</Text>
  1536. </Text>
  1537. <AtIcon value='clock' size='20' color='#1E90FF' onClick={() => this.openInteractHis('interviewFeedback')}></AtIcon>
  1538. </View>
  1539. <View className="val">
  1540. <AtTextarea
  1541. value={dtails.interviewFeedback}
  1542. maxLength={200}
  1543. placeholder='请编写本次面谈后的反馈~'
  1544. height={70}
  1545. onChange={value => {
  1546. dtails.interviewFeedback = value;
  1547. this.setState({ dtails });
  1548. }}
  1549. />
  1550. </View>
  1551. <View className="tit">
  1552. <Text>
  1553. 后续跟进计划
  1554. <Text className="txt">(20字以上)</Text>
  1555. </Text>
  1556. <AtIcon value='clock' size='20' color='#1E90FF' onClick={() => this.openInteractHis('followUpPlan')}></AtIcon>
  1557. </View>
  1558. <View className="val">
  1559. <AtTextarea
  1560. value={dtails.followUpPlan}
  1561. maxLength={200}
  1562. placeholder='请编写后续跟进计划~'
  1563. height={70}
  1564. onChange={value => {
  1565. dtails.followUpPlan = value;
  1566. this.setState({ dtails });
  1567. }}
  1568. />
  1569. </View>
  1570. </>
  1571. ) : null }
  1572. <View style={{ display: 'flex', marginTop: '24rpx'}}>
  1573. <AtButton type="secondary" circle onClick={this.handlePrevClick.bind(this)}>上一页</AtButton>
  1574. <AtButton type="primary" circle onClick={this.handleNextClick.bind(this)}>下一页</AtButton>
  1575. </View>
  1576. </View>
  1577. </View>
  1578. }
  1579. </View>
  1580. )}
  1581. </View>
  1582. <AtModal
  1583. isOpened={this.state.isOpened}
  1584. onClose={() => {
  1585. this.setState({
  1586. isOpened: false,
  1587. checkProject: [],
  1588. checkOptions: []
  1589. })
  1590. }}
  1591. >
  1592. <AtModalHeader>信息修改</AtModalHeader>
  1593. <AtModalContent>
  1594. {
  1595. upType == 1 &&
  1596. <View>
  1597. <AtInput
  1598. name='inventionPatentCount'
  1599. title='发明专利'
  1600. type='number'
  1601. value={info.inventionPatentCount}
  1602. onChange={e => {
  1603. this.setState({
  1604. info: Object.assign(info, {
  1605. inventionPatentCount: e,
  1606. })
  1607. })
  1608. }}
  1609. cursor={-1}
  1610. />
  1611. <AtInput
  1612. name='utilityModelCount'
  1613. title='实用新型'
  1614. type='number'
  1615. value={info.utilityModelCount}
  1616. onChange={e => {
  1617. this.setState({
  1618. info: Object.assign(info, {
  1619. utilityModelCount: e,
  1620. })
  1621. })
  1622. }}
  1623. cursor={-1}
  1624. />
  1625. <AtInput
  1626. name='appearancePatentCount'
  1627. title='外观专利'
  1628. type='number'
  1629. value={info.appearancePatentCount}
  1630. onChange={e => {
  1631. this.setState({
  1632. info: Object.assign(info, {
  1633. appearancePatentCount: e,
  1634. })
  1635. })
  1636. }}
  1637. cursor={-1}
  1638. />
  1639. <AtInput
  1640. name='softwareWorksCount'
  1641. title='软著'
  1642. type='number'
  1643. value={info.softwareWorksCount}
  1644. onChange={e => {
  1645. this.setState({
  1646. info: Object.assign(info, {
  1647. softwareWorksCount: e,
  1648. })
  1649. })
  1650. }}
  1651. cursor={-1}
  1652. />
  1653. <View style={{display: 'flex', margin: '12rpx 0'}}>
  1654. <Text style={{ fontSize: '32rpx', marginRight: '16rpx', width: '172rpx' }}>标准</Text>
  1655. <RadioGroup title="标准" onChange={e => {
  1656. dtails.standard = Number(e.target.value);
  1657. this.setState({ dtails });
  1658. }}>
  1659. <Label className='radio-list__label'>
  1660. <Radio className='radio-list__radio' value={1} checked={dtails.standard == 1}>有</Radio>
  1661. </Label>
  1662. <Label className='radio-list__label'>
  1663. <Radio className='radio-list__radio' value={0} checked={!dtails.standard}>无</Radio>
  1664. </Label>
  1665. </RadioGroup>
  1666. </View>
  1667. <AtInput
  1668. name='otherCount'
  1669. title='其他'
  1670. type='number'
  1671. value={dtails.otherCount}
  1672. onChange={e => {
  1673. this.setState({
  1674. info: Object.assign(dtails, {
  1675. otherCount: e,
  1676. })
  1677. })
  1678. }}
  1679. cursor={-1}
  1680. />
  1681. </View>
  1682. }
  1683. {
  1684. upType == 5 &&
  1685. <View>
  1686. <AtSearchBar
  1687. placeholder="请输入项目名称"
  1688. showActionButton
  1689. value={this.state.value}
  1690. onChange={this.onSearchChange}
  1691. onActionClick={() => {
  1692. this.getBusinessProjectByName(this.state.value);
  1693. }}
  1694. onClear={() => {
  1695. this.setState({
  1696. value: "",
  1697. }, () => { this.getBusinessProjectByName(this.state.value) });
  1698. }}
  1699. cursor={-1}
  1700. />
  1701. {/* 高新项目 */}
  1702. { this.state.checkProject.length && this.state.checkProject[0].cSort == 9 ? <View style={{backgroundColor: '#eee', padding: '20rpx 24rpx', margin: '24rpx'}}>
  1703. <RadioGroup onChange={e => {
  1704. const { info } = this.state;
  1705. info.examineStatus = e.target.value;
  1706. this.setState({ info });
  1707. }}>
  1708. <Label className='radio-list__label'>
  1709. <Radio className='radio-list__radio' checked={info.examineStatus == 1} value={1}>初次审核</Radio>
  1710. </Label>
  1711. <Label className='radio-list__label'>
  1712. <Radio className='radio-list__radio' checked={info.examineStatus == 2} value={2}>复审</Radio>
  1713. </Label>
  1714. </RadioGroup>
  1715. { this.state.info.examineStatus == 2 && <View>
  1716. <Text>复审年份:</Text>
  1717. <Text style={{textDecoration: 'underline'}} onClick={() => this.handleOpenMultiplePicker('examineStatusOther')}>{ info.examineStatusOther || '请选择' }</Text>
  1718. </View> }
  1719. </View> : null}
  1720. {/* 会员项目 */}
  1721. { this.state.checkProject.length && this.state.checkProject[0].cSort == 6 ? <View style={{backgroundColor: '#eee', padding: '20rpx 24rpx', margin: '24rpx'}}>
  1722. <RadioGroup onChange={e => {
  1723. const { info } = this.state;
  1724. info.buyStatus = e.target.value;
  1725. this.setState({ info });
  1726. }}>
  1727. <Label className='radio-list__label'>
  1728. <Radio className='radio-list__radio' checked={info.buyStatus == 1} value={1}>新购</Radio>
  1729. </Label>
  1730. <Label className='radio-list__label'>
  1731. <Radio className='radio-list__radio' checked={info.buyStatus == 2} value={2}>复购/复审</Radio>
  1732. </Label>
  1733. </RadioGroup>
  1734. { this.state.info.buyStatus == 2 && <View>
  1735. <Text>复购/复审年份:</Text>
  1736. <Text style={{textDecoration: 'underline'}} onClick={() => this.handleOpenMultiplePicker('buyStatusOther')}>{ info.buyStatusOther || '请选择' }</Text>
  1737. </View> }
  1738. </View> : null}
  1739. { this.state.isOpened && <RadioGroup onChange={e => {
  1740. let currProject = this.state.allProjectList.find(item => item.id == e.target.value);
  1741. this.setState({
  1742. checkOptions: [e.target.value],
  1743. checkProject: [currProject]
  1744. });
  1745. }}>
  1746. {this.state.options.map((item, i) => {
  1747. return (
  1748. <View>
  1749. <Label className='radio-list__label' for={i} key={i}>
  1750. <Radio className='radio-list__radio' value={item.value} checked={this.state.checkOptions.indexOf(item.value) > -1}>{item.label}</Radio>
  1751. </Label>
  1752. </View>
  1753. )
  1754. })}
  1755. </RadioGroup>}
  1756. </View>
  1757. }
  1758. </AtModalContent>
  1759. <AtModalAction>
  1760. <Button type='secondary' onClick={() => {
  1761. this.setState({
  1762. isOpened: false,
  1763. checkOptions: [],
  1764. checkProject: []
  1765. })
  1766. }}>取消</Button>
  1767. <Button type='primary' onClick={this.update}>确定修改</Button>
  1768. </AtModalAction>
  1769. </AtModal>
  1770. <AtModal
  1771. isOpened={this.state.isAdd}
  1772. onClose={() => {
  1773. this.setState({
  1774. isAdd: false
  1775. })
  1776. }}
  1777. >
  1778. <AtModalHeader>联系人</AtModalHeader>
  1779. <AtModalContent>
  1780. {
  1781. userList.map((item) =>
  1782. <View key={item.id} className="additem">
  1783. <Text className="txt">{item.name || " "}</Text>
  1784. <Text className="txt">{item.position || " "}</Text>
  1785. <Text className="txt">{item.department || " "}</Text>
  1786. <Text className="mobile">{item.mobile || " "}</Text>
  1787. <View
  1788. className={item.major == 1 ? "bts" : "bt"}
  1789. onClick={() => {
  1790. item.major != 1 && this.updateMainContact(item.id)
  1791. }}
  1792. >
  1793. {item.major == 1 ? "已选" : "选择"}
  1794. </View>
  1795. </View>
  1796. )
  1797. }
  1798. <AtInput
  1799. required
  1800. name='name'
  1801. title='姓名'
  1802. type='text'
  1803. placeholder='请填写姓名'
  1804. value={obj.name}
  1805. onChange={e => {
  1806. this.setState({
  1807. obj: Object.assign(obj, {
  1808. name: e,
  1809. })
  1810. })
  1811. }}
  1812. cursor={-1}
  1813. />
  1814. <AtInput
  1815. required
  1816. name='position'
  1817. title='职位'
  1818. type='text'
  1819. placeholder='请填写职位'
  1820. value={obj.position}
  1821. onChange={e => {
  1822. this.setState({
  1823. obj: Object.assign(obj, {
  1824. position: e,
  1825. })
  1826. })
  1827. }}
  1828. cursor={-1}
  1829. />
  1830. <AtInput
  1831. required
  1832. name='department'
  1833. title='部门'
  1834. type='text'
  1835. placeholder='请填写部门'
  1836. value={obj.department}
  1837. onChange={e => {
  1838. this.setState({
  1839. obj: Object.assign(obj, {
  1840. department: e,
  1841. })
  1842. })
  1843. }}
  1844. cursor={-1}
  1845. />
  1846. <AtInput
  1847. required
  1848. name='mobile'
  1849. title='手机'
  1850. type='phone'
  1851. placeholder='请填写手机号'
  1852. value={obj.mobile}
  1853. onChange={e => {
  1854. this.setState({
  1855. obj: Object.assign(obj, {
  1856. mobile: e,
  1857. })
  1858. })
  1859. }}
  1860. cursor={-1}
  1861. />
  1862. </AtModalContent>
  1863. <AtModalAction>
  1864. <Button type='secondary'
  1865. onClick={() => {
  1866. this.setState({
  1867. isAdd: false,
  1868. }, () => {
  1869. this.queryByUidAll()
  1870. })
  1871. }}>取消</Button>
  1872. <Button type='primary' onClick={this.add}>保存</Button>
  1873. </AtModalAction>
  1874. </AtModal>
  1875. {/* 新增项目 */}
  1876. <AtModal
  1877. isOpened={this.state.addItemShow}
  1878. onClose={this.handleCloseAddItemDialog}
  1879. >
  1880. <AtModalHeader>新增对外投资控股的企业</AtModalHeader>
  1881. <AtModalContent>
  1882. <AtInput
  1883. required
  1884. name='companyName'
  1885. title='企业名称'
  1886. placeholder='请输入企业名称'
  1887. value={this.state.addItemInputVal}
  1888. onChange={value => this.setState({ addItemInputVal: value })}
  1889. cursor={-1}
  1890. />
  1891. </AtModalContent>
  1892. <AtModalAction>
  1893. <Button type='secondary' onClick={this.handleCloseAddItemDialog}>取消</Button>
  1894. <Button type='primary' onClick={this.handleAddItemSave}>保存</Button>
  1895. </AtModalAction>
  1896. </AtModal>
  1897. {/* 多选框 */}
  1898. <CheckboxPicker
  1899. isOpened={this.state.multiplePickerShow}
  1900. title={this.state.multiplePickerTitle}
  1901. options={this.state.multiplePickerOptions}
  1902. checkedList={this.state.multiplePickerCheckedList}
  1903. onClose={() => {this.setState({multiplePickerShow: false, multiplePickerCheckedList: []})}}
  1904. onConfirm={this.handleMultipleConfirm}
  1905. ></CheckboxPicker>
  1906. {/* 沟通情况历史记录 */}
  1907. <InteractList
  1908. isOpened={this.state.interactShow}
  1909. list={this.state.interactList}
  1910. type={this.state.interactShowType}
  1911. title={this.state.interactTitle}
  1912. onClose={() => {
  1913. this.setState({ interactShow: false })
  1914. }}
  1915. />
  1916. {/* 省市区选择器 */}
  1917. <AddressPicker
  1918. pickerShow={this.state.addressPickerShow}
  1919. onHandleToggleShow={this.toggleAddressPicker.bind(this)}
  1920. />
  1921. </View>
  1922. );
  1923. }
  1924. }
  1925. export default CustomerProfile;