index.vue 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. <template>
  2. <view class="caseInfo_wrap">
  3. <template v-if="clueDetail.id">
  4. <view class="caseInfo_content_wrap">
  5. <view class="caseInfo_title">
  6. <image src="/static/clueDetail/icon-caseInfo.png" mode=""></image>
  7. <text class="info_text">线索基础信息</text>
  8. </view>
  9. <view class="caseInfo_main_wrap">
  10. <template v-if="params.type === '1'">
  11. <view class="Info_item" v-for="(item,index) in caseInfoColumn" :key="item.prop">
  12. <text class="label">{{item.label}}</text>
  13. <show-real-text :real="clueDetail.telephone" :type='params.type'
  14. v-if="item.prop === 'telephone'"></show-real-text>
  15. <view class="input_wrap" v-else-if="item.input">
  16. <input v-model="clueDetail[item.prop]"
  17. :disabled="!hasEditPermission"
  18. style="text-align: right; padding-right: 10px;"
  19. @blur="updateClueMainInfo" />
  20. </view>
  21. <text v-else-if="item.color" class="value highlight" :style="handleStyle(item.color)">
  22. {{clueDetail[item.prop]}}
  23. </text>
  24. <text v-else class="value">{{clueDetail[item.prop]}}</text>
  25. </view>
  26. </template>
  27. <template v-if="params.type === '2'">
  28. <view class="Info_item" v-for="(item,index) in caseInfoColumn" :key="item.prop">
  29. <text class="label">{{item.label}}</text>
  30. <view class="input_wrap" v-if="item.input">
  31. <input v-model="clueDetail[item.prop]"
  32. :disabled="!hasEditPermission"
  33. style="text-align: right; padding-right: 10px;"
  34. @blur="updateClueMainInfo" />
  35. </view>
  36. <text v-else-if="item.color" class="value highlight" :style="handleStyle(item.color)">
  37. {{clueDetail[item.prop]}}
  38. </text>
  39. <text v-else class="value">{{clueDetail[item.prop]}}</text>
  40. </view>
  41. </template>
  42. <template v-if="parsedRemarkDict && Object.keys(parsedRemarkDict).length > 0">
  43. <view class="Info_item" v-for="(value, key) in parsedRemarkDict" :key="key">
  44. <text class="label">{{ key }}</text>
  45. <text class="value">{{ value }}</text>
  46. </view>
  47. </template>
  48. </view>
  49. </view>
  50. </template>
  51. </view>
  52. </template>
  53. <script>
  54. import {
  55. cloneDeep,
  56. isEqual
  57. } from 'lodash';
  58. import { checkPermi } from '@/utils/permission';
  59. const caseInfoColumn = [{
  60. prop: 'name',
  61. label: '姓名',
  62. input: true
  63. },
  64. {
  65. prop: 'telephone',
  66. label: '电话',
  67. input: true
  68. },
  69. {
  70. prop: 'genderTypeCode',
  71. label: '性别',
  72. },
  73. {
  74. prop: 'age',
  75. label: '年龄',
  76. },
  77. {
  78. prop: 'weixin',
  79. label: '微信',
  80. input: true
  81. },
  82. {
  83. prop: 'corporateStatus',
  84. label: '企业号状态',
  85. },
  86. {
  87. prop: 'userDouyinId',
  88. label: '抖音号',
  89. },
  90. {
  91. prop: 'autoAddress',
  92. label: '自动定位城市',
  93. },
  94. {
  95. prop: 'telAddr',
  96. label: '手机号归属地',
  97. },
  98. {
  99. prop: 'createTime',
  100. label: '线索创建时间',
  101. },
  102. {
  103. prop: 'updateTime',
  104. label: '最新修改时间',
  105. },
  106. {
  107. prop: 'address',
  108. label: '详细地址',
  109. },
  110. {
  111. prop: 'remark',
  112. label: '备注',
  113. },
  114. {
  115. prop: 'qq',
  116. label: 'QQ号',
  117. },
  118. {
  119. prop: 'email',
  120. label: '邮箱',
  121. },
  122. {
  123. prop: 'date',
  124. label: '日期',
  125. },
  126. {
  127. prop: 'manualAddressCode',
  128. label: '手动填写地域',
  129. }
  130. ]
  131. export default {
  132. props: {
  133. clueId: {
  134. required: true
  135. },
  136. params: {
  137. type: Object,
  138. required: true
  139. },
  140. clueDetailVo : {
  141. type : Object,
  142. required : true
  143. },
  144. },
  145. computed : {
  146. parsedRemarkDict() {
  147. try {
  148. const remarkDict = this.clueDetailVo.remarkDict
  149. if (!remarkDict) {
  150. return null
  151. }
  152. if (typeof remarkDict === 'string') {
  153. const parsed = JSON.parse(remarkDict)
  154. return typeof parsed === 'object' && parsed !== null ? parsed : null
  155. }
  156. return typeof remarkDict === 'object' && remarkDict !== null ? remarkDict : null
  157. } catch (error) {
  158. console.error('解析remarkDict失败:', error)
  159. return null
  160. }
  161. },
  162. hasEditPermission() {
  163. if (this.params?.type === '2') return true;
  164. if (this.params?.type === '1') return checkPermi(['crm:PublicClue:detail:edit']);
  165. return false;
  166. }
  167. },
  168. methods: {
  169. async updateClueMainInfo() {
  170. if (!this.clueDetail.name) {
  171. uni.$u.toast("姓名不能为空");
  172. return;
  173. }
  174. if (!isEqual(this.cloneClueDetail, this.clueDetail)) {
  175. await uni.$u.api.updateClueMainInfo(this.clueDetail);
  176. uni.$u.toast("修改成功");
  177. this.getData();
  178. }
  179. },
  180. async getData() {
  181. const {
  182. data
  183. } = await uni.$u.api.getClueMainInfoById({
  184. id: this.clueId
  185. });
  186. this.clueDetail = data;
  187. this.cloneClueDetail = cloneDeep(data);
  188. }
  189. },
  190. created() {
  191. this.getData();
  192. },
  193. data() {
  194. return {
  195. cloneClueDetail: {},
  196. clueDetail: {},
  197. caseInfoColumn,
  198. }
  199. }
  200. }
  201. </script>
  202. <style lang="scss" scoped>
  203. .caseInfo_wrap {
  204. min-height: 400px;
  205. .caseInfo_title {
  206. display: flex;
  207. align-items: center;
  208. height: 80rpx;
  209. background: #f4f4f6;
  210. padding-left: 40rpx;
  211. image {
  212. width: 24rpx;
  213. height: 24rpx;
  214. margin-right: 10rpx;
  215. }
  216. .info_text {
  217. font-size: 24rpx;
  218. color: #202020;
  219. }
  220. .tabs_wrap {
  221. display: flex;
  222. .tab_item {
  223. margin-left: 30rpx;
  224. }
  225. }
  226. }
  227. .caseInfo_main_wrap {
  228. .caseCards_list_wrap {
  229. background: #ebf6ff;
  230. margin-bottom: 10rpx;
  231. margin-left: 10rpx;
  232. margin-right: 10rpx;
  233. }
  234. .Info_item {
  235. padding: 18rpx 40rpx;
  236. display: flex;
  237. justify-content: space-between;
  238. .label {
  239. color: #999999;
  240. font-size: 26rpx;
  241. }
  242. .input_wrap {
  243. border-bottom: 1px solid #ddd;
  244. }
  245. .value {
  246. font-size: 26rpx;
  247. color: #202020;
  248. border-radius: 100rpx;
  249. }
  250. .highlight {
  251. font-size: 22rpx;
  252. font-weight: 900;
  253. padding: 6rpx 20rpx;
  254. }
  255. }
  256. }
  257. }
  258. </style>