|
|
@@ -0,0 +1,362 @@
|
|
|
+import React, { useState, useEffect, useRef } from 'react'
|
|
|
+import { Modal, Form, Select, Input, Spin, Button, Radio, Popconfirm, message } from 'antd'
|
|
|
+import styles from './index.less'
|
|
|
+import { SearchOutlined } from '@ant-design/icons'
|
|
|
+import { queryClient } from '@/services/customer'
|
|
|
+import { queryLock } from '@/services/product'
|
|
|
+import consts from '@/basic/consts'
|
|
|
+import { useDebounceFn } from 'ahooks'
|
|
|
+import { apiSoftwareAddLonglelog } from '@/services/product'
|
|
|
+import { useDispatch, connect } from 'umi'
|
|
|
+// import { createUid } from '@/utils/utils'
|
|
|
+// import DragIniter from '@/components/Modal/src/components/DragIniter'
|
|
|
+import { ProFormTextArea } from '@ant-design/pro-form'
|
|
|
+
|
|
|
+export const lockTypeEnum = {
|
|
|
+ REMARK: 0, // 备注
|
|
|
+ UPDATE: 1, // 升级
|
|
|
+ CHANGE: 2, // 更换
|
|
|
+ RECOVER: 3, // 收回
|
|
|
+ RECEIVE: 5, // 接收
|
|
|
+ SALE: 6
|
|
|
+}
|
|
|
+
|
|
|
+const LockModal = props => {
|
|
|
+ const modalTitleEnum = {
|
|
|
+ 1: '升级软件锁',
|
|
|
+ 0: '备注信息',
|
|
|
+ 3: '确认收回',
|
|
|
+ 5: '确认接收'
|
|
|
+ }
|
|
|
+ const placeholderEnum = {
|
|
|
+ 6: '搜索客户(姓名、手机、QQ、公司名称)',
|
|
|
+ 2: '输入新锁号'
|
|
|
+ }
|
|
|
+ const [form] = Form.useForm()
|
|
|
+ const dispatch = useDispatch()
|
|
|
+ const scrollRef = useRef()
|
|
|
+ const { visible, onCancel, onConfirm, loading, type, longleId, keyNum, prodList } = props
|
|
|
+ const layout = {
|
|
|
+ layout: 'vertical'
|
|
|
+ }
|
|
|
+ const [state, setState] = useState({
|
|
|
+ loading: false,
|
|
|
+ longle: [],
|
|
|
+ client: [],
|
|
|
+ search: '',
|
|
|
+ sellStatus: 1,
|
|
|
+ noMore: false,
|
|
|
+ current: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ total: 0
|
|
|
+ })
|
|
|
+
|
|
|
+ // 获取软件锁产品列表
|
|
|
+ function fetchSoftProducts() {
|
|
|
+ dispatch({
|
|
|
+ type: 'lock/fetchProdList',
|
|
|
+ payload: 'longleId'
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const initData = async params => {
|
|
|
+ setState({ ...state, loading: true })
|
|
|
+ if (type === lockTypeEnum.CHANGE) {
|
|
|
+ const { data: { longle, total } = { longle: [], total: 0 }, code = -1 } = await queryLock({
|
|
|
+ ...params,
|
|
|
+ waiver: true
|
|
|
+ })
|
|
|
+ if (code === consts.RET_CODE.SUCCESS) {
|
|
|
+ if (params?.current === 1) {
|
|
|
+ scrollRef.current?.scrollTo({ top: 0 })
|
|
|
+ // 请求的是第一页
|
|
|
+ setState({ ...state, longle, total, loading: false, ...params })
|
|
|
+ } else {
|
|
|
+ setState({
|
|
|
+ ...state,
|
|
|
+ longle: state.longle.concat(longle),
|
|
|
+ total,
|
|
|
+ loading: false,
|
|
|
+ ...params
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (type === lockTypeEnum.SALE) {
|
|
|
+ const { data: { client, total } = { client: [], total: 0 }, code = -1 } = await queryClient({
|
|
|
+ ...params,
|
|
|
+ waiver: true
|
|
|
+ })
|
|
|
+ if (code === consts.RET_CODE.SUCCESS) {
|
|
|
+ if (params?.current === 1) {
|
|
|
+ scrollRef.current?.scrollTo({ top: 0 })
|
|
|
+ // 请求的是第一页
|
|
|
+ setState({
|
|
|
+ ...state,
|
|
|
+ client,
|
|
|
+ total,
|
|
|
+ loading: false,
|
|
|
+ ...params
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ setState({
|
|
|
+ ...state,
|
|
|
+ client: state.client.concat(client),
|
|
|
+ total,
|
|
|
+ loading: false,
|
|
|
+ ...params
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const onChange = e => {
|
|
|
+ const { value = '' } = e.target || e.currentTarget
|
|
|
+ if (type === lockTypeEnum.CHANGE || type === lockTypeEnum.SALE) {
|
|
|
+ const params = { search: value, current: 1, pageSize: state.pageSize }
|
|
|
+ if (type === lockTypeEnum.SALE) {
|
|
|
+ params.sellStatus = state.sellStatus
|
|
|
+ }
|
|
|
+ initData(params)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const { run: handleInputChange } = useDebounceFn(onChange)
|
|
|
+ useEffect(() => {
|
|
|
+ if (visible) {
|
|
|
+ if (type === lockTypeEnum.CHANGE) {
|
|
|
+ initData({ current: 1, pageSize: 10 })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (type === lockTypeEnum.SALE) {
|
|
|
+ initData({ current: 1, pageSize: 10, sellStatus: state.sellStatus })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ form.resetFields()
|
|
|
+ if (type === lockTypeEnum.RECOVER) {
|
|
|
+ form.setFieldsValue({ longleId })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, [visible, type])
|
|
|
+
|
|
|
+ const handleonOk = () => {
|
|
|
+ form.validateFields().then(values => {
|
|
|
+ onConfirm({ ...values, preserveStatus: type })
|
|
|
+ dispatch({
|
|
|
+ type: 'refresh/commitAction',
|
|
|
+ payload: 'longle'
|
|
|
+ })
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const checkGroupOnChange = e => {
|
|
|
+ // const logStatusEnum = {
|
|
|
+ // 3: 1,
|
|
|
+ // 4: 2,
|
|
|
+ // 9: 3
|
|
|
+ // }
|
|
|
+ const { value = '' } = e.target || {}
|
|
|
+ initData({
|
|
|
+ // logStatus: logStatusEnum[state.logStatus],
|
|
|
+ sellStatus: value,
|
|
|
+ current: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ search: state.search
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 关联客户
|
|
|
+ const connectClient = async id => {
|
|
|
+ const { code = -1 } = await apiSoftwareAddLonglelog({
|
|
|
+ clientId: id,
|
|
|
+ sellStatus: state.sellStatus,
|
|
|
+ longleId
|
|
|
+ })
|
|
|
+ if (code === consts.RET_CODE.SUCCESS) {
|
|
|
+ message.success('新增成功')
|
|
|
+ dispatch({
|
|
|
+ type: 'refresh/commitAction',
|
|
|
+ payload: 'longle'
|
|
|
+ })
|
|
|
+ onCancel()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 更换软件锁
|
|
|
+ const connectLongle = async id => {
|
|
|
+ const { code = -1 } = await apiSoftwareAddLonglelog({
|
|
|
+ newLongleId: id,
|
|
|
+ preserveStatus: type,
|
|
|
+ longleId
|
|
|
+ })
|
|
|
+ if (code === consts.RET_CODE.SUCCESS) {
|
|
|
+ message.success('新增成功')
|
|
|
+ dispatch({
|
|
|
+ type: 'refresh/commitAction',
|
|
|
+ payload: 'longle'
|
|
|
+ })
|
|
|
+ onCancel()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleListScroll = () => {
|
|
|
+ // 未滚动到底部
|
|
|
+ if (
|
|
|
+ scrollRef.current.scrollHeight - scrollRef.current.clientHeight <=
|
|
|
+ scrollRef.current.scrollTop
|
|
|
+ ) {
|
|
|
+ // 已到底部
|
|
|
+ if (state.current * state.pageSize > state.total) {
|
|
|
+ setState({ ...state, noMore: true })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const params = { current: state.current + 1, pageSize: state.pageSize, search: state.search }
|
|
|
+ if (type === lockTypeEnum.SALE) params.sellStatus = state.sellStatus
|
|
|
+ state.current * state.pageSize < state.total && initData(params)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Modal
|
|
|
+ getContainer={false}
|
|
|
+ title={
|
|
|
+ modalTitleEnum[type] ?? (
|
|
|
+ <Input
|
|
|
+ className={styles.inputSearch}
|
|
|
+ placeholder={placeholderEnum[type]}
|
|
|
+ prefix={<SearchOutlined />}
|
|
|
+ onChange={handleInputChange}
|
|
|
+ allowClear={true}
|
|
|
+ />
|
|
|
+ )
|
|
|
+ }
|
|
|
+ visible={visible}
|
|
|
+ confirmLoading={loading}
|
|
|
+ onCancel={onCancel}
|
|
|
+ width={800}
|
|
|
+ footer={
|
|
|
+ type !== lockTypeEnum.UPDATE &&
|
|
|
+ type !== lockTypeEnum.RECOVER &&
|
|
|
+ type !== lockTypeEnum.RECEIVE &&
|
|
|
+ type !== lockTypeEnum.REMARK ? null : (
|
|
|
+ <div>
|
|
|
+ <Button className="mr-3" onClick={onCancel}>
|
|
|
+ 取消
|
|
|
+ </Button>
|
|
|
+ <Button key="submit" type="primary" loading={loading} onClick={handleonOk}>
|
|
|
+ 确定
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }>
|
|
|
+ {type === lockTypeEnum.SALE ? (
|
|
|
+ <div className="text-center mb-6">
|
|
|
+ <Radio.Group value={state.sellStatus} buttonStyle="solid" onChange={checkGroupOnChange}>
|
|
|
+ <Radio.Button value={1}>借出</Radio.Button>
|
|
|
+ <Radio.Button value={2}>销售</Radio.Button>
|
|
|
+ <Radio.Button value={3}>赠送</Radio.Button>
|
|
|
+ </Radio.Group>
|
|
|
+ </div>
|
|
|
+ ) : null}
|
|
|
+ {type === lockTypeEnum.CHANGE || type === lockTypeEnum.SALE ? (
|
|
|
+ <div
|
|
|
+ className={styles.modalContainer}
|
|
|
+ ref={scrollRef}
|
|
|
+ onScroll={handleListScroll}
|
|
|
+ style={{ paddingBottom: 0 }}>
|
|
|
+ <div className={styles.modalContent}>
|
|
|
+ <Spin spinning={state.loading}>
|
|
|
+ {type === lockTypeEnum.SALE &&
|
|
|
+ state.client.map((item, index) => (
|
|
|
+ <div key={index} className={styles.card}>
|
|
|
+ <span className="w-1/6">{item.clientName}</span>
|
|
|
+ <span className="w-1/6">{item.position}</span>
|
|
|
+ <span className="w-1/6">{item.telephone}</span>
|
|
|
+ <span className="w-1/2 flex justify-between">
|
|
|
+ <span>{item.companyName}</span>
|
|
|
+ <Popconfirm
|
|
|
+ title="确认选择ta"
|
|
|
+ onConfirm={() => connectClient(item.id)}
|
|
|
+ okText="确认"
|
|
|
+ cancelText="取消">
|
|
|
+ <Button type="primary" size="small">
|
|
|
+ 选择ta
|
|
|
+ </Button>
|
|
|
+ </Popconfirm>
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ {type === lockTypeEnum.CHANGE &&
|
|
|
+ state.longle.map(item => (
|
|
|
+ <div key={item.id} className={styles.card}>
|
|
|
+ <div className="w-1/3">{item.keyNum}</div>
|
|
|
+ <div className="w-2/3 flex justify-between">
|
|
|
+ <span>{item.product}</span>
|
|
|
+ <Popconfirm
|
|
|
+ title="确认选择ta"
|
|
|
+ onConfirm={() => connectLongle(item.id)}
|
|
|
+ okText="确认"
|
|
|
+ cancelText="取消">
|
|
|
+ <Button type="primary" size="small">
|
|
|
+ 更换
|
|
|
+ </Button>
|
|
|
+ </Popconfirm>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </Spin>
|
|
|
+ {state.noMore && <div className="text-center text-gray-400 my-4">已到底部</div>}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ <Form {...layout} form={form}>
|
|
|
+ {type === lockTypeEnum.UPDATE ? (
|
|
|
+ <>
|
|
|
+ <Form.Item name="product" label="新增产品">
|
|
|
+ <Select
|
|
|
+ placeholder="请选择产品"
|
|
|
+ onDropdownVisibleChange={async e => {
|
|
|
+ e && !prodList?.length && (await fetchSoftProducts())
|
|
|
+ }}
|
|
|
+ options={prodList.map(item => ({ value: item.title }))}
|
|
|
+ />
|
|
|
+ </Form.Item>
|
|
|
+ </>
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ {type === lockTypeEnum.REMARK ? (
|
|
|
+ <>
|
|
|
+ <ProFormTextArea name="mark" label="备注" />
|
|
|
+ </>
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ {type === lockTypeEnum.RECOVER ? (
|
|
|
+ <>
|
|
|
+ <p>
|
|
|
+ 收回锁号 <b>{keyNum}</b>
|
|
|
+ </p>
|
|
|
+ <Form.Item name="longleId" hidden>
|
|
|
+ <Input />
|
|
|
+ </Form.Item>
|
|
|
+ </>
|
|
|
+ ) : null}
|
|
|
+
|
|
|
+ {type === lockTypeEnum.RECEIVE ? (
|
|
|
+ <>
|
|
|
+ <p>
|
|
|
+ 确认接收锁 <b>{keyNum}</b>
|
|
|
+ </p>
|
|
|
+ <Form.Item name="longleId" hidden>
|
|
|
+ <Input />
|
|
|
+ </Form.Item>
|
|
|
+ </>
|
|
|
+ ) : null}
|
|
|
+ </Form>
|
|
|
+ </Modal>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+export default connect(({ lock }) => ({
|
|
|
+ prodList: lock.prodList
|
|
|
+}))(LockModal)
|