feat:客户管理对接85%

This commit is contained in:
Haiyi 2022-10-27 18:24:18 +08:00
parent bd494b1759
commit 05e9e4d532
13 changed files with 234 additions and 64 deletions

View File

@ -7,3 +7,17 @@ export const mppurchaser = () => {
method: "get",
})
}
//新建客户
export const mppurchaserpost = () => {
return useRequest({
url: `/v1/mp/purchaser`,
method: "post",
})
}
//编辑客户
export const mppurchaserput = () => {
return useRequest({
url: `/v1/mp/purchaser`,
method: "put",
})
}

View File

@ -15,6 +15,7 @@ export const BASE_URL = CURRENT_BASE_URL
// export const BASE_URL = `http://192.168.1.7:50002/lymarket` // 添
// export const BASE_URL = `http://192.168.1.42:50002/lymarket` // 杰
// export const BASE_URL = `http://192.168.1.95:40001/lymarket` // 华
// export const BASE_URL = 'http://192.168.1.22:50002/lymarket' // 婷
// CDN
// 生成密钥

View File

@ -140,8 +140,12 @@ const AddressList = memo(forwardRef((props: Params, AddressListRef) => {
<IconFont name={'icon-bianji'} size={40} ></IconFont>
</Navigator>
</View>
<View className='line'></View>
<View className='bottom-font'></View>
{
item.factory !== '' && <>
<View className='line'></View>
<View className='bottom-font'>{item.factory}</View></>
}
</View>
);
}) :

View File

@ -15,13 +15,14 @@
.leftBox {
width: 176px;
font-size: 28px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #000000;
display: flex;
align-items: center;
margin-right: 50px;
// margin-right: 50px;
}
.inputClass {
@ -46,13 +47,14 @@
margin-bottom: 40px;
.leftBox {
width: 176px;
font-size: 28px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #000000;
display: flex;
align-items: center;
padding-right: 25px;
// padding-right: 25px;
}
.inputClass {
@ -78,7 +80,8 @@
color: #000000;
display: flex;
align-items: center;
margin-right: 50px;
// margin-right: 50px;
width: 176px;
}
.inputClass {

View File

@ -19,6 +19,13 @@ export default () => {
type: 'text',
value: '',
},
{
title: '加工厂',
require: false,
placeholderFont: '请输入加工厂(选填)',
type: 'text',
value: '',
},
{
title: '联系方式',
require: true,
@ -48,7 +55,7 @@ export default () => {
const [ischecked, setIsChecked] = useState(false)
const onChange = (eq) => {
setIsChecked(eq.detail.value)
setFormData((e) => ({ ...e, is_default: eq.detail.value, address_detail: itemList[3].value }))
setFormData((e) => ({ ...e, is_default: eq.detail.value, address_detail: itemList[4].value }))
}
const router = useRouter()
@ -70,9 +77,11 @@ export default () => {
address_detail: "",
is_default: false,
id: '',
factory: '',
})
//获取相应id的信息
const { fetchData: infoFetch } = mppurchaseraddressget()
const [infoObj, setinfoObj] = useState<any>()
const getInfo = async () => {
let res = await infoFetch({
id: router.params.id,
@ -93,9 +102,10 @@ export default () => {
district_id: res.data.district_id,
is_default: res.data.is_default,
id: res.data.id,
factory: res.data.factory
// purchaser_id: res.data.purchaser_id
})
setinfoObj(res.data)
itemList.map(item => {
if (item.title === '联系人') {
item.value = res.data.name
@ -109,6 +119,9 @@ export default () => {
if (item.title === '详细地址') {
item.value = res.data.address_detail
}
if (item.title === '加工厂') {
item.value = res.data.factory
}
return item
})
setItemList([...itemList])
@ -124,7 +137,7 @@ export default () => {
const obj = itemList.filter(item => {
return item.value !== ''
})
if (obj.length !== 4) {
if (obj.length < 4) {
canShow = true
} else {
canShow = false
@ -152,13 +165,14 @@ export default () => {
}
setFormData({
name: itemList[0]?.value,
phone: itemList[1]?.value,
phone: itemList[2]?.value,
site: addressName.join(' '),
district_id: ev[ev.length - 1]?.id,
is_default: ischecked,
address_detail: itemList[3]?.value,
id: router.params.id ? router.params.id : '',
siteArray: ev
id: infoObj?.id ? infoObj?.id : '',
siteArray: ev,
factory: itemList[1]?.value
})
}
@ -182,7 +196,7 @@ export default () => {
return it
})
setItemList([...itemList])
setFormData((e) => ({ ...e, name: itemList[0].value, phone: itemList[1].value, address_detail: itemList[3].value }))
setFormData((e) => ({ ...e, name: itemList[0].value, phone: itemList[2].value, address_detail: itemList[4].value, factory: itemList[1].value }))
}
@ -202,6 +216,7 @@ export default () => {
//新增地址
const { fetchData: addAddressFetch } = mppurchaseraddress()
const handAdd = async () => {
if (!btnDisabled) return false
let res = await addAddressFetch({ ...getFilterData(formData), purchaser_id: Number(router.params.purchaser_id) })
if (res.data) {
Taro.showToast({
@ -219,7 +234,8 @@ export default () => {
// 编辑地址
const { fetchData: putFetch } = mppurchaseraddressput()
const handEdit = async () => {
let res = await putFetch({ ...getFilterData(formData), purchaser_id: Number(router.params.purchaser_id), id: Number(router.params.purchaser_id) })
if (!btnDisabled) return false
let res = await putFetch({ ...getFilterData(formData), purchaser_id: Number(router.params.purchaser_id), id: Number(infoObj?.id) })
if (res.msg === 'success') {
Taro.showToast({
title: '成功',
@ -264,7 +280,10 @@ export default () => {
return (
<View className={styles.itemBox} key={index}>
<View className={styles.leftBox}>
{item.title}<Text style={{ color: 'red' }}>*</Text>
{item.title}
{
item.require && <Text style={{ color: 'red' }}>*</Text>
}
</View>
<Input
maxlength={item.maxLength ? 11 : 100}

View File

@ -68,8 +68,8 @@ export default () => {
<View className={styles.itemPhone}>{infoObj?.phone}</View>
</View>
<View className={styles.item_tag_box}>
<View className={styles.item_tagItem}></View>
<View className={styles.item_tagItem}>{infoObj?.sale_user_name}</View>
<View className={styles.item_tagItem}>{infoObj?.purchaser_type_name || '暂无'}</View>
<View className={styles.item_tagItem}>{infoObj?.sale_user_name || '暂无'}</View>
<View className={styles.item_tagAdd} onClick={() => setshowPopup(true)}>
<View className={styles.item_add}>+</View>
<View className={styles.item_add_font}></View>
@ -82,21 +82,21 @@ export default () => {
</View>
{
status === 1 && <View className={styles.formBox}>
<Form title={'客户全称'} des={infoObj?.name} ></Form>
<Form title={'客户简称'} des={infoObj?.short_name} ></Form>
<Form title={'客户类型'} des={infoObj?.purchaser_type_name} ></Form>
<Form title={'联系人'} des={infoObj?.director} ></Form>
<Form title={'联系电话'} des={infoObj?.phone} isPhone></Form>
<Form title={'省市区'} des={infoObj?.province_name + infoObj?.city_name + infoObj?.district_name} ></Form>
<Form title={'详细地址'} des={infoObj?.address_detail} ></Form>
<Form title={'业务人员'} des={infoObj?.sale_user_name} ></Form>
<Form title={'客户来源'} des={infoObj?.qqq} ></Form>
<Form title={'备注信息'} des={infoObj?.qqqq} ></Form>
<Form title={'下单时间'} des={infoObj?.qqq} ></Form>
<Form title={'创建时间'} des={infoObj?.qqqq} ></Form>
<Form title={'创建人'} des={infoObj?.qqqq} ></Form>
<Form title={'更新人'} des={infoObj?.qqqqq} ></Form>
<Form title={'更新时间'} des={infoObj?.qqqqq} isBorder={false}></Form>
<Form title={'客户全称'} des={infoObj?.name || '暂无'} ></Form>
<Form title={'客户简称'} des={infoObj?.short_name || '暂无'} ></Form>
<Form title={'客户类型'} des={infoObj?.purchaser_type_name || '暂无'} ></Form>
<Form title={'联系人'} des={infoObj?.director || '暂无'} ></Form>
<Form title={'联系电话'} des={infoObj?.phone || '暂无'} isPhone></Form>
<Form title={'省市区'} des={infoObj?.province_name + infoObj?.city_name + infoObj?.district_name || '暂无'} ></Form>
<Form title={'详细地址'} des={infoObj?.address_detail || '暂无'} ></Form>
<Form title={'业务人员'} des={infoObj?.sale_user_name || '暂无'} ></Form>
<Form title={'客户来源'} des={infoObj?.purchaser_source_name || '暂无'} ></Form>
<Form title={'备注信息'} des={infoObj?.remark || '暂无'} ></Form>
<Form title={'下单时间'} des={formatDateTime(infoObj?.recent_order_time) || '暂无'} ></Form>
<Form title={'创建时间'} des={formatDateTime(infoObj?.create_time) || '暂无'} ></Form>
<Form title={'创建人'} des={infoObj?.creator || '暂无'} ></Form>
<Form title={'更新人'} des={infoObj?.update_user_name || '暂无'} ></Form>
<Form title={'更新时间'} des={formatDateTime(infoObj?.update_time) || '暂无'} isBorder={false}></Form>
</View>
}
{

View File

@ -10,7 +10,7 @@ import { formatPriceDiv, formatDateTime, formatWeightDiv } from '@/common/format
import Form from "./components/form"
import Remark from '../orderDetails/components/remark';
import Address from "@/components/address"
import { mppurchaser } from '@/api/customer'
import { mppurchaser, mppurchaserpost, mppurchaserput } from '@/api/customer'
export default () => {
@ -20,12 +20,18 @@ export default () => {
const [formData, setformData] = useState<any>()
useEffect(() => {
if (router.params.type === 'edit') {
getInfo()
}
}, [])
//默认业务员
useDidShow(() => {
if (router.params.type === 'add') {
setNavigationBarTitle({ title: "新增客户" })
} else {
getInfo()
setNavigationBarTitle({ title: "客户编辑" })
}
let userInfo = JSON.parse(Taro.getStorageSync('userInfo'))
@ -34,8 +40,8 @@ export default () => {
let currPage = pages[pages.length - 1]; // 获取当前页面
//判断是否有跳转选择业务员
if (currPage.data?.saleuserId && currPage.data?.saleuserId !== '') {
setformData((e) => ({
...e,
setformData((val) => ({
...val,
sale_user_id: currPage.data?.saleuserId,
sale_user_name: currPage.data?.saleuserName
}))
@ -78,8 +84,8 @@ export default () => {
address_detail: res.data?.address_detail,
purchaser_type: res.data?.purchaser_type,
district_id: res.data?.district_id
// remark: res.data?.remark
})
setremarkDesc(res.data?.remark)
Taro.hideLoading()
}
@ -140,10 +146,12 @@ export default () => {
}
//备注操作
const [remarkDesc, setremarkDesc] = useState('')
const [showDesc, setShowDesc] = useState(false)
const getRemark = useCallback(async (e) => {
setShowDesc(false)
setformData((val) => ({ ...val, remark: e }))
setremarkDesc(e)
// setformData((val) => ({ ...val, remark: e }))
}, [])
//地址选择
@ -198,6 +206,48 @@ export default () => {
})
}
const { fetchData: postFetch } = mppurchaserpost()
const { fetchData: putFetch } = mppurchaserput()
//提交
const handSure = async () => {
if (!isDisabled) return false
let query = {
...formData,
remark: remarkDesc,
id: infoObj?.id
}
if (router.params.type == 'add') {
delete query.id
}
Taro.showModal({
content: "确定要提交吗?",
confirmText: "确认",
cancelText: "取消",
success: async function (res) {
if (res.confirm) {
const res = await (router.params.type == 'add' ? postFetch(query) : putFetch(query))
Taro.showLoading({
title: '请稍等...',
mask: true
})
if (res.msg === 'success') {
Taro.showToast({
title: '成功'
})
Taro.hideLoading()
Taro.navigateBack({
delta: 1
})
} else {
Taro.showToast({
title: res.msg,
icon: 'error'
})
}
}
}
})
}
return (
@ -269,7 +319,7 @@ export default () => {
></Form>
</View>
<DefaultBox title={'备注信息'} showMode={true} modeName={`${'填写/修改备注'} >`} clickNode={() => setShowDesc(true)}>
<View className={styles.remarkFont}>{infoObj?.remark === '' ? '尚未备注信息' : infoObj?.remark}</View>
<View className={styles.remarkFont}>{remarkDesc === '' ? '尚未备注信息' : remarkDesc}</View>
</DefaultBox>
<Popup show={showDesc} showTitle={false} onClose={() => setShowDesc(false)}>
<Remark onSave={(e) => getRemark(e)} defaultValue={infoObj?.remark} showInput={showDesc ? true : false} />

View File

@ -1,5 +1,5 @@
import { View, ScrollView } from '@tarojs/components'
import React, { useCallback, memo, useEffect, useMemo, useRef, useState, ReactNode } from 'react'
import React, { useCallback, memo, useEffect, useMemo, useRef, useState, ReactNode, forwardRef, useImperativeHandle } from 'react'
import styles from "./index.module.scss"
import classnames from "classnames";
import Taro, { usePullDownRefresh, useRouter, useDidShow } from '@tarojs/taro';
@ -10,15 +10,19 @@ import { GetAddressListApi } from "@/api/addressList";
import Tabs from "../tabs"
import IconFont from '@/components/iconfont/iconfont';
interface Props {
handCity?: (any) => void
handCity?: (province: any, city: any) => void
}
export default memo((props: Props) => {
export default memo(forwardRef((props: Props, ref) => {
useImperativeHandle(ref, () => ({
close
}))
const DropDownItemRef = useRef<any>()
// const close = () => {
// DropDownItemRef.current.closePopup()
// }
const close = () => {
DropDownItemRef.current.closePopup()
}
//获取地址
const { fetchData } = GetAddressListApi()
@ -36,7 +40,9 @@ export default memo((props: Props) => {
}
//已选的集合市
// const [choseCityArr, setchoseCityArr] = useState<any[]>([])
const choseCityArr = useRef<any>({ list: [] })
//省数组
const [list, setlist] = useState<any[]>([])
@ -65,8 +71,6 @@ export default memo((props: Props) => {
list.map(it => {
if (item.id == it.id) {
it.check = true
} else {
it.check = false
}
return it
})
@ -77,7 +81,6 @@ export default memo((props: Props) => {
if (it.id == currentValue) {
it.name = item.name
it.showBorder = false
} else {
it.showBorder = true
}
@ -91,6 +94,14 @@ export default memo((props: Props) => {
const getCity = async (id) => {
let res = await fetchData({ parent_id: id })
if (res.data) {
res.data.list.map(item => {
choseCityArr.current.list.forEach(it => {
if (item.id == it.id) {
item.check = true
}
})
return item
})
setcityList([...res.data.list])
}
}
@ -105,10 +116,32 @@ export default memo((props: Props) => {
return it
})
setcityList([...cityList])
let arr = cityList.filter(next => { return next.check })
props.handCity?.(arr)
let provinceArr = list.filter(next => { return next.check })
if (item.check) {
choseCityArr.current.list.push(item)
} else {
deleteById(item.id, choseCityArr.current.list)
}
props.handCity?.(provinceArr, choseCityArr.current.list)
}
/**
* id删除数组项
* @param {Number} id id
* @param {Array} list
*
* @return {Array}
*/
function deleteById(id, list) {
for (let index = list.length - 1; index >= 0; index--) {
if (list[index] && list[index].id === id) {
list.splice(index, 1)
}
}
return list
}
return (
<DropDownItem ref={DropDownItemRef} title={'所有省市'} value={-1} activeColor='#337fff'>
<View className={styles.mainBox}>
@ -144,4 +177,4 @@ export default memo((props: Props) => {
</View>
</DropDownItem>
)
})
}))

View File

@ -37,7 +37,7 @@ export default memo((props: Props) => {
</View>
<View className={styles.item_tag_box}>
<View className={styles.item_tagItem}></View>
<View className={styles.item_tagItem}>{props.obj.sale_user_name}</View>
<View className={styles.item_tagItem}>{props.obj.sale_user_name || '暂无'}</View>
</View>
</View>
</View>
@ -48,8 +48,8 @@ export default memo((props: Props) => {
</View>
<View className={styles.line}></View>
<View className={styles.flex_bottom}>
<View className={styles.flex_left}>{props.obj.default_address.province_name + props.obj.default_address.city_name + props.obj.default_address.district_name}</View>
<View className={styles.flex_right}>{formatDateTime(props.obj.recent_order_time)}</View>
<View className={styles.flex_left}>{props.obj.default_address.province_name + props.obj.default_address.city_name + props.obj.default_address.district_name || '暂无'}</View>
<View className={styles.flex_right}>{formatDateTime(props.obj.recent_order_time) || '暂无'}</View>
</View>
</View >
)

View File

@ -6,9 +6,12 @@ import Taro, { usePullDownRefresh, useRouter, useDidShow } from '@tarojs/taro';
import { alert } from '@/common/common'
import { formatPriceDiv, formatDateTime, formatWeightDiv } from '@/common/format'
import DropDownItem from '@/components/dropDown-item'
interface Props {
handType: (any) => void,
handTags: (any) => void
}
export default memo(() => {
export default memo((props: Props) => {
const DropDownItemRef = useRef<any>()
@ -53,11 +56,14 @@ export default memo(() => {
const handItem = (it) => {
list.map(item => {
if (item.id == it.id) {
item.checked = !item.checked
item.checked = true
} else {
item.checked = false
}
return item
})
setlist([...list])
props.handType(list)
}
const handTag = (it) => {
@ -68,6 +74,7 @@ export default memo(() => {
return item
})
settaglist([...taglist])
props.handTags(taglist)
}
return (

View File

@ -36,7 +36,7 @@
}
.order_list {
height: calc(100vh - env(safe-area-inset-bottom) - 160px);
height: calc(100vh - env(safe-area-inset-bottom) - 200px);
background: #f7f7f7;
}

View File

@ -18,10 +18,24 @@ import { ClientListApi } from '@/api/order'
import { goLink } from '@/common/common'
export default () => {
const [searchField, setSearchField] = useState<{ page: number; size: number; order_no: string }>({
const [searchField, setSearchField] = useState<
{
page: number;
size: number;
label_ids: any[] | '',
purchaser_type: number | string,
name_phone_or_sale_user: string,
province_id: any[] | string,
city_id: any[] | string,
}
>({
page: 1,
size: 10,
order_no: '',
label_ids: '',
purchaser_type: '',
name_phone_or_sale_user: '',
province_id: '',
city_id: ''
})
const [orderData, setOrderData] = useState<{ list: any[]; total: number }>({ list: [], total: 0 })
@ -44,7 +58,7 @@ export default () => {
const getSearchData = useCallback((e) => {
pageNum.current.page = 1
setOrderData(() => ({ list: [], total: 0 }))
setSearchField((val) => ({ ...val, order_no: e, size: 10 }))
setSearchField((val) => ({ ...val, name_phone_or_sale_user: e, size: 10 }))
}, [])
//数据加载状态
@ -76,7 +90,31 @@ export default () => {
}, [])
//筛选城市
const handCity = useCallback((val) => {
const ChoseCityRef = useRef<any>()
const handCity = useCallback((provinceVal, cityVal) => {
const provinceArr: number[] = []
const cityArr: number[] = []
provinceVal.forEach(item => {
provinceArr.push(item.id)
})
cityVal.forEach(item => {
cityArr.push(item.id)
})
console.log(provinceArr, cityArr)
pageNum.current.page = 1
setSearchField((val) => ({ ...val, province_id: provinceArr, city_id: cityArr, size: 10 }))
// ChoseCityRef.current.close()
}, [])
//选择客户类型
const handType = useCallback((val) => {
val.filter(item => { return item.checked })
pageNum.current.page = 1
setSearchField((val) => ({ ...val, size: 10, purchaser_type: val[0]?.id }))
}, [])
//选择标签
const handTags = useCallback((val) => {
console.log(val, 899999)
}, [])
@ -88,8 +126,8 @@ export default () => {
</View>
<View className={styles.menuBox}>
<Sort handSort={handSort}></Sort>
<ChoseCity handCity={handCity}></ChoseCity>
<Tag></Tag>
<ChoseCity ref={ChoseCityRef} handCity={handCity}></ChoseCity>
<Tag handTags={handTags} handType={handType}></Tag>
</View>
</View>
<View className={styles.totalFont}> {orderData?.total || 0} </View>

View File

@ -256,6 +256,7 @@ export default () => {
} else {
Taro.hideLoading()
Taro.showToast({
icon: 'error',
title: res.msg,
duration: 2000,
});