LowerList.tsx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. import { Button, Popconfirm, Tabs } from 'antd'
  2. import React, { useMemo } from 'react'
  3. import { dayjsFormat } from '@/utils/utils'
  4. import classNames from 'classnames'
  5. import { isDevMode } from '@/utils/env'
  6. import { VList } from 'virtuallist-antd'
  7. import consts from '@/consts'
  8. import type { ProColumns } from '@ant-design/pro-table'
  9. import ProTable from '@ant-design/pro-table'
  10. import {
  11. updateCustomerService,
  12. delCustomerService,
  13. updateClientService,
  14. delClientService
  15. } from '@/services/customer'
  16. import { useModal } from '@/components/ModalStore'
  17. import { useDispatch, useRequest } from 'umi'
  18. const { TabPane } = Tabs
  19. export enum Servicelog {
  20. /** 上门服务 */
  21. VISIT = '1',
  22. /** 电话拜访 */
  23. CALL = '2',
  24. /** 其他事项 */
  25. OTHER = '3',
  26. /** 在线服务 */
  27. ONLINE = '4'
  28. }
  29. export enum ServiceLogType {
  30. CLIENT,
  31. COMPANY
  32. }
  33. export const servicelogEnum = {
  34. [Servicelog.VISIT]: {
  35. title: '上门服务',
  36. bg: 'bg-hex-886ab5',
  37. text: 'text-hex-886ab5',
  38. border: 'border-hex-886ab5'
  39. },
  40. [Servicelog.CALL]: {
  41. title: '电话拜访',
  42. bg: 'bg-hex-246daf',
  43. text: 'text-hex-246daf',
  44. border: 'border-hex-246daf'
  45. },
  46. [Servicelog.OTHER]: {
  47. title: '其他事项',
  48. bg: 'bg-hex-1ca081',
  49. text: 'text-hex-1ca081',
  50. border: 'border-hex-1ca081'
  51. },
  52. [Servicelog.ONLINE]: {
  53. title: '在线服务',
  54. bg: 'bg-hex-b8795e',
  55. text: 'text-hex-b8795e ',
  56. border: 'border-hex-b8795e'
  57. }
  58. }
  59. type ClientLowerListProps = {
  60. logList: {
  61. log: any[]
  62. }
  63. serviceList: API.ServiceLogItem[]
  64. updatePayload: { main: string; target: string }
  65. }
  66. type ServiceLogItemProps = {
  67. item: API.ServiceLogItem
  68. logType: ServiceLogType
  69. updatePayload: { main: string; target: string }
  70. }
  71. export const ServiceLogItem: React.FC<ServiceLogItemProps> = ({ item, logType, updatePayload }) => {
  72. const dispatchModal = useModal()
  73. const dispatch = useDispatch()
  74. const { run: truUpdate } = useRequest(
  75. logType === ServiceLogType.COMPANY ? updateCustomerService : updateClientService,
  76. {
  77. manual: true,
  78. onSuccess: () => {
  79. dispatch({
  80. type: 'refresh/commitAction',
  81. payload: updatePayload
  82. })
  83. }
  84. }
  85. )
  86. const { run: truDel } = useRequest(
  87. logType === ServiceLogType.COMPANY ? delCustomerService : delClientService,
  88. {
  89. manual: true,
  90. onSuccess: () => {
  91. dispatch({
  92. type: 'refresh/commitAction',
  93. payload: updatePayload
  94. })
  95. }
  96. }
  97. )
  98. const handleOnEdit = async (defaultValues: API.ServiceLogItem) => {
  99. dispatchModal('M_RECORD_ADD', { defaultValues, onConfirm: truUpdate })
  100. }
  101. return (
  102. <div
  103. className={classNames(
  104. 'w-full rounded border-l-2px bg-opacity-6',
  105. servicelogEnum[item.status]?.bg,
  106. servicelogEnum[item.status]?.border
  107. )}>
  108. <div className="p-3 flex flex-col">
  109. <div className="flex justify-between">
  110. <div className="flex">
  111. <div
  112. className="rounded-1/2 w-8 h-8"
  113. style={{
  114. backgroundImage: `url(${
  115. (isDevMode() ? 'http://cld2qa.com' : 'http://zhcld.com') +
  116. (item.avatar ?? consts.DEFAULT_AVATAR)
  117. })`,
  118. backgroundSize: 'cover'
  119. }}
  120. />
  121. <div className="flex flex-col items-center ml-2">
  122. <div className="text-sm font-medium text-opacity-80 text-black">{item.staffName}</div>
  123. <div className="text-xs text-opacity-40 text-black h-4">
  124. {dayjsFormat(item.createTime, 'HH:mm:ss')}
  125. </div>
  126. </div>
  127. </div>
  128. <div className="flex flex-nowrap">
  129. <div className={classNames(servicelogEnum[item.status]?.text, 'font-medium text-sm')}>
  130. {servicelogEnum[item.status]?.title}
  131. </div>
  132. <div
  133. className={classNames(
  134. 'ml-1 text-xs bg-opacity-16 rounded-sm h-5 leading-5 px-1',
  135. servicelogEnum[item.status]?.text,
  136. servicelogEnum[item.status]?.bg
  137. )}>
  138. {dayjsFormat(item.date, 'YYYY-MM-DD')}
  139. </div>
  140. </div>
  141. </div>
  142. <div className="bg-white bg-opacity-80 rounded-sm text-black text-opacity-60 text-sm mt-3 p-2">
  143. {item.mark}
  144. </div>
  145. {item.isOperation ? (
  146. <div className="mt-2">
  147. <Button size="small" onClick={() => handleOnEdit(item)}>
  148. 编辑
  149. </Button>
  150. <Popconfirm title="确认删除该服务记录吗?" onConfirm={() => truDel({ id: item.id })}>
  151. <Button size="small" danger className="ml-1">
  152. 删除
  153. </Button>
  154. </Popconfirm>
  155. </div>
  156. ) : null}
  157. </div>
  158. </div>
  159. )
  160. }
  161. const ClientLowerList: React.FC<ClientLowerListProps> = ({
  162. logList: { log: logs = [] },
  163. serviceList,
  164. updatePayload
  165. }) => {
  166. const tableHeight = (document.body.clientHeight - 124 - 78) / 2
  167. const columns: ProColumns<API.LogItem>[] = [
  168. {
  169. title: '日期',
  170. dataIndex: 'createTime',
  171. key: 'createTime',
  172. width: 160
  173. },
  174. {
  175. title: '操作人',
  176. dataIndex: 'operatorName',
  177. key: 'operatorName',
  178. ellipsis: true,
  179. width: 115
  180. },
  181. {
  182. title: '操作',
  183. dataIndex: 'operationType',
  184. key: 'operationType',
  185. ellipsis: true,
  186. width: 120
  187. },
  188. {
  189. title: '操作内容',
  190. dataIndex: 'content',
  191. key: 'content',
  192. ellipsis: true
  193. }
  194. ]
  195. const vList = useMemo(() => {
  196. return VList({
  197. height: tableHeight,
  198. vid: 'client_log_list'
  199. })
  200. }, [])
  201. return (
  202. <div>
  203. <div className="pl-4">
  204. <Tabs>
  205. <TabPane tab="客户服务记录" key="客户服务记录">
  206. <div className="sheet-panel-record">
  207. {serviceList.map(item => (
  208. <div className="mb-3" key={item.id}>
  209. <ServiceLogItem item={item} logType={ServiceLogType.CLIENT} updatePayload={updatePayload} />
  210. </div>
  211. ))}
  212. </div>
  213. </TabPane>
  214. <TabPane tab="日志" key="日志">
  215. <div className="sheet-panel-record">
  216. <ProTable<API.LogItem>
  217. search={false}
  218. toolBarRender={false}
  219. rowKey="id"
  220. size="small"
  221. columns={columns}
  222. dataSource={logs}
  223. pagination={false}
  224. scroll={{ y: tableHeight }}
  225. components={vList}
  226. />
  227. </div>
  228. </TabPane>
  229. </Tabs>
  230. </div>
  231. </div>
  232. )
  233. }
  234. export default ClientLowerList