From af12929083731d30650e54f2586a8b3fc3538f47 Mon Sep 17 00:00:00 2001 From: xuan Date: Thu, 16 Feb 2023 11:10:10 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(ID1000873):=20=E5=95=86?= =?UTF-8?q?=E5=9F=8E=E7=94=A8=E6=88=B7=E5=89=AA=E6=A0=B7=EF=BC=88A4?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【商城用户剪样(A4)】 https://www.tapd.cn/53459131/prong/stories/view/1153459131001000873 --- project.private.config.json | 23 +- src/api/colorCard/colorCardOrder.ts | 10 +- src/api/colorCard/enum.ts | 13 + src/api/colorCard/index.ts | 3 + src/api/sampleCutting/enum.ts | 13 + src/api/sampleCutting/index.ts | 11 + src/api/sampleCutting/sampleCutting.ts | 67 +++ src/app.config.ts | 4 + src/components/LabAndImg2/index.module.scss | 35 ++ src/components/LabAndImg2/index.tsx | 81 ++++ .../SelectColorCardStatus/index.module.scss | 20 + .../SelectColorCardStatus/index.tsx | 78 ++++ .../index.module.scss | 20 + .../SelectSampleCuttingStatus/index.tsx | 78 ++++ .../getColorCard/colorCardDetail/index.tsx | 276 ++++++----- src/pages/getColorCard/index.tsx | 33 +- .../addSampleCutting/index.config.ts | 3 + .../addSampleCutting/index.module.scss | 132 ++++++ .../sampleCutting/addSampleCutting/index.tsx | 434 ++++++++++++++++++ .../components/itemList/index.module.scss | 138 ++++++ .../components/itemList/index.tsx | 99 ++++ .../components/productColorPopup/index.tsx | 4 + src/pages/sampleCutting/index.config.ts | 3 + src/pages/sampleCutting/index.module.scss | 66 +++ src/pages/sampleCutting/index.tsx | 164 +++++++ .../sampleCuttingDetail/index.config.ts | 3 + .../sampleCuttingDetail/index.module.scss | 203 ++++++++ .../sampleCuttingDetail/index.tsx | 233 ++++++++++ .../sampleCuttingList/index.config.ts | 3 + .../sampleCuttingList/index.module.scss | 186 ++++++++ .../sampleCutting/sampleCuttingList/index.tsx | 355 ++++++++++++++ src/pages/user/index.tsx | 6 + 32 files changed, 2620 insertions(+), 177 deletions(-) create mode 100644 src/api/colorCard/enum.ts create mode 100644 src/api/sampleCutting/enum.ts create mode 100644 src/api/sampleCutting/index.ts create mode 100644 src/api/sampleCutting/sampleCutting.ts create mode 100644 src/components/LabAndImg2/index.module.scss create mode 100644 src/components/LabAndImg2/index.tsx create mode 100644 src/components/SelectColorCardStatus/index.module.scss create mode 100644 src/components/SelectColorCardStatus/index.tsx create mode 100644 src/components/SelectSampleCuttingStatus/index.module.scss create mode 100644 src/components/SelectSampleCuttingStatus/index.tsx create mode 100644 src/pages/sampleCutting/addSampleCutting/index.config.ts create mode 100644 src/pages/sampleCutting/addSampleCutting/index.module.scss create mode 100644 src/pages/sampleCutting/addSampleCutting/index.tsx create mode 100644 src/pages/sampleCutting/components/itemList/index.module.scss create mode 100644 src/pages/sampleCutting/components/itemList/index.tsx create mode 100644 src/pages/sampleCutting/components/productColorPopup/index.tsx create mode 100644 src/pages/sampleCutting/index.config.ts create mode 100644 src/pages/sampleCutting/index.module.scss create mode 100644 src/pages/sampleCutting/index.tsx create mode 100644 src/pages/sampleCutting/sampleCuttingDetail/index.config.ts create mode 100644 src/pages/sampleCutting/sampleCuttingDetail/index.module.scss create mode 100644 src/pages/sampleCutting/sampleCuttingDetail/index.tsx create mode 100644 src/pages/sampleCutting/sampleCuttingList/index.config.ts create mode 100644 src/pages/sampleCutting/sampleCuttingList/index.module.scss create mode 100644 src/pages/sampleCutting/sampleCuttingList/index.tsx diff --git a/project.private.config.json b/project.private.config.json index 2426a34..26bc576 100644 --- a/project.private.config.json +++ b/project.private.config.json @@ -320,7 +320,28 @@ { "name": "色卡详情", "pathName": "pages/getColorCard/colorCardDetail/index", - "query": "id=5", + "query": "id=20", + "launchMode": "default", + "scene": null + }, + { + "name": "领取剪样", + "pathName": "pages/sampleCutting/index", + "query": "", + "launchMode": "default", + "scene": null + }, + { + "name": "添加剪样", + "pathName": "pages/sampleCutting/sampleCuttingList/index", + "query": "", + "launchMode": "default", + "scene": null + }, + { + "name": "剪样详情", + "pathName": "pages/sampleCutting/sampleCuttingDetail/index", + "query": "id=1", "launchMode": "default", "scene": null } diff --git a/src/api/colorCard/colorCardOrder.ts b/src/api/colorCard/colorCardOrder.ts index c2842db..a433990 100644 --- a/src/api/colorCard/colorCardOrder.ts +++ b/src/api/colorCard/colorCardOrder.ts @@ -6,7 +6,7 @@ import { useRequest } from '@/use/useHttp' */ export const GetColorCardOrderList = () => { return useRequest({ - url: '/v2/mp/colorCardOrder/list', + url: '/v1/mp/colorCardOrder/list', method: 'get', }) } @@ -17,7 +17,7 @@ export const GetColorCardOrderList = () => { */ export const GetColorCardOrderDetail = () => { return useRequest({ - url: '/v2/mp/colorCardOrder', + url: '/v1/mp/colorCardOrder', method: 'get', }) } @@ -28,7 +28,7 @@ export const GetColorCardOrderDetail = () => { */ export const SubmitColorCardOrder = () => { return useRequest({ - url: '/v2/mp/colorCardOrder/submit', + url: '/v1/mp/colorCardOrder/submit', method: 'post', }) } @@ -39,7 +39,7 @@ export const SubmitColorCardOrder = () => { */ export const GetCanAddCardList = () => { return useRequest({ - url: '/v2/mp/colorCardOrder/canAddCard', + url: '/v1/mp/colorCardOrder/canAddCard', method: 'post', }) } @@ -50,7 +50,7 @@ export const GetCanAddCardList = () => { */ export const CancelColorCardOrder = () => { return useRequest({ - url: '/v2/mp/colorCardOrder/cancel', + url: '/v1/mp/colorCardOrder/cancel', method: 'post', }) } diff --git a/src/api/colorCard/enum.ts b/src/api/colorCard/enum.ts new file mode 100644 index 0000000..88c5cd5 --- /dev/null +++ b/src/api/colorCard/enum.ts @@ -0,0 +1,13 @@ + +import { useRequest } from '@/use/useHttp' + +/** + * 获取剪样订单列表 + * @returns + */ +export const EnumColorCardStatus = () => { + return useRequest({ + url: '/v1/mp/colorCardOrder/enum/auditStatus', + method: 'get', + }) +} diff --git a/src/api/colorCard/index.ts b/src/api/colorCard/index.ts index 66432e3..be6f345 100644 --- a/src/api/colorCard/index.ts +++ b/src/api/colorCard/index.ts @@ -5,3 +5,6 @@ export { GetCanAddCardList, CancelColorCardOrder, } from './colorCardOrder' +export { + EnumColorCardStatus, +} from './enum' diff --git a/src/api/sampleCutting/enum.ts b/src/api/sampleCutting/enum.ts new file mode 100644 index 0000000..1a48ed4 --- /dev/null +++ b/src/api/sampleCutting/enum.ts @@ -0,0 +1,13 @@ + +import { useRequest } from '@/use/useHttp' + +/** + * 获取剪样订单列表 + * @returns + */ +export const EnumCutSampleOrderStatus = () => { + return useRequest({ + url: '/v1/mp/cutSampleOrder/status', + method: 'get', + }) +} diff --git a/src/api/sampleCutting/index.ts b/src/api/sampleCutting/index.ts new file mode 100644 index 0000000..4c4cb2a --- /dev/null +++ b/src/api/sampleCutting/index.ts @@ -0,0 +1,11 @@ +export { + GetCutSampleOrderList, + GetCutSampleOrderProducts, + SubmitCutSampleOrder, + GetCutSampleOrderDetail, + CancelCutSampleOrder, + GetCutSampleOrderColorList, +} from './sampleCutting' +export { + EnumCutSampleOrderStatus, +} from './enum' diff --git a/src/api/sampleCutting/sampleCutting.ts b/src/api/sampleCutting/sampleCutting.ts new file mode 100644 index 0000000..ccbfce2 --- /dev/null +++ b/src/api/sampleCutting/sampleCutting.ts @@ -0,0 +1,67 @@ +import { useRequest } from '@/use/useHttp' + +/** + * 获取剪样订单列表 + * @returns + */ +export const GetCutSampleOrderList = () => { + return useRequest({ + url: '/v1/mp/cutSampleOrder/list', + method: 'get', + }) +} + +/** + * 搜索剪样面料 + * @returns + */ +export const GetCutSampleOrderProducts = () => { + return useRequest({ + url: '/v1/mp/cutSampleOrder/products', + method: 'get', + }) +} + +/** + * 剪样提交订单 + * @returns + */ +export const SubmitCutSampleOrder = () => { + return useRequest({ + url: '/v1/mp/cutSampleOrder/submit', + method: 'post', + }) +} + +/** + * 获取剪样订单详情 + * @returns + */ +export const GetCutSampleOrderDetail = () => { + return useRequest({ + url: '/v1/mp/cutSampleOrder/detail', + method: 'get', + }) +} + +/** + * 取消剪样订单 + * @returns + */ +export const CancelCutSampleOrder = () => { + return useRequest({ + url: '/v1/mp/cutSampleOrder/cancel', + method: 'put', + }) +} + +/** + * 取消剪样订单 + * @returns + */ +export const GetCutSampleOrderColorList = () => { + return useRequest({ + url: '/v1/mp/product/color/absorb/list', + method: 'get', + }) +} diff --git a/src/app.config.ts b/src/app.config.ts index 42a0abf..864ee1c 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -36,6 +36,10 @@ export default defineAppConfig({ 'custom-wrapper': '/custom-wrapper', }, subPackages: [ + { + root: 'pages/sampleCutting', + pages: ['index', 'addSampleCutting/index', 'sampleCuttingList/index', 'sampleCuttingDetail/index'], + }, { root: 'pages/getColorCard', pages: ['index', 'addColorCard/index', 'colorCardList/index', 'colorCardDetail/index'], diff --git a/src/components/LabAndImg2/index.module.scss b/src/components/LabAndImg2/index.module.scss new file mode 100644 index 0000000..a2eac8c --- /dev/null +++ b/src/components/LabAndImg2/index.module.scss @@ -0,0 +1,35 @@ +.labAndImg_main { + width: 100%; + height: 100%; + overflow: hidden; + position: relative; + // border: 1px #eee solid; + display: flex; + justify-content: center; + .boxColor { + width: 100%; + height: 100%; + border-radius: 20px; + // border: 1px solid #818181; + box-sizing: border-box; + } + .labAndImg_image { + width: 100%; + height: 100%; + border-radius: 20px; + } + .labAndImg_name { + position: absolute; + margin: auto; + bottom: 0; + left: 0; + right: 0; + width: 80%; + text-align: center; + font-size: 24px; + border-radius: 50px; + padding: 7px; + background-color: #fff; + @include common_ellipsis; + } +} diff --git a/src/components/LabAndImg2/index.tsx b/src/components/LabAndImg2/index.tsx new file mode 100644 index 0000000..33677ef --- /dev/null +++ b/src/components/LabAndImg2/index.tsx @@ -0,0 +1,81 @@ +import { Image, View } from '@tarojs/components' +import { memo, useCallback, useEffect, useMemo, useState } from 'react' +import LabAndImgShow from '../LabAndImgShow' +import styles from './index.module.scss' +import { formatImgUrl, formatRemoveHashTag } from '@/common/format' + +// 该组件宽高为100%需调整外层元素宽高 +interface Param { + value: { + texture_url?: string // 纹理图路径 + lab?: { l: number; a: number; b: number } // lab + rgb?: { r: number; g: number; b: number } // rgb + title?: string + } + customImageStyle?: React.CSSProperties + showStatus?: true | false + onClick?: (val: Param['value']) => void + round?: boolean + name?: string +} +const LabAndImg = ({ value, onClick, showStatus = false, round = false, name = '', customImageStyle = {} }: Param) => { + const [imgs, setImgs] = useState('') + + // lab是否都是0 + const rgbStyle = useMemo(() => { + if (value?.lab && (value?.lab.l || value?.lab.a || value?.lab.b)) { + return { backgroundColor: `rgb(${value.rgb?.r} ${value.rgb?.g} ${value.rgb?.b})` } + } + else { + return null + } + }, [value]) + + useEffect(() => { + if (value?.texture_url) { + const imgs = value.texture_url.split(',').map((item) => { + return formatImgUrl(item) + }) + setImgs(() => imgs[0]) + } + }, [value]) + + const [labAndImgShow, setLabAndImgShow] = useState(false) + const closeLabAndImgShow = useCallback(() => { + setLabAndImgShow(false) + }, []) + + const onShowLabAndImg = (e) => { + onClick?.(value) + if (!showStatus) { return false } + setLabAndImgShow(true) + } + + const checkLoad = (val) => { + setImgs(() => formatImgUrl('')) + } + + return ( + <> + + {value.texture_url && ( + checkLoad(e)} + className={styles.labAndImg_image} + style={{ borderRadius: round ? '50%' : '', ...customImageStyle }} + > + )} + {!value.texture_url && rgbStyle && } + {!value.texture_url && !rgbStyle && ( + + )} + {name && {name}} + + + + ) +} +export default memo(LabAndImg) diff --git a/src/components/SelectColorCardStatus/index.module.scss b/src/components/SelectColorCardStatus/index.module.scss new file mode 100644 index 0000000..2469554 --- /dev/null +++ b/src/components/SelectColorCardStatus/index.module.scss @@ -0,0 +1,20 @@ +.grid { + padding: 24px 40px; + display: grid; + grid-gap: 24px 24px; + grid-template-columns: 1fr 1fr; +} +.tab_bar { + position: relative; + z-index: 99; + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + align-items: center; + padding: 20px; + background-color: white; + box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); +} +.button { + padding: 0 60px; +} diff --git a/src/components/SelectColorCardStatus/index.tsx b/src/components/SelectColorCardStatus/index.tsx new file mode 100644 index 0000000..55dec01 --- /dev/null +++ b/src/components/SelectColorCardStatus/index.tsx @@ -0,0 +1,78 @@ +import { View } from '@tarojs/components' +import { FC, forwardRef, memo, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react' +import DropDownItem from '../dropDown-item' +import FilterButton from '../filterButton' +import styles from './index.module.scss' +import { EnumColorCardStatus } from '@/api/colorCard' + +type ChangedValue = string | number + +interface SelectSaleTypeProps { + onChange?: (value: ChangedValue) => void + onCloseOverlay?: () => void + defaultValue?: ChangedValue +} + +interface EnumList { + id: number + code: string + name: string +} +// 色卡订单状态 +const SelectColorCardStatus = (props: SelectSaleTypeProps, ref) => { + const selectName = '色卡订单状态' + const { onChange, defaultValue = 0 } = props + console.log(props) + const { fetchData } = EnumColorCardStatus() + const [enumList, setEnumList] = useState([]) + + const getData = async() => { + const res = await fetchData() + setEnumList([{ id: 0, code: '', name: '全部记录' }, ...res.data.list]) + } + + useEffect(() => { + getData() + }, []) + + const [currentValue, setCurrentValue] = useState(defaultValue) + + const handleClick = (value: ChangedValue) => { + setCurrentValue(value) + onChange?.(value) + } + + const dropDownRef = useRef(null) + + useImperativeHandle( + ref, + () => { + return { + show: dropDownRef.current.show, + showPopup: dropDownRef.current.showPopup, + closePopup: dropDownRef.current.closePopup, + } + }, + [dropDownRef.current], + ) + + return ( + + {!!enumList.length + && enumList.map((item: EnumList, key) => { + // 1 申请中 2 已完成 + if ([1, 2, 0].includes(item.id)) { + return ( + handleClick(item.id)}> + {item.name} + + ) + } + else { + return null + } + })} + + ) +} +export default memo(forwardRef(SelectColorCardStatus)) diff --git a/src/components/SelectSampleCuttingStatus/index.module.scss b/src/components/SelectSampleCuttingStatus/index.module.scss new file mode 100644 index 0000000..2469554 --- /dev/null +++ b/src/components/SelectSampleCuttingStatus/index.module.scss @@ -0,0 +1,20 @@ +.grid { + padding: 24px 40px; + display: grid; + grid-gap: 24px 24px; + grid-template-columns: 1fr 1fr; +} +.tab_bar { + position: relative; + z-index: 99; + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + align-items: center; + padding: 20px; + background-color: white; + box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); +} +.button { + padding: 0 60px; +} diff --git a/src/components/SelectSampleCuttingStatus/index.tsx b/src/components/SelectSampleCuttingStatus/index.tsx new file mode 100644 index 0000000..78766d3 --- /dev/null +++ b/src/components/SelectSampleCuttingStatus/index.tsx @@ -0,0 +1,78 @@ +import { View } from '@tarojs/components' +import { FC, forwardRef, memo, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react' +import DropDownItem from '../dropDown-item' +import FilterButton from '../filterButton' +import styles from './index.module.scss' +import { EnumCutSampleOrderStatus } from '@/api/sampleCutting' + +type ChangedValue = string | number + +interface SelectSaleTypeProps { + onChange?: (value: ChangedValue) => void + onCloseOverlay?: () => void + defaultValue?: ChangedValue +} + +interface EnumList { + id: number + code: string + name: string +} +// 剪样订单状态 +const SelectSampleCuttingStatus = (props: SelectSaleTypeProps, ref) => { + const selectName = '剪样订单状态' + const { onChange, defaultValue = 0 } = props + console.log(props) + const { fetchData } = EnumCutSampleOrderStatus() + const [enumList, setEnumList] = useState([]) + + const getData = async() => { + const res = await fetchData() + setEnumList([{ id: 0, code: '', name: '全部记录' }, ...res.data.list]) + } + + useEffect(() => { + getData() + }, []) + + const [currentValue, setCurrentValue] = useState(defaultValue) + + const handleClick = (value: ChangedValue) => { + setCurrentValue(value) + onChange?.(value) + } + + const dropDownRef = useRef(null) + + useImperativeHandle( + ref, + () => { + return { + show: dropDownRef.current.show, + showPopup: dropDownRef.current.showPopup, + closePopup: dropDownRef.current.closePopup, + } + }, + [dropDownRef.current], + ) + + return ( + + {!!enumList.length + && enumList.map((item: EnumList, key) => { + // 5 申请中 6 已完成 + if ([5, 6, 0].includes(item.id)) { + return ( + handleClick(item.id)}> + {item.name} + + ) + } + else { + return null + } + })} + + ) +} +export default memo(forwardRef(SelectSampleCuttingStatus)) diff --git a/src/pages/getColorCard/colorCardDetail/index.tsx b/src/pages/getColorCard/colorCardDetail/index.tsx index d784be5..9af5348 100644 --- a/src/pages/getColorCard/colorCardDetail/index.tsx +++ b/src/pages/getColorCard/colorCardDetail/index.tsx @@ -8,7 +8,7 @@ import AddressDetailBox from '@/pages/orderDetails/components/addressDetailBox' import LabAndImg from '@/components/LabAndImg' import Tag from '@/components/tag' import Cell from '@/components/cell' -import { formatDateTime, formatRemoveHashTag } from '@/common/format' +import { formatDateTime, formatRemoveHashTag, formatUrl } from '@/common/format' import NormalButton from '@/components/normalButton' import Steps from '@/components/steps' import Step from '@/components/steps/components/step' @@ -83,163 +83,151 @@ const ColorCardDetail = () => { getData() }, []) - return - - - - 订单进程 - - - - {/* + return + + + 订单进程 + + + + {/* 申请中 -> 已完成 2 申请中 -> 已取消 4 申请中 -> 已拒绝 3 */} - { + return - 申请中 - {formatDateTime(order?.order_progress?.[0].audit_time)} + {item.order_status_name} + {formatDateTime(item.audit_time)} - } - /> - {/* order.order_status === 1 申请中 */} - { - order.order_status !== 1 - ? - {order?.order_progress?.[1].order_status_name} - {formatDateTime(order?.order_progress?.[1].audit_time)} - - } description={ - <> - { - order?.order_progress?.[1].audit_remark ? {formatDateTime(order?.order_progress?.[1].audit_remark)} : null - } - { - order?.order_progress?.[1].delivery_appendix_url - ? + } description={ + <> + { + item.audit_remark && {item.audit_remark} + } + { + item.delivery_appendix_url + && { - order?.order_progress?.[1].delivery_appendix_url?.map((url, index) => { + item.delivery_appendix_url?.map((url, index) => { return - + }) } - : null - } - - } - /> - : - } - - - - - - 客户信息 - - - {order?.purchaser_name} - {order?.purchaser_phone} - - - - - - - - - - - - - {order?.address} - - - - {order.target_user_name} - {order.target_user_phone} - - {order.shipment_mode_name} - - - - - {/* 色卡信息 */} - - 色卡信息 - - { - order.color_card_info?.map((item) => { - return ( - - - - - - - - - - - {item.name} - - - { - item.affiliation_product?.map((product_color, index) => { - return {formatRemoveHashTag(product_color)} - }) - } - - - - x{item.count}本 - - - - - - ) - }) - } - 快递到付 - - - 订单信息 - - - - {order.order_no} - handleCopy(order.order_no)}>复制 - + } + + } + /> + }) } - > - - - - - - 备注信息 - - {order?.remark || '暂无备注信息'} - - - - { - order.order_status === 1 - ? - 取消订单 - - : null - } - + + + + + 客户信息 + + + {order?.purchaser_name} + {order?.purchaser_phone} + + + + + + + + + + + + + {order?.address} + + + + {order.target_user_name} + {order.target_user_phone} + + {order.shipment_mode_name} + + + + + {/* 色卡信息 */} + + 色卡信息 + + { + order.color_card_info?.map((item) => { + return ( + + + + + + + + + + + {item.name} + + + { + item.affiliation_product?.map((product_color, index) => { + return {formatRemoveHashTag(product_color)} + }) + } + + + + x{item.count}本 + + + + + + ) + }) + } + 快递到付 + + + 订单信息 + + + + {order.order_no} + handleCopy(order.order_no)}>复制 + + } + > + + + + + + 备注信息 + + {order?.remark || '暂无备注信息'} + - + + { + order.order_status === 1 + ? + 取消订单 + + : null + } + + + } export default ColorCardDetail diff --git a/src/pages/getColorCard/index.tsx b/src/pages/getColorCard/index.tsx index 28a7bcf..669d34b 100644 --- a/src/pages/getColorCard/index.tsx +++ b/src/pages/getColorCard/index.tsx @@ -8,12 +8,11 @@ import Search from '@/components/search' import NormalButton from '@/components/normalButton' import InfiniteScroll from '@/components/infiniteScroll' import { dataLoadingStatus, debounce, getFilterData } from '@/common/util' -import FilterButton from '@/components/filterButton' import { alert, goLink } from '@/common/common' import { CancelColorCardOrder, GetColorCardOrderList } from '@/api/colorCard' -import IconFont from '@/components/iconfont/iconfont' import Empty from '@/components/empty' import { COLOR_CARD_LIST_EMPTY_IMAGE } from '@/common/constant' +import SelectColorCardStatus from '@/components/SelectColorCardStatus' const GetColorCard = () => { const { fetchData, state } = GetColorCardOrderList() @@ -23,6 +22,7 @@ const GetColorCard = () => { return alert.error(res.msg) } setColorList({ list: res.data.list, total: res.data.total }) + setRefresherTriggeredStatus(false) } // status 1 申请中 2 已完成 @@ -68,24 +68,9 @@ const GetColorCard = () => { setSearchField(e => ({ ...e, name: value })) }, 300) - const FilterOptions = [ - { - key: 0, - label: '全部记录', - }, - { - key: 1, - label: '申请中', - }, - { - key: 2, - label: '已完成', - }, - ] - - const handleClickFilter = (item: typeof FilterOptions[number]) => { - if (searchField.status === item.key) { return } - setSearchField(e => ({ ...e, status: item.key })) + const handleClickFilter = (value) => { + if (searchField.status === value) { return } + setSearchField(e => ({ ...e, status: value })) } useEffect(() => { @@ -127,13 +112,7 @@ const GetColorCard = () => { - - { - FilterOptions.map((item, index) => { - return handleClickFilter(item)}>{item.label} - }) - } - + } diff --git a/src/pages/sampleCutting/addSampleCutting/index.config.ts b/src/pages/sampleCutting/addSampleCutting/index.config.ts new file mode 100644 index 0000000..70948c5 --- /dev/null +++ b/src/pages/sampleCutting/addSampleCutting/index.config.ts @@ -0,0 +1,3 @@ +export default { + navigationBarTitleText: '领取剪样', +} diff --git a/src/pages/sampleCutting/addSampleCutting/index.module.scss b/src/pages/sampleCutting/addSampleCutting/index.module.scss new file mode 100644 index 0000000..9c00d31 --- /dev/null +++ b/src/pages/sampleCutting/addSampleCutting/index.module.scss @@ -0,0 +1,132 @@ +page { + background: #f7f7f7; + height: 100%; + display: flex; + flex-flow: column nowrap; +} +.layoutBlock { + padding: 24px 34px; +} +.main { + background-color: $color_bg_one; + height: 100%; + display: flex; + flex-flow: column nowrap; + overflow: hidden; +} +.context { + flex: 1 1 auto; + height: 100%; + overflow-y: scroll; +} +.addButton { + margin-left: 24px; + margin-right: 24px; + margin-top: 24px; +} +.customerTop { + color: #333333; + font-size: 28px; +} +.customerBottom { + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + color: #9b9b9b; + font-size: 28px; +} + +.colorCardTop { + font-size: 28px; +} +.colorCardBottom { + width: 100%; + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + overflow: hidden; + margin-bottom: 24px; + .leftCont { + width: 134px; + height: 134px; + border-radius: 8px; + margin-right: 24px; + } + .rightCont { + flex: 1 1 auto; + overflow: hidden; + display: flex; + flex-flow: column nowrap; + justify-content: space-between; + &__top { + font-size: 28px; + @include common_ellipsis(1); + } + &__bottom { + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + width: 100%; + align-items: flex-end; + } + &__left { + flex: 1 1 auto; + overflow: hidden; + } + &__right { + width: 30%; + } + } +} +.paymentMethod { + text-align: right; + font-size: 28px; + color: #f64861; +} + +.remarkTop { + display: flex; + justify-content: space-between; + .remarkTitle { + font-size: 28px; + font-weight: 500; + color: #393939; + } + .remarkTag { + display: flex; + flex-flow: row nowrap; + font-size: 24px; + color: #626262; + } +} + +.remarkBottom { + .remarkContent { + font-size: 28px; + color: #999999; + } +} + +.bottomBar { + .bottomTotal { + color: #aeaeae; + font-size: 24px; + } + position: relative; + z-index: 99; + box-shadow: 0 -4px 6px -1px rgb(0 0 0 / 0.1), 0 -2px 4px -2px rgb(0 0 0 / 0.1); + flex: none; + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + align-items: center; + padding-left: 20px; + padding-right: 20px; + padding-top: 24px; + background-color: white; + padding-bottom: calc(20px + constant(safe-area-inset-bottom)); + padding-bottom: calc(20px + env(safe-area-inset-bottom)); +} +.bottomBar__button { + font-size: 28px; +} diff --git a/src/pages/sampleCutting/addSampleCutting/index.tsx b/src/pages/sampleCutting/addSampleCutting/index.tsx new file mode 100644 index 0000000..8e3917e --- /dev/null +++ b/src/pages/sampleCutting/addSampleCutting/index.tsx @@ -0,0 +1,434 @@ +import { Text, View } from '@tarojs/components' +import Taro, { useDidShow, useUnload } from '@tarojs/taro' +import { useCallback, useEffect, useMemo, useState } from 'react' +import type { SampleCuttingCache } from '../sampleCuttingList' +import styles from './index.module.scss' +import LayoutBlock from '@/components/layoutBlock' +import NormalButton from '@/components/normalButton' +import Divider from '@/components/divider' +import IconFont from '@/components/iconfont/iconfont' +import LabAndImg from '@/components/LabAndImg' +import Counter from '@/components/counter' +import { alert, goLink } from '@/common/common' +import { ClientListApi } from '@/api/order' +import AddressDetailBox from '@/pages/orderDetails/components/addressDetailBox' +import Popup from '@/components/popup' +import Remark from '@/pages/orderDetails/components/remark' +import { formatRemoveHashTag } from '@/common/format' +import { SubmitCutSampleOrder } from '@/api/sampleCutting' + +const AddColorCard = () => { + // 获取选择的客户 + const pages = Taro.getCurrentPages() + const currPage = pages[pages.length - 1] // 获取当前页面 + const [addressInfo, setAddressInfo] = useState({}) + + // 获取客户 + const [clientList, setClientList] = useState([]) + const { fetchData: fetchClientData } = ClientListApi() + + const [order, setOrder] = useState([]) + + useDidShow(() => { + const sampleCuttingCache = Taro.getStorageSync('sampleCuttingCache') + if (sampleCuttingCache) { + console.log('sampleCuttingCache', JSON.parse(sampleCuttingCache)) + setOrder(JSON.parse(sampleCuttingCache)) + } + }) + + const [clientInfo, setClientInfo] = useState({ + clientId: -1, + clientName: '', + clientPhone: '', + }) + + const getClient = async() => { + const res = await fetchClientData({ + page: 1, size: 10, + }) + if (!res.success) { + return alert.error(res.msg) + } + currPage.data.clientId = res.data.list.length > 0 ? res.data.list[0]?.id : -1 + currPage.data.clientName = res.data.list.length > 0 ? res.data.list[0]?.name : '' + currPage.data.clientPhone = res.data.list.length > 0 ? res.data.list[0]?.phone : '' + const { + clientId, + clientName, + clientPhone, + } = currPage.data + setClientInfo({ + clientId, + clientName, + clientPhone, + }) + setClientList([...res.data.list]) + } + + useEffect(() => { + getClient() + }, []) + + useUnload(() => { + Taro.removeStorageSync('sampleCuttingCache') + }) + + // 选择客户 + const handleSelectCustomer = () => { + goLink(`/pages/customerPage/index?clientId=${clientInfo?.clientId}`) + } + // 添加剪样 + const handleAddColorCard = () => { + Taro.setStorageSync('sampleCuttingCache', JSON.stringify(order)) + + goLink('/pages/sampleCutting/sampleCuttingList/index', { isGoBack: true, isAddSampleCutIdList: order.map(item => item.product_id) }) + } + + const { fetchData } = SubmitCutSampleOrder() + // 提交订单 + const handleSubmitOrder = async() => { + if (!addressInfo.address_id) { + Taro.showToast({ + title: '请选择地址', + icon: 'none', + duration: 2000, + }) + return + } + if (!clientInfo.clientId) { + Taro.showToast({ + title: '请选择客户', + icon: 'none', + duration: 2000, + }) + return + } + const productColorList: any[] = [] + order.forEach((item) => { + item.multipleSelection.forEach((mul) => { + productColorList.push({ + product_color_id: mul.product_color_id, + color_num: mul.count, + }) + }) + }) + // 请求数据 + const res = await fetchData({ + address_id: addressInfo.address_id, + cut_sample_order_product_color_list: productColorList, + purchaser_id: clientInfo.clientId, + remark, + shipment_mode: 2, // 物流 + }) + if (res.success) { + Taro.showToast({ + title: '提交成功', + icon: 'success', + duration: 2000, + }) + Taro.removeStorageSync('sampleCuttingCache') + setTimeout(() => { + goLink('/pages/sampleCutting/sampleCuttingDetail/index', { id: res.data.id }, 'redirectTo') + }, 2000) + } + } + + const labAndImgObj = useCallback((item) => { + return { lab: item?.lab, rgb: item?.rgb, texture_url: item?.texture_url } + }, []) + + const getInputValue = () => { + + } + + const deleteColorCard = (productId: number, colorId: number) => { + setOrder((prev) => { + let newOlder: SampleCuttingCache[] = [] + const targetProductIndex = prev.findIndex(item => item.product_id === productId) + + if (prev[targetProductIndex].multipleSelection.length === 1) { + if (prev.length === 1) { + alert.none('最后一个剪样不能删除') + return prev + } + prev.splice(targetProductIndex, 1) + newOlder = [...prev] + } + else { + newOlder = prev.map((item) => { + if (item.product_id === productId) { + item.multipleSelection = item.multipleSelection.filter(mul => mul.product_color_id !== colorId) + } + return item + }) + } + Taro.setStorageSync('sampleCuttingCache', JSON.stringify(newOlder)) + return newOlder + }) + } + + const handleCountChange = (value: number, productId: number, colorId: number) => { + console.log('value', value) + if (order.length === 1 && value === 0) { + Taro.showToast({ + title: '最后一个剪样不能删除', + icon: 'none', + duration: 2000, + }) + return + } + if (value === 0) { + Taro.showModal({ + content: '确认删除所选剪样?', + confirmText: '删除', + confirmColor: '#337fff', + success(res) { + if (res.confirm) { + deleteColorCard(productId, colorId) + } + }, + }) + return + } + setOrder((prev) => { + const newOlder = prev.map((item) => { + if (item.product_id === productId) { + item.multipleSelection = item.multipleSelection.map((mul) => { + if (mul.product_color_id === colorId) { + mul.count = value + } + return mul + }) + } + return item + }) + Taro.setStorageSync('sampleCuttingCache', JSON.stringify(newOlder)) + return newOlder + }) + } + + const handSelect = () => { + goLink(`/pages/addressManager/index?purchaser_id=${clientInfo.clientId}`) + } + // 接受选择客户页面传递过来的数据 + useDidShow(() => { + // 判断是否有跳转选择客户 + if (currPage.data?.clientId && currPage.data?.clientId !== '') { + setClientInfo({ + clientId: currPage.data?.clientId, + clientName: currPage.data?.clientName, + clientPhone: currPage.data?.clientPhone, + }) + } + // 默认客户 + if (currPage.data?.clientId == null) { + setClientInfo(() => { + return { + clientId: clientList.length > 0 ? clientList[0]?.id : -1, + clientName: clientList.length > 0 ? clientList[0]?.name : '', + clientPhone: clientList.length > 0 ? clientList[0]?.phone : '', + } + }) + } + }) + + const initAddressInfo = () => { + setAddressInfo(val => ({ + ...val, + province_name: '', + address_id: '', + city_name: '', + address_detail: '', + district_name: '', + target_user_name: '', + purchaser_phone: '', + })) + } + + useDidShow(() => { + // 获取选择的地址 + console.log('addressObj', currPage.data?.addressObj, clientInfo.clientId, currPage.data?.clientId) + if (!currPage.data?.addressObj) { return initAddressInfo() } + const { + purchaser_id, + province_name, + id, + city_name, + address_detail, + district_name, + name, + phone, + } = currPage.data?.addressObj + if (purchaser_id === currPage.data?.clientId) { + setAddressInfo(val => ({ + ...val, + province_name: province_name || '', + address_id: id || '', + city_name: city_name || '', + address_detail: address_detail || '', + district_name: district_name || '', + target_user_name: name || '', + purchaser_phone: phone || '', + })) + } + else { + initAddressInfo() + } + const selectId = id + const obj = currPage?.data?.ids?.filter((item) => { return item == selectId }) + console.log('ids', currPage?.data?.ids) + if (currPage?.data?.ids && obj.length === 0) { + initAddressInfo() + } + }) + + // 备注操作 + const [showDesc, setShowDesc] = useState(false) + const [remark, setRemark] = useState('') + const handleShowDesc = () => { + setShowDesc(true) + } + + const getRemark = useCallback((value: string) => { + setShowDesc(false) + console.log('remark', value) + setRemark(value) + }, []) + + const totalColorNumber = useMemo(() => { + return order.reduce((prev, curr) => { + return prev + curr.multipleSelection.length + }, 0) + }, [order]) + + const totalColorCount = useMemo(() => { + return order.reduce((prev, curr) => { + return prev + curr.multipleSelection.reduce((subPrev, subCurr) => { + return subPrev + subCurr.count + }, 0) + }, 0) + }, [order]) + + return + + {/* 客户信息 */} + + + 客户信息 + + + + { + clientInfo.clientId !== -1 + ? (<> + + {clientInfo.clientName} + + + {clientInfo.clientPhone} + + + ) + : 选择领取客户 + } + + + + { + clientInfo.clientId !== -1 && } + > + } + + 添加剪样 + { + order.map((item, index) => { + return + {item.product_code_and_name} + + { + item.multipleSelection.map((mul) => { + return ( + + + + + + + + + {`#${formatRemoveHashTag(mul.product_color_code)} ${mul.product_color_name}`} + + + + {/* { + item.affiliation_product.map((product_color, index) => { + return {formatRemoveHashTag(product_color.code)} + }) + } */} + + + handleCountChange(e, item.product_id, mul.product_color_id)} + onClickBtn={getInputValue} + unit="份" + minNum={0} + maxNum={999} + /> + + + + + + ) + }) + } + 快递到付 + + }) + } + + {/* 备注信息 */} + + + 备注信息 + + 填写/修改备注 + + + + + + { remark || '尚未备注信息' } + + + + + + + 当前共 {order.length} 种面料, {totalColorNumber || 0} 种色号,共 {totalColorCount || 0} 份 + + + 提交订单 + + + + setShowDesc(false)}> + + + +} +export default AddColorCard diff --git a/src/pages/sampleCutting/components/itemList/index.module.scss b/src/pages/sampleCutting/components/itemList/index.module.scss new file mode 100644 index 0000000..40a40fc --- /dev/null +++ b/src/pages/sampleCutting/components/itemList/index.module.scss @@ -0,0 +1,138 @@ +.topItem { + display: flex; + align-items: center; + justify-content: space-between; + + .orderNo { + font-size: 28px; + font-weight: 550; + color: #000000; + } + + .status { + font-size: 28px; + font-weight: 550; + color: #0d7cff; + } +} +.flexBox { + display: flex; + align-items: center; + .pussName { + margin-right: 10px; + font-size: 28px; + font-weight: 500; + color: #666666; + } + .tag { + background-color: #e3ecff; + border-color: transparent; + color: #337fff; + } +} + +.contBox { + width: 100%; + display: flex; + justify-content: space-between; + overflow: hidden; + .leftCont { + width: 134px; + height: 134px; + border-radius: 8px; + position: relative; + } + + .rightCont { + width: calc(100% - 134px); + flex: 1 1 auto; + display: flex; + flex-flow: column nowrap; + overflow: hidden; + margin-left: 24px; + justify-content: space-between; + .rightTop { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 12px; + + .productName { + width: 70%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + margin-right: 8px; + font-size: 28px; + color: #000000; + } + + .shipMode { + width: 25%; + font-size: 28px; + color: #000000; + text-align: right; + } + } + + .colorsBox { + display: flex; + align-items: center; + justify-content: space-between; + font-size: 24px; + .colorName { + flex: 1 1 auto; + color: #797979; + @include common_ellipsis(1); + } + .colorCount { + color: #797979; + } + } + } +} + +.lineOne { + // width: 638px; + margin-right: 32px; + height: 1px; + background: #e7e7e7; + // opacity: 0.1; + margin-left: 32px; + margin-top: 24px; +} + +.bottomMsg { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 16px; + + .msgLeft { + font-size: 24px; + font-weight: 400; + color: #a1a1a1; + } + + .msgRight { + font-size: 24px; + font-weight: 400; + color: #a1a1a1; + } +} +.paymentMethod { + display: flex; + justify-content: flex-end; + .msgRightOne { + font-size: 28px; + font-weight: 500; + color: #f64861; + align-self: flex-end; + } +} + +.bottomBox { + display: flex; + justify-content: flex-end; + margin-top: 32px; +} diff --git a/src/pages/sampleCutting/components/itemList/index.tsx b/src/pages/sampleCutting/components/itemList/index.tsx new file mode 100644 index 0000000..407559b --- /dev/null +++ b/src/pages/sampleCutting/components/itemList/index.tsx @@ -0,0 +1,99 @@ +import type { ITouchEvent } from '@tarojs/components' +import { ScrollView, View } from '@tarojs/components' +import Taro from '@tarojs/taro' +import { memo, useCallback, useEffect, useMemo, useState } from 'react' +import classnames from 'classnames' +import styles from './index.module.scss' +import BottomBtns from '@/components/BottomBtns' +import { formatHashTag, formatPriceDiv } from '@/common/format' +import LabAndImg from '@/components/LabAndImg' +import NormalButton from '@/components/normalButton' +import Divider from '@/components/divider' +import Tag from '@/components/tag' +import LayoutBlock from '@/components/layoutBlock' +import { goLink } from '@/common/common' + +interface PropsType { + data?: any + cancel?: (e: ITouchEvent) => void +} +const ItemList = (props: PropsType) => { + const { data, cancel } = props + + const labAndImgObj = useCallback((item) => { + return { lab: item?.lab, rgb: item?.rgb, texture_url: item?.texture_url } + }, []) + // 进入详情页 + const navTo = () => { + goLink('/pages/sampleCutting/sampleCuttingDetail/index', { id: data.order_id }) + } + + return ( + + + 单号:{data.order_no} + {data.mp_cut_sample_audit_status_name} + + + {data.purchaser_name} + { + data.sale_user_name && + {data.sale_user_name} + + } + + + + + + + + + + + + {data.cut_sample_order_product_list[0].name} + {data.shipment_mode_name} + + { + data.cut_sample_order_product_list[0].product_colors?.map((item, index) => { + if (index < 2) { + return + {formatHashTag(item.code, item.name)} + x{item.color_num || 0}份 + + } + else { + return null + } + }) + } + + + + + 剪样信息: + {data?.total_fabrics || 0} 种面料,{data?.total_colors || 0} 种剪样,共 {data?.total_number || 0} 份 + + + 快递到付 + + + { + data.order_status === 1 && + 取消订单 + + } + + + + ) +} +export default memo(ItemList) diff --git a/src/pages/sampleCutting/components/productColorPopup/index.tsx b/src/pages/sampleCutting/components/productColorPopup/index.tsx new file mode 100644 index 0000000..c8ee469 --- /dev/null +++ b/src/pages/sampleCutting/components/productColorPopup/index.tsx @@ -0,0 +1,4 @@ +const ProductColorPopup = (props) => { + +} +export default ProductColorPopup diff --git a/src/pages/sampleCutting/index.config.ts b/src/pages/sampleCutting/index.config.ts new file mode 100644 index 0000000..70948c5 --- /dev/null +++ b/src/pages/sampleCutting/index.config.ts @@ -0,0 +1,3 @@ +export default { + navigationBarTitleText: '领取剪样', +} diff --git a/src/pages/sampleCutting/index.module.scss b/src/pages/sampleCutting/index.module.scss new file mode 100644 index 0000000..b6ba5a5 --- /dev/null +++ b/src/pages/sampleCutting/index.module.scss @@ -0,0 +1,66 @@ +page { + background: #f7f7f7; + height: 100%; + display: flex; + flex-flow: column nowrap; +} +.main { + background-color: $color_bg_one; + height: 100%; + display: flex; + flex-flow: column nowrap; + overflow: hidden; + + .search { + width: 100%; + display: flex; + justify-content: space-between; + padding: 20px; + box-sizing: border-box; + align-items: center; + background-color: #fff; + border-bottom: 1px solid #e5e5e5; + } + .tab_bar{ + position: relative; + z-index: 99; + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + align-items: center; + padding: 20px; + background-color: white; + box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1); + } + .color_card_list{ + flex: 1 1 auto; + height: 100%; + overflow: hidden; + .order_item{ + margin: 20px 0; + } + } + .bottomBar { + position: relative; + z-index: 99; + box-shadow: 0 -4px 6px -1px rgb(0 0 0 / 0.1), 0 -2px 4px -2px rgb(0 0 0 / 0.1); + flex: none; + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + align-items: center; + padding-left: 20px; + padding-right: 20px; + padding-top: 24px; + background-color: white; + padding-bottom: calc(20px + constant(safe-area-inset-bottom)); + padding-bottom: calc(20px + env(safe-area-inset-bottom)); + } +} +.tab_bar .button{ + padding: 0 60px; +} +.bottomBar__button{ + width: 100%; + font-size: 28px; +} diff --git a/src/pages/sampleCutting/index.tsx b/src/pages/sampleCutting/index.tsx new file mode 100644 index 0000000..25e3455 --- /dev/null +++ b/src/pages/sampleCutting/index.tsx @@ -0,0 +1,164 @@ +import type { ITouchEvent } from '@tarojs/components' +import { View } from '@tarojs/components' +import Taro from '@tarojs/taro' +import { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import styles from './index.module.scss' +import ItemList from './components/itemList' +import Search from '@/components/search' +import NormalButton from '@/components/normalButton' +import InfiniteScroll from '@/components/infiniteScroll' +import { dataLoadingStatus, debounce, getFilterData } from '@/common/util' +import FilterButton from '@/components/filterButton' +import { alert, goLink } from '@/common/common' +import Empty from '@/components/empty' +import { COLOR_CARD_LIST_EMPTY_IMAGE } from '@/common/constant' +import { CancelCutSampleOrder, GetCutSampleOrderList } from '@/api/sampleCutting' +import SelectSampleCuttingStatus from '@/components/SelectSampleCuttingStatus' + +const GetSampleCutting = () => { + const { fetchData, state } = GetCutSampleOrderList() + const getData = async() => { + const res = await fetchData(getFilterData(searchField)) + if (!res.success) { + return alert.error(res.msg) + } + setSampleCuttingList({ list: res.data.list, total: res.data.total }) + setRefresherTriggeredStatus(false) + } + + // status 1 申请中 2 已完成 + // 页码和页数 + const [searchField, setSearchField] = useState<{ purchaser_and_sale_user?: string; mp_cut_sample_audit_status?: number; page: number; size: number }>({ + purchaser_and_sale_user: '', + mp_cut_sample_audit_status: 0, + page: 1, + size: 10, + }) + const [sampleCuttingList, setSampleCuttingList] = useState<{ list: any[]; total: number }>({ list: [], total: 0 }) + + // 列表下拉刷新 + const [refresherTriggeredStatus, setRefresherTriggeredStatus] = useState(false) + // 数据加载状态 + const statusMore = useMemo(() => { + return dataLoadingStatus({ list: sampleCuttingList.list, total: sampleCuttingList.total, status: state.loading! }) + }, [sampleCuttingList, state.loading]) + // 筛选参数 + // 上拉加载数据 + const pageNum = useRef({ size: searchField.size, page: searchField.page }) + + const getRefresherRefresh = async() => { + pageNum.current.size = 1 + setRefresherTriggeredStatus(true) + setSearchField(val => ({ ...val, size: 10 })) + } + const getScrollToLower = useCallback(() => { + if (sampleCuttingList.list.length < sampleCuttingList.total) { + pageNum.current.page++ + const size = pageNum.current.size * pageNum.current.page + setSearchField({ ...searchField, size }) + } + }, [sampleCuttingList]) + + // 领取剪样 + const getSampleCutting = () => { + goLink('/pages/sampleCutting/sampleCuttingList/index') + } + + // 搜索 + const getSearchData = debounce((value: string) => { + setSearchField(e => ({ ...e, purchaser_and_sale_user: value })) + }, 300) + + const FilterOptions = [ + { + key: 0, + label: '全部记录', + }, + { + key: 5, + label: '申请中', + }, + { + key: 6, + label: '已完成', + }, + ] + + const handleClickFilter = (value) => { + if (searchField.mp_cut_sample_audit_status === value) { return } + setSearchField(e => ({ ...e, mp_cut_sample_audit_status: value })) + } + + useEffect(() => { + getData() + }, [searchField]) + + const { fetchData: cancelOrderApi } = CancelCutSampleOrder() + + const cancelOrder = async(id: number) => { + const res = await cancelOrderApi({ id }) + if (res.success) { + getData() + } + } + + // 取消订单 + const handleCancel = (e: ITouchEvent, id: number) => { + e.stopPropagation() + Taro.showModal({ + content: '确定取消该订单?', + confirmColor: '#337fff', + confirmText: '确认', + success: (res) => { + if (res.confirm) { + cancelOrder(id) + console.log('用户点击确定') + } + }, + }) + } + + // 监听选择的类型 + // useEffect(() => { + // setSearchObj(search) + // if (search.goodsId) { getGoodList() } + // }, [search]) + + return + + + + + + } + statusMore={statusMore} + selfonScrollToLower={getScrollToLower} + refresherEnabled + refresherTriggered={refresherTriggeredStatus} + selfOnRefresherRefresh={getRefresherRefresh} + safeAreaInsetBottom={false} + > + {sampleCuttingList?.list?.map((item, index) => { + return ( + + handleCancel(e, item.order_id)}> + + ) + })} + + + + + 领取剪样 + + + +} + +export default GetSampleCutting diff --git a/src/pages/sampleCutting/sampleCuttingDetail/index.config.ts b/src/pages/sampleCutting/sampleCuttingDetail/index.config.ts new file mode 100644 index 0000000..720e41a --- /dev/null +++ b/src/pages/sampleCutting/sampleCuttingDetail/index.config.ts @@ -0,0 +1,3 @@ +export default { + navigationBarTitleText: '剪样订单详情', +} diff --git a/src/pages/sampleCutting/sampleCuttingDetail/index.module.scss b/src/pages/sampleCutting/sampleCuttingDetail/index.module.scss new file mode 100644 index 0000000..d245899 --- /dev/null +++ b/src/pages/sampleCutting/sampleCuttingDetail/index.module.scss @@ -0,0 +1,203 @@ +page { + background: #f7f7f7; + height: 100%; + display: flex; + flex-flow: column nowrap; +} +.main { + background-color: $color_bg_one; + height: 100%; + display: flex; + flex-flow: column nowrap; + overflow: hidden; + .context { + flex: 1 1 auto; + height: 100%; + overflow-y: scroll; + } + .orderProcess { + font-size: 28px; + } + .orderInfoTop { + font-size: 28px; + color: $color_font_one; + } + .customerTop { + color: #333333; + font-size: 28px; + } + .customerBottom { + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + color: #343434; + font-size: 28px; + } + + .colorCardTop { + font-size: 28px; + } + .colorCardBottom { + width: 100%; + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + overflow: hidden; + margin-bottom: 24px; + .leftCont { + width: 134px; + height: 134px; + border-radius: 8px; + margin-right: 24px; + } + .rightCont { + flex: 1 1 auto; + overflow: hidden; + display: flex; + flex-flow: column nowrap; + justify-content: space-between; + &__top { + font-size: 28px; + @include common_ellipsis(1); + } + &__bottom { + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + width: 100%; + } + &__container { + display: flex; + flex-flow: row nowrap; + } + &__left { + flex: 1 1 auto; + overflow: hidden; + display: flex; + flex-flow: column nowrap; + } + &__right { + font-size: 28px; + } + } + } + .paymentMethod { + text-align: right; + font-size: 28px; + color: #f64861; + } +} +.address_box { + display: flex; + .address_box_left { + margin-right: 24px; + .cirle { + border-radius: 50%; + width: 64px; + height: 64px; + background: #4a7fff; + display: flex; + align-items: center; + justify-content: center; + } + } + .address_box_right { + flex: 1 1 auto; + .address { + height: 78px; + font-size: 28px; + font-weight: 500; + @include common_ellipsis(2); + color: #000000; + margin-right: 41px; + display: flex; + align-items: center; + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-line-clamp: 2; /*这里设置几行*/ + overflow: hidden; + } + .bottom { + display: flex; + align-items: center; + justify-content: space-between; + .reatName { + font-size: 28px; + font-weight: 500; + color: #337fff; + margin-right: 32px; + } + .leftbottom { + display: flex; + align-items: center; + .name { + line-height: 34px; + width: 84px; + height: 34px; + @include common_ellipsis(); + font-size: 28px; + font-weight: 400; + color: #343434; + margin-right: 16px; + } + + .phone { + height: 34px; + font-size: 28px; + font-weight: 400; + color: #343434; + } + } + } + } +} + +.bottomBar { + position: relative; + z-index: 99; + box-shadow: 0 -4px 6px -1px rgb(0 0 0 / 0.1), 0 -2px 4px -2px rgb(0 0 0 / 0.1); + flex: none; + display: flex; + flex-flow: row nowrap; + justify-content: flex-end; + align-items: center; + padding-left: 20px; + padding-right: 20px; + padding-top: 24px; + background-color: white; + padding-bottom: calc(20px + constant(safe-area-inset-bottom)); + padding-bottom: calc(20px + env(safe-area-inset-bottom)); +} +.bottomBar__button { + font-size: 28px; +} +.remark { + font-size: 28px; + color: #9b9b9b; +} + +.step-title { + display: flex; + flex-flow: row nowrap; + font-size: 28px; + align-items: center; +} +.step-status { + font-weight: 550; + color: #393939; + margin-right: 40px; +} +.attachment{ + display: flex; + flex-flow: row nowrap; + .step-url-container { + margin-right: 16px; + width: 128px; + height: 128px; + } + .step-url { + width: 100%; + height: 100%; + border-radius: 8px; + } +} diff --git a/src/pages/sampleCutting/sampleCuttingDetail/index.tsx b/src/pages/sampleCutting/sampleCuttingDetail/index.tsx new file mode 100644 index 0000000..2e516c6 --- /dev/null +++ b/src/pages/sampleCutting/sampleCuttingDetail/index.tsx @@ -0,0 +1,233 @@ +import { Image, Text, View } from '@tarojs/components' +import Taro, { useRouter } from '@tarojs/taro' +import { useCallback, useEffect, useState } from 'react' +import styles from './index.module.scss' +import LayoutBlock from '@/components/layoutBlock' +import Divider from '@/components/divider' +import LabAndImg from '@/components/LabAndImg' +import Tag from '@/components/tag' +import Cell from '@/components/cell' +import { formatDateTime, formatHashTag, formatRemoveHashTag, formatUrl } from '@/common/format' +import NormalButton from '@/components/normalButton' +import Steps from '@/components/steps' +import Step from '@/components/steps/components/step' +import { alert } from '@/common/common' +import IconFont from '@/components/iconfont/iconfont' +import { CancelCutSampleOrder, GetCutSampleOrderDetail } from '@/api/sampleCutting' + +const SampleCuttingDetail = () => { + const { fetchData } = GetCutSampleOrderDetail() + + const router = useRouter() + + const getData = async() => { + console.log('id', router.params.id) + const res = await fetchData({ id: Number(router.params.id) }) + if (!res.success) { + return alert.error(res.msg) + } + setOrder(res.data) + } + + const [order, setOrder] = useState({}) + + const labAndImgObj = useCallback((item) => { + return { lab: item?.lab, rgb: item?.rgb, texture_url: item?.texture_url } + }, []) + // 复制 + const handleCopy = (data: string) => { + Taro.setClipboardData({ + data, + success() { + Taro.showToast({ + title: '复制成功', + }) + }, + }) + } + + const { fetchData: cancelOrderApi } = CancelCutSampleOrder() + + const cancelOrder = async(id: number) => { + const res = await cancelOrderApi({ id }) + if (res.success) { + getData() + alert.success('取消成功') + } + else { + alert.error(res.msg) + } + } + + // 取消订单 + const handleCancel = () => { + Taro.showModal({ + content: '确定取消该订单?', + confirmColor: '#337fff', + confirmText: '确认', + success: (res) => { + if (res.confirm) { + cancelOrder(Number(router.params.id)) + console.log('用户点击确定') + } + }, + }) + } + + useEffect(() => { + getData() + }, []) + + return + + + 订单进程 + + + + {/* + 申请中5 -> 已完成 6 + 申请中5 -> 已取消 3 + 申请中5 -> 已拒绝 4 + */} + { + order.order_form?.map((item, index) => { + return + {item.order_status_name} + {formatDateTime(item.order_time)} + + } description={ + <> + { + item.audit_remark && {item.audit_remark} + } + { + item.delivery_appendix_url + && + { + item.delivery_appendix_url?.map((url, index) => { + return + + + }) + } + + } + + } + /> + }) + } + + + + + + 客户信息 + + + {order?.purchaser_name} + {order?.phone} + {/* 占位作用勿删除 */} + + + + + + + + + + + + + {order?.province_name}{order?.city_name}{order?.district_name}{order?.address_detail} + + + + {order.target_user_name} + {order.target_user_phone} + + {order.shipment_mode_name} + + + + + { + order.cut_sample_order_product_list?.map((item, index) => { + return + {formatHashTag(item.code, item.name)} + + { + item.product_colors?.map((mul) => { + return ( + + + + + + + + + + + {`#${formatRemoveHashTag(mul.code)} ${mul.name}`} + + + {/* { + item.affiliation_product?.map((product_color, index) => { + return {formatRemoveHashTag(product_color)} + }) + } */} + + + + x{mul.color_num}份 + + + + + + ) + }) + } + 快递到付 + + }) + } + + + 订单信息 + + + + {order?.order_no} + handleCopy(order?.order_no)}>复制 + + } + > + + + + + + 备注信息 + + {order?.order_remark || '暂无备注信息'} + + + + { + order.order_form?.[0].order_status === 5 + ? + 取消订单 + + : null + } + + + +} +export default SampleCuttingDetail diff --git a/src/pages/sampleCutting/sampleCuttingList/index.config.ts b/src/pages/sampleCutting/sampleCuttingList/index.config.ts new file mode 100644 index 0000000..2b97086 --- /dev/null +++ b/src/pages/sampleCutting/sampleCuttingList/index.config.ts @@ -0,0 +1,3 @@ +export default { + navigationBarTitleText: '添加剪样', +} diff --git a/src/pages/sampleCutting/sampleCuttingList/index.module.scss b/src/pages/sampleCutting/sampleCuttingList/index.module.scss new file mode 100644 index 0000000..49204f2 --- /dev/null +++ b/src/pages/sampleCutting/sampleCuttingList/index.module.scss @@ -0,0 +1,186 @@ +page { + background: #f7f7f7; + height: 100%; + display: flex; + flex-flow: column nowrap; +} +.main { + background-color: $color_bg_one; + height: 100%; + display: flex; + flex-flow: column nowrap; + overflow: hidden; +} +.search { + width: 100%; + display: flex; + justify-content: space-between; + padding: 20px; + box-sizing: border-box; + align-items: center; + background-color: #fff; + border-bottom: 1px solid #e5e5e5; + &__cancel { + margin: 0 32px; + color: #727272; + font-size: 28px; + } +} + +.context { + flex: 1 1 auto; + height: 100%; + overflow: hidden; + background-color: white; +} + +.bottomBar { + position: relative; + z-index: 99; + box-shadow: 0 -4px 6px -1px rgb(0 0 0 / 0.1), 0 -2px 4px -2px rgb(0 0 0 / 0.1); + flex: none; + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + align-items: center; + padding-left: 20px; + padding-right: 20px; + padding-top: 24px; + background-color: white; + padding-bottom: calc(20px + constant(safe-area-inset-bottom)); + padding-bottom: calc(20px + env(safe-area-inset-bottom)); +} +.bottomBar__button { + width: 100%; + font-size: 28px; +} + +.colorCard { + padding: 24px 0; + border-bottom: 1px solid #f6f6f6; + display: flex; + flex-flow: row nowrap; + justify-content: space-between; + &__image { + width: 144px; + height: 144px; + border-radius: 8px; + margin-right: 24px; + overflow: hidden; + position: relative; + } + &__title { + font-size: 28px; + color: #383838; + } + &__code { + font-size: 24px; + color: #b3b3b3; + } + &__content { + flex: 1 1 auto; + display: flex; + flex-flow: column nowrap; + } + .addButton { + width: 30%; + display: flex; + justify-content: flex-end; + align-items: center; + } +} +.imageTag { + width: 50%; + background-color: #000; + box-sizing: border-box; + position: absolute; + padding: 7px; + bottom: 0px; + right: 0px; + opacity: 0.55; + color: #ffffff; + text-align: center; + font-size: 22px; + z-index: 1; + border-top-left-radius: 16px; + transform: perspective(1em) scale(1, 1.1) rotateX(5deg); + /* 镜头距离元素表面的位置为8px,x轴为1.1倍y轴为1.3倍,绕x轴旋转-5度 */ + transform-origin: bottom right; +} + +.collection_con { + display: flex; + flex-flow: column nowrap; + max-height: 75vh; + + .header { + padding: 32px 48px; + .title { + font-size: 32px; + @include common_ellipsis; + color: #3d3d3d; + font-weight: 500; + } + .sub_title { + font-size: 28px; + color: #b6b6b6; + margin-top: 8px; + } + } + .productList { + flex: 1 1 auto; + overflow-y: scroll; + margin-top: 30px; + padding: 0 48px; + display: grid; + grid-template-columns: 25% 25% 25% 25%; + justify-content: space-between; + .item { + width: 100%; + margin-bottom: 28px; + display: flex; + flex-direction: column; + align-items: center; + box-sizing: border-box; + .item_color { + box-sizing: border-box; + width: 136px; + height: 136px; + border-radius: 50%; + } + .item_name { + text-align: center; + margin-top: 10px; + font-size: 24px; + color: #666666; + + @include common_ellipsis; + } + } + } +} +.popup_bottom { + padding: 12px; + padding-bottom: 0; +} +.productColorActive { + border: 4px solid $color_main; + position: relative; + .activeIcon { + display: flex; + flex-flow: row nowrap; + justify-content: center; + align-items: center; + border: 4px solid white; + background-color: $color_main; + position: absolute; + top: -2px; + right: -2px; + box-sizing: border-box; + width: 32px; + height: 32px; + border: 2px solid $color_main; + border-radius: 50%; + z-index: 99; + } +} diff --git a/src/pages/sampleCutting/sampleCuttingList/index.tsx b/src/pages/sampleCutting/sampleCuttingList/index.tsx new file mode 100644 index 0000000..7af9b3b --- /dev/null +++ b/src/pages/sampleCutting/sampleCuttingList/index.tsx @@ -0,0 +1,355 @@ +import { ScrollView, Text, View } from '@tarojs/components' +import Taro, { useDidShow, useRouter, useUnload } from '@tarojs/taro' +import { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import classNames from 'classnames' +import styles from './index.module.scss' +import Search from '@/components/search' +import NormalButton from '@/components/normalButton' +import LabAndImg from '@/components/LabAndImg2' +import Tag from '@/components/tag' +import MCheckbox from '@/components/checkbox' +import InfiniteScroll from '@/components/infiniteScroll' +import { dataLoadingStatus, debounce, getFilterData } from '@/common/util' +import { alert, goLink } from '@/common/common' +import { formatHashTag, formatRemoveHashTag } from '@/common/format' +import Popup from '@/components/popup' +import IconFont from '@/components/iconfont/iconfont' +import { GetCutSampleOrderColorList, GetCutSampleOrderProducts } from '@/api/sampleCutting' + +export interface SampleCuttingCache { + product_id: number + product_code_and_name: string + multipleSelection: { + product_color_id: number + product_color_code: string + product_color_name: string + lab: { + l: number + a: number + b: number + } + rgb: { + r: number + g: number + b: number + } + texture_url: string + count: number + }[] +} +const SampleCuttingList = () => { + const router = useRouter() + const isAdd = router?.params?.isAddSampleCutIdList + + const { fetchData, state } = GetCutSampleOrderProducts() + + const [orderList, setOrderList] = useState<{ list: any[]; total: number }>({ + list: [], + total: 0, + }) + const multipleSelection = useRef([]) + // 搜索 + const getSearchData = debounce((value: string) => { + console.log('search', value) + setSearchField(val => ({ ...val, product_code_and_name: value })) + }, 300) + // 取消 + const handleCancel = () => { + Taro.navigateBack() + } + + // redirectTo 会触发 onLoad 事件 + let isRedirect = false + // 确认 + const handleSubmit = () => { + Taro.setStorageSync('sampleCuttingCache', JSON.stringify(multipleSelection.current)) + if (router?.params.isGoBack) { + isRedirect = true + Taro.navigateBack({ + delta: 1, + }) + } + else { + isRedirect = true + // 携带id跳转 + goLink('/pages/sampleCutting/addSampleCutting/index', null, 'redirectTo') + } + } + + const labAndImgObj = useCallback((item) => { + return { lab: item?.lab, rgb: item?.rgb, texture_url: item?.texture_url } + }, []) + // 页码和页数 + const [searchField, setSearchField] = useState<{ product_code_and_name?: string; product_ids?: string; page: number; size: number }>({ + product_code_and_name: '', + product_ids: '', + page: 1, + size: 10, + }) + + const getData = async() => { + console.log('searchField==>', searchField) + const res = await fetchData(getFilterData(searchField)) + if (!res.success) { + return alert.error(res.msg) + } + setOrderList({ list: res.data.list, total: res.data.total }) + } + + useEffect(() => { + getData() + }, [searchField]) + + useDidShow(() => { + const cache = Taro.getStorageSync('sampleCuttingCache') + if (cache) { + multipleSelection.current = JSON.parse(cache) as SampleCuttingCache[] + } + + if (isAdd) { + console.log('isAdd', isAdd) + // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain + setSearchField(val => ({ ...val, product_ids: isAdd })) + } + }) + + // 上拉加载数据 + const pageNum = useRef({ size: searchField.size, page: searchField.page }) + // 列表下拉刷新 + const [refresherTriggeredStatus, setRefresherTriggeredStatus] = useState(false) + // 下拉刷新 + const getRefresherRefresh = async() => { + pageNum.current.size = 1 + setRefresherTriggeredStatus(true) + setSearchField(val => ({ ...val, size: 10 })) + } + // 数据加载状态 + const statusMore = useMemo(() => { + return dataLoadingStatus({ list: orderList.list, total: orderList.total, status: state.loading! }) + }, [orderList, state.loading]) + + const getScrollToLower = useCallback(() => { + if (orderList.list.length < orderList.total) { + pageNum.current.page++ + const size = pageNum.current.size * pageNum.current.page + setSearchField({ ...searchField, size }) + } + }, [orderList]) + + const { fetchData: getColorList } = GetCutSampleOrderColorList() + const currentSelect = useRef({}) + const handleClickAddButton = async(item: any) => { + currentSelect.current = item + const res = await getColorList({ id: item.id }) + if (res.success) { + setProductList(res.data.list) + const index = multipleSelection.current.findIndex(val => val.product_id === item.id) + if (index !== -1) { + setProductMultipleSelection(multipleSelection.current[index].multipleSelection) + } + else { + setProductMultipleSelection([]) + } + setShow(true) + } + else { + return alert.error(res.msg) + } + } + + useUnload(() => { + console.log('onUnload', isRedirect) + if (!isRedirect) { + Taro.removeStorageSync('sampleCuttingCache') + } + }) + + const [show, setShow] = useState(false) + + const onClose = () => { + setShow(false) + setProductMultipleSelection([]) + } + + const [productList, setProductList] = useState([]) + // 点击产品颜色 + const handleClickProductColor = (item: any) => { + const index = productMultipleSelection.findIndex(val => val.product_color_id === item.product_color_id) + console.log(index, productMultipleSelection) + if (index !== -1) { + setProductMultipleSelection((prev) => { + prev.splice(index, 1) + return [...prev] + }) + } + else { + setProductMultipleSelection(prev => [...prev, { + product_color_id: item.product_color_id, + product_color_code: item.product_color_code, + product_color_name: item.product_color_name, + lab: item.lab, + rgb: item.rgb, + texture_url: item.texture_url, + count: 1, + }]) + } + } + + const handleClose = () => { + onClose() + } + const handleAddProduct = () => { + const index = multipleSelection.current.findIndex(mul => mul.product_id === currentSelect.current.id) + if (index !== -1) { + multipleSelection.current[index].multipleSelection = productMultipleSelection + } + else { + multipleSelection.current.push({ + product_id: currentSelect.current.id, + product_code_and_name: formatHashTag(currentSelect.current.code, currentSelect.current.name) as string, + multipleSelection: productMultipleSelection, + }) + } + onClose() + } + const [productMultipleSelection, setProductMultipleSelection] = useState([]) + + return + + + 取消 + + + + + { + orderList.list.map((item) => { + return + + + + + { + item.is_multiple_product ? 24色 : null + } + + + + {formatHashTag(item.code, item.name)} + + {item.width} + {item.weight_density} + + + {item.component} + + + + handleClickAddButton(item)} + > + { + isAdd?.includes(item.id) || multipleSelection.current.some(mul => mul.product_id === item.id) ? '继续添加' : '添加' + } + + {/* onSelect(item)} + onClose={() => onUnSelect(item)} + /> */} + + + + }) + } + + + + + + { + multipleSelection.current.length ? `确认(已选 ${multipleSelection.current.length} 个)` : '确认' + } + + + + + + + {formatHashTag(currentSelect.current.code, currentSelect.current.name)}( {productList.length} ) + + 剪样大小为A4,大约22cm*30cm + + + + { + productList.map((item, index) => { + const isChecked = productMultipleSelection.some(mul => mul.product_color_id === item.product_color_id) + return handleClickProductColor(item)}> + + { + isChecked + ? + + + : null + } + + + {item.product_color_name} + + }) + } + + + + + + 取消 + + + 领取剪样({productMultipleSelection.length}) + + + + + +} +export default SampleCuttingList diff --git a/src/pages/user/index.tsx b/src/pages/user/index.tsx index 42484b1..47946b3 100644 --- a/src/pages/user/index.tsx +++ b/src/pages/user/index.tsx @@ -85,6 +85,12 @@ const feature: IconCardType[] = [ path: '/pages/getColorCard/index', jurisdiction: 'receive_color_card_page', }, + { + iconName: 'icon-lingquseka', + name: '领取剪样', + path: '/pages/sampleCutting/index', + jurisdiction: 'receive_color_card_page', + }, ] const fabric: IconCardType[] = [