addRecord.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. <template>
  2. <view class="uni-app">
  3. <view class="status-bar" />
  4. <view class="main-container">
  5. <wk-nav-bar title="写跟进">
  6. <!-- #ifndef MP-WEIXIN -->
  7. <button
  8. class="button white-btn"
  9. @click="handleSave">
  10. 保存
  11. </button>
  12. <!-- #endif -->
  13. </wk-nav-bar>
  14. <view class="container">
  15. <view class="scroll-content">
  16. <wk-form ref="form" :fields="fieldArr" />
  17. <view class="textarea-wrapper">
  18. <view class="title">
  19. 跟进内容
  20. </view>
  21. <view class="content">
  22. <textarea
  23. v-model="content"
  24. maxlength="500"
  25. placeholder="请填写跟进记录内容"
  26. placeholder-class="wk-placeholder"
  27. class="textraea-core" />
  28. </view>
  29. </view>
  30. <view class="cell-box">
  31. <view class="cell" @click="addPic">
  32. <view class="cell-left">
  33. <image :src="$static('images/icon/image.png')" class="pic-icon" />
  34. 图片
  35. </view>
  36. <view class="cell-right add-icon">
  37. <text class="wk wk-plus" />
  38. </view>
  39. </view>
  40. <wk-image-content
  41. v-if="imgList.length > 0"
  42. :list="imgList"
  43. show-delete
  44. @delete="deleteImg" />
  45. </view>
  46. <view class="cell-box">
  47. <view class="cell" @click="addAdjunct">
  48. <view class="cell-left">
  49. <image :src="$static('images/icon/clip.png')" class="pic-icon" />
  50. 附件
  51. </view>
  52. <view class="cell-right add-icon">
  53. <text class="wk wk-plus" />
  54. </view>
  55. </view>
  56. <wk-file-content
  57. v-if="fileList.length > 0"
  58. :list="fileList"
  59. show-delete
  60. @delete="deleteFile" />
  61. </view>
  62. <view
  63. v-if="type === 'crm_customer'"
  64. class="cell-box">
  65. <view class="cell" @click="handlePopShow">
  66. <view class="cell-left">
  67. <image :src="$static('images/icon/relate.png')" class="pic-icon" />
  68. 关联业务
  69. </view>
  70. <view class="cell-right add-icon">
  71. <text class="wk wk-plus" />
  72. </view>
  73. </view>
  74. <relevance-section
  75. v-if="showRelevance"
  76. :is-add="true"
  77. :relevance-data="relevanceData"
  78. @delete="relevanceDelete" />
  79. </view>
  80. </view>
  81. </view>
  82. <!-- #ifdef MP-WEIXIN -->
  83. <view class="footer-btn-group">
  84. <button class="button" @click="handleSave">
  85. 保存
  86. </button>
  87. </view>
  88. <!-- #endif -->
  89. </view>
  90. <uni-popup ref="popup">
  91. <view class="pop-wrapper">
  92. <view
  93. v-for="(item, index) in popOptions"
  94. :key="index"
  95. class="pop-item"
  96. @click.stop="handleSelectOptions(item)">
  97. {{ item.label }}
  98. </view>
  99. </view>
  100. </uni-popup>
  101. </view>
  102. </template>
  103. <script>
  104. import {
  105. GetCrmActivityPageList,
  106. AddCrmActivityRecord,
  107. QueryRecordOptions
  108. } from 'API/crm/crmActivity'
  109. import { FileDeleteById } from 'API/file'
  110. import { QueryContacts, QueryBusiness } from 'API/crm/customer.js'
  111. import RelevanceSection from '@/components/base/relevance-section.vue'
  112. import Fields from '@/utils/fields.js'
  113. import WkFile from '@/utils/file.js'
  114. import moment from 'moment'
  115. export default {
  116. name: 'AddRecord',
  117. components: {
  118. RelevanceSection
  119. },
  120. data() {
  121. return {
  122. guid: null,
  123. type: '',
  124. id: '',
  125. activityMap: {
  126. crm_leads: 1,
  127. crm_customer: 2,
  128. crm_contacts: 3,
  129. crm_product: 4,
  130. crm_business: 5,
  131. crm_contract: 6,
  132. crm_receivables: 7
  133. },
  134. fieldArr: [
  135. new Fields({
  136. name: '记录类型',
  137. formType: 'select',
  138. fieldName: 'category',
  139. setting: [],
  140. isNull: 1,
  141. value: '',
  142. }),
  143. new Fields({
  144. name: '下次联系时间',
  145. formType: 'datetime',
  146. fieldName: 'nextTime',
  147. isNull: 0,
  148. value: null
  149. })
  150. ],
  151. batchId: '',
  152. content: '', // 跟进内容
  153. imgList: [], // 图片列表
  154. fileList: [], // 附件列表
  155. contactsList: [], // 联系人列表
  156. businessList: [], // 商机列表
  157. controlList: [], // 底部控制按钮列表
  158. popOptions: [
  159. { label: '联系人', value: 'contacts' },
  160. { label: '商机', value: 'business' },
  161. ]
  162. }
  163. },
  164. computed: {
  165. showRelevance() {
  166. return this.contactsList.length > 0 ||
  167. this.businessList.length > 0
  168. },
  169. relevanceData() {
  170. return {
  171. contactsList: this.contactsList,
  172. businessList: this.businessList
  173. }
  174. }
  175. },
  176. onLoad(options) {
  177. this.type = options.type
  178. this.id = options.id
  179. this.guid = this.$guid()
  180. this.getRecordOptions()
  181. },
  182. methods: {
  183. getRecordOptions() {
  184. QueryRecordOptions().then(res => {
  185. this.$set(this.fieldArr[0], 'setting', res)
  186. this.$set(this.fieldArr[0], 'value', [{ label: res[0], value: res[0]}])
  187. }).catch()
  188. },
  189. /**
  190. * 添加图片
  191. */
  192. addPic() {
  193. const params = {
  194. type: 'img'
  195. }
  196. if (this.batchId) {
  197. params.batchId = this.batchId
  198. }
  199. const fileUpload = new WkFile(params)
  200. fileUpload.choose().then(data => {
  201. console.log('upload res: ', data)
  202. this.batchId = data[0].batchId
  203. this.imgList = this.imgList.concat(data)
  204. })
  205. },
  206. /**
  207. * 添加附件
  208. */
  209. addAdjunct() {
  210. const params = {}
  211. if (this.batchId) {
  212. params.batchId = this.batchId
  213. }
  214. const fileUpload = new WkFile(params)
  215. fileUpload.choose().then(data => {
  216. console.log('upload res: ', data)
  217. this.batchId = data[0].batchId
  218. this.fileList = this.fileList.concat(data)
  219. })
  220. },
  221. /**
  222. * 删除图片
  223. * @param {Number} index
  224. */
  225. deleteImg(index) {
  226. const fileId = this.imgList[index].fileId
  227. this.imgList.splice(index, 1)
  228. FileDeleteById({id: fileId}).then().catch()
  229. },
  230. /**
  231. * 删除附件
  232. * @param {Number} index
  233. */
  234. deleteFile(index) {
  235. const fileId = this.fileList[index].fileId
  236. this.fileList.splice(index, 1)
  237. FileDeleteById({id: fileId}).then().catch()
  238. },
  239. handlePopShow() {
  240. this.$refs.popup.open()
  241. },
  242. handleSelectOptions(item) {
  243. this.$refs.popup.close()
  244. switch (item.value) {
  245. case 'contacts':
  246. this.hanldeToChooseRevelance('contacts')
  247. break
  248. case 'business':
  249. this.hanldeToChooseRevelance('business')
  250. break
  251. }
  252. },
  253. hanldeToChooseRevelance(type) {
  254. const bridge = getApp().globalData.selectedValBridge
  255. bridge[type] = {
  256. guid: this.guid,
  257. defaultVal: this[`${type}List`] || [],
  258. params: {
  259. customerId: this.id
  260. },
  261. request: type === 'contacts' ? QueryContacts : QueryBusiness
  262. }
  263. uni.$once('selected-relevance', this.selectedRelevance)
  264. this.$Router.navigateTo({
  265. url: '/pages_common/selectList/relevance',
  266. query: {
  267. type: type
  268. }
  269. })
  270. },
  271. selectedRelevance(data) {
  272. if (this.guid === data.guid) {
  273. this[`${data.type}List`] = data.data
  274. console.log('data: ', this)
  275. }
  276. uni.$off('selected-relevance')
  277. },
  278. relevanceDelete(type, index) {
  279. this[`${type}List`].splice(index, 1)
  280. },
  281. handleSave() {
  282. this.$refs.form.getForm().then(form => {
  283. const params = form.entity
  284. if (!this.content) {
  285. this.$toast('跟进内容不能为空')
  286. return
  287. }
  288. if (this.type === 'crm_customer') {
  289. params.businessIds = this.businessList.map(item => {
  290. return item.businessId
  291. })
  292. params.contactsIds = this.contactsList.map(item => {
  293. return item.contactsId
  294. })
  295. }
  296. params.content = this.content
  297. params.activityTypeId = this.id
  298. params.activityType = this.activityMap[this.type]
  299. // params.category = params.category instanceof Array ? params.category[0] : params.category
  300. params.batchId = this.batchId || ''
  301. console.log('save: ', params)
  302. AddCrmActivityRecord(params).then(res => {
  303. this.$toast('添加成功')
  304. this.$refreshAndToPrev(this)
  305. }).catch()
  306. }).catch()
  307. }
  308. }
  309. }
  310. </script>
  311. <style scoped lang="scss">
  312. .container {
  313. flex: 1;
  314. margin-top: 20rpx;
  315. overflow: hidden;
  316. .scroll-content {
  317. width: 100%;
  318. height: 100%;
  319. overflow: auto;
  320. .cell-box {
  321. background-color: white;
  322. padding: 15rpx 32rpx;
  323. .cell {
  324. width: 100%;
  325. font-size: 30rpx;
  326. @include left;
  327. .cell-left {
  328. flex: 1;
  329. @include left;
  330. .pic-icon {
  331. width: 38rpx;
  332. height: 38rpx;
  333. margin-right: 15rpx;
  334. }
  335. }
  336. .add-icon {
  337. width: 38rpx;
  338. height: 38rpx;
  339. background-color: #E1E1E1;
  340. border-radius: 50%;
  341. @include center;
  342. .wk {
  343. font-size: $wk-font-mini;
  344. line-height: normal;
  345. color: white;
  346. }
  347. }
  348. }
  349. }
  350. .textarea-wrapper {
  351. background-color: white;
  352. margin-top: 20rpx;
  353. padding: 0 30rpx;
  354. .title {
  355. font-size: 30rpx;
  356. padding: 24rpx 0;
  357. }
  358. .textraea-core {
  359. width: 100%;
  360. height: 200rpx;
  361. font-size: 28rpx;
  362. }
  363. }
  364. .file-section, .revelance-section {
  365. background-color: white;
  366. padding: 0 30rpx 10rpx;
  367. overflow: hidden;
  368. }
  369. }
  370. }
  371. </style>