activityListItem.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. <template>
  2. <view class="activity-list-item">
  3. <template v-for="(field, index) in fieldsMap[itemData.activityType]">
  4. <view
  5. :key="index"
  6. class="row-item">
  7. <text class="row-item__label">
  8. {{ getLabel(field) }}:
  9. </text>
  10. <view
  11. v-if="['products'].includes(field.fieldName)"
  12. class="row-item__content">
  13. <template v-if="getContent(field).length">
  14. <view
  15. v-for="(child, childIndex) in getContent(field)"
  16. :key="childIndex"
  17. :class="{ 'special': !!field.type }"
  18. @click="handleClick(field.type, child.id)">
  19. {{ childIndex == getContent(field).length - 1 && child.name || (child.name + ',') }}
  20. </view>
  21. </template>
  22. </view>
  23. <view
  24. v-else-if="['contractId'].includes(field.typeName)"
  25. class="row-item__content">
  26. <template v-if="getContent(field).length">
  27. <view
  28. :class="{ 'special': !!field.type }"
  29. @click="handleClick(field.type, itemData.content[field.typeName])">
  30. {{ getContent(field) || '' }}
  31. </view>
  32. </template>
  33. </view>
  34. <view
  35. v-else
  36. class="row-item__content">
  37. <view
  38. v-if="field.type && !field.disabled"
  39. class="special"
  40. @click="handleClick(field.type, itemData[field.idField] ? itemData[field.idField] : null)">
  41. {{ getContent(field) || '' }}
  42. </view>
  43. <view v-else>
  44. {{ getContent(field) || '' }}
  45. </view>
  46. <view
  47. v-if="getShowTag(field)"
  48. :style="{
  49. color: examineStautsObj.color,
  50. backgroundColor: examineStautsObj.bg
  51. }"
  52. class="tag">
  53. {{ examineStautsObj.label }}
  54. </view>
  55. </view>
  56. </view>
  57. </template>
  58. <!-- </view> -->
  59. </view>
  60. </view>
  61. </view>
  62. </template>
  63. <script>
  64. import { mapGetters } from 'vuex'
  65. import { isObject } from '@/utils/types'
  66. import moment from 'moment'
  67. export default {
  68. name: 'ActivityListItem',
  69. props: {
  70. itemData: {
  71. type: Object,
  72. required: true
  73. }
  74. },
  75. data() {
  76. return {
  77. fieldsMap: {
  78. // 线索
  79. 1: [
  80. { fieldName: 'name', name: '线索名称', type: 'leads' }
  81. ],
  82. // 客户
  83. 2: [
  84. { fieldName: 'name', name: '客户名称', type: 'customer', idField: 'activityTypeId' },
  85. { fieldName: 'industry', name: '客户行业' },
  86. { fieldName: 'level', name: '客户级别' }
  87. ],
  88. // 联系人
  89. 3: [
  90. { fieldName: 'name', name: '联系人名称', type: 'contacts', idField: 'activityTypeId' },
  91. { fieldName: 'post', name: '职务' },
  92. { fieldName: 'mobile', name: '手机' }
  93. ],
  94. // 产品
  95. 4: [
  96. { fieldName: 'name', name: '产品名称', type: 'product' }
  97. ],
  98. // 商机
  99. 5: [
  100. { fieldName: 'name', name: '商机名称', type: 'business', idField: 'activityTypeId' },
  101. { fieldName: 'money', name: '商机金额' },
  102. { fieldName: 'flowName', name: '商机状态组' },
  103. { fieldName: 'products', name: '相关产品', type: 'product' }
  104. ],
  105. // 合同
  106. 6: [
  107. { fieldName: 'name', name: '合同名称', type: 'contract', idField: 'activityTypeId' },
  108. { fieldName: 'num', name: '合同编号' },
  109. { fieldName: 'money', name: '合同金额' },
  110. // { fieldName: 'timeLine', name: '合同有效期' }
  111. ],
  112. // 回款
  113. 7: [
  114. { fieldName: 'name', name: '回款编号', type: 'receivables', idField: 'activityTypeId' },
  115. { fieldName: 'contractNum', name: '合同编号', type: 'contract', typeName: 'contractId' },
  116. { fieldName: 'num', name: '回款编号' },
  117. { fieldName: 'money', name: '回款金额' },
  118. { fieldName: 'returnTime', name: '回款日期' }
  119. ],
  120. // 日志
  121. 8: [
  122. { fieldName: 'name', name: '日志名称', type: 'log', idField: 'activityTypeId' },
  123. { fieldName: 'content', name: '日志内容' }
  124. ],
  125. // 审批
  126. 9: [
  127. { fieldName: 'name', name: '审批名称', type: 'examine', idField: 'activityTypeId' },
  128. { fieldName: 'type', name: '审批类型' },
  129. { fieldName: 'content', name: '' },
  130. { fieldName: 'endAddress', name: '出差地点' },
  131. { fieldName: 'duration', name: '出差总天数' },
  132. { fieldName: 'timeLine', name: '起止时间' }
  133. ],
  134. // 日程
  135. 10: [
  136. { fieldName: 'name', name: '日程内容' },
  137. { fieldName: 'type', name: '日程类型' },
  138. { fieldName: 'timeLine', name: '起止时间' }
  139. ],
  140. // 任务
  141. 11: [
  142. { fieldName: 'name', name: '任务名称', type: 'task', idField: 'activityTypeId' },
  143. { fieldName: 'ownerUser', name: '负责人' },
  144. { fieldName: 'timeLine', name: '起止时间' },
  145. { fieldName: 'tasks', name: '子任务', type: 'task', disabled: true }
  146. ],
  147. // 发邮件
  148. 12: [],
  149. // 回款计划
  150. 14: [
  151. { fieldName: 'name', name: '计划回款期数', type: 'receivablesPlan', idField: 'activityTypeId', disabled: true },
  152. { fieldName: 'contractNum', name: '合同编号', type: 'contract', typeName: 'contractId' },
  153. { fieldName: 'money', name: '计划回款金额' },
  154. { fieldName: 'returnTime', name: '计划回款日期' }
  155. ]
  156. }
  157. }
  158. },
  159. computed: {
  160. ...mapGetters({
  161. calcStatus: 'base/calcStatus'
  162. }),
  163. contentData() {
  164. return this.itemData.content || {}
  165. },
  166. examineStautsObj() {
  167. if (!this.contentData.hasOwnProperty('checkStatus')) return {}
  168. return this.calcStatus(this.contentData.checkStatus)
  169. }
  170. },
  171. methods: {
  172. /**
  173. * 判断字段是否展示
  174. * @param field
  175. * @return {boolean}
  176. */
  177. getShow(field) {
  178. if (field.fieldName === 'timeLine') return true
  179. return this.contentData.hasOwnProperty(field.fieldName)
  180. },
  181. formatTime(time) {
  182. if (!time) return ''
  183. return moment(time).format('YYYY-MM-DD HH:mm')
  184. },
  185. /**
  186. * 获取字段名
  187. * @param field
  188. * @return {string}
  189. */
  190. getLabel(field) {
  191. if (
  192. this.itemData.activityType === 9 &&
  193. field.fieldName === 'content'
  194. ) {
  195. // type 审批类型 1 普通审批 2 请假审批 3 出差审批 4 加班审批 5 差旅报销 6 借款申请 0 自定义审批
  196. return {
  197. 1: '审批内容',
  198. 2: '请假原因',
  199. 3: '出差原因',
  200. 4: '加班原因',
  201. 5: '差旅报销',
  202. 6: '审批内容',
  203. 0: '审批内容'
  204. }[this.contentData.type] || ''
  205. }
  206. return field.name
  207. },
  208. /**
  209. * 获取字段值
  210. * @param field
  211. * @return {string|*}
  212. */
  213. getContent(field) {
  214. if (
  215. field.fieldName === 'timeLine' &&
  216. (
  217. this.contentData.hasOwnProperty('startTime') ||
  218. this.contentData.hasOwnProperty('endTime')
  219. )
  220. ) {
  221. return `${this.contentData.startTime}~${this.contentData.endTime}`
  222. }
  223. if (
  224. this.itemData.activityType === 9 &&
  225. field.fieldName === 'type'
  226. ) {
  227. return {
  228. 1: '普通审批',
  229. 2: '请假审批',
  230. 3: '出差审批',
  231. 4: '加班审批',
  232. 5: '差旅报销',
  233. 6: '借款申请',
  234. 0: '自定义审批'
  235. }[this.contentData.type]
  236. }
  237. if ([
  238. 'tasks'
  239. ].includes(field.fieldName)) {
  240. return (this.contentData[field.fieldName] || [])
  241. .map(item => item.name)
  242. .join('、')
  243. }
  244. if ([
  245. 'products'
  246. ].includes(field.fieldName)) {
  247. return this.contentData[field.fieldName] || []
  248. }
  249. if (field.fieldName === 'ownerUser') {
  250. const userData = this.contentData[field.fieldName]
  251. return isObject(userData) ? userData.realname : ''
  252. }
  253. return this.contentData[field.fieldName]
  254. },
  255. /**
  256. * 判断是否展示审批状态标签
  257. * @param {Object} field
  258. */
  259. getShowTag(field) {
  260. return field.fieldName === 'name' && this.contentData.hasOwnProperty('checkStatus')
  261. },
  262. /**
  263. * 点击跳转到详情
  264. * @param {Object} type
  265. * @param {Object} id
  266. */
  267. handleClick(type, id) {
  268. console.log('click', type, id)
  269. switch (type) {
  270. case 'examine':
  271. this.$Router.navigateTo({
  272. url: `/pages_examine/detail`,
  273. query: {
  274. id: id
  275. }
  276. })
  277. return;
  278. case 'log':
  279. this.$Router.navigateTo({
  280. url: `/pages_log/detail`,
  281. query: {
  282. id: id
  283. }
  284. })
  285. return;
  286. case 'task':
  287. this.$Router.navigateTo({
  288. url: `/pages_task/detail`,
  289. query: {
  290. id: id
  291. }
  292. })
  293. return;
  294. }
  295. this.$Router.navigateTo({
  296. url: `/pages_crm/${type}/detail`,
  297. query: {
  298. id: id
  299. }
  300. })
  301. }
  302. }
  303. }
  304. </script>
  305. <style scoped lang="scss">
  306. .activity-list-item {
  307. .activity-item {
  308. .user-info {
  309. margin-bottom: 20rpx;
  310. @include left;
  311. .avatar {
  312. width: 65rpx;
  313. height: 65rpx;
  314. }
  315. .info {
  316. flex: 1;
  317. margin-left: 16rpx;
  318. .username {
  319. font-size: $wk-font-base;
  320. color: #333;
  321. @include left;
  322. .dynamic-name {
  323. margin-left: 10rpx;
  324. }
  325. }
  326. .text {
  327. font-size: $wk-font-mini;
  328. color: $light;
  329. }
  330. }
  331. .category {
  332. font-size: $wk-font-mini;
  333. color: $light;
  334. background-color: #EEEEEE;
  335. border-radius: 5rpx;
  336. padding: 5rpx 15rpx;
  337. }
  338. }
  339. }
  340. .row-item {
  341. display: flex;
  342. align-items: flex-start;
  343. padding-left: 10rpx;
  344. justify-content: flex-start;
  345. font-size: $wk-font-base;
  346. .row-item__label {
  347. color: $gray;
  348. }
  349. .row-item__content {
  350. @include left;
  351. flex-wrap: wrap;
  352. flex: 1;
  353. .special {
  354. color: $theme-color;
  355. }
  356. .tag {
  357. margin-left: 10rpx;
  358. padding: 5rpx 10rpx;
  359. border-radius: 4rpx;
  360. font-size: $wk-font-sm;
  361. float: right;
  362. }
  363. }
  364. }
  365. }
  366. </style>