diff --git a/src/api/index.ts b/src/api/index.ts index 0b01765..c9504df 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,4 +1,6 @@ +// 关于登录 export { LoginApi } from './login/index' + export { productabsorbcontrast, SelectProductListApi, @@ -9,8 +11,10 @@ export { FindColorListApi, } from './product/index' +// 关于购物页面 export { ShoppingCartUpdateApi, ShoppingCartDeleteApi, ShoppingCartListApi } from './shopping/index' +// 关于发货列表 export { DeliverNoticeOrderList, DeliverNoticeOrder, @@ -21,6 +25,7 @@ export { EnumSaleorderStatus, } from './delivery/index' +// 关于提货列表 export { EnumTakeGoodsOrderStatus, EnumTakeGoodsOrderTypeList, @@ -32,6 +37,9 @@ export { GenBarCodeOrQrCode, } from './takeDelivery/index' +// 关于销售统计 +export { EnumMarketingDepartmentApi, EnumSalesTypeApi, SalesmanRankApi, ProductRankApi, PurchaserRankApi, SupplierRankApi, CensusApi } from './statistic/index' + import { useRequest } from '@/use/useHttp' /** * 系列列表 diff --git a/src/api/statistic/enum.ts b/src/api/statistic/enum.ts new file mode 100644 index 0000000..d8d5562 --- /dev/null +++ b/src/api/statistic/enum.ts @@ -0,0 +1,23 @@ +import { useRequest } from "@/use/useHttp" + +/** + * 销售类型下拉列表 + * @returns + */ +export const EnumSalesTypeApi = () => { + return useRequest({ + url: `/v1/mp/enum/saleType`, + method: 'get', + }) +} + +/** + * 营销部门下拉列表 + * @returns + */ + export const EnumMarketingDepartmentApi = () => { + return useRequest({ + url: `/v1/mp/enum/saleDepartment/list`, + method: "get" + }) +} diff --git a/src/api/statistic/index.ts b/src/api/statistic/index.ts new file mode 100644 index 0000000..a97bcaf --- /dev/null +++ b/src/api/statistic/index.ts @@ -0,0 +1,2 @@ +export { EnumSalesTypeApi, EnumMarketingDepartmentApi } from './enum' +export { CensusApi, ProductRankApi, PurchaserRankApi, SupplierRankApi, SalesmanRankApi } from './saleStatistic' diff --git a/src/api/statistic/saleStatistic.ts b/src/api/statistic/saleStatistic.ts new file mode 100644 index 0000000..a78ca82 --- /dev/null +++ b/src/api/statistic/saleStatistic.ts @@ -0,0 +1,56 @@ +import { useRequest } from '@/use/useHttp' + +/** + * 客户列表 + * @returns + */ +export const CensusApi = () => { + return useRequest({ + url: `/v1/mp/saleOrderDataForm`, + method: "get" + }) +} + +/** + * 面料销售排行 + * @returns + */ +export const ProductRankApi = () => { + return useRequest({ + url: `/v1/mp/saleOrderDataForm/product/list`, + method: 'get', + }) +} + +/** + * 客户销售排行 + * @returns + */ +export const PurchaserRankApi = () => { + return useRequest({ + url: `/v1/mp/saleOrderDataForm/purchaser/list`, + method: 'get', + }) +} + +/** + * 经销商销售排行 + * @returns + */ +export const SupplierRankApi = () => { + return useRequest({ + url: `/v1/mp/saleOrderDataForm/supplier/list`, + method: 'get', + }) +} + +/** + * 业务员销售排行 + * @returns + */ +export const SalesmanRankApi = () => { + return useRequest({ + url: `/v1/mp/saleOrderDataForm/saleUser/list`, + method: 'get', + }) +} diff --git a/src/common/constant.js b/src/common/constant.js index c7f5b9b..a0ac6bd 100644 --- a/src/common/constant.js +++ b/src/common/constant.js @@ -1,4 +1,4 @@ -export const BASE_URL = CURRENT_BASE_URL +// export const BASE_URL = CURRENT_BASE_URL // export const BASE_URL = `http://192.168.0.75:50001/lymarket` // export const BASE_URL = `http://192.168.0.89:50001/lymarket` // export const BASE_URL = `http://10.0.0.5:50001/lymarket` @@ -12,7 +12,7 @@ export const BASE_URL = CURRENT_BASE_URL // export const BASE_URL = `https://dev.zzfzyc.com/lymarket` // 开发环境 // export const BASE_URL = `https://www.zzfzyc.com/lymarket` // 正式环境 // export const BASE_URL = `http://192.168.1.5:40001/lymarket` // 王霞 -// export const BASE_URL = `http://192.168.1.7:50002/lymarket` // 添 +export const BASE_URL = `http://192.168.1.7:50002/lymarket` // 添 // export const BASE_URL = `http://192.168.1.42:50001/lymarket` // 杰 // export const BASE_URL = `http://192.168.1.95:40001/lymarket` // 华 diff --git a/src/components/SelectMarketingDepartment/index.module.scss b/src/components/SelectMarketingDepartment/index.module.scss new file mode 100644 index 0000000..f9e161d --- /dev/null +++ b/src/components/SelectMarketingDepartment/index.module.scss @@ -0,0 +1,6 @@ +.grid { + padding: 24px 40px; + display: grid; + grid-gap: 24px 24px; + grid-template-columns: 1fr 1fr; +} diff --git a/src/components/SelectMarketingDepartment/index.tsx b/src/components/SelectMarketingDepartment/index.tsx new file mode 100644 index 0000000..0cf05ab --- /dev/null +++ b/src/components/SelectMarketingDepartment/index.tsx @@ -0,0 +1,68 @@ +import { FC, useEffect, useMemo, useState } from 'react' +import DropDownItem from '../dropDown-item' +import FilterButton from '../filterButton' +import { EnumMarketingDepartmentApi } from '@/api/index' +import { View } from '@tarojs/components' +import styles from './index.module.scss' + +type ChangedValue = string | number + +interface SelectSaleTypeProps { + onChange?: (value: ChangedValue) => void +} + +type EnumList = { + id: number + code: string + name: string +} +// 营销部门 +const SelectSaleType: FC = props => { + + const selectName = '营销部门' + + const { onChange } = props + console.log(props) + const { fetchData } = EnumMarketingDepartmentApi() + + const getData = async () => { + const res = await fetchData() + setEnumList([{ id: -1, code: '', name: '全部' }, ...res.data.list]) + } + + const [enumList, setEnumList] = useState([]) + + useEffect(() => { + getData() + }, []) + + const [currentValue, setCurrentValue] = useState(-1) + + const handleClick = (value: ChangedValue) => { + setCurrentValue(value) + onChange?.(value) + } + + const displayTitle = useMemo(() => { + if (currentValue === -1) { + return selectName + } + return !!enumList.length ? enumList.filter(option => option.id === currentValue)?.[0]?.name : selectName + }, [enumList, currentValue]) + + return ( + + + {!!enumList.length && + enumList.map((item: EnumList) => { + return ( + handleClick(item.id)}> + {item.name} + + ) + })} + + + ) +} +export default SelectSaleType diff --git a/src/components/SelectSaleType/index.module.scss b/src/components/SelectSaleType/index.module.scss new file mode 100644 index 0000000..f9e161d --- /dev/null +++ b/src/components/SelectSaleType/index.module.scss @@ -0,0 +1,6 @@ +.grid { + padding: 24px 40px; + display: grid; + grid-gap: 24px 24px; + grid-template-columns: 1fr 1fr; +} diff --git a/src/components/SelectSaleType/index.tsx b/src/components/SelectSaleType/index.tsx new file mode 100644 index 0000000..44c8e81 --- /dev/null +++ b/src/components/SelectSaleType/index.tsx @@ -0,0 +1,67 @@ +import { FC, useEffect, useMemo, useState } from 'react' +import DropDownItem from '../dropDown-item' +import FilterButton from '../filterButton' +import { EnumSalesTypeApi } from '@/api/index' +import { View } from '@tarojs/components' +import styles from './index.module.scss' + +type ChangedValue = string | number + +interface SelectSaleTypeProps { + onChange?: (value: ChangedValue) => void + defaultValue?: string +} + +type EnumList = { + id: number + code: string + name: string +} +// 销售类型 +const SelectSaleType: FC = props => { + const selectName = '销售类型' + const { onChange } = props + console.log(props) + const { fetchData } = EnumSalesTypeApi() + + const getData = async () => { + const res = await fetchData() + setEnumList([{ id: -1, code: '', name: '全部' }, ...res.data.list]) + } + + const [enumList, setEnumList] = useState([]) + + useEffect(() => { + getData() + }, []) + + const [currentValue, setCurrentValue] = useState(-1) + + const handleClick = (value: ChangedValue) => { + setCurrentValue(value) + onChange?.(value) + } + + const displayTitle = useMemo(() => { + if (currentValue === -1) { + return selectName + } + return !!enumList.length ? enumList.filter(option => option.id === currentValue)?.[0]?.name : selectName + }, [enumList, currentValue]) + + return ( + + + {!!enumList.length && + enumList.map((item: EnumList) => { + return ( + handleClick(item.id)}> + {item.name} + + ) + })} + + + ) +} +export default SelectSaleType diff --git a/src/components/SelectTimePicker/index.module.scss b/src/components/SelectTimePicker/index.module.scss new file mode 100644 index 0000000..2636be4 --- /dev/null +++ b/src/components/SelectTimePicker/index.module.scss @@ -0,0 +1,13 @@ +.grid { + padding: 24px 40px; + display: grid; + grid-gap: 24px 24px; + grid-template-columns: 1fr 1fr 1fr; +} +.customFilterTime{ + grid-column-start: span 3; + display: flex; + flex-flow: row nowrap; + justify-content: center; + align-items: center; +} diff --git a/src/components/SelectTimePicker/index.tsx b/src/components/SelectTimePicker/index.tsx new file mode 100644 index 0000000..3b0cc80 --- /dev/null +++ b/src/components/SelectTimePicker/index.tsx @@ -0,0 +1,113 @@ +import { View, Text } from '@tarojs/components' +import dayjs from 'dayjs' +import { FC, useState } from 'react' +import DropDownItem from '../dropDown-item' +import FilterButton from '../filterButton' +import IconFont from '../iconfont/iconfont' +import TimePicker from '../timePicker' +import styles from './index.module.scss' + +type ChangedValue = string | number + +interface SelectSaleTypeProps { + onChange?: (value: ChangedValue) => void +} + +const FilterTimeOptions = { + '0': { + name: '全部', + date_min: undefined, + date_max: undefined, + }, + '1': { + name: '今天', + date_min: `${dayjs(new Date()) + .add(0, 'day') + .format('YYYY-MM-DD')} 00:00:00`, + date_max: `${dayjs(new Date()) + .add(1, 'day') + .format('YYYY-MM-DD')} 00:00:00`, + }, + '2': { + name: '昨日', + date_min: `${dayjs(new Date()) + .add(-1, 'day') + .format('YYYY-MM-DD')} 00:00:00`, + date_max: `${dayjs(new Date()) + .add(0, 'day') + .format('YYYY-MM-DD')} 00:00:00`, + }, + '3': { + name: '近7日', + date_min: `${dayjs(new Date()) + .add(-7, 'day') + .format('YYYY-MM-DD')} 00:00:00`, + date_max: `${dayjs(new Date()) + .add(0, 'day') + .format('YYYY-MM-DD')} 00:00:00`, + }, + '4': { + name: '近30日', + date_min: `${dayjs(new Date()) + .add(-30, 'day') + .format('YYYY-MM-DD')} 00:00:00`, + date_max: `${dayjs(new Date()) + .add(0, 'day') + .format('YYYY-MM-DD')} 00:00:00`, + }, + '5': { + name: '近90日', + date_min: `${dayjs(new Date()) + .add(-90, 'day') + .format('YYYY-MM-DD')} 00:00:00`, + date_max: `${dayjs(new Date()) + .add(0, 'day') + .format('YYYY-MM-DD')} 00:00:00`, + }, +} as const + +type Key = keyof typeof FilterTimeOptions +type Value = (typeof FilterTimeOptions)[Key] + +const SelectTimePicker: FC = props => { + const { onChange: change } = props + const [currentValue, setCurrentValue] = useState('0') + + const [currentDate, setCurrentDate] = useState({ + start: new Date(), + end: new Date(), + }) + + + + const onSelectDate = time => { + console.log(time) + change?.(time) + } + + const handleClick = (key: Key) => { + setCurrentValue(key) + } + + return ( + + + {Object.entries(FilterTimeOptions).map(([key, value]) => { + return ( + handleClick(key as Key)}> + {value.name} + + ) + })} + handleClick('6' as Key)}> + 自定义时间 + + + + + + + + ) +} +export default SelectTimePicker diff --git a/src/components/dropDown-item/index.module.scss b/src/components/dropDown-item/index.module.scss index 260ff3f..777b8bb 100644 --- a/src/components/dropDown-item/index.module.scss +++ b/src/components/dropDown-item/index.module.scss @@ -1,7 +1,7 @@ -.dropDownItem{ +.dropDownItem { width: 100%; - &--title{ + &--title { position: relative; z-index: 2000; background-color: white; @@ -10,9 +10,14 @@ justify-content: center; align-items: center; padding: 24px 0; - &--text{ + color: #8c8c8c; + font-size: 28px; + &--text { display: block; margin-right: 12px; } } + &Options { + padding: 24px 40px; + } } diff --git a/src/components/dropDown-item/index.tsx b/src/components/dropDown-item/index.tsx index 0d29a3f..3586ad4 100644 --- a/src/components/dropDown-item/index.tsx +++ b/src/components/dropDown-item/index.tsx @@ -1,10 +1,10 @@ import { View, Text } from '@tarojs/components' -import { useCallback, useEffect, useMemo, useRef, useState, memo } from 'react' +import { useEffect, useMemo, useRef, useState } from 'react' import styles from './index.module.scss' -import classnames from 'classnames' -import Iconfont, { IconNames } from '../iconfont/iconfont' +import Iconfont from '../iconfont/iconfont' import Popup from '../popup' -import FilterButton from '../filterButton' +import Cell from '../cell' +import Taro from '@tarojs/taro' // 弹窗选择向上弹窗还是向下弹窗 type Direction = 'up' | 'down' // 配置 菜单可选项 @@ -14,42 +14,42 @@ export type DropDownOptions = { } interface DropDownEvent { - change?: (value: DropDownOptions['value']) => void // value 变化时触发 + change?: (value: DropDownOptions['value']) => void // value 变化时触发 } -interface PropsType extends DropDownEvent{ +interface PropsType extends DropDownEvent { direction?: Direction - title: string // 已选中的菜单标题 options?: DropDownOptions[] - value?: number | string // 当前选中的值 + title?: string + value: number | string // 当前选中的值 children?: React.ReactNode activeColor?: string + showOverlay?: boolean + customClassName?: string + customStyle?: React.CSSProperties } export default (props: PropsType) => { - const { children, direction = 'down', title, value, options, change, activeColor } = props + const { children, direction = 'down', title = '', value, options = [], change, activeColor, showOverlay = true } = props const [showPopup, setShowPopup] = useState(false) const handleClickOption = (value: DropDownOptions['value']) => { - change?.(value) } + const [text, setText] = useState(options?.[0]?.text || '') + const defaultOptions = useMemo(() => { const currentValue = value - return options?.map(({text, value})=>{ - return ( - handleClickOption(value)}> - {text} - - ) - + return options?.map(({ text, value }) => { + currentValue === value && setText(text) + return handleClickOption(value)}> }) }, [value]) const getIconName = () => { - if(direction === 'up'){ + if (direction === 'up') { return showPopup ? 'icon-zhankai1' : 'icon-shouqi1' } // down @@ -64,23 +64,58 @@ export default (props: PropsType) => { setShowPopup(false) } + const [overlayOffsetTop, setOverlayOffsetTop] = useState('unset') + // 获取遮罩层的样式 + const getOverlayStyle = (): React.CSSProperties => { + return { position: 'absolute', top: 0 } + } + + // 获取整个页面的完整高度 + const [scrollHeight, setScrollHeight] = useState(0) + + useEffect(() => { + const query = Taro.createSelectorQuery() + query.select('#DropDownItem').boundingClientRect() + query.selectViewport().scrollOffset() + query.exec(res => { + console.log('res==>', res) + setScrollHeight(res[1].scrollHeight) + if (direction === 'down') { + setOverlayOffsetTop(res[0].bottom + 'px') + } else { + setOverlayOffsetTop(res[0].top + 'px') + } + }) + }, []) + + // 获取样式 + const getCustomStyle: React.CSSProperties = useMemo(() => { + if (direction === 'up') { + return { position: 'absolute', top: 0, height: overlayOffsetTop } + } else { + return { position: 'absolute', top: overlayOffsetTop, height: `calc(${scrollHeight + 'px'} - ${overlayOffsetTop})` } + } + }, [overlayOffsetTop]) + + return ( - + - - {title} + + {title ? title : text} - + - {children ? children : defaultOptions} + {children ? children : {defaultOptions}} ) diff --git a/src/components/popup/index.module.scss b/src/components/popup/index.module.scss index 4756285..88cf2d4 100644 --- a/src/components/popup/index.module.scss +++ b/src/components/popup/index.module.scss @@ -15,6 +15,9 @@ $am-ms: 200ms; &_active { opacity: 1; } + &--hidden { + background: transparent; + } } .drawer_main { @@ -32,7 +35,7 @@ $am-ms: 200ms; z-index: 1000; visibility: hidden; transition: visibility $am-ms ease-in-out; - + overflow: hidden; .drawer_container { display: flex; flex-direction: column; diff --git a/src/components/popup/index.tsx b/src/components/popup/index.tsx index 9c3acd2..d2fedfe 100644 --- a/src/components/popup/index.tsx +++ b/src/components/popup/index.tsx @@ -22,6 +22,7 @@ export interface Params extends PopupEvent { customStyle?: React.CSSProperties overlayStyle?: React.CSSProperties safeAreaInsetBottom?: boolean // 是否为iphoneX提供小黑条适配 + showOverLay?: boolean // 是否显示遮罩层 } export default memo( ({ @@ -36,6 +37,7 @@ export default memo( animationEnd, customStyle, safeAreaInsetBottom = true, + showOverLay = true, overlayStyle, }: Params) => { const animationTime = useRef(null) @@ -60,9 +62,12 @@ export default memo( <> - + e.stopPropagation()}> {showTitle && {title}} diff --git a/src/components/timePicker/index.tsx b/src/components/timePicker/index.tsx index 1b7cd1d..92a369f 100644 --- a/src/components/timePicker/index.tsx +++ b/src/components/timePicker/index.tsx @@ -7,15 +7,13 @@ import dayjs from 'dayjs' type DateArg = string | number | Date interface Props { - showTime: boolean - closePopup?: () => void end?: DateArg start?: DateArg onSelectDate?: (any) => void } export default memo((props: Props) => { - let { showTime = false, closePopup, start = '', end = '', onSelectDate } = props + let { start = '', end = '', onSelectDate } = props const [time, setTime] = useState({}) const handTime = (e) => { @@ -33,7 +31,7 @@ export default memo((props: Props) => { return ( - closePopup?.()}> + <> { onSelectDate?.(time)}> 确认 - + ) }) diff --git a/src/components/timePickerPopup/index.scss b/src/components/timePickerPopup/index.scss new file mode 100644 index 0000000..b808aa6 --- /dev/null +++ b/src/components/timePickerPopup/index.scss @@ -0,0 +1,19 @@ + + +.time-box { + padding: 40px; +} + +.sure-box { + // padding: 16px 102px 30px 102px; + margin-left: 102px; + margin-right: 102px; + height: 80px; + background: #337FFF; + border-radius: 44px; + font-size: 28px; + font-weight: 500; + color: #FFFFFF; + text-align: center; + line-height: 80px; +} diff --git a/src/components/timePickerPopup/index.tsx b/src/components/timePickerPopup/index.tsx new file mode 100644 index 0000000..92b23f8 --- /dev/null +++ b/src/components/timePickerPopup/index.tsx @@ -0,0 +1,24 @@ +import Popup from '@/components/popup' +import { memo } from 'react' +import './index.scss' +import TimePicker from '../timePicker' + +type DateArg = string | number | Date +interface Props { + showTime: boolean + closePopup?: () => void + end?: DateArg + start?: DateArg + onSelectDate?: (any) => void +} + +export default memo((props: Props) => { + let { showTime = false, closePopup, start = '', end = '', onSelectDate } = props + + + return ( + closePopup?.()}> + + + ) +}) diff --git a/src/pages/delivery/index.tsx b/src/pages/delivery/index.tsx index 918cdd9..c7e6b55 100644 --- a/src/pages/delivery/index.tsx +++ b/src/pages/delivery/index.tsx @@ -13,7 +13,7 @@ import ItemList from './components/ItemList' import DeliveryStatusList from './components/DeliveryStatusList' import Popup from '@/components/popup' import DeliveryFilter, { SearchField } from './components/Filter' -import TimePicker from '@/components/timePicker' +import TimePickerPopup from '@/components/timePickerPopup' type SearchData = { delivery_notice_order_no?: string // 发货单号 @@ -196,7 +196,7 @@ const Delivery: FC = () => { - handTime(e)}> + handTime(e)}> ) } diff --git a/src/pages/newCollection/index.tsx b/src/pages/newCollection/index.tsx index 3e0812a..b8c7bf4 100644 --- a/src/pages/newCollection/index.tsx +++ b/src/pages/newCollection/index.tsx @@ -12,7 +12,7 @@ import { formatDateTime, formatHashTag, formatImgUrl, formatPriceDiv, formatWeig import { mpcashManagementOrderlist } from "@/api/newCollection" -import TimePicker from "@/components/timePicker" +import TimePickerPopup from '@/components/timePickerPopup' import dayjs from 'dayjs' import IconFont from '@/components/iconfont/iconfont' @@ -294,13 +294,13 @@ export default () => { - handTime(e)} - > + > ) -} \ No newline at end of file +} diff --git a/src/pages/refundPage/index.tsx b/src/pages/refundPage/index.tsx index 3cf0c3f..4b2b3cf 100644 --- a/src/pages/refundPage/index.tsx +++ b/src/pages/refundPage/index.tsx @@ -15,7 +15,7 @@ import { mpenumreturnType } from "@/api/refound" import Tabs from "./components/tabs" -import TimePicker from "@/components/timePicker" +import TimePickerPopup from '@/components/timePickerPopup' import dayjs from 'dayjs' import IconFont from '@/components/iconfont/iconfont' export default () => { @@ -395,13 +395,13 @@ export default () => { {/* */} - handTime(e)} - > + > ) } diff --git a/src/pages/saleStatistic/index.tsx b/src/pages/saleStatistic/index.tsx index f3ca5a1..07652e3 100644 --- a/src/pages/saleStatistic/index.tsx +++ b/src/pages/saleStatistic/index.tsx @@ -1,5 +1,12 @@ +import AtCalendar from '@/components/calendar' import DropDownItem, { DropDownOptions } from '@/components/dropDown-item' +import SelectMarketingDepartment from '@/components/SelectMarketingDepartment' +import SelectSaleType from '@/components/SelectSaleType' +import SelectTimePicker from '@/components/SelectTimePicker' +import TimePicker from '@/components/timePicker' import { View } from '@tarojs/components' +import classnames from 'classnames' +import dayjs from 'dayjs' import { useState } from 'react' import styles from './index.module.scss' @@ -17,13 +24,30 @@ const saleStatistic = () => { text: 'name2', value: 2, }, + { + text: 'name3', + value: 3, + }, ]) + const onChangeTimePicker = (value) => { + console.log(value) + } + const onChangeSaleType = (saleType) => { + console.log(saleType) + + } + const onChangeDepartment = (department) => { + console.log(department) + + } + return ( - sdflkajsfdlk - + + + ) diff --git a/src/pages/takeDelivery/index.tsx b/src/pages/takeDelivery/index.tsx index cb6fda9..97cdc3c 100644 --- a/src/pages/takeDelivery/index.tsx +++ b/src/pages/takeDelivery/index.tsx @@ -13,7 +13,7 @@ import ItemList from './components/ItemList' import DeliveryStatusList from './components/DeliveryStatusList' import Popup from '@/components/popup' import DeliveryFilter, { SearchField } from './components/Filter' -import TimePicker from '@/components/timePicker' +import TimePickerPopup from '@/components/timePickerPopup' type SearchData = { take_goods_order_no?: string // 提货单号 @@ -191,7 +191,7 @@ const Delivery: FC = () => { - handTime(e)}> + handTime(e)}> ) }