✨ feat(添加数据):
This commit is contained in:
parent
464746ef97
commit
23f4885111
@ -31,4 +31,4 @@ export const certificationTypeListApi = () => {
|
|||||||
url: '/v1/mall/enum/companyAuthenticationType',
|
url: '/v1/mall/enum/companyAuthenticationType',
|
||||||
method: 'get',
|
method: 'get',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
67
src/api/codeManage.ts
Normal file
67
src/api/codeManage.ts
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import { useRequest } from '@/use/useHttp'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取自定义码单详情
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const GetCustomCodeDetailApi = () => {
|
||||||
|
return useRequest({
|
||||||
|
url: '/v1/mall/customPrint',
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取自定义码单列表
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const GetCustomCodeLApi = () => {
|
||||||
|
return useRequest({
|
||||||
|
url: '/v1/mall/customPrint/list',
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取初始化自定义码单
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const GetCustomCodeInitApi = () => {
|
||||||
|
return useRequest({
|
||||||
|
url: '/v1/mall/customPrint/init',
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新自定义码单
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const UpdateCustomCodeApi = () => {
|
||||||
|
return useRequest({
|
||||||
|
url: '/v1/mall/customPrint',
|
||||||
|
method: 'put',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新建自定义码单
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const CreateCustomCodeApi = () => {
|
||||||
|
return useRequest({
|
||||||
|
url: '/v1/mall/customPrint/add',
|
||||||
|
method: 'post',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算合计信息
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const CustomPrintCalculationApi = () => {
|
||||||
|
return useRequest({
|
||||||
|
url: '/v1/mall/customPrint/calculation',
|
||||||
|
method: 'post',
|
||||||
|
})
|
||||||
|
}
|
||||||
@ -5,11 +5,11 @@
|
|||||||
// export const BASE_URL = `http://192.168.0.89:40001/lymarket`
|
// export const BASE_URL = `http://192.168.0.89:40001/lymarket`
|
||||||
// export const BASE_URL = `http://192.168.1.165:40001/lymarket` // 王霞
|
// export const BASE_URL = `http://192.168.1.165:40001/lymarket` // 王霞
|
||||||
// export const BASE_URL = 'https://test.zzfzyc.com/lymarket' // 测试环境
|
// export const BASE_URL = 'https://test.zzfzyc.com/lymarket' // 测试环境
|
||||||
export const BASE_URL = 'https://pre.zzfzyc.com/lymarket' // 预发布
|
// export const BASE_URL = 'https://pre.zzfzyc.com/lymarket' // 预发布
|
||||||
// export const BASE_URL = `http://192.168.1.9:40001/lymarket` // 发
|
// export const BASE_URL = `http://192.168.1.9:40001/lymarket` // 发
|
||||||
// export const BASE_URL = `http://192.168.1.9:50005/lymarket` // 发
|
// export const BASE_URL = `http://192.168.1.9:50005/lymarket` // 发
|
||||||
// export const BASE_URL = `http://192.168.1.30:50001/lymarket` // 发
|
// export const BASE_URL = `http://192.168.1.30:50001/lymarket` // 发
|
||||||
// export const BASE_URL = `https://dev.zzfzyc.com/lymarket` // 开发环境
|
// export const BASE_URL = 'https://dev.zzfzyc.com/lymarket' // 开发环境
|
||||||
// export const BASE_URL = 'https://www.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.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' // 添
|
||||||
|
|||||||
@ -70,3 +70,11 @@ export const REFUND_STATUS_ORDER = {
|
|||||||
ReturnApplyOrderTypeReturnForRefund: { value: 1, label: '退货退款' }, // 退货退款
|
ReturnApplyOrderTypeReturnForRefund: { value: 1, label: '退货退款' }, // 退货退款
|
||||||
ReturnApplyOrderTypeSalesRefund: { value: 3, label: '销售退款' }, // 销售退款
|
ReturnApplyOrderTypeSalesRefund: { value: 3, label: '销售退款' }, // 销售退款
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 码单调整枚举
|
||||||
|
export const Adjust_Type = {
|
||||||
|
AdjustTypeAllAdjustType: { value: 1, label: '整单调整' },
|
||||||
|
AdjustTypeProductAdjustType: { value: 2, label: '按面料调整' },
|
||||||
|
AdjustTypeProductColor: { value: 3, label: '按色号调整' },
|
||||||
|
}
|
||||||
|
export type adjustType = 1 | 2 | 3
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import type { SelectorQuery } from '@tarojs/taro'
|
||||||
import Taro from '@tarojs/taro'
|
import Taro from '@tarojs/taro'
|
||||||
import { formatImgUrl } from './fotmat'
|
import { formatImgUrl } from './fotmat'
|
||||||
import { analysisShortCodeApi } from './shortCode'
|
import { analysisShortCodeApi } from './shortCode'
|
||||||
@ -149,3 +150,26 @@ export const shareShop = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function delay(delayTime = 25): Promise<null> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
// @ts-expect-error no error
|
||||||
|
resolve()
|
||||||
|
}, delayTime)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function delayQuerySelector(selectorStr: string, delayTime = 500): Promise<any[]> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const selector: SelectorQuery = Taro.createSelectorQuery()
|
||||||
|
delay(delayTime).then(() => {
|
||||||
|
selector
|
||||||
|
.select(selectorStr)
|
||||||
|
.boundingClientRect()
|
||||||
|
.exec((res: any[]) => {
|
||||||
|
resolve(res)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
365
src/components/calendar/body/index.tsx
Normal file
365
src/components/calendar/body/index.tsx
Normal file
@ -0,0 +1,365 @@
|
|||||||
|
import { Swiper, SwiperItem, View } from '@tarojs/components'
|
||||||
|
import classnames from 'classnames'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import React from 'react'
|
||||||
|
import type {
|
||||||
|
BaseEventOrig,
|
||||||
|
ITouch,
|
||||||
|
ITouchEvent,
|
||||||
|
} from '@tarojs/components/types/common'
|
||||||
|
import type {
|
||||||
|
AtCalendarBodyListGroup,
|
||||||
|
AtCalendarBodyProps,
|
||||||
|
AtCalendarBodyState,
|
||||||
|
Calendar,
|
||||||
|
} from '../../../types/calendar'
|
||||||
|
import generateCalendarGroup from '../common/helper'
|
||||||
|
import AtCalendarDateList from '../ui/date-list/index'
|
||||||
|
import AtCalendarDayList from '../ui/day-list/index'
|
||||||
|
import { delayQuerySelector } from '@/common/util'
|
||||||
|
|
||||||
|
const ANIMTE_DURATION = 300
|
||||||
|
|
||||||
|
const defaultProps: Partial<AtCalendarBodyProps> = {
|
||||||
|
marks: [],
|
||||||
|
selectedDate: {
|
||||||
|
end: Date.now(),
|
||||||
|
start: Date.now(),
|
||||||
|
},
|
||||||
|
format: 'YYYY/MM/DD',
|
||||||
|
generateDate: Date.now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class AtCalendarBody extends React.Component<
|
||||||
|
AtCalendarBodyProps,
|
||||||
|
Readonly<AtCalendarBodyState>
|
||||||
|
> {
|
||||||
|
static defaultProps: Partial<AtCalendarBodyProps> = defaultProps
|
||||||
|
|
||||||
|
public constructor(props: AtCalendarBodyProps) {
|
||||||
|
super(props)
|
||||||
|
const {
|
||||||
|
validDates,
|
||||||
|
marks,
|
||||||
|
format,
|
||||||
|
minDate,
|
||||||
|
maxDate,
|
||||||
|
generateDate,
|
||||||
|
selectedDate,
|
||||||
|
selectedDates,
|
||||||
|
} = props
|
||||||
|
|
||||||
|
this.generateFunc = generateCalendarGroup({
|
||||||
|
validDates,
|
||||||
|
format,
|
||||||
|
minDate,
|
||||||
|
maxDate,
|
||||||
|
marks,
|
||||||
|
selectedDates,
|
||||||
|
})
|
||||||
|
const listGroup = this.getGroups(generateDate, selectedDate)
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
listGroup,
|
||||||
|
offsetSize: 0,
|
||||||
|
isAnimate: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public componentDidMount(): void {
|
||||||
|
delayQuerySelector('.at-calendar-slider__main').then((res) => {
|
||||||
|
this.maxWidth = res[0].width
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public UNSAFE_componentWillReceiveProps(
|
||||||
|
nextProps: AtCalendarBodyProps,
|
||||||
|
): void {
|
||||||
|
const {
|
||||||
|
validDates,
|
||||||
|
marks,
|
||||||
|
format,
|
||||||
|
minDate,
|
||||||
|
maxDate,
|
||||||
|
generateDate,
|
||||||
|
selectedDate,
|
||||||
|
selectedDates,
|
||||||
|
} = nextProps
|
||||||
|
|
||||||
|
this.generateFunc = generateCalendarGroup({
|
||||||
|
validDates,
|
||||||
|
format,
|
||||||
|
minDate,
|
||||||
|
maxDate,
|
||||||
|
marks,
|
||||||
|
selectedDates,
|
||||||
|
})
|
||||||
|
const listGroup = this.getGroups(generateDate, selectedDate)
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
offsetSize: 0,
|
||||||
|
listGroup,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private changeCount = 0
|
||||||
|
private currentSwiperIndex = 1
|
||||||
|
private startX = 0
|
||||||
|
private swipeStartPoint = 0
|
||||||
|
private isPreMonth = false
|
||||||
|
private maxWidth = 0
|
||||||
|
private isTouching = false
|
||||||
|
|
||||||
|
private generateFunc: (
|
||||||
|
generateDate: number,
|
||||||
|
selectedDate: Calendar.SelectedDate,
|
||||||
|
isShowStatus?: boolean
|
||||||
|
) => Calendar.ListInfo<Calendar.Item>
|
||||||
|
|
||||||
|
private getGroups = (
|
||||||
|
generateDate: number,
|
||||||
|
selectedDate: Calendar.SelectedDate,
|
||||||
|
): AtCalendarBodyListGroup => {
|
||||||
|
const dayjsDate = dayjs(generateDate)
|
||||||
|
const arr: AtCalendarBodyListGroup = []
|
||||||
|
const preList: Calendar.ListInfo<Calendar.Item> = this.generateFunc(
|
||||||
|
dayjsDate.subtract(1, 'month').valueOf(),
|
||||||
|
selectedDate,
|
||||||
|
)
|
||||||
|
|
||||||
|
const nowList: Calendar.ListInfo<Calendar.Item> = this.generateFunc(
|
||||||
|
generateDate,
|
||||||
|
selectedDate,
|
||||||
|
true,
|
||||||
|
)
|
||||||
|
|
||||||
|
const nextList: Calendar.ListInfo<Calendar.Item> = this.generateFunc(
|
||||||
|
dayjsDate.add(1, 'month').valueOf(),
|
||||||
|
selectedDate,
|
||||||
|
)
|
||||||
|
|
||||||
|
const preListIndex
|
||||||
|
= this.currentSwiperIndex === 0 ? 2 : this.currentSwiperIndex - 1
|
||||||
|
const nextListIndex
|
||||||
|
= this.currentSwiperIndex === 2 ? 0 : this.currentSwiperIndex + 1
|
||||||
|
|
||||||
|
arr[preListIndex] = preList
|
||||||
|
arr[nextListIndex] = nextList
|
||||||
|
arr[this.currentSwiperIndex] = nowList
|
||||||
|
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleTouchStart = (e: ITouchEvent): void => {
|
||||||
|
if (!this.props.isSwiper) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.isTouching = true
|
||||||
|
this.startX = e.touches[0].clientX
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleTouchMove = (e: ITouchEvent): void => {
|
||||||
|
if (!this.props.isSwiper) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!this.isTouching) { return }
|
||||||
|
|
||||||
|
const { clientX } = e.touches[0]
|
||||||
|
const offsetSize = clientX - this.startX
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
offsetSize,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private animateMoveSlide = (offset: number, callback?: Function): void => {
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
isAnimate: true,
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
this.setState({
|
||||||
|
offsetSize: offset,
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
this.setState(
|
||||||
|
{
|
||||||
|
isAnimate: false,
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
callback && callback()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}, ANIMTE_DURATION)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleTouchEnd = (): void => {
|
||||||
|
if (!this.props.isSwiper) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const { offsetSize } = this.state
|
||||||
|
|
||||||
|
this.isTouching = false
|
||||||
|
const isRight = offsetSize > 0
|
||||||
|
|
||||||
|
const breakpoint = this.maxWidth / 2
|
||||||
|
const absOffsetSize = Math.abs(offsetSize)
|
||||||
|
|
||||||
|
if (absOffsetSize > breakpoint) {
|
||||||
|
const res = isRight ? this.maxWidth : -this.maxWidth
|
||||||
|
return this.animateMoveSlide(res, () => {
|
||||||
|
this.props.onSwipeMonth(isRight ? -1 : 1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.animateMoveSlide(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleChange = (
|
||||||
|
e: BaseEventOrig<{
|
||||||
|
current: number
|
||||||
|
source: string
|
||||||
|
}>,
|
||||||
|
): void => {
|
||||||
|
const { current, source } = e.detail
|
||||||
|
|
||||||
|
if (source === 'touch') {
|
||||||
|
this.currentSwiperIndex = current
|
||||||
|
this.changeCount += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleAnimateFinish = (): void => {
|
||||||
|
if (this.changeCount > 0) {
|
||||||
|
this.props.onSwipeMonth(
|
||||||
|
this.isPreMonth ? -this.changeCount : this.changeCount,
|
||||||
|
)
|
||||||
|
this.changeCount = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleSwipeTouchStart = (
|
||||||
|
e: ITouchEvent & { changedTouches: Array<ITouch> },
|
||||||
|
): void => {
|
||||||
|
const { clientY, clientX } = e.changedTouches[0]
|
||||||
|
this.swipeStartPoint = this.props.isVertical ? clientY : clientX
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleSwipeTouchEnd = (
|
||||||
|
e: ITouchEvent & { changedTouches: Array<ITouch> },
|
||||||
|
): void => {
|
||||||
|
const { clientY, clientX } = e.changedTouches[0]
|
||||||
|
this.isPreMonth = this.props.isVertical
|
||||||
|
? clientY - this.swipeStartPoint > 0
|
||||||
|
: clientX - this.swipeStartPoint > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): JSX.Element {
|
||||||
|
const { isSwiper } = this.props
|
||||||
|
const { isAnimate, offsetSize, listGroup } = this.state
|
||||||
|
|
||||||
|
if (!isSwiper) {
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
className={classnames(
|
||||||
|
'main',
|
||||||
|
'at-calendar-slider__main',
|
||||||
|
`at-calendar-slider__main--${process.env.TARO_ENV}`,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<AtCalendarDayList />
|
||||||
|
<View className="main__body body">
|
||||||
|
<View className="body__slider body__slider--now">
|
||||||
|
<AtCalendarDateList
|
||||||
|
list={listGroup[1].list}
|
||||||
|
onClick={this.props.onDayClick}
|
||||||
|
onLongClick={this.props.onLongClick}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 需要 Taro 组件库维护 Swiper 使 小程序 和 H5 的表现保持一致 */
|
||||||
|
if (process.env.TARO_ENV === 'h5') {
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
className={classnames(
|
||||||
|
'main',
|
||||||
|
'at-calendar-slider__main',
|
||||||
|
`at-calendar-slider__main--${process.env.TARO_ENV}`,
|
||||||
|
)}
|
||||||
|
onTouchEnd={this.handleTouchEnd}
|
||||||
|
onTouchMove={this.handleTouchMove}
|
||||||
|
onTouchStart={this.handleTouchStart}
|
||||||
|
>
|
||||||
|
<AtCalendarDayList />
|
||||||
|
<View
|
||||||
|
className={classnames('main__body body', {
|
||||||
|
'main__body--slider': isSwiper,
|
||||||
|
'main__body--animate': isAnimate,
|
||||||
|
})}
|
||||||
|
style={{
|
||||||
|
transform: isSwiper
|
||||||
|
? `translateX(-100%) translate3d(${offsetSize},0,0)`
|
||||||
|
: '',
|
||||||
|
WebkitTransform: isSwiper
|
||||||
|
? `translateX(-100%) translate3d(${offsetSize}px,0,0)`
|
||||||
|
: '',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<View className="body__slider body__slider--pre">
|
||||||
|
<AtCalendarDateList list={listGroup[0].list} />
|
||||||
|
</View>
|
||||||
|
<View className="body__slider body__slider--now">
|
||||||
|
<AtCalendarDateList
|
||||||
|
list={listGroup[1].list}
|
||||||
|
onClick={this.props.onDayClick}
|
||||||
|
onLongClick={this.props.onLongClick}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View className="body__slider body__slider--next">
|
||||||
|
<AtCalendarDateList list={listGroup[2].list} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
className={classnames(
|
||||||
|
'main',
|
||||||
|
'at-calendar-slider__main',
|
||||||
|
`at-calendar-slider__main--${process.env.TARO_ENV}`,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<AtCalendarDayList />
|
||||||
|
<Swiper
|
||||||
|
circular
|
||||||
|
current={1}
|
||||||
|
skipHiddenItemLayout
|
||||||
|
className={classnames('main__body')}
|
||||||
|
onChange={this.handleChange}
|
||||||
|
vertical={this.props.isVertical}
|
||||||
|
onAnimationFinish={this.handleAnimateFinish}
|
||||||
|
onTouchEnd={this.handleSwipeTouchEnd}
|
||||||
|
onTouchStart={this.handleSwipeTouchStart}
|
||||||
|
>
|
||||||
|
{listGroup.map((item, key) => (
|
||||||
|
<SwiperItem key={key} itemId={key.toString()}>
|
||||||
|
<AtCalendarDateList
|
||||||
|
list={item.list}
|
||||||
|
onClick={this.props.onDayClick}
|
||||||
|
onLongClick={this.props.onLongClick}
|
||||||
|
/>
|
||||||
|
</SwiperItem>
|
||||||
|
))}
|
||||||
|
</Swiper>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
5
src/components/calendar/common/constant.ts
Normal file
5
src/components/calendar/common/constant.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export const TYPE_PRE_MONTH = -1
|
||||||
|
|
||||||
|
export const TYPE_NOW_MONTH = 0
|
||||||
|
|
||||||
|
export const TYPE_NEXT_MONTH = 1
|
||||||
119
src/components/calendar/common/helper.ts
Normal file
119
src/components/calendar/common/helper.ts
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
import type { Dayjs } from 'dayjs'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import _flow from 'lodash/flow'
|
||||||
|
import type { Calendar } from '../../../types/calendar'
|
||||||
|
import * as constant from './constant'
|
||||||
|
import plugins from './plugins'
|
||||||
|
|
||||||
|
const TOTAL = 7 * 6
|
||||||
|
|
||||||
|
function getFullItem(
|
||||||
|
item: Partial<Calendar.Item>,
|
||||||
|
options: Calendar.GroupOptions,
|
||||||
|
selectedDate: Calendar.SelectedDate,
|
||||||
|
isShowStatus?: boolean,
|
||||||
|
): any {
|
||||||
|
if (options.marks.find(x => x.value === item.value)) {
|
||||||
|
(item.marks as Array<Calendar.Mark>) = [{
|
||||||
|
value: item.value as string,
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
if (!isShowStatus) { return item }
|
||||||
|
|
||||||
|
const bindedPlugins = plugins.map(fn =>
|
||||||
|
fn.bind(null, {
|
||||||
|
options,
|
||||||
|
selectedDate,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
return _flow(bindedPlugins)(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function generateCalendarGroup(
|
||||||
|
options: Calendar.GroupOptions,
|
||||||
|
): (
|
||||||
|
generateDate: number,
|
||||||
|
selectedDate: Calendar.SelectedDate,
|
||||||
|
isShowStatus?: boolean
|
||||||
|
) => Calendar.ListInfo<Calendar.Item> {
|
||||||
|
return function(
|
||||||
|
generateDate: number,
|
||||||
|
selectedDate: Calendar.SelectedDate,
|
||||||
|
isShowStatus?: boolean,
|
||||||
|
): Calendar.ListInfo<Calendar.Item> {
|
||||||
|
const date = dayjs(generateDate)
|
||||||
|
|
||||||
|
const { format } = options
|
||||||
|
|
||||||
|
// 获取生成日期的第一天 和 最后一天
|
||||||
|
const firstDate = date.startOf('month')
|
||||||
|
const lastDate = date.endOf('month')
|
||||||
|
|
||||||
|
const preMonthDate = date.subtract(1, 'month')
|
||||||
|
|
||||||
|
const list: Calendar.List<Calendar.Item> = []
|
||||||
|
|
||||||
|
const nowMonthDays: number = date.daysInMonth() // 获取这个月有多少天
|
||||||
|
const preMonthLastDay = preMonthDate.endOf('month').day() // 获取上个月最后一天是周几
|
||||||
|
|
||||||
|
// 生成上个月的日期
|
||||||
|
for (let i = 1; i <= preMonthLastDay + 1; i++) {
|
||||||
|
const thisDate = firstDate.subtract(i, 'day').startOf('day')
|
||||||
|
|
||||||
|
let item = {
|
||||||
|
marks: [],
|
||||||
|
_value: thisDate,
|
||||||
|
text: thisDate.date(),
|
||||||
|
type: constant.TYPE_PRE_MONTH,
|
||||||
|
value: thisDate.format(format),
|
||||||
|
}
|
||||||
|
|
||||||
|
item = getFullItem(item, options, selectedDate, isShowStatus)
|
||||||
|
|
||||||
|
list.push(item)
|
||||||
|
}
|
||||||
|
list.reverse()
|
||||||
|
|
||||||
|
// 生成这个月的日期
|
||||||
|
for (let i = 0; i < nowMonthDays; i++) {
|
||||||
|
const thisDate = firstDate.add(i, 'day').startOf('day')
|
||||||
|
let item = {
|
||||||
|
marks: [],
|
||||||
|
_value: thisDate,
|
||||||
|
text: thisDate.date(),
|
||||||
|
type: constant.TYPE_NOW_MONTH,
|
||||||
|
value: thisDate.format(format),
|
||||||
|
}
|
||||||
|
|
||||||
|
item = getFullItem(item, options, selectedDate, isShowStatus)
|
||||||
|
|
||||||
|
list.push(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成下个月的日期
|
||||||
|
let i = 1
|
||||||
|
while (list.length < TOTAL) {
|
||||||
|
const thisDate = lastDate.add(i++, 'day').startOf('day')
|
||||||
|
let item = {
|
||||||
|
marks: [],
|
||||||
|
_value: thisDate,
|
||||||
|
text: thisDate.date(),
|
||||||
|
type: constant.TYPE_NEXT_MONTH,
|
||||||
|
value: thisDate.format(format),
|
||||||
|
}
|
||||||
|
|
||||||
|
item = getFullItem(item, options, selectedDate, isShowStatus)
|
||||||
|
|
||||||
|
list.push(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
list,
|
||||||
|
value: generateDate,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGenerateDate(date: Calendar.DateArg | undefined): Dayjs {
|
||||||
|
return dayjs(date).startOf('month')
|
||||||
|
}
|
||||||
124
src/components/calendar/common/plugins.ts
Normal file
124
src/components/calendar/common/plugins.ts
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import dayjs from 'dayjs'
|
||||||
|
import _isEmpty from 'lodash/isEmpty'
|
||||||
|
import type { Calendar } from '../../../types/calendar'
|
||||||
|
|
||||||
|
interface PluginArg {
|
||||||
|
options: Calendar.GroupOptions
|
||||||
|
|
||||||
|
selectedDate: Calendar.SelectedDate
|
||||||
|
}
|
||||||
|
|
||||||
|
export function handleActive(
|
||||||
|
args: PluginArg,
|
||||||
|
item: Calendar.Item,
|
||||||
|
): Calendar.Item {
|
||||||
|
const { selectedDate } = args
|
||||||
|
const { _value } = item
|
||||||
|
|
||||||
|
const { start, end } = selectedDate
|
||||||
|
|
||||||
|
const dayjsEnd = dayjs(end)
|
||||||
|
const dayjsStart = start ? dayjs(start) : dayjsEnd
|
||||||
|
|
||||||
|
item.isSelected
|
||||||
|
= _value.isSame(dayjsEnd)
|
||||||
|
|| _value.isSame(dayjsStart)
|
||||||
|
|| (_value.isAfter(dayjsStart) && _value.isBefore(dayjsEnd))
|
||||||
|
|
||||||
|
item.isSelectedHead = _value.isSame(dayjsStart)
|
||||||
|
item.isSelectedTail = _value.isSame(dayjsEnd)
|
||||||
|
|
||||||
|
item.isToday = _value.diff(dayjs(Date.now()).startOf('day'), 'day') === 0
|
||||||
|
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
export function handleMarks(
|
||||||
|
args: PluginArg,
|
||||||
|
item: Calendar.Item,
|
||||||
|
): Calendar.Item {
|
||||||
|
const { options } = args
|
||||||
|
const { _value } = item
|
||||||
|
const { marks } = options
|
||||||
|
|
||||||
|
const markList = marks.filter(mark =>
|
||||||
|
dayjs(mark.value).startOf('day').isSame(_value),
|
||||||
|
)
|
||||||
|
|
||||||
|
item.marks = markList.slice(0, 1)
|
||||||
|
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
// export function handleSelectedDates (args: PluginArg): Calendar.Item {
|
||||||
|
// const { item, options } = args
|
||||||
|
// const { _value } = item
|
||||||
|
// const { selectedDates } = options
|
||||||
|
|
||||||
|
// if (selectedDates.length === 0) return args
|
||||||
|
|
||||||
|
// _forEach(selectedDates, date => {
|
||||||
|
// const { isSelected, isHead, isTail } = item
|
||||||
|
|
||||||
|
// // 如果当前 Item 已经具备了 三种状态下 无需继续判断 跳出循环
|
||||||
|
// if (isSelected) {
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const { start, end } = date
|
||||||
|
|
||||||
|
// const dayjsEnd = dayjs(end).startOf('day')
|
||||||
|
// const dayjsStart = dayjs(start).startOf('day')
|
||||||
|
|
||||||
|
// item.isSelected =
|
||||||
|
// item.isSelected ||
|
||||||
|
// (_value.isAfter(dayjsStart) && _value.isBefore(dayjsEnd))
|
||||||
|
|
||||||
|
// item.isHead = item.isHead || _value.isSame(dayjsStart)
|
||||||
|
|
||||||
|
// item.isTail = item.isTail || _value.isSame(dayjsEnd)
|
||||||
|
// })
|
||||||
|
|
||||||
|
// return item
|
||||||
|
// }
|
||||||
|
|
||||||
|
export function handleDisabled(
|
||||||
|
args: PluginArg,
|
||||||
|
item: Calendar.Item,
|
||||||
|
): Calendar.Item {
|
||||||
|
const { options } = args
|
||||||
|
const { _value } = item
|
||||||
|
const { minDate, maxDate } = options
|
||||||
|
|
||||||
|
const dayjsMinDate = dayjs(minDate)
|
||||||
|
const dayjsMaxDate = dayjs(maxDate)
|
||||||
|
|
||||||
|
item.isDisabled
|
||||||
|
= !!(minDate && _value.isBefore(dayjsMinDate))
|
||||||
|
|| !!(maxDate && _value.isAfter(dayjsMaxDate))
|
||||||
|
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
export function handleValid(
|
||||||
|
args: PluginArg,
|
||||||
|
item: Calendar.Item,
|
||||||
|
): Calendar.Item {
|
||||||
|
const { options } = args
|
||||||
|
const { _value } = item
|
||||||
|
const { validDates } = options
|
||||||
|
|
||||||
|
if (!_isEmpty(validDates)) {
|
||||||
|
const isInclude = validDates.some(date =>
|
||||||
|
dayjs(date.value).startOf('day').isSame(_value),
|
||||||
|
)
|
||||||
|
|
||||||
|
item.isDisabled = !isInclude
|
||||||
|
}
|
||||||
|
|
||||||
|
delete item._value
|
||||||
|
|
||||||
|
return item
|
||||||
|
}
|
||||||
|
|
||||||
|
export default [handleActive, handleMarks, handleDisabled, handleValid]
|
||||||
81
src/components/calendar/controller/index.tsx
Normal file
81
src/components/calendar/controller/index.tsx
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import { Picker, Text, View } from '@tarojs/components'
|
||||||
|
import classnames from 'classnames'
|
||||||
|
import type { Dayjs } from 'dayjs'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import React from 'react'
|
||||||
|
import type {
|
||||||
|
AtCalendarControllerProps,
|
||||||
|
AtCalendarControllerState,
|
||||||
|
} from '../../../types/calendar'
|
||||||
|
|
||||||
|
export default class AtCalendarController extends React.Component<
|
||||||
|
AtCalendarControllerProps,
|
||||||
|
AtCalendarControllerState
|
||||||
|
> {
|
||||||
|
public render(): JSX.Element {
|
||||||
|
const {
|
||||||
|
generateDate,
|
||||||
|
minDate,
|
||||||
|
maxDate,
|
||||||
|
monthFormat,
|
||||||
|
hideArrow,
|
||||||
|
} = this.props
|
||||||
|
|
||||||
|
const dayjsDate: Dayjs = dayjs(generateDate)
|
||||||
|
const dayjsMinDate: Dayjs | boolean = !!minDate && dayjs(minDate)
|
||||||
|
const dayjsMaxDate: Dayjs | boolean = !!maxDate && dayjs(maxDate)
|
||||||
|
|
||||||
|
const isMinMonth: boolean
|
||||||
|
= dayjsMinDate && dayjsMinDate.startOf('month').isSame(dayjsDate)
|
||||||
|
|
||||||
|
const isMaxMonth: boolean
|
||||||
|
= dayjsMaxDate && dayjsMaxDate.startOf('month').isSame(dayjsDate)
|
||||||
|
|
||||||
|
const minDateValue: string = dayjsMinDate
|
||||||
|
? dayjsMinDate.format('YYYY-MM')
|
||||||
|
: ''
|
||||||
|
const maxDateValue: string = dayjsMaxDate
|
||||||
|
? dayjsMaxDate.format('YYYY-MM')
|
||||||
|
: ''
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className="at-calendar__controller controller">
|
||||||
|
{hideArrow
|
||||||
|
? null
|
||||||
|
: (
|
||||||
|
<View
|
||||||
|
className={classnames('controller__arrow controller__arrow--left', {
|
||||||
|
'controller__arrow--disabled': isMinMonth,
|
||||||
|
})}
|
||||||
|
onClick={this.props.onPreMonth.bind(this, isMinMonth)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
<Picker
|
||||||
|
mode="date"
|
||||||
|
fields="month"
|
||||||
|
end={maxDateValue}
|
||||||
|
start={minDateValue}
|
||||||
|
onChange={this.props.onSelectDate}
|
||||||
|
value={dayjsDate.format('YYYY-MM')}
|
||||||
|
>
|
||||||
|
<Text className="controller__info">
|
||||||
|
{dayjsDate.format(monthFormat)}
|
||||||
|
</Text>
|
||||||
|
</Picker>
|
||||||
|
{hideArrow
|
||||||
|
? null
|
||||||
|
: (
|
||||||
|
<View
|
||||||
|
className={classnames(
|
||||||
|
'controller__arrow controller__arrow--right',
|
||||||
|
{
|
||||||
|
'controller__arrow--disabled': isMaxMonth,
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
onClick={this.props.onNextMonth.bind(this, isMaxMonth)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
180
src/components/calendar/index.scss
Normal file
180
src/components/calendar/index.scss
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
|
||||||
|
@import '../../styles/variables/default.scss';
|
||||||
|
@import '../../styles/mixins/index.scss';
|
||||||
|
.at-calendar {
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
/* elements */
|
||||||
|
&__header {
|
||||||
|
.header__flex {
|
||||||
|
@include display-flex;
|
||||||
|
@include align-items(center);
|
||||||
|
|
||||||
|
height: 72px;
|
||||||
|
color: $at-calendar-header-color;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&-item {
|
||||||
|
@include flex(0 0 calc(100% / 7));
|
||||||
|
|
||||||
|
font-size: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__list {
|
||||||
|
&.flex {
|
||||||
|
@include display-flex;
|
||||||
|
@include align-items();
|
||||||
|
@include flex-wrap(wrap);
|
||||||
|
|
||||||
|
color: $at-calendar-day-color;
|
||||||
|
|
||||||
|
.flex__item {
|
||||||
|
@include flex(0 0 calc(100% / 7));
|
||||||
|
|
||||||
|
font-size: 30px;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
margin: 5px 0;
|
||||||
|
|
||||||
|
&-container {
|
||||||
|
@include align-items(center);
|
||||||
|
@include display-flex;
|
||||||
|
|
||||||
|
width: $at-calendar-day-size;
|
||||||
|
height: $at-calendar-day-size;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
.container-text {
|
||||||
|
@include flex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&-extra {
|
||||||
|
.extra-marks {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 5px;
|
||||||
|
line-height: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
|
||||||
|
.mark {
|
||||||
|
width: $at-calendar-mark-size;
|
||||||
|
height: $at-calendar-mark-size;
|
||||||
|
margin-right: 4px;
|
||||||
|
display: inline-block;
|
||||||
|
background-color: $at-calendar-main-color;
|
||||||
|
border-radius: 50%;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--today {
|
||||||
|
color: $at-calendar-main-color;
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--blur {
|
||||||
|
color: #e1e4e7;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--selected {
|
||||||
|
color: white;
|
||||||
|
background-color: rgba($color: $at-calendar-main-color, $alpha: 1);
|
||||||
|
|
||||||
|
&-head {
|
||||||
|
border-top-left-radius: 40px;
|
||||||
|
border-bottom-left-radius: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-tail {
|
||||||
|
border-top-right-radius: 40px;
|
||||||
|
border-bottom-right-radius: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* stylelint-disable-next-line */
|
||||||
|
.extra-marks .mark {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-head.flex__item--selected-tail {
|
||||||
|
background-color: transparent;
|
||||||
|
|
||||||
|
.flex__item-container {
|
||||||
|
background-color: rgba($color: $at-calendar-main-color,
|
||||||
|
$alpha: 0.7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&__controller {
|
||||||
|
@include display-flex;
|
||||||
|
@include align-items(center);
|
||||||
|
@include justify-content(center);
|
||||||
|
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.controller__arrow {
|
||||||
|
@include flex(0 0 40px);
|
||||||
|
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 12px;
|
||||||
|
display: inline-block;
|
||||||
|
background-size: 16px 24px;
|
||||||
|
background-position: center;
|
||||||
|
background-color: #f7f8fc;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAYCAYAAADzoH0MAAAAAXNSR0IArs4c6QAAAnFJREFUOBGVVF1rE0EUnXt3tzFtWmqjKYKfqIhVa1L8FQVRWtwnXwRhidXGDwQf81oCUQMioZRCHwNSgiD4lD9QSYVKsA8KbaW1jbamX8adnWsmMnESbYz7cs6ee8/ZnZm7y9h/Xk/Gs70TE9lOZQNFWsGx1IvDJoozxNDttNpmHOfyTssBj59PHxceP6keREDlYPvBGUMJzTD5LHuKhHtC70EEQe72atMAIoLu0MWzRPxInZnEdxZib2I37L2XEI/HsSvYd44AQrqZIW5b3J8fHR0sS/2ve5DJZIzFFexnSD262QAs+c1js45zyVU6KqIwnU5bS58x0mhGhusbaz153Sw9dW+QSr3yCdwJe4wCKlCigbAWiw7PAYDQdclrAclkxk8+iDBifr3JMq3lO86VQsVMuq549RQSU687mOcNANE+VfiFxuLd6NX3e5llD8qjskqb54E8n24mk5Yf3B6ab2auBsgGC8Q7QOJ1AS6ExrSZ12s6r57CyIi99cNgswywtkkIzDB2eSSdftmuGxp57RgfOfY38HlvRWVNqgmYsDb57sDkZK5hb1RHZQ9+U8bu37S/MtOc0zUg8G2U1yOV4WrTdcXrAqT4MDq0yokXVINEwb32pS9WOJfLmboueW0OGgtP05mj3IXTum6iuXHogDtr27an9D/eQBVijr2AiB/VvUQuePenNXZBfmhKrxEl6Hjv1vAHA2lJ1wRBcH9vf5+cH6k3DZANsei1eWCwIrm6uOf1Jsenq8v7Z4ActFJxrsBMo6gC0GAebPHq/Z6bqJoVyn/EQpGFK08MmF2B/Oj1wZKqtYzxeM5MJKY6dMNPQnnePR8FubkAAAAASUVORK5CYII=");
|
||||||
|
|
||||||
|
&--right {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
&--disabled {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.controller__info {
|
||||||
|
@include flex(0 0 auto);
|
||||||
|
|
||||||
|
font-size: 30px;
|
||||||
|
margin-left: 40px;
|
||||||
|
margin-right: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-calendar-slider__main {
|
||||||
|
.main__body {
|
||||||
|
@include display-flex;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
&--animate {
|
||||||
|
transition: transform 300ms cubic-bezier(0.36, 0.66, 0.04, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.body__slider {
|
||||||
|
@include flex(0 0 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&--weapp,
|
||||||
|
&--swan {
|
||||||
|
.main__body {
|
||||||
|
height: 480px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
324
src/components/calendar/index.tsx
Normal file
324
src/components/calendar/index.tsx
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
import { View } from '@tarojs/components'
|
||||||
|
import classnames from 'classnames'
|
||||||
|
import type { Dayjs } from 'dayjs'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import React from 'react'
|
||||||
|
import type { BaseEventOrig } from '@tarojs/components/types/common'
|
||||||
|
import type {
|
||||||
|
AtCalendarDefaultProps,
|
||||||
|
AtCalendarProps,
|
||||||
|
AtCalendarPropsWithDefaults,
|
||||||
|
AtCalendarState,
|
||||||
|
Calendar,
|
||||||
|
} from '../../types/calendar'
|
||||||
|
import AtCalendarBody from './body/index'
|
||||||
|
import AtCalendarController from './controller/index'
|
||||||
|
import './index.scss'
|
||||||
|
|
||||||
|
const defaultProps: AtCalendarDefaultProps = {
|
||||||
|
validDates: [],
|
||||||
|
marks: [],
|
||||||
|
isSwiper: true,
|
||||||
|
hideArrow: false,
|
||||||
|
isVertical: false,
|
||||||
|
selectedDates: [],
|
||||||
|
isMultiSelect: false,
|
||||||
|
format: 'YYYY/MM/DD',
|
||||||
|
currentDate: Date.now(),
|
||||||
|
monthFormat: 'YYYY年MM月',
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class AtCalendar extends React.Component<
|
||||||
|
AtCalendarProps,
|
||||||
|
Readonly<AtCalendarState>
|
||||||
|
> {
|
||||||
|
static defaultProps: AtCalendarDefaultProps = defaultProps
|
||||||
|
|
||||||
|
public constructor(props: AtCalendarProps) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
const { currentDate, isMultiSelect } = props as AtCalendarPropsWithDefaults
|
||||||
|
|
||||||
|
this.state = this.getInitializeState(currentDate, isMultiSelect)
|
||||||
|
}
|
||||||
|
|
||||||
|
public UNSAFE_componentWillReceiveProps(nextProps: AtCalendarProps): void {
|
||||||
|
const { currentDate, isMultiSelect } = nextProps
|
||||||
|
if (!currentDate || currentDate === this.props.currentDate) { return }
|
||||||
|
|
||||||
|
if (isMultiSelect && this.props.isMultiSelect) {
|
||||||
|
const { start, end } = currentDate as Calendar.SelectedDate
|
||||||
|
const { start: preStart, end: preEnd } = this.props
|
||||||
|
.currentDate as Calendar.SelectedDate
|
||||||
|
|
||||||
|
if (start === preStart && preEnd === end) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const stateValue: AtCalendarState = this.getInitializeState(
|
||||||
|
currentDate,
|
||||||
|
isMultiSelect,
|
||||||
|
)
|
||||||
|
|
||||||
|
this.setState(stateValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
private getSingleSelectdState = (value: Dayjs): Partial<AtCalendarState> => {
|
||||||
|
const { generateDate } = this.state
|
||||||
|
|
||||||
|
const stateValue: Partial<AtCalendarState> = {
|
||||||
|
selectedDate: this.getSelectedDate(value.valueOf()),
|
||||||
|
}
|
||||||
|
|
||||||
|
const dayjsGenerateDate: Dayjs = value.startOf('month')
|
||||||
|
const generateDateValue: number = dayjsGenerateDate.valueOf()
|
||||||
|
|
||||||
|
if (generateDateValue !== generateDate) {
|
||||||
|
this.triggerChangeDate(dayjsGenerateDate)
|
||||||
|
stateValue.generateDate = generateDateValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return stateValue
|
||||||
|
}
|
||||||
|
|
||||||
|
private getMultiSelectedState = (
|
||||||
|
value: Dayjs,
|
||||||
|
): Pick<AtCalendarState, 'selectedDate'> => {
|
||||||
|
const { selectedDate } = this.state
|
||||||
|
const { end, start } = selectedDate
|
||||||
|
|
||||||
|
const valueUnix: number = value.valueOf()
|
||||||
|
const state: Pick<AtCalendarState, 'selectedDate'> = {
|
||||||
|
selectedDate,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end) {
|
||||||
|
state.selectedDate = this.getSelectedDate(valueUnix, 0)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
state.selectedDate.end = Math.max(valueUnix, +start)
|
||||||
|
state.selectedDate.start = Math.min(valueUnix, +start)
|
||||||
|
}
|
||||||
|
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
|
private getSelectedDate = (
|
||||||
|
start: number,
|
||||||
|
end?: number,
|
||||||
|
): Calendar.SelectedDate => {
|
||||||
|
const stateValue: Calendar.SelectedDate = {
|
||||||
|
start,
|
||||||
|
end: start,
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof end !== 'undefined') {
|
||||||
|
stateValue.end = end
|
||||||
|
}
|
||||||
|
|
||||||
|
return stateValue
|
||||||
|
}
|
||||||
|
|
||||||
|
private getInitializeState(
|
||||||
|
currentDate: Calendar.DateArg | Calendar.SelectedDate,
|
||||||
|
isMultiSelect?: boolean,
|
||||||
|
): AtCalendarState {
|
||||||
|
let end: number
|
||||||
|
let start: number
|
||||||
|
let generateDateValue: number
|
||||||
|
|
||||||
|
if (!currentDate) {
|
||||||
|
const dayjsStart = dayjs()
|
||||||
|
start = dayjsStart.startOf('day').valueOf()
|
||||||
|
generateDateValue = dayjsStart.startOf('month').valueOf()
|
||||||
|
return {
|
||||||
|
generateDate: generateDateValue,
|
||||||
|
selectedDate: {
|
||||||
|
start: '',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isMultiSelect) {
|
||||||
|
const { start: cStart, end: cEnd } = currentDate as Calendar.SelectedDate
|
||||||
|
|
||||||
|
const dayjsStart = dayjs(cStart)
|
||||||
|
|
||||||
|
start = dayjsStart.startOf('day').valueOf()
|
||||||
|
generateDateValue = dayjsStart.startOf('month').valueOf()
|
||||||
|
|
||||||
|
end = cEnd ? dayjs(cEnd).startOf('day').valueOf() : start
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const dayjsStart = dayjs(currentDate as Calendar.DateArg)
|
||||||
|
|
||||||
|
start = dayjsStart.startOf('day').valueOf()
|
||||||
|
generateDateValue = dayjsStart.startOf('month').valueOf()
|
||||||
|
|
||||||
|
end = start
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
generateDate: generateDateValue,
|
||||||
|
selectedDate: this.getSelectedDate(start, end),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private triggerChangeDate = (value: Dayjs): void => {
|
||||||
|
const { format } = this.props
|
||||||
|
|
||||||
|
if (typeof this.props.onMonthChange !== 'function') { return }
|
||||||
|
|
||||||
|
this.props.onMonthChange(value.format(format))
|
||||||
|
}
|
||||||
|
|
||||||
|
private setMonth = (vectorCount: number): void => {
|
||||||
|
const { format } = this.props
|
||||||
|
const { generateDate } = this.state
|
||||||
|
|
||||||
|
const _generateDate: Dayjs = dayjs(generateDate).add(vectorCount, 'month')
|
||||||
|
this.setState({
|
||||||
|
generateDate: _generateDate.valueOf(),
|
||||||
|
})
|
||||||
|
|
||||||
|
if (vectorCount && typeof this.props.onMonthChange === 'function') {
|
||||||
|
this.props.onMonthChange(_generateDate.format(format))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleClickPreMonth = (isMinMonth?: boolean): void => {
|
||||||
|
if (isMinMonth === true) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setMonth(-1)
|
||||||
|
|
||||||
|
if (typeof this.props.onClickPreMonth === 'function') {
|
||||||
|
this.props.onClickPreMonth()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleClickNextMonth = (isMaxMonth?: boolean): void => {
|
||||||
|
if (isMaxMonth === true) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setMonth(1)
|
||||||
|
|
||||||
|
if (typeof this.props.onClickNextMonth === 'function') {
|
||||||
|
this.props.onClickNextMonth()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// picker 选择时间改变时触发
|
||||||
|
private handleSelectDate = (e: BaseEventOrig<{ value: string }>): void => {
|
||||||
|
const { value } = e.detail
|
||||||
|
|
||||||
|
const _generateDate: Dayjs = dayjs(value)
|
||||||
|
const _generateDateValue: number = _generateDate.valueOf()
|
||||||
|
|
||||||
|
if (this.state.generateDate === _generateDateValue) { return }
|
||||||
|
|
||||||
|
this.triggerChangeDate(_generateDate)
|
||||||
|
this.setState({
|
||||||
|
generateDate: _generateDateValue,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleDayClick = (item: Calendar.Item): void => {
|
||||||
|
const { isMultiSelect } = this.props
|
||||||
|
const { isDisabled, value } = item
|
||||||
|
|
||||||
|
if (isDisabled) { return }
|
||||||
|
|
||||||
|
const dayjsDate: Dayjs = dayjs(value)
|
||||||
|
|
||||||
|
let stateValue: Partial<AtCalendarState> = {}
|
||||||
|
|
||||||
|
if (isMultiSelect) {
|
||||||
|
stateValue = this.getMultiSelectedState(dayjsDate)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
stateValue = this.getSingleSelectdState(dayjsDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState(stateValue as AtCalendarState, () => {
|
||||||
|
this.handleSelectedDate()
|
||||||
|
})
|
||||||
|
|
||||||
|
if (typeof this.props.onDayClick === 'function') {
|
||||||
|
this.props.onDayClick({ value: item.value })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleSelectedDate = (): void => {
|
||||||
|
const selectDate = this.state.selectedDate
|
||||||
|
if (typeof this.props.onSelectDate === 'function') {
|
||||||
|
const info: Calendar.SelectedDate = {
|
||||||
|
start: dayjs(selectDate.start).format(this.props.format),
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectDate.end) {
|
||||||
|
info.end = dayjs(selectDate.end).format(this.props.format)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.props.onSelectDate({
|
||||||
|
value: info,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleDayLongClick = (item: Calendar.Item): void => {
|
||||||
|
if (typeof this.props.onDayLongClick === 'function') {
|
||||||
|
this.props.onDayLongClick({ value: item.value })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): JSX.Element {
|
||||||
|
const { generateDate, selectedDate } = this.state
|
||||||
|
const {
|
||||||
|
validDates,
|
||||||
|
marks,
|
||||||
|
format,
|
||||||
|
minDate,
|
||||||
|
maxDate,
|
||||||
|
isSwiper,
|
||||||
|
className,
|
||||||
|
hideArrow,
|
||||||
|
isVertical,
|
||||||
|
monthFormat,
|
||||||
|
selectedDates,
|
||||||
|
} = this.props as AtCalendarPropsWithDefaults
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className={classnames('at-calendar', className)}>
|
||||||
|
<AtCalendarController
|
||||||
|
minDate={minDate}
|
||||||
|
maxDate={maxDate}
|
||||||
|
hideArrow={hideArrow}
|
||||||
|
monthFormat={monthFormat}
|
||||||
|
generateDate={generateDate}
|
||||||
|
onPreMonth={this.handleClickPreMonth}
|
||||||
|
onNextMonth={this.handleClickNextMonth}
|
||||||
|
onSelectDate={this.handleSelectDate}
|
||||||
|
/>
|
||||||
|
<AtCalendarBody
|
||||||
|
validDates={validDates}
|
||||||
|
marks={marks}
|
||||||
|
format={format}
|
||||||
|
minDate={minDate}
|
||||||
|
maxDate={maxDate}
|
||||||
|
isSwiper={isSwiper}
|
||||||
|
isVertical={isVertical}
|
||||||
|
selectedDate={selectedDate}
|
||||||
|
selectedDates={selectedDates}
|
||||||
|
generateDate={generateDate}
|
||||||
|
onDayClick={this.handleDayClick}
|
||||||
|
onSwipeMonth={this.setMonth}
|
||||||
|
onLongClick={this.handleDayLongClick}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
225
src/components/calendar/types/calendar.d.ts
vendored
Normal file
225
src/components/calendar/types/calendar.d.ts
vendored
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
import type dayjs from 'dayjs'
|
||||||
|
// import { BaseEvent } from '@tarojs/components/types/common'
|
||||||
|
|
||||||
|
// #region Calendar
|
||||||
|
declare namespace Calendar {
|
||||||
|
export type DateArg = string | number | Date
|
||||||
|
|
||||||
|
export type classNameType =
|
||||||
|
| string
|
||||||
|
| Array<string>
|
||||||
|
| Record<string, boolean>
|
||||||
|
|
||||||
|
export interface Mark {
|
||||||
|
value: DateArg
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ValidDate {
|
||||||
|
value: DateArg
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Item {
|
||||||
|
value: string
|
||||||
|
|
||||||
|
_value: dayjs.Dayjs
|
||||||
|
|
||||||
|
text: number
|
||||||
|
|
||||||
|
type: number
|
||||||
|
|
||||||
|
marks: Array<Mark>
|
||||||
|
|
||||||
|
isActive?: boolean
|
||||||
|
|
||||||
|
isToday?: boolean
|
||||||
|
|
||||||
|
isBeforeMin?: boolean
|
||||||
|
|
||||||
|
isAfterMax?: boolean
|
||||||
|
|
||||||
|
isDisabled?: boolean
|
||||||
|
|
||||||
|
isSelected?: boolean
|
||||||
|
|
||||||
|
isSelectedHead?: boolean
|
||||||
|
|
||||||
|
isSelectedTail?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface GroupOptions {
|
||||||
|
validDates: Array<ValidDate>
|
||||||
|
|
||||||
|
marks: Array<Mark>
|
||||||
|
|
||||||
|
format: string
|
||||||
|
|
||||||
|
selectedDates: Array<SelectedDate>
|
||||||
|
|
||||||
|
minDate?: DateArg
|
||||||
|
|
||||||
|
maxDate?: DateArg
|
||||||
|
}
|
||||||
|
|
||||||
|
export type List<T> = Array<T>
|
||||||
|
|
||||||
|
export interface ListInfo<T> {
|
||||||
|
value: number
|
||||||
|
|
||||||
|
list: List<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SelectedDate {
|
||||||
|
end?: Calendar.DateArg
|
||||||
|
|
||||||
|
start: Calendar.DateArg
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Calendar
|
||||||
|
export { Calendar }
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region AtCalendar
|
||||||
|
export interface AtCalendarPropsBase {
|
||||||
|
format?: string
|
||||||
|
|
||||||
|
validDates?: Array<Calendar.ValidDate>
|
||||||
|
|
||||||
|
minDate?: Calendar.DateArg
|
||||||
|
|
||||||
|
maxDate?: Calendar.DateArg
|
||||||
|
|
||||||
|
isSwiper?: boolean
|
||||||
|
|
||||||
|
marks?: Array<Calendar.Mark>
|
||||||
|
|
||||||
|
monthFormat?: string
|
||||||
|
|
||||||
|
hideArrow?: boolean
|
||||||
|
|
||||||
|
isVertical?: boolean
|
||||||
|
|
||||||
|
className?: Calendar.classNameType
|
||||||
|
|
||||||
|
onClickPreMonth?: () => void
|
||||||
|
|
||||||
|
onClickNextMonth?: () => void
|
||||||
|
|
||||||
|
onSelectDate?: (item: { value: Calendar.SelectedDate }) => void
|
||||||
|
|
||||||
|
onDayClick?: (item: { value: string }) => void
|
||||||
|
|
||||||
|
onDayLongClick?: (item: { value: string }) => void
|
||||||
|
|
||||||
|
onMonthChange?: (value: string) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AtCalendarSingleSelectedProps extends AtCalendarPropsBase {
|
||||||
|
isMultiSelect?: false
|
||||||
|
|
||||||
|
currentDate?: Calendar.DateArg
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AtCalendarMutilSelectedProps extends AtCalendarPropsBase {
|
||||||
|
isMultiSelect?: true
|
||||||
|
|
||||||
|
currentDate?: Calendar.SelectedDate
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AtCalendarProps =
|
||||||
|
| AtCalendarSingleSelectedProps
|
||||||
|
| AtCalendarMutilSelectedProps
|
||||||
|
|
||||||
|
export interface AtCalendarDefaultProps {
|
||||||
|
format: string
|
||||||
|
|
||||||
|
isSwiper: boolean
|
||||||
|
|
||||||
|
validDates: Array<Calendar.ValidDate>
|
||||||
|
|
||||||
|
marks: Array<Calendar.Mark>
|
||||||
|
|
||||||
|
currentDate: Calendar.DateArg | Calendar.SelectedDate
|
||||||
|
|
||||||
|
monthFormat: string
|
||||||
|
|
||||||
|
hideArrow: boolean
|
||||||
|
|
||||||
|
isVertical: boolean
|
||||||
|
|
||||||
|
isMultiSelect: boolean
|
||||||
|
|
||||||
|
selectedDates: Array<Calendar.SelectedDate>
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AtCalendarState {
|
||||||
|
generateDate: number
|
||||||
|
|
||||||
|
selectedDate: Calendar.SelectedDate
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AtCalendarPropsWithDefaults = AtCalendarProps &
|
||||||
|
AtCalendarDefaultProps
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region AtCalendarController
|
||||||
|
export interface AtCalendarControllerProps {
|
||||||
|
generateDate: Calendar.DateArg
|
||||||
|
|
||||||
|
minDate?: Calendar.DateArg
|
||||||
|
|
||||||
|
maxDate?: Calendar.DateArg
|
||||||
|
|
||||||
|
hideArrow: boolean
|
||||||
|
|
||||||
|
monthFormat: string
|
||||||
|
|
||||||
|
onPreMonth: () => void
|
||||||
|
|
||||||
|
onNextMonth: () => void
|
||||||
|
|
||||||
|
onSelectDate: (e: any) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AtCalendarControllerState {}
|
||||||
|
// #endregion
|
||||||
|
|
||||||
|
// #region AtCalendarBody
|
||||||
|
export type AtCalendarBodyListGroup = Array<Calendar.ListInfo<Calendar.Item>>
|
||||||
|
|
||||||
|
export interface AtCalendarBodyProps {
|
||||||
|
format: string
|
||||||
|
|
||||||
|
validDates: Array<Calendar.ValidDate>
|
||||||
|
|
||||||
|
marks: Array<Calendar.Mark>
|
||||||
|
|
||||||
|
isSwiper: boolean
|
||||||
|
|
||||||
|
minDate?: Calendar.DateArg
|
||||||
|
|
||||||
|
maxDate?: Calendar.DateArg
|
||||||
|
|
||||||
|
isVertical: boolean
|
||||||
|
|
||||||
|
generateDate: number
|
||||||
|
|
||||||
|
selectedDate: Calendar.SelectedDate
|
||||||
|
|
||||||
|
selectedDates: Array<Calendar.SelectedDate> | []
|
||||||
|
|
||||||
|
onDayClick: (item: Calendar.Item) => void
|
||||||
|
|
||||||
|
onSwipeMonth: (vectorCount: number) => void
|
||||||
|
|
||||||
|
onLongClick: (item: Calendar.Item) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AtCalendarBodyState {
|
||||||
|
isAnimate: boolean
|
||||||
|
|
||||||
|
offsetSize: number
|
||||||
|
|
||||||
|
listGroup: AtCalendarBodyListGroup
|
||||||
|
}
|
||||||
|
// #endregion
|
||||||
82
src/components/calendar/ui/date-list/index.tsx
Normal file
82
src/components/calendar/ui/date-list/index.tsx
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
import { Text, View } from '@tarojs/components'
|
||||||
|
import classnames from 'classnames'
|
||||||
|
import React from 'react'
|
||||||
|
import type { Calendar } from '../../types/calendar'
|
||||||
|
import * as constant from '../../common/constant'
|
||||||
|
|
||||||
|
const MAP: Record<number, string> = {
|
||||||
|
[constant.TYPE_PRE_MONTH]: 'pre',
|
||||||
|
[constant.TYPE_NOW_MONTH]: 'now',
|
||||||
|
[constant.TYPE_NEXT_MONTH]: 'next',
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
list: Calendar.List<Calendar.Item>
|
||||||
|
|
||||||
|
onClick?: (item: Calendar.Item) => void
|
||||||
|
|
||||||
|
onLongClick?: (item: Calendar.Item) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class AtCalendarList extends React.Component<Props> {
|
||||||
|
private handleClick = (item: Calendar.Item): void => {
|
||||||
|
if (typeof this.props.onClick === 'function') {
|
||||||
|
this.props.onClick(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleLongClick = (item: Calendar.Item): void => {
|
||||||
|
if (typeof this.props.onLongClick === 'function') {
|
||||||
|
this.props.onLongClick(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): JSX.Element | null {
|
||||||
|
const { list } = this.props
|
||||||
|
if (!list || list.length === 0) { return null }
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View className="at-calendar__list flex">
|
||||||
|
{list.map((item: Calendar.Item) => (
|
||||||
|
<View
|
||||||
|
key={`list-item-${item.value}`}
|
||||||
|
onClick={this.handleClick.bind(this, item)}
|
||||||
|
onLongPress={this.handleLongClick.bind(this, item)}
|
||||||
|
className={classnames(
|
||||||
|
'flex__item',
|
||||||
|
`flex__item--${MAP[item.type]}`,
|
||||||
|
{
|
||||||
|
'flex__item--today': item.isToday,
|
||||||
|
'flex__item--active': item.isActive,
|
||||||
|
'flex__item--selected': item.isSelected,
|
||||||
|
'flex__item--selected-head': item.isSelectedHead,
|
||||||
|
'flex__item--selected-tail': item.isSelectedTail,
|
||||||
|
'flex__item--blur':
|
||||||
|
item.isDisabled
|
||||||
|
|| item.type === constant.TYPE_PRE_MONTH
|
||||||
|
|| item.type === constant.TYPE_NEXT_MONTH,
|
||||||
|
},
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<View className="flex__item-container">
|
||||||
|
<View className="container-text">{item.text}</View>
|
||||||
|
</View>
|
||||||
|
<View className="flex__item-extra extra">
|
||||||
|
{item.marks && item.marks.length > 0
|
||||||
|
? (
|
||||||
|
<View className="extra-marks">
|
||||||
|
{item.marks.map((mark, key) => (
|
||||||
|
<Text key={key} className="mark">
|
||||||
|
{mark.value as React.ReactNode}
|
||||||
|
</Text>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
: null}
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/components/calendar/ui/day-list/index.tsx
Normal file
20
src/components/calendar/ui/day-list/index.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { View } from '@tarojs/components'
|
||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
export default class AtCalendarHeader extends React.Component {
|
||||||
|
public render(): JSX.Element {
|
||||||
|
return (
|
||||||
|
<View className="at-calendar__header header">
|
||||||
|
<View className="header__flex">
|
||||||
|
<View className="header__flex-item">日</View>
|
||||||
|
<View className="header__flex-item">一</View>
|
||||||
|
<View className="header__flex-item">二</View>
|
||||||
|
<View className="header__flex-item">三</View>
|
||||||
|
<View className="header__flex-item">四</View>
|
||||||
|
<View className="header__flex-item">五</View>
|
||||||
|
<View className="header__flex-item">六</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -8,16 +8,26 @@ import ViewCodeList from '@/components/viewCodeList/index'
|
|||||||
|
|
||||||
interface param {
|
interface param {
|
||||||
y: number
|
y: number
|
||||||
|
custom_print_id: number
|
||||||
|
sale_order_id: number
|
||||||
|
|
||||||
orderObj?: any
|
orderObj?: any
|
||||||
}
|
}
|
||||||
export default ({ y, orderObj = {} }: param) => {
|
export default ({ y, custom_print_id = 0, sale_order_id = 0, orderObj = {} }: param) => {
|
||||||
const [screenHeight, setScreenHeight] = useState({
|
const [screenHeight, setScreenHeight] = useState({
|
||||||
customer_service_y: 0,
|
customer_service_y: 0,
|
||||||
code_list_y: 0,
|
code_list_y: 0,
|
||||||
})
|
})
|
||||||
const [showCode, setShowCode] = useState(false)
|
const [showCode, setShowCode] = useState(false)
|
||||||
|
|
||||||
const [showPopup, setshowPopup] = useState(false)
|
const onNavigateTo = () => {
|
||||||
|
if (custom_print_id) {
|
||||||
|
goLink(`/pages/codeSetting/index?custom_print_id=${custom_print_id}`)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
goLink(`/pages/codeSetting/index?sale_order_id=${sale_order_id}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (<>
|
return (<>
|
||||||
{showCode && <View className={styles.mask} catchMove onClick={() => setShowCode(!showCode)}></View>}
|
{showCode && <View className={styles.mask} catchMove onClick={() => setShowCode(!showCode)}></View>}
|
||||||
@ -31,9 +41,9 @@ export default ({ y, orderObj = {} }: param) => {
|
|||||||
<IconFont name="icon-zidingyimadanyulan" size={46} />
|
<IconFont name="icon-zidingyimadanyulan" size={46} />
|
||||||
<Text>自定义码单预览</Text>
|
<Text>自定义码单预览</Text>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles['code_list__card--item']} onClick={() => goLink('/pages/codeSetting/index')}>
|
<View className={styles['code_list__card--item']} onClick={onNavigateTo}>
|
||||||
<IconFont name="icon-bianjizidingyimadan" size={46} />
|
<IconFont name="icon-bianjizidingyimadan" size={46} />
|
||||||
<Text>编辑自定义码单</Text>
|
<Text>{custom_print_id ? '编辑自定义码单' : '新建自定义码单'}</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>}
|
</View>}
|
||||||
<View className={styles['code_list--text']} onClick={() => setShowCode(!showCode)}>码单</View>
|
<View className={styles['code_list--text']} onClick={() => setShowCode(!showCode)}>码单</View>
|
||||||
|
|||||||
@ -21,8 +21,9 @@ interface param {
|
|||||||
messagePath?: string
|
messagePath?: string
|
||||||
showCart?: false|true
|
showCart?: false|true
|
||||||
orderObj?: any
|
orderObj?: any
|
||||||
|
orderInfo?: any
|
||||||
}
|
}
|
||||||
const MoveBtn = ({ orderObj = {}, children = null, onShopClick, showList = [], messageTitle = '', messagePath = '', showCart = false }: param) => {
|
const MoveBtn = ({ orderObj = {}, children = null, onShopClick, showList = [], messageTitle = '', messagePath = '', showCart = false, orderInfo = {} }: param) => {
|
||||||
const userInfo = useSelector(state => state.userInfo)
|
const userInfo = useSelector(state => state.userInfo)
|
||||||
// 获取购物车数据数量
|
// 获取购物车数据数量
|
||||||
const { getShopCount, commonData } = useCommonData()
|
const { getShopCount, commonData } = useCommonData()
|
||||||
@ -102,7 +103,7 @@ const MoveBtn = ({ orderObj = {}, children = null, onShopClick, showList = [], m
|
|||||||
>
|
>
|
||||||
<Image mode="aspectFit" src={formatImgUrl('/mall/float_button_customer_service.png')} />
|
<Image mode="aspectFit" src={formatImgUrl('/mall/float_button_customer_service.png')} />
|
||||||
</MovableView>}
|
</MovableView>}
|
||||||
{onShow('code') && <CodeSelect orderObj={orderObj} y={screenHeight.code as number} />}
|
{onShow('code') && <CodeSelect orderObj={orderObj} y={screenHeight.code as number} custom_print_id={orderInfo?.custom_print_id} sale_order_id={orderInfo?.id} />}
|
||||||
<Customer messageTitle={messageTitle} messagePath={messageTitle} show={customer_service_show} showCard={showCart} onClose={customerClose} />
|
<Customer messageTitle={messageTitle} messagePath={messageTitle} show={customer_service_show} showCard={showCart} onClose={customerClose} />
|
||||||
</MovableArea>
|
</MovableArea>
|
||||||
)
|
)
|
||||||
|
|||||||
74
src/components/popupModal/index.module.scss
Normal file
74
src/components/popupModal/index.module.scss
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
.popup_modal_main {
|
||||||
|
position: fixed;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
.popup_modal_con {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 16px;
|
||||||
|
width: 606px;
|
||||||
|
z-index: 1000;
|
||||||
|
.popup_modal_title {
|
||||||
|
height: 112px;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 16px 16px 0px 0px;
|
||||||
|
font-size: 32px;
|
||||||
|
color: #333333;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 112px;
|
||||||
|
}
|
||||||
|
.popup_modal_input {
|
||||||
|
height: 144px;
|
||||||
|
background: #ffffff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
.input {
|
||||||
|
width: 526px;
|
||||||
|
height: 88px;
|
||||||
|
background: #f5f5f5;
|
||||||
|
padding: 20px;
|
||||||
|
border: 1px solid #337fff;
|
||||||
|
border-radius: 16px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.popup_modal_btn {
|
||||||
|
display: flex;
|
||||||
|
width: 606px;
|
||||||
|
height: 112px;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 0px 0px 16px 16px;
|
||||||
|
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
.popup_modal_btn_item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
&:nth-child(1) {
|
||||||
|
color: #333333;
|
||||||
|
border-right: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
&:nth-child(2) {
|
||||||
|
color: #337fffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mask {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
background: rgba($color: #000000, $alpha: 0.6);
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
}
|
||||||
59
src/components/popupModal/index.tsx
Normal file
59
src/components/popupModal/index.tsx
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { Input, View } from '@tarojs/components'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import styles from './index.module.scss'
|
||||||
|
|
||||||
|
export interface Param {
|
||||||
|
show: boolean
|
||||||
|
title: string
|
||||||
|
onConfirm?: (val: string) => void
|
||||||
|
onCancel?: () => void
|
||||||
|
defaultValue?: string
|
||||||
|
onClose?: () => void
|
||||||
|
}
|
||||||
|
export default (props: Param) => {
|
||||||
|
const { show = false, title = '', onConfirm, onCancel, defaultValue = '', onClose } = props
|
||||||
|
const [value, setValue] = useState('')
|
||||||
|
const [openStatus, setOpenStatus] = useState(false)
|
||||||
|
useEffect(() => {
|
||||||
|
if (value !== defaultValue) { setValue(() => defaultValue) }
|
||||||
|
}, [defaultValue])
|
||||||
|
useEffect(() => {
|
||||||
|
if (show !== openStatus) { setOpenStatus(() => show) }
|
||||||
|
}, [show])
|
||||||
|
|
||||||
|
const onInputEven = (e) => {
|
||||||
|
const res = e.detail.value
|
||||||
|
setValue(res)
|
||||||
|
}
|
||||||
|
const onCancelEven = () => {
|
||||||
|
onCancel?.()
|
||||||
|
onCloseEven()
|
||||||
|
}
|
||||||
|
const onCloseEven = () => {
|
||||||
|
onClose?.()
|
||||||
|
setOpenStatus(false)
|
||||||
|
}
|
||||||
|
const onConfirmEven = (val) => {
|
||||||
|
onClose?.()
|
||||||
|
onConfirm?.(val)
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{openStatus && <View className={styles.popup_modal_main}>
|
||||||
|
<View className={styles.popup_modal_con}>
|
||||||
|
<View className={styles.popup_modal_title}>{title}</View>
|
||||||
|
<View className={styles.popup_modal_input}>
|
||||||
|
<View className={styles.input}>
|
||||||
|
<Input onInput={onInputEven} value={value} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View className={styles.popup_modal_btn}>
|
||||||
|
<View className={styles.popup_modal_btn_item} onClick={onCancelEven}>取消</View>
|
||||||
|
<View className={styles.popup_modal_btn_item} onClick={() => onConfirmEven(value)}>确认修改</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View className={styles.mask} catchMove onClick={onCloseEven}></View>
|
||||||
|
</View>}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
12
src/components/timePicker/index.module.scss
Normal file
12
src/components/timePicker/index.module.scss
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
.time-box {
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sure-box {
|
||||||
|
margin-left: 102px;
|
||||||
|
margin-right: 102px;
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
55
src/components/timePicker/index.tsx
Normal file
55
src/components/timePicker/index.tsx
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import { View } from '@tarojs/components'
|
||||||
|
import { memo, useState } from 'react'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import NormalButton from '../normalButton'
|
||||||
|
import styles from './index.module.scss'
|
||||||
|
import AtCalendar from '@/components/calendar/index'
|
||||||
|
import Popup from '@/components/popup'
|
||||||
|
|
||||||
|
type DateArg = string | number | Date
|
||||||
|
interface Props {
|
||||||
|
end?: DateArg
|
||||||
|
start?: DateArg
|
||||||
|
onSelectDate?: (any) => void
|
||||||
|
}
|
||||||
|
const TimePicker = (props: Props) => {
|
||||||
|
const { start = '', end = '', onSelectDate } = props
|
||||||
|
const [time, setTime] = useState<any>({})
|
||||||
|
|
||||||
|
const handTime = (e) => {
|
||||||
|
const { start, end } = e.value
|
||||||
|
// 如果选的是同一天的日期, end 自动加一天
|
||||||
|
if (!end) {
|
||||||
|
// 判断如果没选下一天的时候
|
||||||
|
e.value.end = `${dayjs(new Date(start)).add(1, 'day').format('YYYY-MM-DD')} 00:00:00`
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (start === end) {
|
||||||
|
e.value.end = `${dayjs(new Date(start)).add(1, 'day').format('YYYY-MM-DD')} 00:00:00`
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e.value.start = `${dayjs(start).format('YYYY-MM-DD')} 00:00:00`
|
||||||
|
e.value.end = `${dayjs(end).format('YYYY-MM-DD')} 00:00:00`
|
||||||
|
}
|
||||||
|
console.log('e===>', e)
|
||||||
|
setTime(e)
|
||||||
|
}
|
||||||
|
// 由于小程序的bug,部分ios和安卓显示时间的时候会有问题,原因是格式化时有`-`这个横杠
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<View className={styles['time-box']}>
|
||||||
|
<AtCalendar
|
||||||
|
isMultiSelect
|
||||||
|
format="YYYY-MM-DD 00:00:00"
|
||||||
|
currentDate={{
|
||||||
|
start,
|
||||||
|
end,
|
||||||
|
}}
|
||||||
|
onSelectDate={e => handTime(e)}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<NormalButton type="primary" onClick={() => onSelectDate?.(time)} size="normal" round customClassName={styles['sure-box']}>确认</NormalButton>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default memo(TimePicker)
|
||||||
19
src/components/timePickerPopup/index.scss
Normal file
19
src/components/timePickerPopup/index.scss
Normal file
@ -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;
|
||||||
|
}
|
||||||
23
src/components/timePickerPopup/index.tsx
Normal file
23
src/components/timePickerPopup/index.tsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { memo } from 'react'
|
||||||
|
import './index.scss'
|
||||||
|
import TimePicker from '../timePicker'
|
||||||
|
import Popup from '@/components/popup'
|
||||||
|
|
||||||
|
type DateArg = string | number | Date
|
||||||
|
interface Props {
|
||||||
|
showTime: boolean
|
||||||
|
closePopup?: () => void
|
||||||
|
end?: DateArg
|
||||||
|
start?: DateArg
|
||||||
|
onSelectDate?: (any) => void
|
||||||
|
}
|
||||||
|
const TimePickerPopup = (props: Props) => {
|
||||||
|
const { showTime = false, closePopup, start = '', end = '', onSelectDate } = props
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Popup title="选择时间" show={showTime} onClose={() => closePopup?.()}>
|
||||||
|
<TimePicker start={start} end={end} onSelectDate={onSelectDate}></TimePicker>
|
||||||
|
</Popup>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default memo(TimePickerPopup)
|
||||||
135
src/context/ContextCodeSetting/index.tsx
Normal file
135
src/context/ContextCodeSetting/index.tsx
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import React, { useContext, useReducer } from 'react'
|
||||||
|
import { CustomPrintCalculationApi } from '@/api/codeManage'
|
||||||
|
|
||||||
|
interface params {
|
||||||
|
productData?: any
|
||||||
|
dispatch?: any
|
||||||
|
}
|
||||||
|
interface PropsType {
|
||||||
|
children: React.ReactNode
|
||||||
|
}
|
||||||
|
|
||||||
|
type ACTIONTYPE =
|
||||||
|
| { type: 'setInitData'; data: any }
|
||||||
|
| { type: 'updateData'; data: any }
|
||||||
|
| { type: 'changeAdjustType'; data: number }
|
||||||
|
| { type: 'changeSaveStatus'; data: boolean }
|
||||||
|
|
||||||
|
function createCtx<A extends {} | null>() {
|
||||||
|
const ctx = React.createContext<A | undefined>(undefined)
|
||||||
|
function useCtx() {
|
||||||
|
const c = useContext(ctx)
|
||||||
|
if (c === undefined) { throw new Error('useCtx must be inside a Provider with a value') }
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return [useCtx, ctx.Provider] as const
|
||||||
|
}
|
||||||
|
export const [useCurrenCode, CurrentUserProvider] = createCtx<params>()
|
||||||
|
|
||||||
|
export default (props: PropsType) => {
|
||||||
|
const initialState = {
|
||||||
|
data: null, // 码单数据
|
||||||
|
adjust_type: 1, // 码单调整类型
|
||||||
|
custom_print_id: 0, // 自定义码单id
|
||||||
|
sale_order_id: 0, // 销售码单id
|
||||||
|
admin_data: null, // 需要传给后端的数据
|
||||||
|
save_status: false, // 是否保存了数据
|
||||||
|
}
|
||||||
|
function reducer(state: typeof initialState, action: ACTIONTYPE) {
|
||||||
|
switch (action.type) {
|
||||||
|
case 'setInitData':
|
||||||
|
return onInitData(state, action)
|
||||||
|
case 'updateData':
|
||||||
|
return onUpdateData(state, action)
|
||||||
|
case 'changeAdjustType':
|
||||||
|
return { ...state, adjust_type: action.data }
|
||||||
|
case 'changeSaveStatus':
|
||||||
|
return { ...state, save_status: action.data }
|
||||||
|
default:
|
||||||
|
throw new Error('reducer没找到对应的type')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化数据
|
||||||
|
const onInitData = (state, action) => {
|
||||||
|
const { data, custom_print_id, sale_order_id } = action
|
||||||
|
const custom_order_total = {
|
||||||
|
total_weight_error: data?.total_weight_error,
|
||||||
|
total_sale_weight: data?.total_sale_weight,
|
||||||
|
total_amount: data?.total_amount,
|
||||||
|
}
|
||||||
|
data.weight_admin = 0
|
||||||
|
data.price_admin = 0
|
||||||
|
data.weight_error_admin = 0
|
||||||
|
data?.product_details?.map((item, index) => {
|
||||||
|
item.weight_admin = 0
|
||||||
|
item.price_admin = 0
|
||||||
|
item.weight_error_admin = 0
|
||||||
|
item.index_str = index.toString()
|
||||||
|
return item?.product_color_details?.map((citem, cindex) => {
|
||||||
|
citem.index_str = `${item.index_str}_${cindex}` // 通过这个可以快速定位数组位置
|
||||||
|
citem.weight_setting = citem.weight
|
||||||
|
citem.weight_error_setting = citem.weight_error
|
||||||
|
citem.price_setting = citem.price
|
||||||
|
citem.weight_admin = 0
|
||||||
|
citem.price_admin = 0
|
||||||
|
citem.weight_error_admin = 0
|
||||||
|
return citem
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
data,
|
||||||
|
custom_print_id,
|
||||||
|
sale_order_id,
|
||||||
|
custom_order_total,
|
||||||
|
admin_data: null,
|
||||||
|
init_state: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 后端所需数据
|
||||||
|
const onUpdateData = (state, action) => {
|
||||||
|
const { data } = action
|
||||||
|
const updateData = {
|
||||||
|
adjust_type: parseInt(state.adjust_type),
|
||||||
|
purchaser_form_title_id: 0,
|
||||||
|
custom_print_product: [],
|
||||||
|
price: 0,
|
||||||
|
weight: 0,
|
||||||
|
weight_error: 0,
|
||||||
|
custom_print_id: parseInt(state.custom_print_id!),
|
||||||
|
sale_order_id: parseInt(state.sale_order_id!),
|
||||||
|
}
|
||||||
|
updateData.weight = data?.weight_admin || 0
|
||||||
|
updateData.price = data?.price_admin || 0
|
||||||
|
updateData.weight_error = data?.weight_error_admin || 0
|
||||||
|
data?.product_details?.map((item) => {
|
||||||
|
const product_item = {
|
||||||
|
price: item.price_admin || 0,
|
||||||
|
weight: item.weight_admin || 0,
|
||||||
|
weight_error: item.weight_error_admin || 0,
|
||||||
|
product_id: item.product_id,
|
||||||
|
product_name: item.product_name,
|
||||||
|
custom_print_product_color: [],
|
||||||
|
}
|
||||||
|
item?.product_color_details?.map((citem) => {
|
||||||
|
product_item.custom_print_product_color.push({
|
||||||
|
price: citem.price_admin || 0,
|
||||||
|
weight: citem.weight_admin || 0,
|
||||||
|
weight_error: citem.weight_error_admin || 0,
|
||||||
|
product_color_id: citem.product_color_id,
|
||||||
|
product_color_name: citem.product_color_name,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
updateData.custom_print_product.push(product_item)
|
||||||
|
})
|
||||||
|
return { ...state, admin_data: updateData, data: { ...data } }
|
||||||
|
}
|
||||||
|
|
||||||
|
const [productData, dispatch] = useReducer(reducer, initialState)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<CurrentUserProvider value={{ productData, dispatch }} children={props.children}></CurrentUserProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -1,22 +1,46 @@
|
|||||||
import { Text, View } from '@tarojs/components'
|
import { Text, View } from '@tarojs/components'
|
||||||
import { useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import ColorItem from '../colorItem'
|
import ColorItem from '../colorItem'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
import IconFont from '@/components/iconfont/iconfont'
|
import IconFont from '@/components/iconfont/iconfont'
|
||||||
import SelectList from '@/components/selectList'
|
import SelectList from '@/components/selectList'
|
||||||
import Search from '@/components/search'
|
import Search from '@/components/search'
|
||||||
|
import { GetCustomCodeLApi } from '@/api/codeManage'
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
|
const [formData, setFormData] = useState({
|
||||||
|
sale_start_time: '',
|
||||||
|
sale_end_time: '',
|
||||||
|
any_query: '',
|
||||||
|
})
|
||||||
|
// 获取码单列表
|
||||||
|
const [list, setList] = useState<any[]>([])
|
||||||
|
const { fetchData: getCustomCode } = GetCustomCodeLApi()
|
||||||
|
const onCustomCode = async() => {
|
||||||
|
const res = await getCustomCode(formData)
|
||||||
|
setList(() => res.data?.list)
|
||||||
|
}
|
||||||
|
useEffect(() => {
|
||||||
|
onCustomCode()
|
||||||
|
}, [formData])
|
||||||
|
|
||||||
|
const onSearch = (val) => {
|
||||||
|
setFormData(e => ({ ...e, any_query: val }))
|
||||||
|
}
|
||||||
return <View>
|
return <View>
|
||||||
<View className={styles.code_list_search}>
|
<View className={styles.code_list_search}>
|
||||||
<View className={styles['code_list_search--code']}><Search placeholder="请输入单据抬头/客户/单号" /></View>
|
<View className={styles['code_list_search--code']}><Search placeholder="请输入单据抬头/客户/单号" changeOnSearch={onSearch} debounceTime={300} /></View>
|
||||||
<View className={styles['code_list_search--data']}>
|
<View className={styles['code_list_search--data']}>
|
||||||
<IconFont name="icon-riqi" size={43} />
|
<IconFont name="icon-riqi" size={43} />
|
||||||
<Text>日期</Text>
|
<Text>日期</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.code_list_con}>
|
<View className={styles.code_list_con}>
|
||||||
<ColorItem />
|
{list?.map((item) => {
|
||||||
|
return <View key={item.id}>
|
||||||
|
<ColorItem info={item} />
|
||||||
|
</View>
|
||||||
|
})}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,36 @@
|
|||||||
import { Text, View } from '@tarojs/components'
|
import { Text, View } from '@tarojs/components'
|
||||||
|
import { useMemo } from 'react'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
import LabAndImg from '@/components/LabAndImg'
|
import LabAndImg from '@/components/LabAndImg'
|
||||||
|
import { formatPriceDiv, formatWeightDiv } from '@/common/fotmat'
|
||||||
|
|
||||||
export default () => {
|
interface Param {
|
||||||
|
info: {
|
||||||
|
purchaser_name: string
|
||||||
|
purchaser_phone: string
|
||||||
|
sale_order_no: string
|
||||||
|
title_name: string
|
||||||
|
sale_mode: number
|
||||||
|
product_color_count: number
|
||||||
|
product_count: number
|
||||||
|
roll: number
|
||||||
|
total_amount: number
|
||||||
|
total_sale_weight: number
|
||||||
|
sale_mode_name: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default (props: Param) => {
|
||||||
|
const { info } = props
|
||||||
|
const product = useMemo(() => {
|
||||||
|
return {
|
||||||
|
message: `${formatWeightDiv(info?.total_sale_weight)}kg | ¥${formatPriceDiv(info?.total_amount)}`,
|
||||||
|
count: `订单信息:共 ${info?.product_count} 种面料,${info?.product_color_count} 种颜色,共 ${info?.roll} 条`,
|
||||||
|
}
|
||||||
|
}, [info])
|
||||||
return <View className={styles.code_list_item}>
|
return <View className={styles.code_list_item}>
|
||||||
<View className={styles.code_list_con__title}>
|
<View className={styles.code_list_con__title}>
|
||||||
<Text>订单号:XS-LY-2208220092</Text>
|
<Text>订单号:{info?.sale_order_no}</Text>
|
||||||
<View className={styles.code_list_con__title_mode}>大货</View>
|
<View className={styles.code_list_con__title_mode}>{info?.sale_mode_name}</View>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.code_list_desc}>
|
<View className={styles.code_list_desc}>
|
||||||
<View className={styles.image}>
|
<View className={styles.image}>
|
||||||
@ -15,19 +39,19 @@ export default () => {
|
|||||||
<View className={styles.company}>
|
<View className={styles.company}>
|
||||||
<View className={styles.company_item}>
|
<View className={styles.company_item}>
|
||||||
<Text>公司抬头:</Text>
|
<Text>公司抬头:</Text>
|
||||||
<Text>XL纺织公司</Text>
|
<Text>{info?.title_name}</Text>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.company_item}>
|
<View className={styles.company_item}>
|
||||||
<Text>客户名称:</Text>
|
<Text>客户名称:</Text>
|
||||||
<Text>上生企业制衣厂</Text>
|
<Text>{info?.purchaser_name}</Text>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.company_item}>
|
<View className={styles.company_item}>
|
||||||
<Text>商品信息:</Text>
|
<Text>商品信息:</Text>
|
||||||
<Text>106.60kg|¥1,332.00</Text>
|
<Text>{product.message}</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.code_list_number}> 共 2 种面料,3 种颜色,共 4 条</View>
|
<View className={styles.code_list_number}>{product.count}</View>
|
||||||
<View className={styles.code_list_bottom}>
|
<View className={styles.code_list_bottom}>
|
||||||
<View className={styles.code_list_bottom_item}>码单浏览</View>
|
<View className={styles.code_list_bottom_item}>码单浏览</View>
|
||||||
<View className={styles.code_list_bottom_item}>码单编辑</View>
|
<View className={styles.code_list_bottom_item}>码单编辑</View>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { Text, View } from '@tarojs/components'
|
import { Text, View } from '@tarojs/components'
|
||||||
|
import { useDidShow } from '@tarojs/taro'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import type { CompanyParam } from '../companyItem'
|
import type { CompanyParam } from '../companyItem'
|
||||||
import CompanyItem from '../companyItem'
|
import CompanyItem from '../companyItem'
|
||||||
@ -10,12 +11,12 @@ import { goLink } from '@/common/common'
|
|||||||
export default () => {
|
export default () => {
|
||||||
const { fetchData } = weightListApi()
|
const { fetchData } = weightListApi()
|
||||||
const [list, setList] = useState<CompanyParam['value'][]>([])
|
const [list, setList] = useState<CompanyParam['value'][]>([])
|
||||||
useEffect(() => {
|
useDidShow(() => {
|
||||||
(async() => {
|
(async() => {
|
||||||
const res = await fetchData()
|
const res = await fetchData()
|
||||||
setList(() => res.data?.list)
|
setList(() => res.data?.list)
|
||||||
})()
|
})()
|
||||||
}, [])
|
})
|
||||||
return <View className={styles.company_main}>
|
return <View className={styles.company_main}>
|
||||||
<View className={styles.company_search}>
|
<View className={styles.company_search}>
|
||||||
<View className={styles['code_list_search--code']}><Search placeholder="请输入单据抬头/客户/单号" /></View>
|
<View className={styles['code_list_search--code']}><Search placeholder="请输入单据抬头/客户/单号" /></View>
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
import { View } from '@tarojs/components'
|
import { View } from '@tarojs/components'
|
||||||
import { useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
import CodeModel from './components/codeModel'
|
import CodeModel from './components/codeModel'
|
||||||
import CompanyModel from './components/companyModel'
|
import CompanyModel from './components/companyModel'
|
||||||
import SelectList from '@/components/selectList'
|
import SelectList from '@/components/selectList'
|
||||||
|
import { GetCustomCodeLApi } from '@/api/codeManage'
|
||||||
|
import TimePickerPopup from '@/components/timePickerPopup'
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const selectList = [
|
const selectList = [
|
||||||
@ -15,5 +17,6 @@ export default () => {
|
|||||||
<SelectList list={selectList} defaultIndex={selectIndex} onSelect={index => setSelectIndex(index)} />
|
<SelectList list={selectList} defaultIndex={selectIndex} onSelect={index => setSelectIndex(index)} />
|
||||||
{selectIndex == 1 && <CodeModel />}
|
{selectIndex == 1 && <CodeModel />}
|
||||||
{selectIndex == 2 && <CompanyModel />}
|
{selectIndex == 2 && <CompanyModel />}
|
||||||
|
{/* <TimePickerPopup showTime /> */}
|
||||||
</View>
|
</View>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,17 @@
|
|||||||
import { View } from '@tarojs/components'
|
import { View } from '@tarojs/components'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
|
|
||||||
export default () => {
|
export type BottomItem = 'del'|'preview'|'save'
|
||||||
|
interface Param {
|
||||||
|
onClick?: (val: BottomItem) => void
|
||||||
|
}
|
||||||
|
export default (props: Param) => {
|
||||||
|
const { onClick } = props
|
||||||
return <View>
|
return <View>
|
||||||
<View className={styles.bottom_btn}>
|
<View className={styles.bottom_btn}>
|
||||||
<View className={styles.bottom_btn_item}>删除码单</View>
|
<View className={styles.bottom_btn_item} onClick={() => onClick?.('del')}>删除码单</View>
|
||||||
<View className={styles.bottom_btn_item}>预览码单</View>
|
<View className={styles.bottom_btn_item} onClick={() => onClick?.('preview')}>预览码单</View>
|
||||||
<View className={styles.bottom_btn_item}>保存码单</View>
|
<View className={styles.bottom_btn_item} onClick={() => onClick?.('save')}>保存码单</View>
|
||||||
</View>
|
</View>
|
||||||
<View className="common_safe_area_y"></View>
|
<View className="common_safe_area_y"></View>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@ -15,8 +15,8 @@ export default () => {
|
|||||||
<Text className={styles.mode_status}>大货</Text>
|
<Text className={styles.mode_status}>大货</Text>
|
||||||
</View>
|
</View>
|
||||||
{new Array(5).fill('').map((item, index) => <View key={index} className={styles['product_list__item--con']}>
|
{new Array(5).fill('').map((item, index) => <View key={index} className={styles['product_list__item--con']}>
|
||||||
<ProductItem />
|
<ProductItem codeItem={{}} />
|
||||||
<SettingNumber />
|
{/* <SettingNumber /> */}
|
||||||
</View>)}
|
</View>)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@ -5,39 +5,4 @@
|
|||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
padding: 0 32px 32px 32px;
|
padding: 0 32px 32px 32px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
.product_list__item {
|
|
||||||
.product_list__item--title {
|
|
||||||
height: 82px;
|
|
||||||
font-size: 28px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
color: #000000;
|
|
||||||
align-items: center;
|
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
|
||||||
.product_title {
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
.mode_status {
|
|
||||||
width: 60px;
|
|
||||||
height: 30px;
|
|
||||||
font-size: 20px;
|
|
||||||
background: #337fff;
|
|
||||||
border-radius: 8px;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 30px;
|
|
||||||
color: #fff;
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
.con {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.update {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
color: #337fffff;
|
|
||||||
font-size: 28px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,27 +1,27 @@
|
|||||||
import { Text, View } from '@tarojs/components'
|
import { Text, View } from '@tarojs/components'
|
||||||
|
import { memo, useCallback, useMemo, useState } from 'react'
|
||||||
|
import classNames from 'classnames'
|
||||||
import ProductItem from '../productItem'
|
import ProductItem from '../productItem'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
|
import ProductBlock from './productBlock'
|
||||||
import IconFont from '@/components/iconfont/iconfont'
|
import IconFont from '@/components/iconfont/iconfont'
|
||||||
import LabAndImg from '@/components/LabAndImg'
|
import LabAndImg from '@/components/LabAndImg'
|
||||||
import { goLink } from '@/common/common'
|
import { goLink } from '@/common/common'
|
||||||
|
|
||||||
export default () => {
|
interface Parma {
|
||||||
|
orderData: any
|
||||||
|
}
|
||||||
|
export default memo((props: Parma) => {
|
||||||
|
const { orderData = {} } = props
|
||||||
|
const productList = useMemo(() => {
|
||||||
|
return orderData?.product_details || []
|
||||||
|
}, [orderData])
|
||||||
return <>
|
return <>
|
||||||
<View className={styles.product_list}>
|
<View className={styles.product_list}>
|
||||||
<View className={styles.product_list__item}>
|
{productList?.map((item) => {
|
||||||
<View className={styles['product_list__item--title']}>
|
return <ProductBlock key={item.id} productInfo={item} sale_mode_name={orderData?.sale_mode_name} />
|
||||||
<View className={styles.con}>
|
})}
|
||||||
<Text className={styles.product_title}>5215# 26S双纱亲水滑爽棉</Text>
|
|
||||||
<IconFont name="icon-shuru" size={50} />
|
|
||||||
<Text className={styles.mode_status}>大货</Text>
|
|
||||||
</View>
|
|
||||||
<View className={styles.update} onClick={() => goLink('/pages/codeSetting/codeColorList/index')}>
|
|
||||||
<Text>编辑</Text>
|
|
||||||
<IconFont name="icon-rukou" size={35} />
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
{new Array(5).fill('').map((item, index) => <View key={index}><ProductItem /></View>)}
|
|
||||||
</View>
|
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
}
|
})
|
||||||
|
|||||||
@ -0,0 +1,54 @@
|
|||||||
|
.product_list__item {
|
||||||
|
.product_list__item--title {
|
||||||
|
height: 82px;
|
||||||
|
font-size: 28px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
color: #000000;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
.product_title {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
.mode_status {
|
||||||
|
width: 60px;
|
||||||
|
height: 30px;
|
||||||
|
font-size: 20px;
|
||||||
|
background: #337fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
color: #fff;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
.con {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.update {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: #337fffff;
|
||||||
|
font-size: 28px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.product_list__item--con {
|
||||||
|
transition: height 0.3s ease-in-out;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.open_up_icon {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
.close_up_icon {
|
||||||
|
transform: rotate(0);
|
||||||
|
}
|
||||||
|
.up_btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 72px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 28px;
|
||||||
|
color: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,69 @@
|
|||||||
|
import { Text, View } from '@tarojs/components'
|
||||||
|
import { memo, useCallback, useContext, useState } from 'react'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
import ProductItem from '../../productItem'
|
||||||
|
import styles from './index.module.scss'
|
||||||
|
import IconFont from '@/components/iconfont/iconfont'
|
||||||
|
import PopupModal from '@/components/popupModal'
|
||||||
|
import { useCurrenCode } from '@/context/ContextCodeSetting'
|
||||||
|
import { goLink } from '@/common/common'
|
||||||
|
|
||||||
|
interface Parma {
|
||||||
|
productInfo: any
|
||||||
|
sale_mode_name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type IndexParam = {
|
||||||
|
onChange: (val: string) => void
|
||||||
|
} & Parma
|
||||||
|
|
||||||
|
export default memo((props: Parma) => {
|
||||||
|
const { productInfo } = props
|
||||||
|
const { dispatch, productData } = useCurrenCode()
|
||||||
|
const getNewName = useCallback((name) => {
|
||||||
|
const index = productInfo.index_str.split('_')[0]
|
||||||
|
productData.data.product_details[index] = {
|
||||||
|
...productData.data.product_details[index],
|
||||||
|
product_name: name,
|
||||||
|
}
|
||||||
|
dispatch({ type: 'updateData', data: { ...productData.data } })
|
||||||
|
}, [productInfo])
|
||||||
|
return <>
|
||||||
|
<Index {...props} onChange={getNewName} />
|
||||||
|
</>
|
||||||
|
})
|
||||||
|
|
||||||
|
const Index = memo((props: IndexParam) => {
|
||||||
|
const { productInfo, sale_mode_name } = props
|
||||||
|
const [showEdit, setShowEdit] = useState(false)
|
||||||
|
const [upStatus, setStatus] = useState(false)
|
||||||
|
const [title, setTitle] = useState('')
|
||||||
|
console.log('productInfo内容:::', productInfo)
|
||||||
|
const onUpdate = () => {
|
||||||
|
setTitle(productInfo.product_name)
|
||||||
|
setShowEdit(true)
|
||||||
|
}
|
||||||
|
const onConfirm = (item) => {
|
||||||
|
props.onChange?.(item)
|
||||||
|
}
|
||||||
|
return <>
|
||||||
|
<View className={styles.product_list__item}>
|
||||||
|
<View className={styles['product_list__item--title']} >
|
||||||
|
<View className={styles.con} onClick={onUpdate}>
|
||||||
|
<Text className={styles.product_title}>{productInfo.product_name}</Text>
|
||||||
|
<IconFont name="icon-shuru" size={50} />
|
||||||
|
<Text className={styles.mode_status}>{sale_mode_name}</Text>
|
||||||
|
</View>
|
||||||
|
<View className={styles.update} onClick={() => goLink('/pages/codeSetting/codeColorList/index')}>
|
||||||
|
<Text>编辑</Text>
|
||||||
|
<IconFont name="icon-rukou" size={35} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View style={{ height: upStatus ? '0rpx' : `${194 * productInfo?.product_color_details?.length}rpx` }} className={classNames(styles['product_list__item--con'])}>
|
||||||
|
{productInfo?.product_color_details?.map(citem => <View key={citem?.product_color_id}><ProductItem codeItem={citem} /></View>)}
|
||||||
|
</View>
|
||||||
|
<View className={styles.up_btn} onClick={() => setStatus(!upStatus)}>{upStatus ? '展开' : '收起'}<View className={classNames(styles.up_icon, upStatus ? styles.open_up_icon : styles.close_up_icon)}><IconFont name="icon-shangla" size={35} /></View></View>
|
||||||
|
</View>
|
||||||
|
<PopupModal show={showEdit} title="修改面料名称" defaultValue={title} onClose={() => setShowEdit(false)} onConfirm={onConfirm} />
|
||||||
|
</>
|
||||||
|
})
|
||||||
@ -86,33 +86,33 @@ const CounterDisplayName = (props: params) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onInputEven = (e) => {
|
const onInputEven = (e) => {
|
||||||
const res = e.detail.value
|
// const res = e.detail.value
|
||||||
if (res === '') {
|
// if (res === '') {
|
||||||
onChange?.(minNum)
|
// onChange?.(minNum)
|
||||||
}
|
// }
|
||||||
else if (!Number.isNaN(Number(res))) {
|
// else if (!Number.isNaN(Number(res))) {
|
||||||
let count = formatDigits(res)
|
// let count = formatDigits(res)
|
||||||
count = checkData(count)
|
// count = checkData(count)
|
||||||
onChange?.(parseFloat(count as string))
|
// onChange?.(parseFloat(count as string))
|
||||||
}
|
// }
|
||||||
else {
|
// else {
|
||||||
const num = parseFloat(res)
|
// const num = parseFloat(res)
|
||||||
if (!Number.isNaN(num)) {
|
// if (!Number.isNaN(num)) {
|
||||||
let count = formatDigits(num)
|
// let count = formatDigits(num)
|
||||||
count = checkData(count)
|
// count = checkData(count)
|
||||||
onChange?.(count as number)
|
// onChange?.(count as number)
|
||||||
}
|
// }
|
||||||
else {
|
// else {
|
||||||
onChange?.(defaultNum)
|
// onChange?.(defaultNum)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
const onBluerEven = (e) => {
|
const onBluerEven = (e) => {
|
||||||
const num = parseFloat(e.detail.value)
|
const num = parseFloat(e.detail.value)
|
||||||
if (e.detail.value == '') {
|
if (e.detail.value == '') {
|
||||||
onBlue?.(minNum)
|
onBlue?.(minNum < 0 ? 0 : minNum)
|
||||||
setValue({ count: minNum })
|
setValue({ count: minNum < 0 ? 0 : minNum })
|
||||||
}
|
}
|
||||||
else if (!Number.isNaN(num)) {
|
else if (!Number.isNaN(num)) {
|
||||||
let count = formatDigits(num)
|
let count = formatDigits(num)
|
||||||
|
|||||||
41
src/pages/codeSetting/components/main/index.module.scss
Normal file
41
src/pages/codeSetting/components/main/index.module.scss
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
.code_list__main {
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
min-height: 100vh;
|
||||||
|
padding-bottom: 150px;
|
||||||
|
.code_list__head {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 24px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.code_list_con {
|
||||||
|
padding: 0 24px;
|
||||||
|
margin-top: 24px;
|
||||||
|
.code_des {
|
||||||
|
padding: 0 32px 32px 32px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 16px;
|
||||||
|
margin-top: 24px;
|
||||||
|
.code_des_title {
|
||||||
|
height: 82px;
|
||||||
|
line-height: 82px;
|
||||||
|
font-size: 28px;
|
||||||
|
color: #000000;
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
.code_des_item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
font-size: 28px;
|
||||||
|
color: rgba(0, 0, 0, 0.8);
|
||||||
|
margin-top: 24px;
|
||||||
|
.code_des_weight {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.code_des_price {
|
||||||
|
color: #f64861;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
191
src/pages/codeSetting/components/main/index.tsx
Normal file
191
src/pages/codeSetting/components/main/index.tsx
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
import { Text, View } from '@tarojs/components'
|
||||||
|
import { useRouter } from '@tarojs/taro'
|
||||||
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||||
|
import PayeeHead from '../payeeHead'
|
||||||
|
import type { CompanyItem } from '../payeeHead'
|
||||||
|
import WholeOrderSetting from '../wholeOrderSetting'
|
||||||
|
import type { BottomItem } from '../bottomBtn'
|
||||||
|
import BottomBtn from '../bottomBtn'
|
||||||
|
import ProductSetting from '../productSetting'
|
||||||
|
import ColorSetting from '../colorSetting'
|
||||||
|
import styles from './index.module.scss'
|
||||||
|
import SelectList from '@/components/selectList'
|
||||||
|
import { CreateCustomCodeApi, CustomPrintCalculationApi, GetCustomCodeDetailApi, GetCustomCodeInitApi, UpdateCustomCodeApi } from '@/api/codeManage'
|
||||||
|
import { formatPriceDiv, formatWeightDiv } from '@/common/fotmat'
|
||||||
|
import { useCurrenCode } from '@/context/ContextCodeSetting'
|
||||||
|
import { alert } from '@/common/common'
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
const { productData, dispatch } = useCurrenCode()
|
||||||
|
const { custom_print_id, sale_order_id } = useRouter().params
|
||||||
|
const selectList = [
|
||||||
|
{ value: 1, label: '按整单' },
|
||||||
|
{ value: 2, label: '按面料' },
|
||||||
|
{ value: 3, label: '按颜色' },
|
||||||
|
]
|
||||||
|
const [modeIndex, setModeIndex] = useState(1)
|
||||||
|
const getTypeSelect = useCallback((index) => {
|
||||||
|
setModeIndex(index)
|
||||||
|
dispatch({ type: 'changeAdjustType', data: index })
|
||||||
|
getDataInit()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const companyId = useRef<number>(0)
|
||||||
|
const [codeData, setCodeData] = useState<any>(null)
|
||||||
|
|
||||||
|
// 获取新增码单详情
|
||||||
|
const { fetchData: getCustomCodeInit } = GetCustomCodeInitApi()
|
||||||
|
const onCustomCodeInit = async() => {
|
||||||
|
const res = await getCustomCodeInit({ id: sale_order_id })
|
||||||
|
setCodeData(() => res?.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取码单编辑详情
|
||||||
|
const { fetchData: getCustomCodeDetail } = GetCustomCodeDetailApi()
|
||||||
|
const onGetCustomCodeDetail = async() => {
|
||||||
|
const res = await getCustomCodeDetail({ id: custom_print_id })
|
||||||
|
setCodeData(() => res?.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDataInit = async() => {
|
||||||
|
if (custom_print_id) {
|
||||||
|
await onGetCustomCodeDetail()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await onCustomCodeInit()
|
||||||
|
}
|
||||||
|
dispatch({ type: 'changeSaveStatus', data: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getDataInit()
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (codeData) {
|
||||||
|
companyId.current = codeData?.default_title_id
|
||||||
|
codeData && dispatch({
|
||||||
|
type: 'setInitData',
|
||||||
|
data: codeData,
|
||||||
|
sale_order_id: sale_order_id || 0,
|
||||||
|
custom_print_id: custom_print_id || 0,
|
||||||
|
})
|
||||||
|
setCustomTotal(() => ({
|
||||||
|
total_weight_error: codeData.total_weight_error,
|
||||||
|
total_sale_weight: codeData.total_sale_weight,
|
||||||
|
total_amount: codeData.total_amount,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}, [codeData])
|
||||||
|
|
||||||
|
// 默认抬头
|
||||||
|
const company = useMemo(() => {
|
||||||
|
console.log('productData默认抬头:::', productData)
|
||||||
|
return {
|
||||||
|
title: productData?.data?.title_name,
|
||||||
|
purchaser_name: productData?.data?.purchaser_name,
|
||||||
|
phone: productData?.data?.purchaser_phone,
|
||||||
|
is_default: true,
|
||||||
|
}
|
||||||
|
}, [productData])
|
||||||
|
|
||||||
|
// 修改码单
|
||||||
|
const { fetchData: createCustomCodeApi } = CreateCustomCodeApi()
|
||||||
|
const { fetchData: updateCustomCodeApi } = UpdateCustomCodeApi()
|
||||||
|
|
||||||
|
// 获取码单抬头
|
||||||
|
const getCompany = useCallback((val: CompanyItem) => {
|
||||||
|
companyId.current = val?.id || 0
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
// 按钮事件
|
||||||
|
const onBottomClick = useCallback((type: BottomItem) => {
|
||||||
|
(async() => {
|
||||||
|
if (type === 'save') {
|
||||||
|
const res = custom_print_id
|
||||||
|
? await updateCustomCodeApi({ ...productData.admin_data })
|
||||||
|
: await createCustomCodeApi({ ...productData.admin_data })
|
||||||
|
if (res.success) {
|
||||||
|
getDataInit()
|
||||||
|
dispatch({ type: 'changeSaveStatus', data: true })
|
||||||
|
alert.success('保存成功!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
}, [productData])
|
||||||
|
|
||||||
|
// 自定义码单合计数据
|
||||||
|
const [customTotal, setCustomTotal] = useState({
|
||||||
|
total_weight_error: 0,
|
||||||
|
total_sale_weight: 0,
|
||||||
|
total_amount: 0,
|
||||||
|
})
|
||||||
|
useEffect(() => {
|
||||||
|
if (productData.admin_data) {
|
||||||
|
updateCustomOrderTotal(productData.admin_data)
|
||||||
|
}
|
||||||
|
}, [productData.admin_data])
|
||||||
|
|
||||||
|
// 更新合计数据
|
||||||
|
const { fetchData: customPrintCalculationApi } = CustomPrintCalculationApi()
|
||||||
|
const updateCustomOrderTotal = async(updateData) => {
|
||||||
|
const res = await customPrintCalculationApi(updateData)
|
||||||
|
if (res.success) {
|
||||||
|
setCustomTotal(() => ({
|
||||||
|
total_weight_error: res?.data?.total_weight_error,
|
||||||
|
total_sale_weight: res?.data?.total_sale_weight,
|
||||||
|
total_amount: res?.data?.total_amount,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return <View className={styles.code_list__main}>
|
||||||
|
<View className={styles.code_list__head}>
|
||||||
|
<PayeeHead defaultValue={company} onSelect={getCompany} />
|
||||||
|
</View>
|
||||||
|
<SelectList onSelect={getTypeSelect} list={selectList} defaultIndex={1} />
|
||||||
|
<View className={styles.code_list_con}>
|
||||||
|
<View>
|
||||||
|
{modeIndex == 1 && <WholeOrderSetting orderData={productData?.data} />}
|
||||||
|
</View>
|
||||||
|
<View>
|
||||||
|
{modeIndex == 2 && <ProductSetting orderData={productData?.data} />}
|
||||||
|
</View>
|
||||||
|
<View>
|
||||||
|
{modeIndex == 3 && <ColorSetting orderData={productData?.data} />}
|
||||||
|
</View>
|
||||||
|
<View className={styles.code_des}>
|
||||||
|
<View className={styles.code_des_title}>自定义单据信息</View>
|
||||||
|
<View className={styles.code_des_item}>
|
||||||
|
<Text>合计空差</Text>
|
||||||
|
<Text>{formatWeightDiv(customTotal.total_weight_error)}kg</Text>
|
||||||
|
</View>
|
||||||
|
<View className={styles.code_des_item}>
|
||||||
|
<Text>合计重量</Text>
|
||||||
|
<Text className={styles.code_des_weight}>{formatWeightDiv(customTotal.total_sale_weight)}kg</Text>
|
||||||
|
</View>
|
||||||
|
<View className={styles.code_des_item}>
|
||||||
|
<Text>合计金额</Text>
|
||||||
|
<Text className={styles.code_des_price}>¥{formatPriceDiv(customTotal.total_amount)}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View className={styles.code_des}>
|
||||||
|
<View className={styles.code_des_title}>原始单据信息</View>
|
||||||
|
<View className={styles.code_des_item}>
|
||||||
|
<Text>合计空差</Text>
|
||||||
|
<Text>{formatWeightDiv(productData?.data?.original_total_weight_error)}kg</Text>
|
||||||
|
</View>
|
||||||
|
<View className={styles.code_des_item}>
|
||||||
|
<Text>合计重量</Text>
|
||||||
|
<Text className={styles.code_des_weight}>{formatWeightDiv(productData?.data?.original_total_sale_weight)}kg</Text>
|
||||||
|
</View>
|
||||||
|
<View className={styles.code_des_item}>
|
||||||
|
<Text>合计金额</Text>
|
||||||
|
<Text className={styles.code_des_price}>¥{formatPriceDiv(productData?.data?.original_total_amount)}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<BottomBtn onClick={onBottomClick} />
|
||||||
|
<View className="common_safe_area_y"></View>
|
||||||
|
</View>
|
||||||
|
}
|
||||||
@ -1,18 +1,44 @@
|
|||||||
import { Text, View } from '@tarojs/components'
|
import { Text, View } from '@tarojs/components'
|
||||||
|
import Taro from '@tarojs/taro'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
import IconFont from '@/components/iconfont/iconfont'
|
import IconFont from '@/components/iconfont/iconfont'
|
||||||
|
import { goLink } from '@/common/common'
|
||||||
|
import NameLabel from '@/components/nameLabel'
|
||||||
|
|
||||||
export default () => {
|
export interface CompanyItem { title: string; purchaser_name: string; phone: string; is_default?: boolean; id?: number }
|
||||||
return <View className={styles.payee_head}>
|
interface CompanyParam {
|
||||||
<View className={styles['payee_head--icon']}>布</View>
|
defaultValue?: CompanyItem
|
||||||
|
onSelect?: (data: CompanyItem) => void
|
||||||
|
}
|
||||||
|
export default (props: CompanyParam) => {
|
||||||
|
const { defaultValue, onSelect } = props
|
||||||
|
const [data, setData] = useState<CompanyItem>()
|
||||||
|
useEffect(() => {
|
||||||
|
if (defaultValue) { setData(() => defaultValue) }
|
||||||
|
}, [defaultValue])
|
||||||
|
const goLink = () => {
|
||||||
|
Taro.navigateTo({
|
||||||
|
url: '/pages/weightList/index',
|
||||||
|
events: {
|
||||||
|
getSelectCompanyEvent(data) {
|
||||||
|
console.log('data::', data)
|
||||||
|
setData(() => data)
|
||||||
|
onSelect?.(data as CompanyItem)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return <View className={styles.payee_head} onClick={goLink}>
|
||||||
|
<NameLabel name={data?.title || ''} />
|
||||||
<View className={styles.payee_head__desc}>
|
<View className={styles.payee_head__desc}>
|
||||||
<View className={styles.payee_head__desc__company}>
|
<View className={styles.payee_head__desc__company}>
|
||||||
<Text>布郡纺织有限公司</Text>
|
<Text>{data?.title}</Text>
|
||||||
<Text>默认抬头</Text>
|
{data?.is_default && <Text>默认抬头</Text>}
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.payee_head__desc__name}>
|
<View className={styles.payee_head__desc__name}>
|
||||||
<Text>杨翰俊</Text>
|
<Text>{data?.purchaser_name}</Text>
|
||||||
<Text>189467876642</Text>
|
<Text>{data?.phone}</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.more}><IconFont name="icon-xiala" size={50} color="#979797" /></View>
|
<View className={styles.more}><IconFont name="icon-xiala" size={50} color="#979797" /></View>
|
||||||
|
|||||||
@ -1,24 +1,72 @@
|
|||||||
import { Text, View } from '@tarojs/components'
|
import { Text, View } from '@tarojs/components'
|
||||||
|
import { memo, useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
import LabAndImg from '@/components/LabAndImg'
|
import LabAndImg from '@/components/LabAndImg'
|
||||||
import IconFont from '@/components/iconfont/iconfont'
|
import IconFont from '@/components/iconfont/iconfont'
|
||||||
|
import { formatPriceDiv, formatWeightDiv } from '@/common/fotmat'
|
||||||
|
import PopupModal from '@/components/popupModal'
|
||||||
|
import { useCurrenCode } from '@/context/ContextCodeSetting'
|
||||||
|
|
||||||
export default () => {
|
interface Param {
|
||||||
|
codeItem: any
|
||||||
|
}
|
||||||
|
|
||||||
|
type IndexParam = {
|
||||||
|
onChange: (val: string) => void
|
||||||
|
} & Param
|
||||||
|
|
||||||
|
export default (props: Param) => {
|
||||||
|
const { codeItem } = props
|
||||||
|
const { dispatch, productData } = useCurrenCode()
|
||||||
|
const index = codeItem.index_str.split('_')
|
||||||
|
const productInfo = productData.data.product_details[index[0]]
|
||||||
|
const codeInfo = productInfo.product_color_details[index[1]]
|
||||||
|
const getNewName = useCallback((name) => {
|
||||||
|
productData.data.product_details[index[0]].product_color_details[index[1]] = { ...codeInfo, product_color_name: name }
|
||||||
|
productData.data.product_details[index[0]] = { ...productData.data.product_details[index[0]] }
|
||||||
|
dispatch({ type: 'updateData', data: { ...productData.data } })
|
||||||
|
}, [codeItem])
|
||||||
|
return <>
|
||||||
|
<Index {...props} onChange={getNewName} />
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
|
||||||
|
const Index = memo((props: IndexParam) => {
|
||||||
|
const { codeItem } = props
|
||||||
|
const [showEdit, setShowEdit] = useState(false)
|
||||||
|
const [title, setTitle] = useState('')
|
||||||
|
|
||||||
|
const countData = useMemo(() => {
|
||||||
|
console.log('codeItem内容:::', codeItem)
|
||||||
|
return {
|
||||||
|
old: `重量:${formatWeightDiv(codeItem?.weight_setting)}kg|空差: ${formatWeightDiv(codeItem?.weight_error_setting)}k|单价:¥${formatPriceDiv(codeItem?.price_setting)}/kg`,
|
||||||
|
new: `重量:${formatWeightDiv(codeItem?.original_weight)}kg|空差: ${formatWeightDiv(codeItem?.original_weight_error)}k|单价:¥${formatWeightDiv(codeItem?.original_price)}/kg`,
|
||||||
|
}
|
||||||
|
}, [codeItem])
|
||||||
|
const onUpdate = () => {
|
||||||
|
console.log('点击了')
|
||||||
|
setTitle(codeItem.product_color_name)
|
||||||
|
setShowEdit(true)
|
||||||
|
}
|
||||||
|
const onConfirm = (item) => {
|
||||||
|
props.onChange?.(item)
|
||||||
|
}
|
||||||
return <View className={styles['product_list__item--con']}>
|
return <View className={styles['product_list__item--con']}>
|
||||||
<View className={styles.item_image}>
|
<View className={styles.item_image} >
|
||||||
<LabAndImg value={{}} />
|
<LabAndImg value={{}} />
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.item_desc}>
|
<View className={styles.item_desc}>
|
||||||
<View className={styles.item_name_count}>
|
<View className={styles.item_name_count}>
|
||||||
<View className={styles.name}>
|
<View className={styles.name} onClick={onUpdate}>
|
||||||
<Text>001# 环保黑</Text>
|
<Text>{codeItem?.product_color_name}</Text>
|
||||||
<IconFont name="icon-shuru" size={50} />
|
<IconFont name="icon-shuru" size={50} />
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.number}>x2条</View>
|
<View className={styles.number}>x{codeItem?.roll}条</View>
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.item_specs_new}>重量:400.5kg|空差: 50.5k|单价:¥100.0/kg</View>
|
<View className={styles.item_specs_new}>{countData.old}</View>
|
||||||
<View className={styles.item_specs_old}>重量:400.5kg|空差: 50.5k|单价:¥100.0/kg</View>
|
<View className={styles.item_specs_old}>{countData.new}</View>
|
||||||
</View>
|
</View>
|
||||||
<View className="common_ellipsis"></View>
|
<View className="common_ellipsis"></View>
|
||||||
|
<PopupModal show={showEdit} title="修改面料名称" defaultValue={title} onClose={() => setShowEdit(false)} onConfirm={onConfirm} />
|
||||||
</View>
|
</View>
|
||||||
}
|
})
|
||||||
|
|||||||
@ -5,27 +5,4 @@
|
|||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
padding: 0 32px 32px 32px;
|
padding: 0 32px 32px 32px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
.product_list__item {
|
|
||||||
.product_list__item--title {
|
|
||||||
height: 82px;
|
|
||||||
font-size: 28px;
|
|
||||||
display: flex;
|
|
||||||
color: #000000;
|
|
||||||
align-items: center;
|
|
||||||
.product_title {
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
.mode_status {
|
|
||||||
width: 60px;
|
|
||||||
height: 30px;
|
|
||||||
font-size: 20px;
|
|
||||||
background: #337fff;
|
|
||||||
border-radius: 8px;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 30px;
|
|
||||||
color: #fff;
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,23 +1,27 @@
|
|||||||
import { Text, View } from '@tarojs/components'
|
import { Text, View } from '@tarojs/components'
|
||||||
|
import { memo, useCallback, useMemo, useState } from 'react'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
import type { NumberParam } from '../settingNumber'
|
||||||
import SettingNumber from '../settingNumber'
|
import SettingNumber from '../settingNumber'
|
||||||
import ProductItem from '../productItem'
|
import ProductItem from '../productItem'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
|
import ProductBlock from './productBlock'
|
||||||
import IconFont from '@/components/iconfont/iconfont'
|
import IconFont from '@/components/iconfont/iconfont'
|
||||||
import LabAndImg from '@/components/LabAndImg'
|
import LabAndImg from '@/components/LabAndImg'
|
||||||
|
|
||||||
export default () => {
|
interface Parma {
|
||||||
|
orderData: any
|
||||||
|
}
|
||||||
|
export default memo((props: Parma) => {
|
||||||
|
const { orderData = {} } = props
|
||||||
|
const productList = useMemo(() => {
|
||||||
|
return orderData?.product_details || []
|
||||||
|
}, [orderData])
|
||||||
return <>
|
return <>
|
||||||
|
|
||||||
<View className={styles.product_list}>
|
<View className={styles.product_list}>
|
||||||
<View className={styles.product_list__item}>
|
{productList?.map((item) => {
|
||||||
<View className={styles['product_list__item--title']}>
|
return <ProductBlock key={item.id} productInfo={item} sale_mode_name={orderData?.sale_mode_name} />
|
||||||
<Text className={styles.product_title}>5215# 26S双纱亲水滑爽棉</Text>
|
})}
|
||||||
<IconFont name="icon-shuru" size={50} />
|
|
||||||
<Text className={styles.mode_status}>大货</Text>
|
|
||||||
</View>
|
|
||||||
<SettingNumber />
|
|
||||||
{new Array(5).fill('').map((item, index) => <View key={index}><ProductItem /></View>)}
|
|
||||||
</View>
|
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
}
|
})
|
||||||
|
|||||||
@ -0,0 +1,42 @@
|
|||||||
|
.product_list__item {
|
||||||
|
.product_list__item--title {
|
||||||
|
height: 82px;
|
||||||
|
font-size: 28px;
|
||||||
|
display: flex;
|
||||||
|
color: #000000;
|
||||||
|
align-items: center;
|
||||||
|
.product_title {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
.mode_status {
|
||||||
|
width: 60px;
|
||||||
|
height: 30px;
|
||||||
|
font-size: 20px;
|
||||||
|
background: #337fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
color: #fff;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.product_list__item--con {
|
||||||
|
transition: height 0.3s ease-in-out;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.open_up_icon {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
.close_up_icon {
|
||||||
|
transform: rotate(0);
|
||||||
|
}
|
||||||
|
.up_btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 72px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 28px;
|
||||||
|
color: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,105 @@
|
|||||||
|
import { Text, View } from '@tarojs/components'
|
||||||
|
import { memo, useCallback, useContext, useRef, useState } from 'react'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
import Big from 'big.js'
|
||||||
|
import ProductItem from '../../productItem'
|
||||||
|
import type { NumberParam } from '../../settingNumber'
|
||||||
|
import SettingNumber from '../../settingNumber'
|
||||||
|
import styles from './index.module.scss'
|
||||||
|
import IconFont from '@/components/iconfont/iconfont'
|
||||||
|
import PopupModal from '@/components/popupModal'
|
||||||
|
import { useCurrenCode } from '@/context/ContextCodeSetting'
|
||||||
|
|
||||||
|
interface Parma {
|
||||||
|
productInfo: any
|
||||||
|
sale_mode_name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type IndexParam = {
|
||||||
|
onChangeName: (val: string) => void
|
||||||
|
onChangeNumber: NumberParam
|
||||||
|
} & Parma
|
||||||
|
|
||||||
|
export default memo((props: Parma) => {
|
||||||
|
const { productInfo } = props
|
||||||
|
const { dispatch, productData } = useCurrenCode()
|
||||||
|
const index = productInfo.index_str.split('_')[0]
|
||||||
|
const getNewName = useCallback((name) => {
|
||||||
|
productData.data.product_details[index] = {
|
||||||
|
...productData.data.product_details[index],
|
||||||
|
product_name: name,
|
||||||
|
}
|
||||||
|
dispatch({ type: 'updateData', data: { ...productData.data } })
|
||||||
|
}, [productInfo])
|
||||||
|
|
||||||
|
// 更新整体数据
|
||||||
|
const updateData = useRef({
|
||||||
|
price: 0,
|
||||||
|
weight: 0,
|
||||||
|
weight_error: 0,
|
||||||
|
adjust_type: 1,
|
||||||
|
})
|
||||||
|
const changeNumber: NumberParam = useCallback((num, type) => {
|
||||||
|
if (type === 'weight') {
|
||||||
|
updateData.current.weight = num * 1000
|
||||||
|
}
|
||||||
|
else if (type === 'sale_price') {
|
||||||
|
updateData.current.price = num * 100
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
updateData.current.weight_error = num * 1000
|
||||||
|
}
|
||||||
|
// 需要传给后端
|
||||||
|
productData.data.product_details[index].weight_admin = updateData.current.weight
|
||||||
|
productData.data.product_details[index].price_admin = updateData.current.price
|
||||||
|
productData.data.product_details[index].weight_error_admin = updateData.current.weight_error
|
||||||
|
|
||||||
|
// 更新原始数组
|
||||||
|
productData.data.product_details[index]?.product_color_details?.map((item) => {
|
||||||
|
item.weight_setting = Big(updateData.current.weight).times(item.roll).add(item.weight).toNumber()
|
||||||
|
item.weight_error_setting = Big(updateData.current.weight_error).times(item.roll).add(item.weight_error).toNumber()
|
||||||
|
item.price_setting = Big(updateData.current.price).add(item.price).toNumber()
|
||||||
|
})
|
||||||
|
productData.data.product_details[index] = JSON.parse(JSON.stringify(productData.data.product_details[index]))
|
||||||
|
dispatch({ type: 'updateData', data: { ...productData.data } })
|
||||||
|
}, [productInfo])
|
||||||
|
|
||||||
|
return <>
|
||||||
|
<Index {...props} onChangeName={getNewName} onChangeNumber={changeNumber} />
|
||||||
|
</>
|
||||||
|
})
|
||||||
|
|
||||||
|
const Index = memo((props: IndexParam) => {
|
||||||
|
const { productInfo, sale_mode_name } = props
|
||||||
|
const [showEdit, setShowEdit] = useState(false)
|
||||||
|
const [upStatus, setStatus] = useState(false)
|
||||||
|
const [title, setTitle] = useState('')
|
||||||
|
console.log('productInfo内容:::', productInfo)
|
||||||
|
const onUpdate = () => {
|
||||||
|
setTitle(productInfo.product_name)
|
||||||
|
setShowEdit(true)
|
||||||
|
}
|
||||||
|
const onConfirm = (item) => {
|
||||||
|
props.onChangeName?.(item)
|
||||||
|
}
|
||||||
|
|
||||||
|
const getNumber: NumberParam = (num, type) => {
|
||||||
|
props.onChangeNumber?.(num, type)
|
||||||
|
}
|
||||||
|
|
||||||
|
return <>
|
||||||
|
<View className={styles.product_list__item}>
|
||||||
|
<View className={styles['product_list__item--title']} onClick={onUpdate}>
|
||||||
|
<Text className={styles.product_title}>{productInfo.product_name}</Text>
|
||||||
|
<IconFont name="icon-shuru" size={50} />
|
||||||
|
<Text className={styles.mode_status}>{sale_mode_name}</Text>
|
||||||
|
</View>
|
||||||
|
<SettingNumber onNumber={getNumber} />
|
||||||
|
<View style={{ height: upStatus ? '0rpx' : `${194 * productInfo?.product_color_details?.length}rpx` }} className={classNames(styles['product_list__item--con'])}>
|
||||||
|
{productInfo?.product_color_details?.map(citem => <View key={citem?.product_color_id}><ProductItem codeItem={citem} /></View>)}
|
||||||
|
</View>
|
||||||
|
<View className={styles.up_btn} onClick={() => setStatus(!upStatus)}>{upStatus ? '展开' : '收起'}<View className={classNames(styles.up_icon, upStatus ? styles.open_up_icon : styles.close_up_icon)}><IconFont name="icon-shangla" size={35} /></View></View>
|
||||||
|
</View>
|
||||||
|
<PopupModal show={showEdit} title="修改面料名称" defaultValue={title} onClose={() => setShowEdit(false)} onConfirm={onConfirm} />
|
||||||
|
</>
|
||||||
|
})
|
||||||
@ -1,20 +1,58 @@
|
|||||||
import { View } from '@tarojs/components'
|
import { View } from '@tarojs/components'
|
||||||
|
import { useContext, useEffect, useState } from 'react'
|
||||||
import Counter from '../counter'
|
import Counter from '../counter'
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
|
import { debounce } from '@/common/util'
|
||||||
|
import { useCurrenCode } from '@/context/ContextCodeSetting'
|
||||||
|
|
||||||
export default () => {
|
export type Mode = 'weight'|'weight_error'|'sale_price'
|
||||||
|
export type NumberParam = (num: number, type: Mode) => void
|
||||||
|
interface Props {
|
||||||
|
onNumber?: NumberParam
|
||||||
|
}
|
||||||
|
export default (props: Props) => {
|
||||||
|
const { productData } = useCurrenCode()
|
||||||
|
const { onNumber } = props
|
||||||
|
const [defaultNum, setDefaultNum] = useState({
|
||||||
|
weight: 0,
|
||||||
|
weight_error: 0,
|
||||||
|
sale_price: 0,
|
||||||
|
})
|
||||||
|
useEffect(() => {
|
||||||
|
if (productData.save_status) {
|
||||||
|
console.log('重置数据:::', productData.save_status)
|
||||||
|
setDefaultNum(() => ({
|
||||||
|
weight: 0,
|
||||||
|
weight_error: 0,
|
||||||
|
sale_price: 0,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}, [productData.save_status])
|
||||||
|
const getNumber: NumberParam = debounce((num, type) => {
|
||||||
|
onNumber?.(num, type)
|
||||||
|
if (type === 'weight') {
|
||||||
|
defaultNum.weight = num
|
||||||
|
}
|
||||||
|
else if (type === 'sale_price') {
|
||||||
|
defaultNum.sale_price = num
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
defaultNum.weight_error = num
|
||||||
|
}
|
||||||
|
setDefaultNum(() => ({ ...defaultNum }))
|
||||||
|
}, 300)
|
||||||
return <View className={styles.change_count}>
|
return <View className={styles.change_count}>
|
||||||
<View className={styles.change_count__item}>
|
<View className={styles.change_count__item}>
|
||||||
<View className={styles['change_count__item--title']}>重量</View>
|
<View className={styles['change_count__item--title']}>重量</View>
|
||||||
<Counter />
|
<Counter defaultNum={defaultNum.weight} minNum={-1000} digits={2} onChange={num => getNumber(num, 'weight')} onBlue={num => getNumber(num, 'weight')} />
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.change_count__item}>
|
<View className={styles.change_count__item}>
|
||||||
<View className={styles['change_count__item--title']}>空差</View>
|
<View className={styles['change_count__item--title']}>空差</View>
|
||||||
<Counter />
|
<Counter defaultNum={defaultNum.weight_error} minNum={-1000} digits={2} onChange={num => getNumber(num, 'weight_error')} onBlue={num => getNumber(num, 'weight_error')} />
|
||||||
</View>
|
</View>
|
||||||
<View className={styles.change_count__item}>
|
<View className={styles.change_count__item}>
|
||||||
<View className={styles['change_count__item--title']}>单价</View>
|
<View className={styles['change_count__item--title']}>单价</View>
|
||||||
<Counter />
|
<Counter defaultNum={defaultNum.sale_price} minNum={-1000} digits={2} onChange={num => getNumber(num, 'sale_price')} onBlue={num => getNumber(num, 'sale_price')} />
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,37 +5,4 @@
|
|||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
padding: 0 32px 0 32px;
|
padding: 0 32px 0 32px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
.product_list__item {
|
|
||||||
.product_list__item--title {
|
|
||||||
height: 82px;
|
|
||||||
font-size: 28px;
|
|
||||||
display: flex;
|
|
||||||
color: #000000;
|
|
||||||
align-items: center;
|
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
|
||||||
.product_title {
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
|
||||||
.mode_status {
|
|
||||||
width: 60px;
|
|
||||||
height: 30px;
|
|
||||||
font-size: 20px;
|
|
||||||
background: #337fff;
|
|
||||||
border-radius: 8px;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 30px;
|
|
||||||
color: #fff;
|
|
||||||
margin-left: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.up_btn {
|
|
||||||
width: 100%;
|
|
||||||
height: 72px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
font-size: 28px;
|
|
||||||
color: rgba(0, 0, 0, 0.4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,26 +1,65 @@
|
|||||||
import { Text, View } from '@tarojs/components'
|
import { View } from '@tarojs/components'
|
||||||
|
import { memo, useCallback, useMemo, useRef } from 'react'
|
||||||
|
import Big from 'big.js'
|
||||||
|
import type { NumberParam } from '../settingNumber'
|
||||||
import SettingNumber from '../settingNumber'
|
import SettingNumber from '../settingNumber'
|
||||||
import ProductItem from '../productItem'
|
|
||||||
import styles from './index.module.scss'
|
import styles from './index.module.scss'
|
||||||
import IconFont from '@/components/iconfont/iconfont'
|
import ProductBlock from './productBlock'
|
||||||
import LabAndImg from '@/components/LabAndImg'
|
import { useCurrenCode } from '@/context/ContextCodeSetting'
|
||||||
|
|
||||||
|
interface Parma {
|
||||||
|
orderData: any
|
||||||
|
onUpdateData?: (val: any) => void
|
||||||
|
}
|
||||||
|
export default memo((props: Parma) => {
|
||||||
|
const { dispatch, productData } = useCurrenCode()
|
||||||
|
const { orderData = {}, onUpdateData } = props
|
||||||
|
const productList = useMemo(() => {
|
||||||
|
console.log('productData123:::', orderData)
|
||||||
|
if (!orderData?.product_details) { return [] }
|
||||||
|
return orderData?.product_details
|
||||||
|
}, [orderData])
|
||||||
|
|
||||||
|
// 更新整体数据
|
||||||
|
const updateData = useRef({
|
||||||
|
price: 0,
|
||||||
|
weight: 0,
|
||||||
|
weight_error: 0,
|
||||||
|
adjust_type: 1,
|
||||||
|
})
|
||||||
|
const getNumber: NumberParam = useCallback((num, type) => {
|
||||||
|
if (type === 'weight') {
|
||||||
|
updateData.current.weight = num * 1000
|
||||||
|
}
|
||||||
|
else if (type === 'sale_price') {
|
||||||
|
updateData.current.price = num * 100
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
updateData.current.weight_error = num * 1000
|
||||||
|
}
|
||||||
|
// 需要传给后端
|
||||||
|
productData.data.weight_admin = updateData.current.weight
|
||||||
|
productData.data.price_admin = updateData.current.price
|
||||||
|
productData.data.weight_error_admin = updateData.current.weight_error
|
||||||
|
|
||||||
|
// 更新原始数组
|
||||||
|
productList?.map((item) => {
|
||||||
|
item?.product_color_details?.map((citem) => {
|
||||||
|
citem.weight_setting = Big(updateData.current.weight).times(citem.roll).add(citem.weight).toNumber()
|
||||||
|
citem.weight_error_setting = Big(updateData.current.weight_error).times(citem.roll).add(citem.weight_error).toNumber()
|
||||||
|
citem.price_setting = Big(updateData.current.price).add(citem.price).toNumber()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
orderData.product_details = productList
|
||||||
|
dispatch({ type: 'updateData', data: JSON.parse(JSON.stringify(orderData)) })
|
||||||
|
}, [productList])
|
||||||
|
|
||||||
export default () => {
|
|
||||||
return <>
|
return <>
|
||||||
<SettingNumber />
|
<SettingNumber onNumber={getNumber} />
|
||||||
<View className={styles.product_list}>
|
<View className={styles.product_list}>
|
||||||
<View className={styles.product_list__item}>
|
{productList?.map((item) => {
|
||||||
<View className={styles['product_list__item--title']}>
|
return <ProductBlock key={item.id} productInfo={item} sale_mode_name={orderData?.sale_mode_name} />
|
||||||
<Text className={styles.product_title}>5215# 26S双纱亲水滑爽棉</Text>
|
})}
|
||||||
<IconFont name="icon-shuru" size={50} />
|
|
||||||
<Text className={styles.mode_status}>大货</Text>
|
|
||||||
</View>
|
|
||||||
<View className={styles['product_list__item--con']}>
|
|
||||||
{new Array(5).fill('').map((item, index) => <View key={index}><ProductItem /></View>)}
|
|
||||||
</View>
|
|
||||||
<View className={styles.up_btn}>收起<IconFont name="icon-shangla" size={35} /></View>
|
|
||||||
</View>
|
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
</>
|
</>
|
||||||
}
|
})
|
||||||
|
|||||||
@ -0,0 +1,43 @@
|
|||||||
|
.product_list__item {
|
||||||
|
.product_list__item--title {
|
||||||
|
height: 82px;
|
||||||
|
font-size: 28px;
|
||||||
|
display: flex;
|
||||||
|
color: #000000;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
|
.product_title {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
.mode_status {
|
||||||
|
width: 60px;
|
||||||
|
height: 30px;
|
||||||
|
font-size: 20px;
|
||||||
|
background: #337fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
color: #fff;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.product_list__item--con {
|
||||||
|
transition: height 0.3s ease-in-out;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.open_up_icon {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
.close_up_icon {
|
||||||
|
transform: rotate(0);
|
||||||
|
}
|
||||||
|
.up_btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 72px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 28px;
|
||||||
|
color: rgba(0, 0, 0, 0.4);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,62 @@
|
|||||||
|
import { Text, View } from '@tarojs/components'
|
||||||
|
import { memo, useCallback, useContext, useState } from 'react'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
import ProductItem from '../../productItem'
|
||||||
|
import styles from './index.module.scss'
|
||||||
|
import IconFont from '@/components/iconfont/iconfont'
|
||||||
|
import PopupModal from '@/components/popupModal'
|
||||||
|
import { useCurrenCode } from '@/context/ContextCodeSetting'
|
||||||
|
|
||||||
|
interface Parma {
|
||||||
|
productInfo: any
|
||||||
|
sale_mode_name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
type IndexParam = {
|
||||||
|
onChange: (val: string) => void
|
||||||
|
} & Parma
|
||||||
|
|
||||||
|
export default memo((props: Parma) => {
|
||||||
|
const { productInfo } = props
|
||||||
|
const { dispatch, productData } = useCurrenCode()
|
||||||
|
const getNewName = useCallback((name) => {
|
||||||
|
const index = productInfo.index_str.split('_')[0]
|
||||||
|
productData.data.product_details[index] = {
|
||||||
|
...productData.data.product_details[index],
|
||||||
|
product_name: name,
|
||||||
|
}
|
||||||
|
dispatch({ type: 'updateData', data: { ...productData.data } })
|
||||||
|
}, [productInfo])
|
||||||
|
return <>
|
||||||
|
<Index {...props} onChange={getNewName} />
|
||||||
|
</>
|
||||||
|
})
|
||||||
|
|
||||||
|
const Index = memo((props: IndexParam) => {
|
||||||
|
const { productInfo, sale_mode_name } = props
|
||||||
|
const [showEdit, setShowEdit] = useState(false)
|
||||||
|
const [upStatus, setStatus] = useState(false)
|
||||||
|
const [title, setTitle] = useState('')
|
||||||
|
console.log('productInfo内容:::', productInfo)
|
||||||
|
const onUpdate = () => {
|
||||||
|
setTitle(productInfo.product_name)
|
||||||
|
setShowEdit(true)
|
||||||
|
}
|
||||||
|
const onConfirm = (item) => {
|
||||||
|
props.onChange?.(item)
|
||||||
|
}
|
||||||
|
return <>
|
||||||
|
<View key={productInfo.product_id} className={styles.product_list__item}>
|
||||||
|
<View className={styles['product_list__item--title']} onClick={onUpdate}>
|
||||||
|
<Text className={styles.product_title}>{productInfo.product_name}</Text>
|
||||||
|
<IconFont name="icon-shuru" size={50} />
|
||||||
|
<Text className={styles.mode_status}>{sale_mode_name}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={{ height: upStatus ? '0rpx' : `${194 * productInfo?.product_color_details?.length}rpx` }} className={classNames(styles['product_list__item--con'])}>
|
||||||
|
{productInfo?.product_color_details?.map(citem => <View key={citem?.product_color_id}><ProductItem codeItem={citem} /></View>)}
|
||||||
|
</View>
|
||||||
|
<View className={styles.up_btn} onClick={() => setStatus(!upStatus)}>{upStatus ? '展开' : '收起'}<View className={classNames(styles.up_icon, upStatus ? styles.open_up_icon : styles.close_up_icon)}><IconFont name="icon-shangla" size={35} /></View></View>
|
||||||
|
</View>
|
||||||
|
<PopupModal show={showEdit} title="修改面料名称" defaultValue={title} onClose={() => setShowEdit(false)} onConfirm={onConfirm} />
|
||||||
|
</>
|
||||||
|
})
|
||||||
@ -1,41 +0,0 @@
|
|||||||
.code_list__main {
|
|
||||||
background-color: #f7f7f7;
|
|
||||||
min-height: 100vh;
|
|
||||||
padding-bottom: 150px;
|
|
||||||
.code_list__head {
|
|
||||||
background-color: #fff;
|
|
||||||
padding: 24px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
.code_list_con {
|
|
||||||
padding: 0 24px;
|
|
||||||
margin-top: 24px;
|
|
||||||
.code_des {
|
|
||||||
padding: 0 32px 32px 32px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 16px;
|
|
||||||
margin-top: 24px;
|
|
||||||
.code_des_title {
|
|
||||||
height: 82px;
|
|
||||||
line-height: 82px;
|
|
||||||
font-size: 28px;
|
|
||||||
color: #000000;
|
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
.code_des_item {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
font-size: 28px;
|
|
||||||
color: rgba(0, 0, 0, 0.8);
|
|
||||||
margin-top: 24px;
|
|
||||||
.code_des_weight {
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
.code_des_price {
|
|
||||||
color: #f64861;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,70 +1,10 @@
|
|||||||
import { Text, View } from '@tarojs/components'
|
import Main from './components/main'
|
||||||
import classnames from 'classnames'
|
import ContextCodeSetting from '@/context/ContextCodeSetting'
|
||||||
import { useCallback, useState } from 'react'
|
|
||||||
import styles from './index.module.scss'
|
|
||||||
import PayeeHead from './components/payeeHead'
|
|
||||||
import Counter from './components/counter'
|
|
||||||
import SettingNumber from './components/settingNumber'
|
|
||||||
import WholeOrderSetting from './components/wholeOrderSetting'
|
|
||||||
import BottomBtn from './components/bottomBtn'
|
|
||||||
import ProductSetting from './components/productSetting'
|
|
||||||
import ColorSetting from './components/colorSetting'
|
|
||||||
import SelectList from '@/components/selectList'
|
|
||||||
import useLogin from '@/use/useLogin'
|
|
||||||
import IconFont from '@/components/iconfont/iconfont'
|
|
||||||
import LabAndImg from '@/components/LabAndImg'
|
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const selectList = [
|
return <>
|
||||||
{ value: 1, label: '按整单' },
|
<ContextCodeSetting>
|
||||||
{ value: 2, label: '按面料' },
|
<Main />
|
||||||
{ value: 3, label: '按颜色' },
|
</ContextCodeSetting>
|
||||||
]
|
</>
|
||||||
const [modeIndex, setModeIndex] = useState(1)
|
|
||||||
const getTypeSelect = useCallback((index) => {
|
|
||||||
setModeIndex(index)
|
|
||||||
}, [])
|
|
||||||
return <View className={styles.code_list__main}>
|
|
||||||
<View className={styles.code_list__head}>
|
|
||||||
<PayeeHead />
|
|
||||||
</View>
|
|
||||||
<SelectList onSelect={getTypeSelect} list={selectList} defaultIndex={1} />
|
|
||||||
<View className={styles.code_list_con}>
|
|
||||||
{modeIndex == 1 && <WholeOrderSetting />}
|
|
||||||
{modeIndex == 2 && <ProductSetting />}
|
|
||||||
{modeIndex == 3 && <ColorSetting />}
|
|
||||||
<View className={styles.code_des}>
|
|
||||||
<View className={styles.code_des_title}>自定义单据信息</View>
|
|
||||||
<View className={styles.code_des_item}>
|
|
||||||
<Text>合计空差</Text>
|
|
||||||
<Text>60kg</Text>
|
|
||||||
</View>
|
|
||||||
<View className={styles.code_des_item}>
|
|
||||||
<Text>合计重量</Text>
|
|
||||||
<Text className={styles.code_des_weight}>230.2kg</Text>
|
|
||||||
</View>
|
|
||||||
<View className={styles.code_des_item}>
|
|
||||||
<Text>合计金额</Text>
|
|
||||||
<Text className={styles.code_des_price}>¥22,332.00</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<View className={styles.code_des}>
|
|
||||||
<View className={styles.code_des_title}>原始单据信息</View>
|
|
||||||
<View className={styles.code_des_item}>
|
|
||||||
<Text>合计空差</Text>
|
|
||||||
<Text>60kg</Text>
|
|
||||||
</View>
|
|
||||||
<View className={styles.code_des_item}>
|
|
||||||
<Text>合计重量</Text>
|
|
||||||
<Text className={styles.code_des_weight}>230.2kg</Text>
|
|
||||||
</View>
|
|
||||||
<View className={styles.code_des_item}>
|
|
||||||
<Text>合计金额</Text>
|
|
||||||
<Text className={styles.code_des_price}>¥22,332.00</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
<BottomBtn />
|
|
||||||
<View className="common_safe_area_y"></View>
|
|
||||||
</View>
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -287,7 +287,7 @@ const Order = () => {
|
|||||||
[orderDetail],
|
[orderDetail],
|
||||||
)
|
)
|
||||||
return (
|
return (
|
||||||
<MoveBtn orderObj={orderDetail} showList={['order', 'code']} messageTitle={orderDetail?.order_no} messagePath={`/pages/order/index?id=${orderDetail?.id}`} showCart>
|
<MoveBtn orderObj={orderDetail} showList={['order', 'code']} orderInfo={orderDetail} messageTitle={orderDetail?.order_no} messagePath={`/pages/order/index?id=${orderDetail?.id}`} showCart>
|
||||||
<View className={styles.order_main}>
|
<View className={styles.order_main}>
|
||||||
{(orderDetail?.status != SaleorderstatusWaitingPrePayment.value && <OrderState orderInfo={orderDetail} />) || (
|
{(orderDetail?.status != SaleorderstatusWaitingPrePayment.value && <OrderState orderInfo={orderDetail} />) || (
|
||||||
<AdvanceOrderState orderInfo={orderDetail} onRefresh={refresh} />
|
<AdvanceOrderState orderInfo={orderDetail} onRefresh={refresh} />
|
||||||
|
|||||||
@ -59,7 +59,7 @@ export default () => {
|
|||||||
|
|
||||||
const menuList = [
|
const menuList = [
|
||||||
{ label: '地址管理', icon: 'icon-dizhiguanli', callback: () => goLink('/pages/addressManager/index') },
|
{ label: '地址管理', icon: 'icon-dizhiguanli', callback: () => goLink('/pages/addressManager/index') },
|
||||||
{ label: '码单管理', icon: 'icon-mdgl', icon_status: 'local', callback: () => goLink('/pages/weightList/index') },
|
{ label: '码单管理', icon: 'icon-mdgl', icon_status: 'local', callback: () => goLink('/pages/codeList/index') },
|
||||||
{ label: '颜色对比', icon: 'icon-yanseduibi', callback: () => goLink('/pages/sampleComparison/index') },
|
{ label: '颜色对比', icon: 'icon-yanseduibi', callback: () => goLink('/pages/sampleComparison/index') },
|
||||||
{ label: '我的客服', icon: 'icon-wodekefu', text: '7x24小时服务', callback: () => (set_customer_service_show(true)) },
|
{ label: '我的客服', icon: 'icon-wodekefu', text: '7x24小时服务', callback: () => (set_customer_service_show(true)) },
|
||||||
]
|
]
|
||||||
|
|||||||
@ -4,12 +4,14 @@ import IconFont from '@/components/iconfont/iconfont'
|
|||||||
import { goLink } from '@/common/common'
|
import { goLink } from '@/common/common'
|
||||||
import NameLabel from '@/components/nameLabel'
|
import NameLabel from '@/components/nameLabel'
|
||||||
|
|
||||||
|
export interface CompanyItem { title: string; purchaser_name: string; id: number; phone: string }
|
||||||
export interface CompanyParam {
|
export interface CompanyParam {
|
||||||
value: { title: string; purchaser_name: string; id: number; phone: string }
|
value: CompanyItem
|
||||||
|
onClick?: (val: CompanyItem) => void
|
||||||
}
|
}
|
||||||
export default (props: CompanyParam) => {
|
export default (props: CompanyParam) => {
|
||||||
const { value } = props
|
const { value, onClick } = props
|
||||||
return <View className={styles.company_item} onClick={() => goLink(`/pages/weightListAdd/index?type=edit&id=${value.id}`)}>
|
return <View className={styles.company_item} onClick={() => onClick?.(value)}>
|
||||||
<NameLabel name={value.title} />
|
<NameLabel name={value.title} />
|
||||||
<View className={styles.desc}>
|
<View className={styles.desc}>
|
||||||
<Text>{value?.title }</Text>
|
<Text>{value?.title }</Text>
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
|
|
||||||
import { Button, Navigator, ScrollView, Text, View } from '@tarojs/components'
|
import { Button, Navigator, ScrollView, Text, View } from '@tarojs/components'
|
||||||
|
import Taro, { getCurrentPages, showModal } from '@tarojs/taro'
|
||||||
import { memo, useEffect, useState } from 'react'
|
import { memo, useEffect, useState } from 'react'
|
||||||
import CompanyItem from './components/companyItem'
|
import CompanyItem from './components/companyItem'
|
||||||
import { weightDeleteApi, weightListApi } from '@/api/weightList'
|
import { weightDeleteApi, weightListApi } from '@/api/weightList'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
import Taro, { showModal } from '@tarojs/taro'
|
|
||||||
import { alert } from '@/common/common'
|
import { alert } from '@/common/common'
|
||||||
|
|
||||||
const weightListManager = () => {
|
const weightListManager = () => {
|
||||||
@ -16,7 +16,6 @@ const weightListManager = () => {
|
|||||||
}
|
}
|
||||||
interface Params{
|
interface Params{
|
||||||
refresherEnabled?: boolean// 是否开启刷新
|
refresherEnabled?: boolean// 是否开启刷新
|
||||||
onSelect?: (item: any, index: number) => void// 列表选择
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// 码单列表
|
// 码单列表
|
||||||
@ -60,17 +59,23 @@ const WeightList = (props: Params) => {
|
|||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
const onSelect = (item) => {
|
||||||
|
const pages = getCurrentPages()
|
||||||
|
const current = pages[pages.length - 1]
|
||||||
|
const eventChannel = current.getOpenerEventChannel()
|
||||||
|
eventChannel.emit('getSelectCompanyEvent', item)
|
||||||
|
Taro.navigateBack()
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View className="weight-list-scroll-view">
|
<View className="weight-list-scroll-view">
|
||||||
<ScrollView scrollY refresherEnabled enhanced refresherTriggered={refreshState} onRefresherRefresh={handleRefresh}>
|
<ScrollView scrollY refresherEnabled enhanced refresherTriggered={refreshState} onRefresherRefresh={handleRefresh}>
|
||||||
{
|
{
|
||||||
// data.length>0?
|
|
||||||
state?.data?.list?.length > 0
|
state?.data?.list?.length > 0
|
||||||
? state?.data?.list?.map((item, index) => {
|
? state?.data?.list?.map((item) => {
|
||||||
return (
|
return (
|
||||||
<View key={item.id} className="weight-list-con">
|
<View key={item.id} className="weight-list-con" >
|
||||||
<CompanyItem value={item} />
|
<CompanyItem value={item} onClick={onSelect} />
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
18
src/styles/mixins/index.scss
Normal file
18
src/styles/mixins/index.scss
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/**
|
||||||
|
* Mixins
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* library */
|
||||||
|
// @import './libs/absolute-center';
|
||||||
|
// @import './libs/clearfix';
|
||||||
|
// @import './libs/line';
|
||||||
|
// @import './libs/overlay';
|
||||||
|
// @import './libs/shade';
|
||||||
|
@import './libs/tint';
|
||||||
|
@import './libs/flex';
|
||||||
|
// @import './libs/border';
|
||||||
|
// @import './libs/active';
|
||||||
|
// @import './libs/disabled';
|
||||||
|
// @import './libs/placeholder';
|
||||||
|
// @import './libs/alignhack';
|
||||||
|
// @import './libs/hairline';
|
||||||
50
src/styles/mixins/libs/flex.scss
Normal file
50
src/styles/mixins/libs/flex.scss
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
@mixin display-flex {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin flex-wrap($value: nowrap) {
|
||||||
|
flex-wrap: $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin align-items($value: stretch) {
|
||||||
|
align-items: $value;
|
||||||
|
@if $value == flex-start {
|
||||||
|
-webkit-box-align: start;
|
||||||
|
} @else if $value == flex-end {
|
||||||
|
-webkit-box-align: end;
|
||||||
|
} @else {
|
||||||
|
-webkit-box-align: $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin align-content($value: flex-start) {
|
||||||
|
align-content: $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin justify-content($value: flex-start) {
|
||||||
|
justify-content: $value;
|
||||||
|
@if $value == flex-start {
|
||||||
|
-webkit-box-pack: start;
|
||||||
|
} @else if $value == flex-end {
|
||||||
|
-webkit-box-pack: end;
|
||||||
|
} @else if $value == space-between {
|
||||||
|
-webkit-box-pack: justify;
|
||||||
|
} @else {
|
||||||
|
-webkit-box-pack: $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flex Item */
|
||||||
|
@mixin flex($fg: 1, $fs: null, $fb: null) {
|
||||||
|
flex: $fg $fs $fb;
|
||||||
|
-webkit-box-flex: $fg;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin flex-order($n) {
|
||||||
|
order: $n;
|
||||||
|
-webkit-box-ordinal-group: $n;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin align-self($value: auto) {
|
||||||
|
align-self: $value;
|
||||||
|
}
|
||||||
23
src/styles/mixins/libs/tint.scss
Normal file
23
src/styles/mixins/libs/tint.scss
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/**
|
||||||
|
* Mixes a color with white. It's different from lighten()
|
||||||
|
*
|
||||||
|
* @param {color} $color
|
||||||
|
* @param {number (percentage)} $percent [The amout of white to be mixed in]
|
||||||
|
* @return {color}
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* .element {
|
||||||
|
* background-color: tint(#6ecaa6 , 40%);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // CSS Output
|
||||||
|
* .element {
|
||||||
|
* background-color: #a8dfc9;
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
// @function tint(
|
||||||
|
// $color,
|
||||||
|
// $percent
|
||||||
|
// ) {
|
||||||
|
// @return mix(#FFF, $color, $percent);
|
||||||
|
// }
|
||||||
457
src/styles/variables/default.scss
Normal file
457
src/styles/variables/default.scss
Normal file
@ -0,0 +1,457 @@
|
|||||||
|
/**
|
||||||
|
* Default variables
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import '../mixins/libs/tint';
|
||||||
|
|
||||||
|
$hd: 2 !default; // 基本单位
|
||||||
|
|
||||||
|
/* The Color of O2Team Brand */
|
||||||
|
$color-brand: #337fff !default;
|
||||||
|
$color-brand-light: #78A4F4 !default;
|
||||||
|
$color-brand-dark: #346FC2 !default;
|
||||||
|
|
||||||
|
/* Color */
|
||||||
|
$color-success: #13CE66 !default;
|
||||||
|
$color-error: #FF4949 !default;
|
||||||
|
$color-warning: #FFC82C !default;
|
||||||
|
$color-info: #78A4FA !default;
|
||||||
|
|
||||||
|
/* Color Palette */
|
||||||
|
$color-black-0: #000 !default;
|
||||||
|
$color-black-1: #333 !default;
|
||||||
|
$color-black-2: #7F7F7F !default;
|
||||||
|
$color-black-3: #B2B2B2 !default;
|
||||||
|
|
||||||
|
$color-grey-0: #333 !default;
|
||||||
|
$color-grey-1: #666 !default;
|
||||||
|
$color-grey-2: #999 !default;
|
||||||
|
$color-grey-3: #CCC !default;
|
||||||
|
$color-grey-4: #E5E5E5 !default;
|
||||||
|
$color-grey-5: #F0F0F0 !default;
|
||||||
|
$color-grey-6: #F7F7F7 !default;
|
||||||
|
|
||||||
|
$color-white: #FFF !default;
|
||||||
|
|
||||||
|
/* Text Color */
|
||||||
|
$color-text-base: #333 !default; // 文字的基本色
|
||||||
|
$color-text-base-inverse: #FFF !default; // 反色
|
||||||
|
$color-text-secondary: #36D57D !default; // 辅助色
|
||||||
|
$color-text-placeholder: #C9C9C9 !default;
|
||||||
|
$color-text-disabled: #CCC !default;
|
||||||
|
$color-text-title: #2C405A !default; // 文章标题
|
||||||
|
$color-text-paragraph: #3F536E !default; // 文章段落
|
||||||
|
|
||||||
|
/* Link */
|
||||||
|
$color-link: #6190E8 !default;
|
||||||
|
$color-link-hover: #79A1EB !default;
|
||||||
|
$color-link-active: #4F7DE2 !default;
|
||||||
|
$color-link-disabled: #BFBFBF !default;
|
||||||
|
|
||||||
|
/* 背景色 */
|
||||||
|
$color-bg: #FFF !default;
|
||||||
|
$color-bg-base: #FAFBFC !default;
|
||||||
|
$color-bg-light: #ECF5FD !default;
|
||||||
|
$color-bg-lighter: tint($color-bg-light, 50%) !default;
|
||||||
|
$color-bg-grey: #F7F7F7 !default;
|
||||||
|
|
||||||
|
/* 边框颜色 */
|
||||||
|
$color-border-base: #C5D9E8 !default;
|
||||||
|
$color-border-split: tint($color-border-base, 20%) !default; // 分割线
|
||||||
|
$color-border-light: tint($color-border-base, 30%) !default;
|
||||||
|
$color-border-lighter: tint($color-border-base, 50%) !default;
|
||||||
|
$color-border-lightest: tint($color-border-base, 80%) !default;
|
||||||
|
$color-border-grey: #CCC !default;
|
||||||
|
|
||||||
|
/* 图标颜色 */
|
||||||
|
$color-icon-base: #CCC !default;
|
||||||
|
|
||||||
|
/* Border Radius */
|
||||||
|
$border-radius-sm: 2px * $hd !default;
|
||||||
|
$border-radius-md: 4px * $hd !default;
|
||||||
|
$border-radius-lg: 6px * $hd !default;
|
||||||
|
$border-radius-circle: 50% !default;
|
||||||
|
|
||||||
|
/* 透明度 */
|
||||||
|
$opacity-active: 0.6 !default; // Button 等组件点击态额透明度
|
||||||
|
$opacity-disabled: 0.3 !default; // Button 等组件禁用态的透明度
|
||||||
|
|
||||||
|
/* Font */
|
||||||
|
$font-size-xs: 10px * $hd !default; // 非常用字号,用于标签
|
||||||
|
$font-size-sm: 12px * $hd !default; // 用于辅助信息
|
||||||
|
$font-size-base: 14px * $hd !default; // 常用字号
|
||||||
|
$font-size-lg: 16px * $hd !default; // 常规标题
|
||||||
|
$font-size-xl: 18px * $hd !default; // 大标题
|
||||||
|
$font-size-xxl: 20px * $hd !default; // 用于大号的数字
|
||||||
|
|
||||||
|
/* Line Height */
|
||||||
|
$line-height-base: 1 !default; // 单行
|
||||||
|
$line-height-en: 1.3 !default; // 英文多行
|
||||||
|
$line-height-zh: 1.5 !default; // 中文多行
|
||||||
|
|
||||||
|
/* 水平间距 */
|
||||||
|
$spacing-h-sm: 5px * $hd !default;
|
||||||
|
$spacing-h-md: 8px * $hd !default;
|
||||||
|
$spacing-h-lg: 12px * $hd !default;
|
||||||
|
$spacing-h-xl: 16px * $hd !default;
|
||||||
|
|
||||||
|
/* 垂直间距 */
|
||||||
|
$spacing-v-xs: 3px * $hd !default;
|
||||||
|
$spacing-v-sm: 6px * $hd !default;
|
||||||
|
$spacing-v-md: 9px * $hd !default;
|
||||||
|
$spacing-v-lg: 12px * $hd !default;
|
||||||
|
$spacing-v-xl: 15px * $hd !default;
|
||||||
|
|
||||||
|
/* 图标尺寸 */
|
||||||
|
$icon-size-sm: 18px * $hd !default;
|
||||||
|
$icon-size-md: 22px * $hd !default;
|
||||||
|
$icon-size-lg: 36px * $hd !default;
|
||||||
|
|
||||||
|
/* z-index */
|
||||||
|
$zindex-divider: 100 !default;
|
||||||
|
$zindex-steps: 500 !default;
|
||||||
|
$zindex-tab: 600 !default;
|
||||||
|
$zindex-form: 700 !default;
|
||||||
|
$zindex-nav: 800 !default;
|
||||||
|
$zindex-search-bar: 800 !default;
|
||||||
|
$zindex-indexes: 805 !default;
|
||||||
|
$zindex-flot-layout: 810 !default;
|
||||||
|
$zindex-drawer: 900 !default;
|
||||||
|
$zindex-modal: 1000 !default;
|
||||||
|
$zindex-action-sheet: 1010 !default;
|
||||||
|
$zindex-picker: 1010 !default;
|
||||||
|
$zindex-curtain: 1080 !default;
|
||||||
|
$zindex-message: 1090 !default;
|
||||||
|
$zindex-toast: 1090 !default;
|
||||||
|
|
||||||
|
/* timing function */
|
||||||
|
$timing-func: cubic-bezier(0.36, 0.66, 0.04, 1) !default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CSS cubic-bezier timing functions
|
||||||
|
* http://bourbon.io/docs/#timing-functions
|
||||||
|
*/
|
||||||
|
$ease-in-quad: cubic-bezier(0.550, 0.085, 0.680, 0.530) !default;
|
||||||
|
$ease-in-cubic: cubic-bezier(0.550, 0.055, 0.675, 0.190) !default;
|
||||||
|
$ease-in-quart: cubic-bezier(0.895, 0.030, 0.685, 0.220) !default;
|
||||||
|
$ease-in-quint: cubic-bezier(0.755, 0.050, 0.855, 0.060) !default;
|
||||||
|
$ease-in-sine: cubic-bezier(0.470, 0.000, 0.745, 0.715) !default;
|
||||||
|
$ease-in-expo: cubic-bezier(0.950, 0.050, 0.795, 0.035) !default;
|
||||||
|
$ease-in-circ: cubic-bezier(0.600, 0.040, 0.980, 0.335) !default;
|
||||||
|
$ease-in-back: cubic-bezier(0.600, -0.280, 0.735, 0.045) !default;
|
||||||
|
|
||||||
|
$ease-out-quad: cubic-bezier(0.250, 0.460, 0.450, 0.940) !default;
|
||||||
|
$ease-out-cubic: cubic-bezier(0.215, 0.610, 0.355, 1.000) !default;
|
||||||
|
$ease-out-quart: cubic-bezier(0.165, 0.840, 0.440, 1.000) !default;
|
||||||
|
$ease-out-quint: cubic-bezier(0.230, 1.000, 0.320, 1.000) !default;
|
||||||
|
$ease-out-sine: cubic-bezier(0.390, 0.575, 0.565, 1.000) !default;
|
||||||
|
$ease-out-expo: cubic-bezier(0.190, 1.000, 0.220, 1.000) !default;
|
||||||
|
$ease-out-circ: cubic-bezier(0.075, 0.820, 0.165, 1.000) !default;
|
||||||
|
$ease-out-back: cubic-bezier(0.175, 0.885, 0.320, 1.275) !default;
|
||||||
|
|
||||||
|
$ease-in-out-quad: cubic-bezier(0.455, 0.030, 0.515, 0.955) !default;
|
||||||
|
$ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1.000) !default;
|
||||||
|
$ease-in-out-quart: cubic-bezier(0.770, 0.000, 0.175, 1.000) !default;
|
||||||
|
$ease-in-out-quint: cubic-bezier(0.860, 0.000, 0.070, 1.000) !default;
|
||||||
|
$ease-in-out-sine: cubic-bezier(0.445, 0.050, 0.550, 0.950) !default;
|
||||||
|
$ease-in-out-expo: cubic-bezier(1.000, 0.000, 0.000, 1.000) !default;
|
||||||
|
$ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.150, 0.860) !default;
|
||||||
|
$ease-in-out-back: cubic-bezier(0.680, -0.550, 0.265, 1.550) !default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 组件变量
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Accordion */
|
||||||
|
$at-accordion-color-arrow: $color-grey-3 !default;
|
||||||
|
|
||||||
|
/* Activity Indicator */
|
||||||
|
$at-activity-indicator-font-size: 28px !default;
|
||||||
|
$at-activity-indicator-font-color: $color-grey-2 !default;
|
||||||
|
|
||||||
|
/* Avatar */
|
||||||
|
$at-avatar-color: $color-white !default;
|
||||||
|
$at-avatar-bg-color: $color-grey-4 !default;
|
||||||
|
$at-avatar-size-sm: 80px !default;
|
||||||
|
$at-avatar-size-md: 100px !default;
|
||||||
|
$at-avatar-size-lg: 120px !default;
|
||||||
|
|
||||||
|
/* Badge */
|
||||||
|
$at-badge-color: $color-white !default;
|
||||||
|
$at-badge-bg-color: $color-error !default;
|
||||||
|
$at-badge-bg: $at-badge-bg-color !default;
|
||||||
|
$at-badge-font-size: $font-size-xs !default;
|
||||||
|
$at-badge-dot-size: 20px !default;
|
||||||
|
|
||||||
|
/* Button */
|
||||||
|
$at-button-height: 92px !default;
|
||||||
|
$at-button-height-sm: 60px !default;
|
||||||
|
$at-button-color: $color-brand !default;
|
||||||
|
$at-button-border-color-primary: $color-brand !default;
|
||||||
|
$at-button-border-color-secondary: $color-brand !default;
|
||||||
|
$at-button-bg: $at-button-color !default;
|
||||||
|
|
||||||
|
/* Float Button */
|
||||||
|
$at-fab-size: 56px * $hd !default;
|
||||||
|
$at-fab-size-sm: 40px * $hd !default;
|
||||||
|
$at-fab-icon-size: 24px * $hd !default;
|
||||||
|
$at-fab-bg-color: $color-brand;
|
||||||
|
$at-fab-bg-color-active: $color-brand-dark;
|
||||||
|
$at-fab-box-shadow:
|
||||||
|
0 6px 10px -2px rgba(0, 0, 0, 0.2),
|
||||||
|
0 12px 20px 0 rgba(0, 0, 0, 0.14),
|
||||||
|
0 2px 36px 0 rgba(0, 0, 0, 0.12) !default;
|
||||||
|
$at-fab-box-shadow-active:
|
||||||
|
0 14px 16px -8px rgba(0, 0, 0, 0.2),
|
||||||
|
0 24px 34px 4px rgba(0, 0, 0, 0.14),
|
||||||
|
0 10px 44px 8px rgba(0, 0, 0, 0.12) !default;
|
||||||
|
|
||||||
|
/* Calendar */
|
||||||
|
$at-calendar-day-size: 72px !default;
|
||||||
|
$at-calendar-mark-size: 8px !default;
|
||||||
|
$at-calendar-header-color: #B8BFC6 !default;
|
||||||
|
$at-calendar-main-color: $color-brand !default;
|
||||||
|
$at-calendar-day-color: #7C86A2 !default;
|
||||||
|
|
||||||
|
/* Card */
|
||||||
|
$at-card-thumb-size: 32px !default;
|
||||||
|
$at-card-icon-size: 32px !default;
|
||||||
|
$at-card-title-color: $color-text-title !default;
|
||||||
|
$at-card-extra-color: $color-text-title !default;
|
||||||
|
$at-card-info-color: $color-text-base !default;
|
||||||
|
$at-card-note-color: $color-grey-2 !default;
|
||||||
|
|
||||||
|
/* Checkbox */
|
||||||
|
$at-checkbox-circle-size: 40px !default;
|
||||||
|
$at-checkbox-icon-size: $font-size-sm !default;
|
||||||
|
$at-checkbox-icon-color: $color-brand !default;
|
||||||
|
$at-checkbox-icon-color-checked: $color-white !default;
|
||||||
|
$at-checkbox-title-color: $color-text-base !default;
|
||||||
|
$at-checkbox-title-font-size: $font-size-lg !default;
|
||||||
|
$at-checkbox-desc-font-size: $font-size-sm !default;
|
||||||
|
$at-checkbox-desc-color: $color-grey-2 !default;
|
||||||
|
|
||||||
|
/* Countdown */
|
||||||
|
$at-countdown-font-size: $font-size-lg !default;
|
||||||
|
$at-countdown-num-color: $color-text-base !default;
|
||||||
|
$at-countdown-card-num-color: #FF4949 !default;
|
||||||
|
$at-countdown-card-num-bg-color: $color-white !default;
|
||||||
|
|
||||||
|
/* Curtain */
|
||||||
|
$at-curtain-btn-color: $color-white !default;
|
||||||
|
|
||||||
|
/* Divider */
|
||||||
|
$at-divider-height: 112px;
|
||||||
|
$at-divider-content-color: $color-brand !default;
|
||||||
|
$at-divider-font-size: $font-size-lg !default;
|
||||||
|
$at-divider-line-color: $color-grey-3 !default;
|
||||||
|
|
||||||
|
/* Drawer */
|
||||||
|
$at-drawer-content-width: 460px !default;
|
||||||
|
|
||||||
|
/* FloatLayout */
|
||||||
|
$float-layout-height-min: 600px !default;
|
||||||
|
$float-layout-height-max: 950px !default;
|
||||||
|
$float-layout-header-bg-color: $color-bg-grey !default;
|
||||||
|
$float-layout-title-color: $color-text-base !default;
|
||||||
|
$float-layout-title-font-size: $font-size-lg !default;
|
||||||
|
$float-layout-btn-color: $color-grey-3 !default;
|
||||||
|
|
||||||
|
/* Grid */
|
||||||
|
$at-grid-text-color: $color-text-base !default;
|
||||||
|
$at-grid-font-size: $font-size-lg !default;
|
||||||
|
$at-grid-img-size: 80px !default;
|
||||||
|
$at-gird-img-size-sm: 50px !default;
|
||||||
|
|
||||||
|
/* ImagePicker */
|
||||||
|
$at-image-picker-btn-add-color: $color-grey-3 !default;
|
||||||
|
$at-image-picker-btn-remove-color: $color-white !default;
|
||||||
|
$at-image-picker-btn-remove-bg-color: $color-grey-2 !default;
|
||||||
|
|
||||||
|
/* Indexes */
|
||||||
|
$at-indexes-nav-color: $color-link !default;
|
||||||
|
$at-indexes-nav-font-size: $font-size-sm !default;
|
||||||
|
$at-indexes-title-color: $color-black-2 !default;
|
||||||
|
$at-indexes-title-font-size: $font-size-sm !default;
|
||||||
|
$at-indexes-title-bg-color: $color-grey-6 !default;
|
||||||
|
|
||||||
|
/* InputNumber */
|
||||||
|
$at-input-number-text-color: $color-text-base !default;
|
||||||
|
$at-input-number-font-size: $font-size-base !default;
|
||||||
|
$at-input-number-font-size-lg: $font-size-xl !default;
|
||||||
|
$at-input-number-btn-color: $color-brand !default;
|
||||||
|
$at-input-number-btn-size: 30px !default;
|
||||||
|
$at-input-number-btn-size-lg: 36px !default;
|
||||||
|
$at-input-number-width-min: 80px !default;
|
||||||
|
$at-input-number-width-min-lg: 120px !default;
|
||||||
|
|
||||||
|
/* Input */
|
||||||
|
$at-input-label-color: $color-text-base !default;
|
||||||
|
$at-input-text-color: $color-text-base !default;
|
||||||
|
$at-input-font-size: $font-size-lg !default;
|
||||||
|
$at-input-placeholder-color: $color-grey-3 !default;
|
||||||
|
|
||||||
|
/* List */
|
||||||
|
$at-list-thumb-size: 56px !default;
|
||||||
|
$at-list-arrow-color: $color-grey-3 !default;
|
||||||
|
$at-list-text-color: $color-text-base !default;
|
||||||
|
$at-list-content-color: $color-grey-2 !default;
|
||||||
|
$at-list-extra-color: $color-grey-2 !default;
|
||||||
|
$at-list-extra-width: 235px !default;
|
||||||
|
|
||||||
|
/* LoadMore */
|
||||||
|
$at-load-more-height: 80PX !default;
|
||||||
|
$at-load-more-tips-color: $color-grey-1 !default;
|
||||||
|
$at-load-more-tips-size: $font-size-lg !default;
|
||||||
|
|
||||||
|
/* Loading */
|
||||||
|
$at-loading-size: 36px !default;
|
||||||
|
$at-loading-color: $color-brand !default;
|
||||||
|
|
||||||
|
/* Message */
|
||||||
|
$at-message-color: $color-white !default;
|
||||||
|
$at-message-font-size: $font-size-base !default;
|
||||||
|
$at-message-bg-color: $color-info !default;
|
||||||
|
|
||||||
|
/* Modal */
|
||||||
|
$at-modal-width: 540px !default;
|
||||||
|
$at-modal-header-text-color: $color-text-base !default;
|
||||||
|
$at-modal-content-text-color: $color-text-base !default;
|
||||||
|
$at-modal-btn-default-color: $color-text-base !default;
|
||||||
|
$at-modal-btn-confirm-color: $color-brand !default;
|
||||||
|
$at-modal-bg-color: $color-white !default;
|
||||||
|
|
||||||
|
/* NavBar */
|
||||||
|
$at-nav-bar-title-color: $color-text-base !default;
|
||||||
|
$at-nav-bar-link-color: $color-brand !default;
|
||||||
|
|
||||||
|
/* NoticeBar */
|
||||||
|
$at-noticebar-text-color: #DE8C17 !default;
|
||||||
|
$at-noticebar-bg-color: #FCF6ED !default;
|
||||||
|
$at-noticebar-font-size: $font-size-sm !default;
|
||||||
|
$at-noticebar-icon-size: 30px !default;
|
||||||
|
$at-noticebar-btn-close-size: 32px !default;
|
||||||
|
$at-noticebar-btn-close-color: $color-grey-3 !default;
|
||||||
|
|
||||||
|
/* Pagination */
|
||||||
|
$at-pagination-margin: 40px !default;
|
||||||
|
$at-pagination-num-color: $color-text-base !default;
|
||||||
|
$at-pagination-num-font-size: $font-size-base !default;
|
||||||
|
$at-pagination-current-num-color: $color-brand !default;
|
||||||
|
$at-pagination-icon-color: $color-text-base !default;
|
||||||
|
$at-pagination-icon-font-size: 32px !default;
|
||||||
|
|
||||||
|
/* Progress */
|
||||||
|
$at-progress-height: 16px !default;
|
||||||
|
$at-progress-text-size: $font-size-sm !default;
|
||||||
|
$at-progress-icon-size: $font-size-xl !default;
|
||||||
|
$at-progress-inner-bg-color: $color-grey-6 !default;
|
||||||
|
$at-progress-bar-bg-color: $color-brand-light !default;
|
||||||
|
$at-progress-bar-bg-color-active: $color-white !default;
|
||||||
|
|
||||||
|
/* Radio */
|
||||||
|
$at-radio-title-color: $color-text-base !default;
|
||||||
|
$at-radio-title-size: $font-size-lg !default;
|
||||||
|
$at-radio-desc-color: $color-grey-2 !default;
|
||||||
|
$at-radio-desc-size: $font-size-sm !default;
|
||||||
|
$at-radio-check-color: $color-brand !default;
|
||||||
|
|
||||||
|
/* Range */
|
||||||
|
$at-range-slider-size: 28PX !default;
|
||||||
|
$at-range-rail-height: 2PX !default;
|
||||||
|
$at-range-rail-bg-color: #E9E9E9 !default;
|
||||||
|
$at-range-track-bg-color: $color-brand !default;
|
||||||
|
$at-range-slider-color: $color-white !default;
|
||||||
|
$at-range-slider-shadow: 0 0 4PX 0 rgba(0, 0, 0, 0.2) !default;
|
||||||
|
|
||||||
|
/* Rate */
|
||||||
|
$at-rate-icon-size: 20PX !default;
|
||||||
|
$at-rate-star-color: #ECECEC !default;
|
||||||
|
$at-rate-star-color-on: #FFCA3E !default;
|
||||||
|
|
||||||
|
/* SearchBar */
|
||||||
|
$at-search-bar-btn-color: $color-white !default;
|
||||||
|
$at-search-bar-btn-bg-color: $color-brand !default;
|
||||||
|
|
||||||
|
/* SegmentedControl */
|
||||||
|
$at-segmented-control-color: $color-brand !default;
|
||||||
|
$at-segmented-control-color-active: $color-white !default;
|
||||||
|
$at-segmented-control-bg-color: transparent !default;
|
||||||
|
$at-segmented-control-font-size: $font-size-base !default;
|
||||||
|
|
||||||
|
/* Slider */
|
||||||
|
$at-slider-text-color: $color-grey-2 !default;
|
||||||
|
$at-slider-text-size: $font-size-base !default;
|
||||||
|
|
||||||
|
/* Steps */
|
||||||
|
$at-steps-circle-size: 56px !default;
|
||||||
|
$at-steps-icon-size: $font-size-sm !default;
|
||||||
|
$at-steps-color: $color-white !default;
|
||||||
|
$at-steps-color-active: $color-grey-2 !default;
|
||||||
|
$at-steps-bg-color: $color-grey-4 !default;
|
||||||
|
$at-steps-bg-color-active: $color-brand !default;
|
||||||
|
$at-steps-line-color: $color-grey-3 !default;
|
||||||
|
$at-steps-title-color: $color-black-0 !default;
|
||||||
|
$at-steps-title-size: $font-size-lg !default;
|
||||||
|
$at-steps-desc-color: $color-grey-3 !default;
|
||||||
|
$at-steps-desc-size: $font-size-sm !default;
|
||||||
|
|
||||||
|
/* SwipeAction */
|
||||||
|
$at-swipe-action-color: $color-white !default;
|
||||||
|
$at-swipe-action-font-size: $font-size-base !default;
|
||||||
|
$at-swipe-action-bg-color: $color-white !default;
|
||||||
|
$at-swipe-action-option-bg-color: $color-grey-2 !default;
|
||||||
|
|
||||||
|
/* Switch */
|
||||||
|
$at-switch-title-color: $color-text-base !default;
|
||||||
|
$at-switch-title-size: $font-size-base !default;
|
||||||
|
|
||||||
|
/* TabBar */
|
||||||
|
$at-tab-bar-bg-color: $color-white !default;
|
||||||
|
$at-tab-bar-color: $color-text-base !default;
|
||||||
|
$at-tab-bar-color-active: $color-brand !default;
|
||||||
|
$at-tab-bar-font-size: $font-size-base !default;
|
||||||
|
$at-tab-bar-icon-color: $color-grey-0 !default;
|
||||||
|
$at-tab-bar-icon-font-size: 48px !default;
|
||||||
|
$at-tab-bar-icon-image-size: 50px !default;
|
||||||
|
|
||||||
|
/* Tabs */
|
||||||
|
$at-tabs-color: $color-text-base !default;
|
||||||
|
$at-tabs-color-active: $color-brand !default;
|
||||||
|
$at-tabs-font-size: $font-size-base !default;
|
||||||
|
$at-tabs-line-height: 1PX !default;
|
||||||
|
$at-tabs-underline-color: $color-grey-5 !default;
|
||||||
|
$at-tabs-bg-color: $color-bg !default;
|
||||||
|
|
||||||
|
/* Tag */
|
||||||
|
$at-tag-height: 60px !default;
|
||||||
|
$at-tag-height-sm: 40px !default;
|
||||||
|
$at-tag-color: $color-grey-1 !default;
|
||||||
|
$at-tag-color-primary: $color-grey-1 !default;
|
||||||
|
$at-tag-color-active: $color-brand-light !default;
|
||||||
|
$at-tag-color-primary-active: $color-text-base-inverse !default;
|
||||||
|
$at-tag-font-size: $font-size-base !default;
|
||||||
|
$at-tag-font-size-sm: $font-size-xs !default;
|
||||||
|
$at-tag-bg-color: $color-bg-grey !default;
|
||||||
|
$at-tag-bg-color-primary: $color-bg-grey !default;
|
||||||
|
$at-tag-bg-color-active: $color-white !default;
|
||||||
|
$at-tag-bg-color-primary-active: $at-tag-color-active !default;
|
||||||
|
$at-tag-border-color: $at-tag-bg-color !default;
|
||||||
|
$at-tag-border-color-primary: $at-tag-bg-color !default;
|
||||||
|
$at-tag-border-color-active: $at-tag-color-active !default;
|
||||||
|
|
||||||
|
/* Textarea */
|
||||||
|
$at-textarea-font-size: $font-size-lg !default;
|
||||||
|
$at-textarea-tips-color: $color-text-placeholder !default;
|
||||||
|
$at-textarea-tips-size: $font-size-base !default;
|
||||||
|
|
||||||
|
/* Timeline */
|
||||||
|
$at-timeline-offset-left: 40px !default;
|
||||||
|
$at-timeline-title-color: $color-grey-0 !default;
|
||||||
|
$at-timeline-title-font-size: $font-size-base !default;
|
||||||
|
$at-timeline-desc-color: $color-grey-1 !default;
|
||||||
|
$at-timeline-desc-font-size: $font-size-sm !default;
|
||||||
|
$at-timeline-dot-size: 24px !default;
|
||||||
|
$at-timeline-dot-color: $color-bg !default;
|
||||||
|
$at-timeline-dot-border-color: $color-brand-light !default;
|
||||||
|
$at-timeline-line-color: $color-border-lighter !default;
|
||||||
Loading…
x
Reference in New Issue
Block a user