feat:初始化

This commit is contained in:
Haiyi 2022-08-19 11:01:36 +08:00
parent 76dca1ef45
commit 74144ad820
242 changed files with 26 additions and 19317 deletions

View File

@ -5,11 +5,11 @@ const versions =
encoding: 'utf8', encoding: 'utf8',
}) != 'HEAD\n' }) != 'HEAD\n'
? childProcess.execSync('git rev-parse --abbrev-ref HEAD', { ? childProcess.execSync('git rev-parse --abbrev-ref HEAD', {
encoding: 'utf8', encoding: 'utf8',
}) })
: childProcess.execSync('git describe --tags --abbrev=0', { : childProcess.execSync('git describe --tags --abbrev=0', {
encoding: 'utf8', encoding: 'utf8',
}) })
const CURRENT_GITHASH = childProcess.execSync('git rev-parse --short HEAD', { const CURRENT_GITHASH = childProcess.execSync('git rev-parse --short HEAD', {
encoding: 'utf8', encoding: 'utf8',
}) })
@ -18,19 +18,6 @@ const CURRENT_VERSION = `Version: ${JSON.stringify(process.env.CODE_BRANCH || ve
'', '',
) )
const CIPluginOpt = {
// 微信小程序
weapp: {
appid: 'wx64fe67f111d52457',
privateKeyPath: 'key/private.wx64fe67f111d52457.key',
// devToolsInstallPath: 'D:/weixin/微信web开发者工具',
},
// 版本号
version: versions,
// 版本发布描述
desc: versions,
}
const config = { const config = {
projectName: 'EShop', projectName: 'EShop',
date: '2022-4-6', date: '2022-4-6',
@ -42,7 +29,6 @@ const config = {
}, },
sourceRoot: 'src', sourceRoot: 'src',
outputRoot: 'dist', outputRoot: 'dist',
plugins: [['@tarojs/plugin-mini-ci', CIPluginOpt]],
defineConstants: { defineConstants: {
CURRENT_VERSION: JSON.stringify(CURRENT_VERSION), CURRENT_VERSION: JSON.stringify(CURRENT_VERSION),
CURRENT_GITHASH: JSON.stringify(CURRENT_GITHASH), CURRENT_GITHASH: JSON.stringify(CURRENT_GITHASH),

View File

@ -28,10 +28,7 @@
"dev:jd": "npm run build:jd -- --watch", "dev:jd": "npm run build:jd -- --watch",
"dev:quickapp": "npm run build:quickapp -- --watch", "dev:quickapp": "npm run build:quickapp -- --watch",
"build:weapp:pre": "cross-env NODE_ENV=pre taro build --type weapp", "build:weapp:pre": "cross-env NODE_ENV=pre taro build --type weapp",
"dev:weapp:pre": "cross-env NODE_ENV=pre npm run build:weapp -- --watch", "dev:weapp:pre": "cross-env NODE_ENV=pre npm run build:weapp -- --watch"
"buildo:weapp:open": "taro build --type weapp --open",
"build:weapp:upload": "taro build --type weapp --upload",
"build:weapp:preview": "taro build --type weapp --preview"
}, },
"browserslist": [ "browserslist": [
"last 3 versions", "last 3 versions",

View File

@ -1,8 +1,8 @@
{ {
"miniprogramRoot": "dist/", "miniprogramRoot": "dist/",
"projectname": "EShop", "projectname": "Mall-lymarket",
"description": "项目配置文件详见文档https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html", "description": "项目配置文件详见文档https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"appid": "wx68d92d7cbf0b6963", "appid": "wxa41b2eda1c6b557a",
"setting": { "setting": {
"urlCheck": true, "urlCheck": true,
"es6": false, "es6": false,

View File

@ -1,6 +1,7 @@
export default { export default {
pages: [ pages: [
'pages/index/index', 'pages/index/index',
'pages/order/index',
'pages/user/index', 'pages/user/index',
], ],
window: { window: {
@ -15,14 +16,20 @@ export default {
{ {
pagePath: 'pages/index/index', pagePath: 'pages/index/index',
text: '首页', text: '首页',
iconPath: './styles/tabbar/home.png', iconPath: './styles/tabbar/list.png',
selectedIconPath: './styles/tabbar/home_selected.png', selectedIconPath: './styles/tabbar/list_on.png',
},
{
pagePath: 'pages/order/index',
text: '订单',
iconPath: './styles/tabbar/order.png',
selectedIconPath: './styles/tabbar/order_on.png',
}, },
{ {
pagePath: 'pages/user/index', pagePath: 'pages/user/index',
text: '我的', text: '我的',
iconPath: './styles/tabbar/my.png', iconPath: './styles/tabbar/my.png',
selectedIconPath: './styles/tabbar/my_selected.png', selectedIconPath: './styles/tabbar/my_on.png',
} }
], ],
'color': '#707070', 'color': '#707070',
@ -31,156 +38,7 @@ export default {
'borderStyle': 'white' 'borderStyle': 'white'
}, },
subPackages: [ subPackages: [
{
root: "pages/search",
pages: [
"index"
]
},
{
root: "pages/classList",
pages: [
"index"
]
},
{
root: "pages/details",
pages: [
"index",
]
},
{
root: "pages/searchList",
pages: [
"searchList",
"hightSearchList",
"search"
]
},
{
root: "pages/userEdit",
pages: [
"index"
]
},
{
root: "pages/addressManager",
pages: [
"index"
]
},
{
root: "pages/addressAdd",
pages: [
"index"
]
},
{
root: "pages/company",
pages: [
"index"
]
},
{
root: "pages/weightList",
pages: [
"index"
]
},
{
root: "pages/weightListAdd",
pages: [
"index"
]
},
{
root: "pages/order",
pages: [
"index",
"comfirm",
"orderList/index"
]
},
{
root: "pages/editOrder",
pages: [
"index",
]
},
{
root: "pages/subjectList",
pages: [
"index",
]
},
{
root: "pages/creditLine",
pages: [
"index"
]
},
{
root: "pages/creditUsed",
pages: [
"index"
]
},
{
root: "pages/depositBeforehandDetail",
pages: [
"index"
]
},
{
root: "pages/depositBeforehand",
pages: [
"index"
]
},
{
root: "pages/depositList",
pages: [
"index"
]
},
{
root: "pages/salesAfter",
pages: [
"index",
"salesAfterList/index"
]
},
{
root: "pages/certification",
pages: [
"index",
]
},
{
root: "pages/applyAfterSales",
pages: [
"index",
]
},
{
root: "pages/collection",
pages: [
"index",
"collectionClass/index"
]
},
{
root: "pages/sampleComparison",
pages: [
"index",
]
},
{
root: "pages/bindSalesman",
pages: [
"index",
]
},
] ]
} }

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '',
enableShareAppMessage: true,
}

View File

@ -1,47 +0,0 @@
.add-address{
display: flex;
flex-direction: column;
.add-address-default{
display: flex;align-items: center;justify-content: space-between;
margin: 70px 30px 0;
font-size: 26px;
font-weight: 700;
color: #000000;
}
.add-address-default-active{
width: 50px;
height: 50px;
background: #007aff;
border-radius: 50%;
display: flex;align-items: center;
justify-content: center;
font-size: 45px;
color: white;
box-sizing: border-box;
}
.add-address-default-active text{
font-size: 35px;
}
.add-address-default-noactive{
width: 50px;
height: 50px;
border: 2px solid #707070;
border-radius: 50%;
box-sizing: border-box;
display: flex;align-items: center;justify-content: center;
}
.add-address-save{
width: 668px;
height: 82px;
background: #68b4ff;
border-radius: 40px;
font-size: 32px;
font-weight: 400;
color: #ffffff;
display: flex;align-items: center;justify-content: center;
// margin: 620px auto 0;
position: fixed;left: 50%;bottom: 50px;
transform: translateX(-50%);
}
}

View File

@ -1,144 +0,0 @@
import { alert, retrieval } from "@/common/common"
import Address from "@/components/address"
import FromList from "@/components/FromList"
import { Button, Input, Text, Textarea, View } from "@tarojs/components"
import Taro, { setNavigationBarTitle, useRouter } from "@tarojs/taro"
import { useEffect, useState } from "react"
import "./index.scss"
import {addressAddApi, addressDetailApi,addressEditApi} from "@/api/addressManager"
import useLogin from "@/use/useLogin"
export default ()=>{
useLogin()
const [showSiteModal, setShowSiteModal] = useState(false);
const {type,id} = useRouter().params;
useEffect(()=>{
if(type=="add"){
setNavigationBarTitle({title:"新增收货地址"})
}else{
initalFormData();
setNavigationBarTitle({title:"编辑收货地址"})
}
},[])
// 获取编辑地址信息
const {fetchData: getFromData} = addressDetailApi()
const initalFormData = async ()=>{
const detail = await getFromData({id});
const { province_id,province_name,city_id,city_name,district_id,district_name } = detail.data;
const siteArray = [{id: province_id, name: province_name}];
city_id&&siteArray.push({id: city_id, name: city_name});
district_id&&siteArray.push({id: district_id, name: district_name});
setFormData({
name: detail.data.name,
phone: detail.data.phone,
site: siteArray.map(item=>item.name).join(" "),
siteArray: siteArray as any,
district_id: detail.data.district_id,
address_detail: detail.data.address_detail,
is_default: detail.data.is_default,
id: detail.data.id,
})
}
const {fetchData} = addressAddApi()
const {fetchData: editFetch} = addressEditApi()
// 保存
const [formData, setFormData] = useState({
name: "",
phone:"",
site:"",
siteArray: [],
district_id:"",
address_detail: "",
is_default: false,
id: 0
})
const rules = {
name: [{
message: "请输入正确收货人姓名",
// validator: (value:any, rule:any)=>{ // 自定义验证返回true表示匹配到了(错误)
// return value.length>5;
// }
}],
phone: [{
message: "请输入正确的电话号码", regex: /^1[3|5|6|9|2|8|7]\d{9}$/
}],
district_id: [{
message: "请选择地址"
}],
address_detail: [{
message: "请输入详细地址"
}],
}
const handleSave = ()=>{
retrieval(formData, rules).then(async ()=>{
const result = type=="add"?await fetchData({
name: formData.name,
phone:formData.phone,
district_id:formData.district_id,
address_detail: formData.address_detail,
is_default: formData.is_default
}):await editFetch({
name: formData.name,
phone:formData.phone,
district_id:formData.district_id,
address_detail: formData.address_detail,
is_default: formData.is_default,
id: formData.id
});
if(result.success){
Taro.eventCenter.trigger("addressList:refresh");
Taro.navigateBack();
alert.success("保存成功");
}else{
alert.error(result.msg);
}
}).catch((message)=>{
alert.none(message)
})
}
// 监听表单完善
const [hozon, setHozon] = useState(false);
useEffect(()=>{
if(retrieval){
retrieval(formData).then(()=>setHozon(true)).catch(()=>setHozon(false))
}
},[formData])
// 设置选择地址
const handleSetSite = (ev:any)=>{
if(ev.length > 0){
setFormData({
...formData,
siteArray: ev,
site: ev.map(item=>item.name+" "),
district_id: ev[ev.length-1]?.id
})
}else{
alert.error("请选择地址");
}
}
return (
<View className="add-address">
<FromList onInput={(ev:any)=>setFormData({...formData,name:ev.detail.value})} value={formData["name"]} label="联系人" placeholder="请输入收货人姓名"/>
<FromList primordialType="number" onInput={(ev:any)=>setFormData({...formData,phone:ev.detail.value})} value={formData["phone"]} label="联系方式" placeholder="请输入联系方式"/>
<FromList value={formData["site"]} onClick={()=>setShowSiteModal(true)} label="收货地址" type="select" placeholder="请选择/省/市/区"/>
<FromList onInput={(ev:any)=>setFormData({...formData,address_detail:ev.detail.value})} value={formData["address_detail"]} label="详细地址" type="textarea" placeholder="请输入详细地址(街道、门牌号等)"/>
<View className="add-address-default">
<Text></Text>
<View onClick={()=>setFormData({...formData ,is_default: !formData.is_default})}>
{
formData.is_default?<View className="add-address-default-active"><Text className="iconfont icon-tick"/></View>
:<View className="add-address-default-noactive"></View>
}
</View>
</View>
<Button style={{"background": hozon?'#007aff':''}} hoverClass="none" className={`add-address-save`} onClick={handleSave}>
</Button>
<Address addressOnChange={handleSetSite} defaultValue={formData.siteArray} addressOnClose={()=>setShowSiteModal(false)} show={showSiteModal}/>
</View>
)
}

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '地址管理',
enableShareAppMessage: true,
}

View File

@ -1,3 +0,0 @@
.address-manager{
height: 100vh;
}

View File

@ -1,16 +0,0 @@
import AddressList from "@/components/AddressList"
import useLogin from "@/use/useLogin"
import { Button, ScrollView, Text, View } from "@tarojs/components"
import { stopPullDownRefresh, usePullDownRefresh } from "@tarojs/taro"
import { useState } from "react"
import "./index.scss"
export default ()=>{
useLogin()
return (
<View className="address-manager">
<AddressList refresherEnabled={true}/>
</View>
)
}

View File

@ -1,64 +0,0 @@
.apply_after_sales_list{
padding: 0 20px;
.apply_after_sales_item{
margin-bottom: 50px;
.apply_after_sales_title{
display: flex;
align-items: center;
.tag{
font-size: $font_size_min;
background-color: #CDE5FF;
padding: 5px 10px;
border-radius: 6px;
color: $color_main;
}
.title{
font-weight: 700;
font-size: $font_size;
margin-left: 20px;
flex:1;
}
}
.color_list {
.color_item{
display: flex;
align-items: center;
margin: 30px 0;
}
.image{
width: 70px;
height: 70px;
image{
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.name_and_number{
padding-left: 30px;
flex:1;
text{
&:nth-child(1) {
font-weight: 700;
font-size: $font_size;
}
&:nth-child(2) {
color: $color_font_two;
font-size: $font_size;
margin-left: 20px;
}
}
}
.btn_count{
width: 216px;
height: 64px;
background-color: #ECF5FF;
border-radius: 40px 0px 16px 0px;
padding: 0 20px;
display: flex;
align-items: center;
}
}
}
}

View File

@ -1,56 +0,0 @@
import { formatHashTag, formatImgUrl } from "@/common/fotmat";
import Counter from "@/components/counter";
import MCheckbox from "@/components/checkbox";
import { Image, Text, View } from "@tarojs/components";
import { FC, memo, useCallback } from "react";
import styles from './index.module.scss'
type OrderParam = {
list?: any[],
sale_mode?: number,
sale_mode_name?: string,
unit?: string,
total_colors?: number,
total_fabrics?: number,
total_number?: number,
status?: number, //订单状态
av_return_product?: any[] //申请售后列表
}
type Param = {
order: OrderParam,
onSelectChange?: (val: {color_id:number, length: number, status: true|false, sale_order_detail_id:number}) => void
}
const kindeList:FC<Param> = memo(({order, onSelectChange}) => {
//checkbox选中回调
const selectCallBack = (colorItem) => {
onSelectChange?.({color_id:colorItem.product_color_id, length:colorItem.length, sale_order_detail_id:colorItem.sale_order_detail_id, status: true})
}
//checkbox关闭回调
const colseCallBack = (colorItem) => {
onSelectChange?.({color_id:colorItem.product_color_id, length:colorItem.length, status: false, sale_order_detail_id:colorItem.sale_order_detail_id,})
}
return (
<View className={styles.apply_after_sales_list}>
{order?.av_return_product?.map(item => <View className={styles.apply_after_sales_item} >
<View className={styles.apply_after_sales_title}>
<View className={styles.tag}>{order.sale_mode_name}</View>
<View className={styles.title}>{formatHashTag(item.product_code, item.product_name)}</View>
</View>
<View className={styles.color_list}>
{item?.av_product_color?.map(colorItem => <View className={styles.color_item}>
<View className={styles.image}><Image src={formatImgUrl('')}/></View>
<View className={styles.name_and_number}><Text>{colorItem.product_color_code + ' ' + colorItem.product_color_name}</Text><Text>x {colorItem.length/100} m</Text></View>
<MCheckbox status={item.select} onSelect={() => selectCallBack(colorItem)} onClose={() => colseCallBack(colorItem)}/>
</View>)}
</View>
</View>)}
</View>
)
})
export default kindeList

View File

@ -1,64 +0,0 @@
.apply_after_sales_list{
padding: 0 20px;
.apply_after_sales_item{
margin-bottom: 50px;
.apply_after_sales_title{
display: flex;
align-items: center;
.tag{
font-size: $font_size_min;
background-color: #CDE5FF;
padding: 5px 10px;
border-radius: 6px;
color: $color_main;
}
.title{
font-weight: 700;
font-size: $font_size;
margin-left: 20px;
flex:1;
}
}
.color_list {
.color_item{
display: flex;
align-items: center;
margin: 30px 0;
}
.image{
width: 70px;
height: 70px;
image{
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.name_and_number{
padding-left: 30px;
flex:1;
text{
&:nth-child(1) {
font-weight: 700;
font-size: $font_size;
}
&:nth-child(2) {
color: $color_font_two;
font-size: $font_size;
margin-left: 20px;
}
}
}
.btn_count{
width: 216px;
height: 64px;
background-color: #ECF5FF;
border-radius: 40px 0px 16px 0px;
padding: 0 20px;
display: flex;
align-items: center;
}
}
}
}

View File

@ -1,55 +0,0 @@
import { formatHashTag, formatImgUrl } from "@/common/fotmat";
import Counter from "@/components/counter";
import MCheckbox from "@/components/checkbox";
import { Image, Text, View } from "@tarojs/components";
import { FC, memo, useCallback } from "react";
import styles from './index.module.scss'
type OrderParam = {
list?: any[],
sale_mode?: number,
sale_mode_name?: string,
unit?: string,
total_colors?: number,
total_fabrics?: number,
total_number?: number,
status?: number, //订单状态
av_return_product?: any[] //申请售后列表
}
type Param = {
order: OrderParam,
onNumChange?: (val:any) => void
}
const kindeList:FC<Param> = memo(({order, onNumChange}) => {
//计步器返回值
const getCounterChange = useCallback((colorItem) => {
return (number) => {
onNumChange?.({number, color_id: colorItem.product_color_id, sale_order_detail_id:colorItem.sale_order_detail_id})
}
}, [order])
return (
<View className={styles.apply_after_sales_list}>
{order?.av_return_product?.map(item => <View className={styles.apply_after_sales_item}>
<View className={styles.apply_after_sales_title}>
<View className={styles.tag}>{order.sale_mode_name}</View>
<View className={styles.title}>{formatHashTag(item.product_code, item.product_name)}</View>
</View>
<View className={styles.color_list}>
{item?.av_product_color?.map(colorItem => <View className={styles.color_item}>
<View className={styles.image}><Image src={formatImgUrl('')}/></View>
<View className={styles.name_and_number}><Text>{colorItem.product_color_code + ' ' + colorItem.product_color_name}</Text><Text>x {colorItem.roll}</Text></View>
<View className={styles.btn_count}>
<Counter maxNum={colorItem.roll} onChange={getCounterChange(colorItem)}/>
</View>
</View>)}
</View>
</View>)}
</View>
)
})
export default kindeList

View File

@ -1,36 +0,0 @@
.other_desc{
padding: 0 20px;
box-sizing: border-box;
.title{
font-size: $font_size;
font-weight: 700;
}
.textarea{
position: relative;
height: 165.4px;
.descDataNum{
position: absolute;
right: 10px;
bottom: 10px;
font-size: 22px;
color: #ABABAB;
}
}
.textarea_con, .textarea_con_pretend{
background-color: #f3f3f3;
border: 2px solid #e6e6e6;
border-radius: 10px;
width: 100%;
font-size: 25px;
height: 165.4px;
padding: 20px 20px 30px 20px;
box-sizing: border-box;
margin-top: 20px;
}
.textarea_con_pretend{
color: $color_font_two;
}
.textarea_con_pretend_ed{
color: #000;
}
}

View File

@ -1,41 +0,0 @@
import {Textarea, View } from "@tarojs/components";
import { memo, useMemo, useState } from "react";
import styles from './index.module.scss'
import classnames from "classnames";
//其他说明
type Param = {
onChange: (val: string) => void
}
export default memo(({onChange}:Param) => {
const [descData, setDescData] = useState({
number: 0,
value: '',
count: 200,
show: false
})
const getDesc = (e) => {
let value = e.detail.value
let res = value
if(value.length > descData.count) {
res = value.slice(0, descData.count)
}
setDescData({...descData, number:res.length, value: res})
onChange?.(res)
}
const toggleShowRealTextarea = (show) => {
setDescData({...descData, show:show})
}
return (
<View className={styles.other_desc}>
<View className={styles.title}></View>
<View className={styles.textarea}>
{descData.show&&<Textarea autoFocus value={descData.value} onBlur={() => toggleShowRealTextarea(false)} className={styles.textarea_con} cursorSpacing={100} maxlength={descData.count} onInput={(e) => getDesc(e)}></Textarea>||
<View className={classnames(styles.textarea_con_pretend, descData.value&&styles.textarea_con_pretend_ed)} onClick={() => toggleShowRealTextarea(true)}>{descData.value||'一般情况下选填,当退货说明=“其它问题”时,必填'}</View>
}
<View className={styles.descDataNum}>{descData.number +'/'+ descData.count}</View>
</View>
</View>
)
})

View File

@ -1,44 +0,0 @@
import Popup from "@/components/popup";
import { ScrollView, Text, View } from "@tarojs/components";
import { memo, useEffect, useMemo, useState } from "react";
import classnames from "classnames";
import styles from './index.module.scss'
//原因选择
type Param = {id:number, name:string, typle?:number}
type ReasonInfoParam = {
show?: boolean, //显示
onClose?: () => void, //关闭
title?: string, //标题
list?: {id:number, name:string, typle?:number, children?:Param[]}[], //数据列表
onSelect?: (val: object) => void, //选择
defaultValue?: number, //默认选中
}
export default memo(({show = false, onClose, title = '', list = [], onSelect, defaultValue}: ReasonInfoParam) => {
const [hasNextData, setHasNextData] = useState(true) //是否有下一级数据
const [selectData, setSelectData] = useState()
const [headerList, setHeaderList] = useState<{id: number, name: string}[]>([])
const onSelectData = (item) => {
setHeaderList((e) => [...e, {id:item.id, name:item.name}])
}
useEffect(() => {
console.log('headerList::', headerList)
}, [headerList])
return (
<Popup showIconButton={false} show={show} title={title} onClose={onClose} >
<View className={styles.reason_return_con}>
<View className={styles.reason_title}>
{headerList.map(item => {
return <Text key={item.id}>{item.name}</Text>
})}
{hasNextData&&<Text></Text>}
</View>
<ScrollView scrollY className={styles.reason_scroll}>
<View className={styles.reason_list}>
{list.map(item => <View onClick={() => onSelectData(item)} key={item.id} className={classnames(styles.reason_item, item.id == defaultValue&&styles.select_item)}>{item.name}</View> )}
</View>
</ScrollView>
</View>
</Popup>
)
})

View File

@ -1,30 +0,0 @@
import Popup from "@/components/popup";
import { ScrollView, Text, View } from "@tarojs/components";
import { memo, useMemo } from "react";
import classnames from "classnames";
import styles from './index.module.scss'
//原因选择
type ReasonInfoParam = {
show?: boolean, //显示
onClose?: () => void, //关闭
title?: string, //标题
list?: {id:number, name:string, typle?:number}[], //数据列表
onSelect?: (val: object) => void, //选择
defaultValue?: number, //默认选中
}
export default memo(({show = false, onClose, title = '', list= [], onSelect, defaultValue}: ReasonInfoParam) => {
return (
<Popup showIconButton={false} show={show} title={title} onClose={onClose} >
<View className={styles.reason_return_con}>
<View className={styles.reason_title}><Text>{title}</Text></View>
<ScrollView scrollY className={styles.reason_scroll}>
<View className={styles.reason_list}>
{list.map(item => <View onClick={() => onSelect?.(item)} key={item.id} className={classnames(styles.reason_item, item.id == defaultValue&&styles.select_item)}>{item.name}</View> )}
</View>
</ScrollView>
</View>
</Popup>
)
})

View File

@ -1,43 +0,0 @@
.reason_return_con{
height: 50vh;
.reason_title{
padding: 10px 20px 0 20px;
border-bottom: 1PX solid #F3F3F3;
box-sizing: border-box;
text{
margin-right: 15px;
font-size: 27px;
display: inline-block;
}
.selectName{
font-size: 26px;
padding: 20px 10px;
font-weight: 400;
color: #ABABAB;
}
.tips{
color: #ABABAB;
border-bottom: 0;
padding: 20px 10px;
}
.select_bottom {
border-bottom: 3px solid #007AFF;
color: #000;
}
}
.reason_scroll{
height: calc(100% - 70px);
.reason_list{
font-size: 26px;
padding: 30px 20px 0 20px;
color: #707070;
.reason_item{
margin-bottom: 36px;
}
.select_item {
color: #007AFF;
}
}
}
}

View File

@ -1,63 +0,0 @@
import Popup from "@/components/popup";
import { ScrollView, Text, View } from "@tarojs/components";
import { Children, memo, useEffect, useMemo, useRef, useState } from "react";
import classnames from "classnames";
import styles from './index.module.scss'
import { ReturnExplainApi, ReturnReasonApi } from "@/api/salesAfterOrder";
//原因选择
type Param = {id:number, name:string, typle?:number}
type ReasonInfoParam = {
show?: boolean, //显示
onClose?: () => void, //关闭
title?: string, //标题
list?: {id:number, name:string, typle?:number}[], //数据列表
onSelect?: (val: object) => void, //选择
onHeaderSelect?: (val: object) => void, //点击头部标题
defaultValue?: number, //默认选中
dataLength?: number, //可显示的数据列数
}
export default memo(({show = false, onClose, title = '', list = [], onSelect, onHeaderSelect, defaultValue, dataLength = 1}: ReasonInfoParam) => {
const [initList, setInitList] = useState<typeof list>([])
useEffect(() => {
setInitList(list)
}, [list])
const [selectIndex, setSelectIndex] = useState(1)
const [headerList, setHeaderList] = useState<{id: number, name: string}[]>([])
const onSelectData = (item) => {
if(selectIndex <= dataLength) {
headerList[selectIndex - 1] = {id:item.id, name:item.name}
onSelect?.({data:headerList, index:selectIndex})
setSelectIndex(selectIndex == dataLength?dataLength:selectIndex + 1)
setHeaderList((e) => [...e])
if(selectIndex == dataLength) onClose?.()
}
}
const onHeaderClick = ({val, index}) => {
let list = headerList.slice(0, index + 1)
setSelectIndex(index + 1)
setHeaderList(list)
onHeaderSelect?.({data:val, index: index + 1})
}
return (
<Popup showIconButton={false} show={show} title={title} onClose={onClose} >
<View className={styles.reason_return_con}>
<View className={styles.reason_title}>
{headerList.map((item, index) => {
return <Text key={item.id} onClick={() => onHeaderClick({val:item, index})} className={classnames(styles.selectName, (headerList.length == index + 1)&&styles.select_bottom)}>{item.name}</Text>
})}
{dataLength > headerList.length&&<Text className={styles.tips}></Text>}
</View>
<ScrollView scrollY className={styles.reason_scroll}>
<View className={styles.reason_list}>
{initList.map(item => <View onClick={() => onSelectData(item)} key={item.id} className={classnames(styles.reason_item, item.id == defaultValue&&styles.select_item)}>{item.name}</View> )}
</View>
</ScrollView>
</View>
</Popup>
)
})

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '申请售后',
enableShareAppMessage: true,
}

View File

@ -1,110 +0,0 @@
.apply_after_sales_main{
.apply_after_sales_head{
font-size: 30px;
text-align: center;
padding: 20px 0;
font-weight: 700;
}
.kind_number{
width: 100%;
padding: 20px;
box-sizing: border-box;
border-bottom: 1PX solid #f3f3f3;
text{
background-color: #F6F6F6;
border-radius: 10px;
font-size: $font_size_medium;
padding: 5px 0;
text-align: center;
width: 100%;
display: block;
color: $color_font_three;
}
}
.apply_after_sales_con{
.scroll{
height: calc(100% - 170px);
}
.scroll_con{
padding: 20px 0 150px 0;
}
.returnSaleInput{
margin: 0 20px;
padding-top: 30px;
border-top: 1px solid #F6F6F6;
.returnSaleInput_item{
display: flex;
align-items: center;
padding-bottom: 30px;
flex-wrap: wrap;
.title{
font-size: $font_size;
font-weight: 700;
width: 119px;
}
.select{
flex:1;
height: 60px;
border: 2px solid #e6e6e6;
border-radius: 10px;
margin-left: 20px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
font-size: 26px;
color: $color_font_two;
.miconfont{
font-size: 30px;
}
.selected{
color: #000;
}
}
.upload_image{
flex:1;
}
}
}
}
.btns_con{
width: 100%;
position: fixed;
bottom:0;
padding: 0 20px;
box-sizing: border-box;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
.btns_two{
display: flex;
height: 82px;
// border: 1PX solid #007aff;
font-size: $font_size_big;
border-radius: 40px;
margin-bottom: 20px;
.rest_btn{
flex:1;
border: 1PX solid #007aff;
border-radius: 40px 0 0 40px;
text-align: center;
line-height: 82px;
color: $color_main;
background-color: #fff;
}
.verify_btn{
flex:1;
border-radius: 0 40px 40px 0;
background: #007aff;
text-align: center;
line-height: 82px;
color: #fff;
}
}
}
}

View File

@ -1,260 +0,0 @@
import { Image, ScrollView, Text, View } from "@tarojs/components";
import { FC, memo, useCallback, useEffect, useMemo, useRef, useState } from "react";
import classnames from "classnames";
import styles from './index.module.scss'
import ReasonPopup from "./components/reasonPopup";
import Taro, { useDidShow, useRouter } from "@tarojs/taro";
import { GetSaleOrderDetailApi } from "@/api/order";
import KindList from "./components/kindList"
import CutKindList from "./components/cutkindList"
import { ReturnApplyOrderApi, ReturnExplainApi, ReturnGoodsStatusApi, ReturnReasonApi } from "@/api/salesAfterOrder";
import { alert, goLink } from "@/common/common";
import UploadImage from "@/components/uploadImage"
import TextareaEnhance from "@/components/textareaEnhance";
import useLogin from "@/use/useLogin";
import { throttle } from "@/common/util";
enum returnStatus {
return_reason = 1, //原因
goods_status = 2, //状况
return_explain = 3, //说明
}
export default () => {
useLogin()
useDidShow(() => {
getSaleOrderPreView()
})
const router = useRouter()
const orderId = useRef<number>(Number(router.params.id))
//需要提交的数据
const [submitData, setSubmitData] = useState<any>({
fabric_piece_accessory_url: [],
goods_status: '', //货物状况
reason_describe: '', //其他说明
return_explain: '', //退货说明
return_reason: '', //退货原因
roll: 0,
roll_list: [],
sale_order_id: orderId.current
})
//获取订单数据
const [orderDetail, setOrderDetail] = useState<any>() //获取到的原始数据
const {fetchData: getOrderFetchData} = GetSaleOrderDetailApi()
const getSaleOrderPreView = async () => {
if(orderId.current) {
let res = await getOrderFetchData({id: orderId.current})
setOrderDetail(res.data)
}
}
//监听获取到的数据
useEffect(() => {
if(orderDetail) {
formatData()
}
}, [orderDetail])
//格式化数据格式
const [formatDetailOrder, setFormatDetailOrder] = useState<any>() //格式化后的数据
const formatData = () => {
setFormatDetailOrder({
...orderDetail,
unit: orderDetail.sale_mode == 0?'条':'m', //单位
list: orderDetail.product_list,
})
}
//数据总量
const dataCount = useMemo(() => {
if(formatDetailOrder) {
let total_number = formatDetailOrder.sale_mode == 0?formatDetailOrder.av_total_number + '条':(formatDetailOrder.av_total_number/100) + '米'
return `${formatDetailOrder.av_total_fabrics}种面料,${formatDetailOrder.av_total_colors}种颜色,共${total_number}`
}
}, [formatDetailOrder])
//面料数据
let roll_list = useRef({})
//大货时获取计步器数据
const getNumChange = useCallback((val) => {
if(parseInt(val.number) > 0) {
roll_list.current[val.color_id] = {product_roll: val.number, sale_order_detail_id: val.sale_order_detail_id}
} else {
delete roll_list.current[val.color_id]
}
setSubmitData((e) => ({...e, roll_list:Object.values(roll_list.current)}))
}, [])
//散剪和剪板
const getSelectChange = useCallback((val) => {
if(val.status) {
roll_list.current[val.color_id] = {product_roll: val.length, sale_order_detail_id: val.sale_order_detail_id}
} else {
delete roll_list.current[val.color_id]
}
setSubmitData((e) => ({...e, roll_list:Object.values(roll_list.current)}))
}, [])
//获取图片列表
const getImageList = useCallback((list) => {
setSubmitData((e) => ({...e, fabric_piece_accessory_url:list}))
}, [])
//其他说明
const getOtherReason = useCallback((val) => {
setSubmitData((e) => ({...e, reason_describe: val}))
}, [])
//提交数据
const {fetchData: fetchDataReturnApply} = ReturnApplyOrderApi()
const onSubmitData = async () => {
if(submitData.roll_list.length <= 0) return alert.none('请选择或输入退货颜色')
console.log('submitData::',submitData)
let res = await fetchDataReturnApply(submitData)
if(res.success) {
alert.success('申请成功')
goLink('/pages/salesAfter/salesAfterList/index',{}, 'reLaunch')
} else {
alert.error(res.msg)
}
}
//底部按钮
const onSubmit = throttle((val) => {
if(val == 2) {
if(submitData.goods_status === '') return alert.error('请选择货物状况')
if(submitData.return_explain === '') return alert.error('请选择退货原因')
if(!submitData.return_explain && !submitData.reason_describe) return alert.error('请填写其他说明')
onSubmitData()
} else {
Taro.navigateBack()
}
}, 600)
//退货原因选择弹窗
const [showReason, setShowReason] = useState(false)
const closeReason = useCallback(() => setShowReason(false), [])
const onShowReason = () => {
setShowReason(true)
}
useEffect(() => {
getReturnReason()
}, [])
//请求获取到的数据
const [returnGoodsInfo, setReturnGoodsInfo] = useState([])
//退货原因
const {fetchData: fetchDataReturnReason} = ReturnReasonApi()
const getReturnReason = async () => {
let res = await fetchDataReturnReason()
setReturnGoodsInfo((e) => (res.data?.list))
}
//售后退货说明
const {fetchData: fetchDataReturnExplain} = ReturnExplainApi()
const getReturnExplain = async (id) => {
let res = await fetchDataReturnExplain({return_reason: id})
setReturnGoodsInfo((e) => (res.data?.list))
}
//退货原因选择列表返回的数据
const [returnObj, setReturnObj] = useState<any>([])
const onReturnSelect = useCallback((val) => {
let res = val.data[val.data.length - 1]
if(val.index == 1) {
getReturnExplain(res.id)
setReturnGoodsInfo(() => [])
}
if(val.index == 2) setReturnObj(val.data)
}, [])
const onHeaderSelect = useCallback((val) => {
setReturnGoodsInfo((e) => [])
if(val.index == 1) getReturnReason()
}, [])
//选择货物状况
const [showStatus, setShowStatus] = useState(false)
const [statusInfo, setStatusInfo] = useState<any>()
const [statusGoodsInfo, setStatusGoodsInfo] = useState([])
const {fetchData: fetchDataGoodsStatus} = ReturnGoodsStatusApi()
const getReturnGoodsStatus = async () => {
let res = await fetchDataGoodsStatus()
setStatusGoodsInfo((e) => (res.data?.list))
}
const onShowStatus = () => {
setShowStatus(() => true)
getReturnGoodsStatus()
}
const closeStatus = useCallback(() => {
setShowStatus(() => false)
}, [])
const onStatusSelect = useCallback((val) => {
let res = val.data[val.data.length - 1]
setStatusInfo(res)
}, [])
useEffect(() => {
if(returnObj.length > 0) {
submitData.return_reason = returnObj[0].id
submitData.return_explain = returnObj[1].id
}
if(statusInfo) {
submitData.goods_status = statusInfo.id
}
setSubmitData(() => ({...submitData}))
}, [returnObj, statusInfo])
return (
<View className={styles.apply_after_sales_main}>
<View className={styles.apply_after_sales_con}>
<View className={styles.kind_number}><Text>{dataCount}</Text></View>
<ScrollView scrollY className={styles.scroll}>
<View className={styles.scroll_con}>
{(orderDetail?.sale_mode == 0)&&<KindList order={formatDetailOrder} onNumChange={getNumChange} />||
<CutKindList order={formatDetailOrder} onSelectChange={getSelectChange}/>}
<View className={styles.returnSaleInput}>
<View className={styles.returnSaleInput_item}>
<View className={styles.title}>退</View>
<View className={styles.select} onClick={onShowReason}>
<Text className={returnObj?.length > 0&&styles.selected}>{returnObj?.length > 0?(returnObj[0]?.name + '/' +returnObj[1]?.name):'请选择'}</Text>
<Text className={classnames(styles.miconfont, 'iconfont icon-a-moreback')}></Text>
</View>
</View>
<View className={styles.returnSaleInput_item}>
<View className={styles.title}></View>
<View className={styles.select} onClick={onShowStatus}>
<Text className={statusInfo?.name&&styles.selected}>{statusInfo?.name||'请选择'}</Text>
<Text className={classnames(styles.miconfont, 'iconfont icon-a-moreback')}></Text>
</View>
</View>
<View className={styles.returnSaleInput_item}>
<View className={styles.title}></View>
<View className={styles.upload_image}>
<UploadImage onChange={getImageList}/>
</View>
</View>
<TextareaEnhance onChange={getOtherReason} title='其他说明'/>
</View>
</View>
</ScrollView>
<View className="common_safe_area_y"></View>
</View>
<View className={styles.btns_con}>
<View className={styles.btns_two}>
<View className={styles.rest_btn} onClick={() => onSubmit(1)}></View>
<View className={styles.verify_btn } onClick={() => onSubmit(2)}></View>
</View >
</View >
<ReasonPopup show={showReason} onClose={closeReason} title='退货原因' list={returnGoodsInfo} onHeaderSelect={onHeaderSelect} onSelect={onReturnSelect} dataLength={2}/>
<ReasonPopup show={showStatus} onClose={closeStatus} title='货物状况' list={statusGoodsInfo} onSelect={onStatusSelect} dataLength={1}/>
</View>
)
}

View File

@ -1,62 +0,0 @@
.bindSalesman_main{
width: 100%;
height: 100vh;
position: fixed;
left:0;
top:0;
.bindSalesman_pop{
width: 654px;
height: 560px;
border-radius: 40px;
display: flex;
flex-direction: column;
align-items: center;
position:absolute;
margin:auto;
left: 0;
right: 0;
bottom: 0;
top: 0;
bottom: 0;
z-index: 1999;
.bindSalesman_header{
width: 654px;
position: relative;
image{
width: 100%;
height: 100%;
border-radius: 40px 40px 0 0;
}
.sale_man{
color: #fff;
text-align: center;
font-size: 26px;
position: absolute;
margin: auto;
left: 0;
right: 0;
bottom: 60px;
height: 100px;
line-height: 100px;
}
}
.btns{
width: 488px;
height: 104px;
margin: 50px;
image{
width: 100%;
}
}
}
.bindSalesman_mask{
z-index: 99;
position: absolute;
left:0;
top:0;
width: 100%;
height: 100%;
opacity: 0.8;
background: #000000;
}
}

View File

@ -1,41 +0,0 @@
import { Image, Swiper, SwiperItem, Text, View } from "@tarojs/components"
import styles from './index.module.scss'
import { formatImgUrl } from "@/common/fotmat"
import Taro from "@tarojs/taro";
import { goLink } from "@/common/common";
import CloseBtn from "@/components/closeBtn";
import { useEffect, useState } from "react";
type params = {
show?: true|false,
onClose?: () => void,
saleMan?: string
}
export default ({show = false, saleMan = '', onClose}:params) => {
const onClick = async () => {
onClose?.()
goLink('/pages/index/index', {}, 'switchTab')
}
const onCloseEven = () => {
onClose?.()
}
return (
<>
{show&&<View className={styles.bindSalesman_main}>
<View className={styles.bindSalesman_pop}>
<View className={styles.bindSalesman_header} onClick={() => onClick()}>
<Image src={formatImgUrl('/mall/invite_code_success.png', '!w400')} mode="widthFix"/>
<View className={styles.sale_man}> {saleMan}</View>
</View>
<View className={styles.btns} >
<Image src={formatImgUrl('/mall/invite_code_btn.png', '!w400')} mode="widthFix" onClick = {() => onClick()}/>
</View>
<CloseBtn styleObj={{backgroundImage: '', border:'2PX solid #fff', color: '#fff'}} onClose={onCloseEven}/>
</View>
<View className={styles.bindSalesman_mask} onClick={onCloseEven}></View>
</View>}
</>
)
}

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '邀请码',
enableShareAppMessage: true,
}

View File

@ -1,83 +0,0 @@
.bindSalesmanPage_main{
display: flex;
flex-direction: column;
align-items: center;
.header_image{
width: 240px;
height: 188px;
padding: 50px 0;
image{
width: 100%;
height: 100%;
}
}
.salesman_name{
font-size: 30px;
color: #007AFF;
box-sizing: border-box;
padding-top: 50px;
text{
&:nth-child(2) {
margin-left: 20px;
}
}
}
.inputCode{
width: 670px;
height: 106px;
background: #f6f6f6;
border: 2px solid #f0f0f0;
border-radius: 20px;
display: flex;
align-items: center;
padding: 20px 0 20px 30px;
box-sizing: border-box;
position: relative;
input{
flex:1;
z-index: 0;
}
.scan_code{
width: 101px;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
border-left: 1PX solid #ccc;
.miconfont{
font-size: 50px;
color: #007AFF;
}
}
.close_btn{
padding: 0 20px;
}
}
.btns{
width: 670px;
height: 90px;
opacity: 0.6;
background: linear-gradient(41deg,#007aff, #3a9bfd 86%, #4ba2fa 100%);
border-radius: 46px;
text-align: center;
line-height: 90px;
color: #fff;
margin-top: 50px;
}
.select_btns{
opacity: 1;
}
.message{
padding: 150px 30px 20px 30px;
color: #ABABAB;
font-size: 28px;
text{
display: block;
margin-bottom: 30px;
&:nth-child(1) {
text-align: center;
font-weight: 700;
}
}
}
}

View File

@ -1,100 +0,0 @@
import { Image, Input, Text, View } from '@tarojs/components'
import styles from './index.module.scss'
import useLogin from '@/use/useLogin'
import classnames from "classnames";
import { formatImgUrl } from '@/common/fotmat'
import { useEffect, useMemo, useRef, useState } from 'react';
import { alert } from '@/common/common';
import CloseBtn from '@/components/closeBtn';
import SuccessBind from './component/successBind';
import Taro, { useDidShow } from "@tarojs/taro";
import { BindInvitationInfoApi, GetInvitationInfoApi } from '@/api/user';
import { debounce, getFilterData, throttle } from '@/common/util';
export default () => {
useLogin()
useEffect(() => {
onClipboardData()
}, [])
const [submitData, setSubmitData] = useState({
invitation_code: '',
})
//获取业务员信息
type Param = {invitation_code: string, name: string, phone: string}
const [salesMan, setSalesMan] = useState<Param|null>(null)
const {fetchData: GetInvitationInfoFetchData} = GetInvitationInfoApi()
const getInvitationInfo = async () => {
let res = await GetInvitationInfoFetchData(getFilterData({...submitData}))
res.success?setSalesMan(res.data):setSalesMan(null)
}
useEffect(() => {
if(submitData.invitation_code.length === 4)
getInvitationInfo()
}, [submitData])
const onInputCode = (e) => {
const value = e.detail.value.replace(/[\W]/g, "")
setSubmitData((val) => ({...val, invitation_code:value}))
}
const oncloseEven = () => {
setSubmitData((val) => ({...val, invitation_code:''}))
setSalesMan(null)
}
//绑定业务员
const [bindShow, setBindShow] = useState(false)
const {fetchData: bindInvitationInfoFetchData} = BindInvitationInfoApi()
const onSubmit = async () => {
if(!submitData.invitation_code) return alert.error('请输入邀请码')
let res = await bindInvitationInfoFetchData({...submitData})
if(res.success) setBindShow(() => true)
}
const onScanCode = () => {
Taro.scanCode({
success: (res) => {
setSubmitData(() => ({invitation_code: res.result}))
}
})
}
//获取粘贴版内容
const onClipboardData = () => {
Taro.getClipboardData({
success: function (res){
let val = res.data.match(/InviteCode:([a-zA-Z0-9]{4})/)
if(val) setSubmitData((e) => ({...e, invitation_code: val?val[1]:''}))
}
})
}
return (
<View className={styles.bindSalesmanPage_main}>
<View className={styles.header_image}>
<Image src={formatImgUrl('/mall/invite_code_bg.png')} mode="aspectFill"/>
</View>
<View className={styles.inputCode}>
<Input maxlength={4} value={submitData.invitation_code} placeholder='请输入邀请码' onInput={onInputCode} type="text" />
<View className={styles.close_btn} >
{submitData.invitation_code&&<CloseBtn styleObj={{backgroundColor: '#ccc', color: '#fff'}} onClose={oncloseEven}/>}
</View>
<View className={styles.scan_code} onClick={() => onScanCode()}>
<Text className={classnames('iconfont icon-saomazhifu', styles.miconfont)}></Text>
</View>
</View>
{salesMan&&<View className={styles.salesman_name}><Text>:</Text><Text>{`${salesMan.name} (${salesMan.phone})`}</Text></View>}
<View className={classnames(styles.btns, salesMan&&styles.select_btns)} onClick={onSubmit}></View>
<View className={styles.message}>
<Text></Text>
<Text>1. 7</Text>
<Text>2. </Text>
</View>
<View className='common_safe_area_y'></View>
<SuccessBind show={bindShow} onClose={() => setBindShow(false)} saleMan={salesMan?.name}/>
</View>
)
}

View File

@ -1,22 +0,0 @@
.select-enterprise-type{
.select-enterprise-type-btn{
color: #ABABAB;
font-size: 28px;
padding: 20px;
display: flex;justify-content: space-between;
border-bottom: 1rpx solid #eaeaea;
}
.select-enterprise-type-content{
padding: 0 20px;
padding-bottom: 120px;
}
.select-enterprise-type-content view{
padding: 20px 0;
font-size: 28px;
display: flex;justify-content: space-between;
}
.select-enterprise-type-content view text:last-child{
color: #007AFF;
font-size: 35px;
}
}

View File

@ -1,56 +0,0 @@
import { Text, View } from "@tarojs/components"
import Popup from "@/components/popup";
import "./SelectEnterpriseType.scss"
import { forwardRef, useEffect, useImperativeHandle, useState } from "react";
import {certificationTypeListApi} from "@/api/certification"
interface Params{
confirm?: (selected:any)=>void, // 确定
}
export default forwardRef((props: Params, ref)=>{
const [modalShow, setModalShow] = useState(false)
// 获取认证信息
const {fetchData, state} = certificationTypeListApi();
useEffect(()=>{
fetchData();
}, [])
const [selected, setSelected] = useState({});
// 确定
const handleSelect = (item)=>{
setSelected(item);
}
// 设置弹窗是否显示
const setShow = (ev)=>{
setModalShow(ev);
}
useImperativeHandle(ref,()=>({
setShow
}))
// 确定
const handleConfirm = ()=>{
props.confirm&&props.confirm(selected);
setModalShow(false);
}
return (
<View className="select-enterprise-type">
<Popup showTitle={false} show={modalShow} onClose={() => setModalShow(false)}>
<View className="select-enterprise-type-btn">
<View onClick={() => setModalShow(false)}></View>
<View onClick={handleConfirm}></View>
</View>
<View className="select-enterprise-type-content">
{
state.data?.list?.map((item,index)=>{
return <View onClick={()=>handleSelect(item)} key={index}>
<Text>{item.name}</Text>
{item.id==(selected as any).id?<Text className="iconfont icon-tick"/>:<Text/>}
</View>
})
}
</View>
</Popup>
</View>
)
})

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '认证信息',
enableShareAppMessage: true,
}

View File

@ -1,115 +0,0 @@
.certification{
display: flex;
flex-direction: column;
background-color: #F0F0F0;
padding-bottom: 300px;
.certification-content{
background-color: white;
padding-bottom: 50px;
}
.certification-content:nth-of-type(3){
margin-top: 18px;
}
.certification-title{
font-size: 26px;
font-weight: 700;
margin-left: 30px;
padding-top: 40px;
color: #000000;
padding-bottom: 20px;
// border-top: 18px solid #F0F0F0;
}
.certification-upload{
width: 642px;
height: 316px;
border: 10px solid #cde5ff;
border-radius: 30px;
margin: 0 auto;
display: flex;align-items: center;justify-content: center;
font-size: 34px;
font-weight: 700;
color: #68b4ff;
background-color: #ECF5FF;
position: relative;
margin-top: 60px;
}
.certification-upload text{
margin-bottom: 60px;
}
.certification-upload-no{
display: flex;flex-direction: column;align-items: center;
}
.certification-upload image{
position: absolute;width: 100%;height: 100%;
object-fit: cover;border-radius: 30px;
}
.certification-upload-no-icon{
width: 104px;
height: 104px;
background: #68b4ff;
box-shadow: 0px 0px 12px 0px #68b4ff;
display: flex;align-items: center;justify-content: center;
border-radius: 50%;
color: white;
}
.certification-upload-no-tips{
margin-top: 30px;
border-radius: 30px;
font-size: 24px;
font-weight: 400;
color: #000000;
}
.certification-button{
position: absolute;bottom: -10px;left: -10px;right: -10px;
background-color: rgba(0,0,0,0.65);
display: flex;
height: 86px;
border-radius: 0 0 30px 30px;
z-index: 1;
}
.certification-button view{
flex: 1;
display: flex;align-items: center;justify-content: center;
font-size: 24px;
font-weight: 400;
color: #ffffff;
}
.certification-button view:first-child{
border-right: 1px solid #CCCCCC;
}
.certification-footer{
width: 750px;
height: 174px;
background: #ffffff;
box-shadow: 6px 0px 12px 0px rgba(0,0,0,0.16);
position: fixed;bottom: 0;left: 0;right: 0;
width: 100%;
display: flex;align-items: center;justify-content: center;
z-index: 2;
}
.certification-footer-button{
width: 696px;
height: 82px;
background: #ffffff;
border: 2px solid #cde5ff;
display: flex;
border-radius: 40px;
box-sizing: border-box;
overflow: hidden;
}
.certification-footer-button view,.certification-footer-button navigator{
flex: 1;
display: flex;align-items: center;justify-content: center;
font-size: 32px;
font-weight: 400;
color: #007aff;
border: 0;border-radius: none;
}
.certification-footer-button navigator::after{
border: 0;border-radius: none;
}
.certification-footer-button view:last-child{
color: white;
background-color: #007AFF;
}
}

View File

@ -1,201 +0,0 @@
import FromListCertification from "@/components/FromListCertification"
import { Button, Image, Input, NavigationBar, Navigator, Text, Textarea, View } from "@tarojs/components"
import Taro, { setNavigationBarTitle, useRouter } from "@tarojs/taro"
import { certificationSaveApi, certificationDetailApi } from "@/api/certification"
import { useEffect, useRef, useState } from "react"
import { alert, retrieval } from "@/common/common"
import "./index.scss"
import useUploadCDNImg from "@/use/useUploadImage";
import Message from "@/components/Message"
import { IMG_CND_Prefix } from "@/common/constant";
import SelectEnterpriseType from "./components/SelectEnterpriseType"
import { useSelector } from "@/reducers/hooks";
import useLogin from "@/use/useLogin";
export default () => {
const { getAdminUserInfo } = useLogin();
const { adminUserInfo } = useSelector(state => state.userInfo);
useEffect(() => {
initalFormData();
}, []);
// 获取认证信息
const { fetchData: getFromData } = certificationDetailApi()
const initalFormData = async () => {
const detail = await getFromData();
setFormData({
...detail.data ?? {},
legal_person_identity_url: detail?.data?.legal_person_identity_url ?? [],
// business_license_url: "https://test.cdn.zzfzyc.com/mall/827082e888860dd9da10f0fbb0ac3cf023081456.png"
} as any)
}
// 保存
const [formData, setFormData] = useState({
authentication_type: 0,
authentication_type_name: "",
business_license_url: "",
legal_person: "",
legal_person_identity: "",
business_license: '',
legal_person_identity_url: [],
name: ""
});
const rules = {
// authentication_type: [{
// message: "请选择认证类型"
// }],
name: [{
message: "请输入企业名称"
}],
business_license: [{
message: "请输入企业营业执照"
}],
business_license_url: [{
message: "请上传营业执照"
}],
legal_person: [{
message: "请输入法人名称"
}],
legal_person_identity: [{
message: "请输入正确法人身份证",
regex: /^[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
}],
legal_person_identity_url: [{
message: "请上传法人身份证",
validator: (value: any, rule: any) => {
if (!value[0] || !value[1]) {
return true;
}
return false;
}
}],
}
const { fetchData } = certificationSaveApi()
const handleSave = () => {
retrieval(formData, rules).then(async () => {
const result = await fetchData({ ...formData, authentication_type: 2 })
if (result.success) {
// Taro.eventCenter.trigger("weightList:refresh");
getAdminUserInfo();
Taro.navigateBack();
alert.success("保存成功");
} else {
alert.error(result.msg);
}
}).catch((message) => {
alert.none(message)
})
}
// 监听表单完善
const [hozon, setHozon] = useState(false);
useEffect(() => {
if (retrieval) {
retrieval(formData).then(() => setHozon(true)).catch(() => setHozon(false))
}
}, [formData])
// 选择类型弹窗显示
const selectTypeRef = useRef(null)
const handleSelectTypeModalShow = () => {
(selectTypeRef.current as any).setShow(true)
}
// 选择类型确定
const handleSelectTypeConfirm = (item) => {
setFormData({
...formData,
authentication_type: item.id,
authentication_type_name: item.name
});
}
// 上传图片
const { getWxPhoto } = useUploadCDNImg();
const handleUploadImage = async (text: any) => {
let result = await getWxPhoto('mall');
if (text == "business_license_url") {
formData.business_license_url = IMG_CND_Prefix + (result as any).url;
} else {
formData.legal_person_identity_url[text] = IMG_CND_Prefix + (result as any).url as never;
}
setFormData({ ...formData });
}
// 查看图片
const handleViewImage = (event, url) => {
event.stopPropagation();
Taro.previewImage({
current: url,
urls: [url]
})
}
return (
<View className="certification">
{(adminUserInfo as any)?.authentication_status == 3 && <Message text={`认证不通过,原因:${(formData as any).authentication_feedback},请重新认证`} />}
<View className="certification-content">
<View className="certification-title"></View>
{/* <FromListCertification type="select" onClick={handleSelectTypeModalShow} value={(formData as any)?.authentication_type_name} label="认证类型" placeholder="企业认证"/> */}
<SelectEnterpriseType ref={selectTypeRef} confirm={handleSelectTypeConfirm} />
<FromListCertification onInput={(ev: any) => setFormData({ ...formData, name: ev.detail.value })} value={formData["name"]} label="企业名称" placeholder="请输入营业执照上的企业名称" required />
{/* <FromListCertification type="select" style={{border: "0"}}label="企业营业执照" placeholder="注册号、统一社会信用代码、组织机构代码" required showIcon={false}/> */}
<FromListCertification onInput={(ev: any) => setFormData({ ...formData, business_license: ev.detail.value })} value={formData["business_license"]} style={{ border: "0" }} label="企业营业执照" placeholder="注册号、统一社会信用代码、组织机构代码" required />
<View onClick={() => handleUploadImage("business_license_url")} className="certification-upload">
{(formData as any)?.business_license_url ?
<>
<Text></Text>
<View className="certification-button">
<View onClick={(e) => handleViewImage(e, (formData as any)?.business_license_url)}></View>
<View></View>
</View>
<Image mode="aspectFit" src={(formData as any)?.business_license_url} />
</> :
<View className="certification-upload-no">
<View className="certification-upload-no-icon">+</View>
<View className="certification-upload-no-tips"></View>
</View>
}
</View>
</View>
<View className="certification-content">
<View className="certification-title"></View>
<FromListCertification onInput={(ev: any) => setFormData({ ...formData, legal_person: ev.detail.value })} value={formData["legal_person"]} label="法人代表" placeholder="填写法人名称" required />
<FromListCertification style={{ border: "0" }} onInput={(ev: any) => setFormData({ ...formData, legal_person_identity: ev.detail.value })} value={formData["legal_person_identity"]} label="法人身份" placeholder="填写法人代表身份证号" required />
<View onClick={() => handleUploadImage(0)} className="certification-upload">
{(formData as any)?.legal_person_identity_url[0] ?
<>
<Text></Text>
<View className="certification-button">
<View onClick={(e) => handleViewImage(e, (formData as any)?.legal_person_identity_url[0])}></View>
<View></View>
</View>
<Image mode="aspectFit" src={(formData as any)?.legal_person_identity_url[0]} />
</> :
<View className="certification-upload-no">
<View className="certification-upload-no-icon">+</View>
<View className="certification-upload-no-tips"></View>
</View>
}
</View>
<View onClick={() => handleUploadImage(1)} className="certification-upload">
{(formData as any)?.legal_person_identity_url[1] ?
<>
<Text></Text>
<View className="certification-button">
<View onClick={(e) => handleViewImage(e, (formData as any)?.legal_person_identity_url[1])}></View>
<View></View>
</View>
<Image mode="aspectFit" src={(formData as any)?.legal_person_identity_url[1]} />
</> :
<View className="certification-upload-no">
<View className="certification-upload-no-icon">+</View>
<View className="certification-upload-no-tips"></View>
</View>
}
</View>
</View>
<View className="certification-footer">
<View className="certification-footer-button">
<Navigator openType="navigateBack"></Navigator>
<View onClick={handleSave}>{[3, 4].includes((adminUserInfo as any)?.authentication_status) ? "重新认证" : "提交"}</View>
</View>
</View>
</View>
)
}

View File

@ -1,126 +0,0 @@
.popup_main{
width: 608px;
height: 100vh;
padding: 20px;
box-sizing: border-box;
display: flex;
flex-direction: column;
.popup_title{
font-size: $font_size;
font-weight: 700;
text-align: center;
padding: 20px 0;
}
.scroll{
flex:1;
height: 0;
}
.popup_filter{
padding-bottom: 100px;
}
.popup_filter_item{
margin-bottom: 20px;
.title{
font-size: $font_size;
color: $color_font_one;
font-weight: 700;
padding: 20px 0;
}
.btn_list{
display: grid;
grid-template-columns: repeat(3, 165.75px);
justify-content: space-between;
.btn_item{
width: 165.75px;
height: 69.2px;
background: #f0f0f0;
border-radius: 34px;
text-align: center;
line-height: 69.2px;
font-size: $font_size_medium;
color: $color_font_one;
margin-bottom: 20px;
}
.select_btn_item{
color: $color_main;
background: #ecf5ff;
border: 2px solid #007aff;
width: 161.75px;
height: 65.2px;
}
}
.btn_list_input{
display: flex;
// justify-content: space-between;
align-items: center;
.btn_width {
width: 220px;
height: 70px;
background: #f0f0f0;
border-radius: 50px;
padding: 10px 20px;
box-sizing: border-box;
input{
width: 100%;
height: 100%;
font-size: $font_size_medium;
}
}
.unit{
color: $color_font_one;
font-size: $font_size;
margin-left: 20px;
}
text{
color: #ccc;
padding: 0 20px;
}
.width_main{
}
}
.btn_list_element{
background-color: #F0F0F0;
border-radius: 30px;
padding: 20px;
box-sizing: border-box;
textarea{
width: 100%;
height: 126px;
font-size: $font_size_medium;
}
}
}
.btns_con{
width: 100%;
position: fixed;
bottom:0;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
.btns_two{
display: flex;
width: 552px;
height: 82px;
border: 2px solid #cde5ff;
font-size: $font_size_big;
border-radius: 40px;
margin-bottom: 20px;
.rest_btn{
flex:1;
border-radius: 0px 40px 40px 0px;
text-align: center;
line-height: 82px;
color: $color_main;
}
.verify_btn{
flex:1;
border-radius: 0px 40px 40px 0px;
background: #007aff;
text-align: center;
line-height: 82px;
color: #fff;
}
}
}
}

View File

@ -1,115 +0,0 @@
import Popup, {Params as PopuParams} from "@/components/popup"
import { Input, ScrollView, Text, Textarea, View } from "@tarojs/components"
import classnames from "classnames";
import { useEffect, useState } from "react";
import styles from './index.module.scss'
type params = {
onFiltr?: (val:object) => void
} & PopuParams
export default ({onClose, onFiltr, show = false}:params) => {
const [filterObj, setFilterObj] = useState({
series: '',
minWidth: '',
maxWidth: '',
minWeight: '',
maxWeight: '',
element: ''
})
const onCloseEven = () => {
onClose?.()
}
const onRest = () => {
console.log('12123')
setFilterObj({
series: '',
minWidth: '',
maxWidth: '',
minWeight: '',
maxWeight: '',
element: ''
})
}
useEffect(() => {
console.log(filterObj)
}, [filterObj])
const onVerify = () => {
console.log(filterObj)
onFiltr?.(filterObj)
}
const setNumber = (e, field) => {
console.log(e)
let num = parseFloat(e.detail.value)
if(isNaN(num)) {
filterObj[field] = null
} else {
filterObj[field] = parseFloat(num.toFixed(2))
}
setFilterObj({...filterObj})
}
const setElement = (e) => {
let res = e.detail.value
setFilterObj({...filterObj, element:res})
}
return (
<Popup position="right" show={show} showTitle={false} onClose={() => onCloseEven()} showIconButton={true}>
<View className={styles.popup_main}>
<View className={styles.popup_title}></View>
<ScrollView scrollY className={styles.scroll}>
<View className={styles.popup_filter}>
<View className={styles.popup_filter_item}>
<View className={styles.title}></View>
<View className={styles.btn_list}>
<View className={classnames(styles.btn_item, styles.select_btn_item)}></View>
<View className={styles.btn_item}></View>
<View className={styles.btn_item}></View>
<View className={styles.btn_item}></View>
<View className={styles.btn_item}></View>
<View className={styles.btn_item}></View>
</View>
</View>
<View className={styles.popup_filter_item}>
<View className={styles.title}></View>
<View className={styles.btn_list_input}>
<View className={styles.btn_width}><Input value={filterObj.minWidth} type="digit" onBlur={(e) => setNumber(e,'minWidth')} placeholder="自定义最低值" placeholderStyle="font-size: 26rpx"/></View>
<Text></Text>
<View className={styles.btn_width}><Input value={filterObj.maxWidth} type="digit" onBlur={(e) => setNumber(e,'maxWidth')} placeholder="自定义最高值" placeholderStyle="font-size: 26rpx"/></View>
<View className={styles.unit}>cm</View>
</View>
</View>
<View className={styles.popup_filter_item}>
<View className={styles.title}></View>
<View className={styles.btn_list_input}>
<View className={styles.btn_width}><Input type="digit" value={filterObj.minWeight} onBlur={(e) => setNumber(e,'minWeight')} placeholder="自定义最低值" placeholderStyle="font-size: 26rpx"/></View>
<Text></Text>
<View className={styles.btn_width}><Input type="digit" value={filterObj.maxWeight} onBlur={(e) => setNumber(e,'maxWeight')} placeholder="自定义最高值" placeholderStyle="font-size: 26rpx"/></View>
<View className={styles.unit}>g</View>
</View>
</View>
<View className={styles.popup_filter_item}>
<View className={styles.title}></View>
<View className={styles.btn_list_element}>
<Textarea placeholder="请输入" cursorSpacing={60} value={filterObj.element} onInput={(e) => setElement(e)}/>
</View>
</View>
<View className="common_safe_area_y"></View>
</View>
</ScrollView>
<View className={styles.btns_con}>
<View className={styles.btns_two}>
<View className={styles.rest_btn} onClick={() => onRest()}></View>
<View className={styles.verify_btn } onClick={() => onVerify()}></View>
</View>
</View>
</View>
</Popup>
)
}

View File

@ -1,3 +0,0 @@
export default {
navigationBarTitleText: '分类标题'
}

View File

@ -1,150 +0,0 @@
.main{
display: flex;
flex-direction: column;
height: 100vh;
background-color: $color_bg_one;
.search{
padding: 20px;
}
.filter{
.filter_all {
display: flex;
justify-content: space-between;
padding: 20px 50px;
font-size: $font_size_medium;
color: $color_font_three;
.text_one{
color: $color_main;
display: flex;
align-items: center;
}
.text_two{
position: relative;
.miconfont{
font-size: 20px;
margin-left: 10px;
}
&::before{
content: '';
width: 2px;
height: 32px;
background-color: #C2C2C2;
position: absolute;
top: 0;
left: -50px;
}
}
}
.filter_btns{
display: flex;
justify-content: space-between;
padding: 20px;
.selected{
background-color: #ecf5ff;
border: 2px solid #cde5ff;
color: $color_main;
width: 122px;
height: 42.93px;
}
}
}
.list{
flex:1;
height: 0;
}
.popup_main{
width: 608px;
height: 100vh;
padding: 20px;
box-sizing: border-box;
display: flex;
flex-direction: column;
.popup_title{
font-size: $font_size;
font-weight: 700;
text-align: center;
padding: 20px 0;
}
.scroll{
flex:1;
height: 0;
}
.popup_filter{
}
.popup_filter_item{
margin-bottom: 20px;
.title{
font-size: $font_size;
color: $color_font_one;
font-weight: 700;
padding: 20px 0;
}
.btn_list{
display: grid;
grid-template-columns: repeat(3, 165.75px);
justify-content: space-between;
.btn_item{
width: 165.75px;
height: 69.2px;
background: #f0f0f0;
border-radius: 34px;
text-align: center;
line-height: 69.2px;
font-size: $font_size_medium;
color: $color_font_one;
margin-bottom: 20px;
}
.select_btn_item{
color: $color_main;
background: #ecf5ff;
border: 2px solid #007aff;
width: 161.75px;
height: 65.2px;
}
}
.btn_list_input{
display: flex;
// justify-content: space-between;
align-items: center;
.btn_width {
width: 220px;
height: 70px;
background: #f0f0f0;
border-radius: 50px;
padding: 10px 20px;
box-sizing: border-box;
input{
width: 100%;
height: 100%;
font-size: $font_size_medium;
}
}
.unit{
color: $color_font_one;
font-size: $font_size;
margin-left: 20px;
}
text{
color: #ccc;
padding: 0 20px;
}
.width_main{
}
}
.btn_list_element{
background-color: #F0F0F0;
border-radius: 30px;
padding: 20px;
box-sizing: border-box;
textarea{
width: 100%;
height: 126px;
font-size: $font_size_medium;
}
}
}
}
}

View File

@ -1,150 +0,0 @@
import { Input, ScrollView, Text, Textarea, View } from '@tarojs/components'
import classnames from 'classnames'
import Search from '@/components/search'
import Product from '@/components/product'
import InfiniteScroll from '@/components/infiniteScroll'
import styles from './index.module.scss'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import Filter from '@/components/filter'
import SortBtn from '@/components/sortBtn'
import SelectData, { ListProps } from '../searchList/components/selectData'
import { GetProductListApi } from '@/api/material'
import { useRouter } from '@tarojs/taro'
import { dataLoadingStatus, getFilterData } from '@/common/util'
import LoadingCard from '@/components/loadingCard'
import Taro from '@tarojs/taro'
import useLogin from '@/use/useLogin'
export default () => {
useLogin()
const [showPopup, setShowPopup] = useState(false)
const router = useRouter()
useEffect(() => {
Taro.setNavigationBarTitle({
title: router.params.title || '分类页面',
})
}, [router])
//搜索参数
const [searchField, setSearchField] = useState({
code_or_name: '',
product_category_id: router.params.id,
page: 1,
size: 10,
width: '',
weight_density: '',
product_kind_id: '',
component: '',
})
//获取列表
const [categoryList, setCategoryList] = useState<{ list: any[]; total: number }>({
list: [],
total: 0,
})
const { fetchData, state } = GetProductListApi()
const getSubjectList = async () => {
let res = await fetchData(getFilterData(searchField))
setCategoryList({ ...categoryList, list: res.data.list, total: res.data.total })
}
//监听筛选数据变化
useEffect(() => {
getSubjectList()
}, [searchField])
//上拉加载数据
const pageNum = useRef({ size: searchField.size, page: searchField.page })
const getScrolltolower = () => {
if (categoryList.list.length < categoryList.total) {
pageNum.current.page++
const size = pageNum.current.size * pageNum.current.page
setSearchField({ ...searchField, size })
}
}
//数据加载状态
const statusMore = useMemo(() => {
return dataLoadingStatus({ list: categoryList.list, total: categoryList.total, status: state.loading })
}, [categoryList, state])
//获取筛选条件
const getFiltr = (e) => {
pageNum.current.page = 1
setCategoryList(() => ({ list: [], total: 0 }))
const { data } = e
setSearchField({
...searchField,
width: data?.width,
weight_density: data?.weight,
size: 10,
component: data?.element,
product_kind_id: data?.seriesId,
})
formatSelectList(e)
}
//筛选条件格式化
const [selectList, setSelectList] = useState<ListProps[]>()
const formatSelectList = (val = { data: {}, field: {} }) => {
let data: ListProps[] = []
for (let key in val.data) {
if (key !== 'seriesId' && val.data[key] != '') {
data.push({ title: val.field[key], value: val.data[key] })
}
}
setSelectList([...data])
}
//输入了搜索关键字
const getSearchData = useCallback((e) => {
pageNum.current.page = 1
setCategoryList(() => ({ list: [], total: 0 }))
setSearchField((val) => ({ ...val, code_or_name: e, size: 10 }))
}, [])
//排序
type sortParam = 'none' | 'top' | 'bottom'
const sortComprehensiveRef = useRef<any>(null)
const [sortStatus, setSortStatus] = useState<{ comprehensive: sortParam }>({
comprehensive: 'none',
})
const changeSort = () => {
setCategoryList(() => ({ list: [], total: 0 }))
const { status, value } = sortComprehensiveRef.current.changeSort()
setSortStatus((e) => ({ ...e, comprehensive: status, collection: 'none' }))
setSearchField((e) => ({ ...e, abstract_sort_key: value, size: 10, page: 1 }))
pageNum.current = { size: 10, page: 1 }
}
return (
<View className={styles.main}>
<View className={styles.search}>
<Search placeIcon='out' showBtn={true} btnStyle={{ color: '#007AFF' }} changeOnSearch={getSearchData} debounceTime={300} />
</View>
<View className={styles.filter}>
<View className={styles.filter_all}>
<View className={styles.text_one} onClick={() => changeSort()}>
<Text></Text>
<SortBtn status={sortStatus.comprehensive} ref={sortComprehensiveRef} sortValue={{ desc: '1', asc: '-1' }} />
</View>
<View className={styles.text_two} onClick={() => setShowPopup(true)}>
<Text></Text>
<Text className={classnames('iconfont icon-bianji_bianji', styles.miconfont)}></Text>
</View>
</View>
<View className={styles.filter_btns}>
<SelectData list={selectList} />
</View>
</View>
<View className={styles.list}>
<InfiniteScroll selfonScrollToLower={() => getScrolltolower()} statusMore={statusMore}>
<Product desStatus={false} productList={categoryList.list} />
</InfiniteScroll>
</View>
<Filter show={showPopup} onClose={() => setShowPopup(false)} onFiltr={getFiltr} />
</View>
)
}

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '收藏详情',
enableShareAppMessage: true,
}

View File

@ -1,59 +0,0 @@
.collection_main {
padding: 0 20px;
min-height: 100%;
background-color: #F8F8F8;
.search {
display: flex;
align-items: center;
.miconfont_con{
padding: 0 20px;
}
.miconfont{
font-size: 30px;
color: #007AFF;
border: 1px solid #007AFF;
border-radius: 50%;
}
}
.operation{
display: flex;
justify-content: space-between;
align-items: center;
padding: 20px 30px 0 30px;
font-size: 26px;
color: #707070;
.operation_check{
display: flex;
align-items: center;
position: relative;
&::after{
content: '';
height: 45px;
width: 1PX;
background-color: #ccc;
position: absolute;
right: -30px;
}
Text{
margin-left: 15px;
height: 100%;
display: inline-block;
}
}
}
.operation_check_right{
.operation_check_move{
color: #707070;
margin-right: 30px;
}
.operation_check_cancel{
color: #007AFF;
}
}
.class_list{
margin-top: 30px;
}
}

View File

@ -1,145 +0,0 @@
import { DelFavoriteProductApi, DetailFavoriteProductApi, MoveFavoriteProductApi } from '@/api/favorite'
import { alert } from '@/common/common'
import { getFilterData } from '@/common/util'
import Product from '../components/product'
import Search from '@/components/search'
import { Text, View } from '@tarojs/components'
import Taro, { useRouter } from '@tarojs/taro'
import classnames from 'classnames'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import styles from './index.module.scss'
import MCheckbox from '@/components/checkbox'
import AddCollection from '@/components/addCollection'
export default () => {
const router = useRouter()
//获取收藏夹面料
const { fetchData: fetchDataDetailFavoriteProduct } = DetailFavoriteProductApi()
const [colorInfo, setColorInfo] = useState<any>({})
const getFavoriteInfo = async () => {
let res = await fetchDataDetailFavoriteProduct(searchData)
if (res.success) {
Taro.setNavigationBarTitle({
title: res.data.name,
})
setColorInfo(res.data)
}
}
//获取搜索数据
const [searchData, setSearchData] = useState({ id: 0, code_or_name: '' })
const onSearch = useCallback((e) => {
setSearchData((val) => ({ ...val, code_or_name: e }))
}, [])
useEffect(() => {
let id = router.params.id || 0
if (id) setSearchData((e) => ({ ...e, id: parseInt(id as string) }))
}, [])
useEffect(() => {
if (searchData.id) getFavoriteInfo()
}, [searchData])
const productList = useMemo(() => {
return colorInfo.product_color_list
}, [colorInfo])
//获取选中的id
const [ids, setIds] = useState<number[]>([])
const getSelectIds = useCallback((val) => {
setIds(() => val)
}, [])
//全选反选
const [allSelectStatus, setAllSelectStatus] = useState(false)
const selectCallBack = useCallback(() => {
setAllSelectStatus(() => true)
setSelectStatus(1)
}, [])
const colseCallBack = useCallback(() => {
setAllSelectStatus(() => false)
setSelectStatus(3)
}, [])
const [selectStatus, setSelectStatus] = useState<1 | 2 | 3>(3)
useEffect(() => {
if (colorInfo.product_color_list?.length) {
if (ids.length == colorInfo.product_color_list.length) {
setSelectStatus(1)
setAllSelectStatus(true)
} else if (0 < ids.length && ids.length < colorInfo.product_color_list.length) {
setSelectStatus(2)
setAllSelectStatus(false)
} else {
setSelectStatus(3)
setAllSelectStatus(false)
}
}
}, [ids, colorInfo])
const [collectionShow, setCollectionShow] = useState(false)
const closeCollection = useCallback(() => {
setCollectionShow(false)
}, [])
//移动面料
const { fetchData: fetchDataMoveFavoriteProduct } = MoveFavoriteProductApi()
const onAdd = async (val) => {
if (ids.length == 0) return alert.none('请选择要移动面料')
let res = await fetchDataMoveFavoriteProduct({
source_favorite_id: searchData.id,
target_favorite_id: val.id,
product_id: ids,
})
if (res.success) {
getFavoriteInfo()
setCollectionShow(false)
alert.success('修改成功')
}
}
//取消收藏
const { fetchData: delFavoriteProductFetchData } = DelFavoriteProductApi()
const delCollectioin = async () => {
if (ids.length == 0) return alert.none('请选择要取消面料')
let showModalRes = await Taro.showModal({
title: '是否要取消收藏',
confirmText: '是',
cancelText: '否',
})
if (showModalRes.confirm) {
let res = await delFavoriteProductFetchData({ favorite_id: searchData.id, product_id: ids })
if (res.success) {
getFavoriteInfo()
alert.none('已取消收藏')
}
}
}
return (
<View className={styles.collection_main}>
<View className={styles.search}>
<Search style={{ width: '100%' }} debounceTime={300} changeOnSearch={onSearch} placeholder='请输入面料关键词' />
</View>
<View className={styles.operation}>
<View className={styles.operation_check}>
<MCheckbox status={allSelectStatus} onSelect={() => selectCallBack()} onClose={() => colseCallBack()} />
<Text className={styles.allSelect}></Text>
</View>
<View className={styles.operation_check_right}>
<Text className={styles.operation_check_move} onClick={() => setCollectionShow(true)}>
</Text>
<Text className={styles.operation_check_cancel} onClick={delCollectioin}>
</Text>
</View>
</View>
<View className={styles.class_list}>
<Product productList={productList} onSelectIds={getSelectIds} selectStatus={selectStatus} openCheckBox={true} />
</View>
<AddCollection show={collectionShow} onAdd={onAdd} onClose={closeCollection} />
</View>
)
}

View File

@ -1,66 +0,0 @@
.collection_con{
padding: 20px;
.title_item{
display: flex;
align-items: center;
padding-bottom: 20px;
flex-wrap: wrap;
.title{
font-size: $font_size;
font-weight: 700;
width: 60px;
}
.select{
flex:1;
height: 60px;
border: 2px solid #e6e6e6;
border-radius: 10px;
margin-left: 20px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
font-size: 26px;
color: #000;
.input{
width: 100%;
height: 100%;
}
}
}
.desc_item{
display: flex;
.title{
font-size: $font_size;
font-weight: 700;
width: 60px;
padding-top: 20px;
}
.desc{
margin-left: 20px;
flex:1;
}
}
.btns_con{
width: 100%;
bottom:0;
box-sizing: border-box;
margin-top: 50px;
.btns_two{
display: flex;
height: 82px;
font-size: $font_size_big;
border-radius: 40px;
margin-bottom: 20px;
.verify_btn{
flex:1;
border-radius: 40px;
background: #007aff;
text-align: center;
line-height: 82px;
color: #fff;
}
}
}
}

View File

@ -1,66 +0,0 @@
import Popup from "@/components/popup";
import { Input, ScrollView, Text, View } from "@tarojs/components";
import { memo, useCallback, useEffect, useMemo, useRef } from "react";
import classnames from "classnames";
import styles from './index.module.scss'
import TextareaEnhance from "@/components/textareaEnhance";
import { CreateFavoriteApi } from "@/api/favorite";
import { alert } from "@/common/common";
//原因选择
type ReasonInfoParam = {
show?: boolean, //显示
onClose?: () => void, //关闭
onSuccess?: (val:any) => void, //成功
defaultValue?: {
remark: string,
name: string
}, //默认数据
}
export default memo(({show = false, onClose, onSuccess, defaultValue}: ReasonInfoParam) => {
const submitData = useRef({
"name": '',
"remark": ''
})
const getOtherReason = (val) => {
submitData.current.remark = val
}
const changeInput = (val) => {
submitData.current.name = val.detail.value
}
const onSubmit = () => {
onSuccess?.(submitData.current)
}
useEffect(() => {
submitData.current = {name: defaultValue?.name!, remark: defaultValue?.remark!}
}, [defaultValue])
return (
<Popup show={show} title="新建收藏夹" onClose={onClose} >
<View className={styles.collection_con}>
<View className={styles.title_item}>
<View className={styles.title}></View>
<View className={styles.select}>
<Input placeholder="请输入文件夹名称" className={styles.input} cursorSpacing={150} onInput={changeInput} value={defaultValue?.name} />
</View>
</View>
<View className={styles.desc_item}>
<View className={styles.title}></View>
<View className={styles.desc}>
<TextareaEnhance defaultValue={defaultValue?.remark} onChange={getOtherReason} placeholder="请输入简介" />
</View>
</View>
<View className={styles.btns_con}>
<View className={styles.btns_two}>
<View className={styles.verify_btn } onClick={() => onSubmit()}></View>
</View >
</View>
</View>
</Popup>
)
})

View File

@ -1,89 +0,0 @@
.products_list{
padding: 0 20px 20px 20px;
box-sizing: border-box;
height: 100%;
}
.products_item{
width: 100%;
background-color: #fff;
border-radius: 20px;
padding: 20px;
box-sizing: border-box;
display: flex;
justify-content: space-between;
position: relative;
&:nth-child(n+2){
margin-top: 16px;
}
.checkbox{
position: absolute;
left: 10px;
top: 10px;
z-index: 999;
}
.item_img{
width: 198px;
height: 198px;
position: relative;
image{
width: 100%;
height: 100%;
border-radius: 10px;
}
.num{
padding: 5px 10px 5px 20px;
font-size: $font_size_min;
position: absolute;
right:0;
bottom: 0;
background: rgba($color: #000, $alpha: 0.3);
border-radius: 36px 0px 10px 0px;
color: #fff;
text-align: center;
}
}
.item_con{
padding-left: 20px;
font-size: $font_size;
flex:1;
.title{
font-size: $font_size;
color: #707070;
text{
color: $color_font_one;
font-weight: bold;
}
}
.tag_list{
display: flex;
margin-top: 16px;
flex-wrap: wrap;
.tag, .tag_g{
max-width: 260rpx;
padding: 3px 10px;
background-color: #CDE5FF;
font-size: $font_size_min;
border-radius: 5px;
color: $color_main;
margin-right: 10px;
margin-bottom: 10px;
}
.tag_g{
background-color: #FFE6CE;
color: #EE7500;
}
}
.introduce{
font-size: $font_size_medium;
color: $color_font_two;
}
.des{
font-size:$font_size_medium;
color: #707070;
margin-top: 16px;
@include common_ellipsis($params:2);
}
}
}

View File

@ -1,84 +0,0 @@
import { Image, View } from "@tarojs/components"
import Taro from "@tarojs/taro"
import { goLink } from "@/common/common"
import styles from './index.module.scss'
import { formatHashTag, formatImgUrl } from "@/common/fotmat"
import LabAndImg from "@/components/LabAndImg"
import MCheckbox from "@/components/checkbox";
import { useCallback, useEffect, useRef, useState } from "react"
type Params = {
productList?: any[],
onSelectIds?: (val: number[]) => void,
selectStatus?: 1|2|3, //1全选2不做处理3全清空
openCheckBox?: true|false //是否开启选择
}
export default ({productList, onSelectIds, selectStatus = 2, openCheckBox = false}:Params) => {
const [list, setList] = useState<any[]>([])
useEffect(() => {
setList(() => productList||[])
},[productList])
useEffect(() => {
if(list.length && selectStatus != 2) {
list.map(item => {
item.check = (selectStatus == 1)
})
setList(() => [...list])
}
}, [selectStatus])
const onChangeSelect = (item) => {
if(item.check) {
onClose(item)
} else {
onSelect(item)
}
}
//选中和取消选中
const onSelect = (item) => {
item.check = true
setList(() => ([...list]))
}
const onClose = (item) => {
item.check = false
setList(() => ([...list]))
}
//监听数据变化
useEffect(() => {
let ids: number[] = []
list.map(item => {
if(item.check) ids.push(item.product_id)
})
onSelectIds?.(ids)
}, [list])
return (
<View className={styles.products_list}>
{list?.map(item => {
return <View className={styles.products_item} onClick={() => openCheckBox?onChangeSelect(item):goLink(`/pages/details/index?id=${item.product_id}`)}>
{openCheckBox&&<View className={styles.checkbox} onClick={(e) => e.stopPropagation()}>
<MCheckbox status={item.check} onSelect={() => onSelect(item)} onClose={() => onClose(item)}/>
</View>}
<View className={styles.item_img}>
<LabAndImg value={{lab:item.lab,rgb:item.rgb,texture_url:item.texture_url}}/>
<View className={styles.num}>{item.enable_product_color_count}</View>
</View>
<View className={styles.item_con}>
<View className={styles.title}><text>{formatHashTag(item.product_code, '')} </text>{item.product_name}</View>
<View className={styles.tag_list}>
<View className={styles.tag}>{item.width}</View>
<View className={styles.tag_g}>{item.weight_density}</View>
</View>
<View className={styles.introduce}>{item.component}</View>
</View>
</View>
})}
<View className="common_safe_area_y"></View>
</View>
)
}

View File

@ -1,18 +0,0 @@
.collection_con{
padding: 20px ;
.collection_item{
display: flex;
font-size: 26px;
padding: 30px 10px;
border-bottom: 1PX solid #F3F3F3;
align-items: center;
.miconfont{
font-size: 36px;
color: #007AFF;
}
.text{
margin-left: 10px;
}
}
}

View File

@ -1,47 +0,0 @@
import Popup from "@/components/popup";
import { Input, ScrollView, Text, View } from "@tarojs/components";
import { memo, useCallback, useMemo, useRef } from "react";
import classnames from "classnames";
import styles from './index.module.scss'
import TextareaEnhance from "@/components/textareaEnhance";
import { CreateFavoriteApi } from "@/api/favorite";
import { alert } from "@/common/common";
//原因选择
type ReasonInfoParam = {
show?: boolean, //显示
onClose?: () => void, //关闭
onUpdate?: () => void, //编辑
onBatchManagement?: () => void, //批量管理
onDelete?: () => void, //删除
}
export default memo(({show = false, onClose, onUpdate, onBatchManagement, onDelete}: ReasonInfoParam) => {
const onClickEven = (val) => {
if (val == 1) {
onUpdate?.()
} else if (val == 2) {
onBatchManagement?.()
} else {
onDelete?.()
}
}
return (
<Popup show={show} onClose={onClose} showTitle={false} >
<View className={styles.collection_con}>
<View className={styles.collection_item} onClick={() => onClickEven(1)}>
<Text className={classnames(styles.miconfont, 'iconfont icon-bianji')}></Text>
<Text className={styles.text}></Text>
</View>
<View className={styles.collection_item} onClick={() => onClickEven(2)}>
<Text className={classnames(styles.miconfont, 'iconfont icon-fenlei')}></Text>
<Text className={styles.text}></Text>
</View>
<View className={styles.collection_item} onClick={() => onClickEven(3)}>
<Text className={classnames(styles.miconfont, 'iconfont icon-shanchu')}></Text>
<Text className={styles.text}></Text>
</View>
</View>
</Popup>
)
})

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '我的收藏',
enableShareAppMessage: true,
}

View File

@ -1,61 +0,0 @@
.collection_main {
padding: 0 20px;
min-height: 100%;
background-color: #F8F8F8;
.search {
display: flex;
align-items: center;
.miconfont_con{
padding: 0 20px;
}
.miconfont{
font-size: 30px;
color: #007AFF;
border: 1px solid #007AFF;
border-radius: 50%;
}
}
.class_list{
margin-top: 30px;
.class_item{
margin: 20px 0;
}
.class_title{
display: flex;
margin-bottom: 20px;
.title{
flex: 1;
color: #000;
font-weight: 700;
font-size: 28px;
padding: 0 20px;
@include common_ellipsis();
}
.fg{
padding: 0 10px;
}
.num, .fg{
color: #707070;
font-weight: normal;
}
.miconfont_left{
font-size: 30px;
color: #707070;
}
.miconfont_open{
transform: rotate(-90deg);
}
.miconfont_close {
transform: rotate(90deg);
}
.more{font-size: 26px;}
}
.class_con{
overflow: hidden;
transition: all 0.5s ease-in-out;
}
}
}

View File

@ -1,164 +0,0 @@
import { CreateFavoriteApi, DelFavoriteApi, FavoriteListApi, UpdateFavoriteApi } from "@/api/favorite";
import { alert, goLink } from "@/common/common";
import { getFilterData } from "@/common/util";
import Product from "./components/product";
import Search from "@/components/search"
import { Text, View } from "@tarojs/components"
import Taro, { useDidHide, useDidShow } from "@tarojs/taro";
import classnames from "classnames";
import { useCallback, useEffect, useRef, useState } from "react";
import CreatePopup from "./components/createPopup";
import UpdatePopup from "./components/updatePopup";
import styles from './index.module.scss'
import useLogin from "@/use/useLogin";
export default () => {
useLogin()
const changeOpenCon = (item) => {
item.openStatus = !item.openStatus
setList((e) => [...e])
}
useDidShow(() => {
getFavoriteList()
})
//获取搜索数据
const [searchData, setSearchData] = useState('')
const onSearch = useCallback((e) => {
setSearchData(() => e)
}, [])
useEffect(() => {
getFavoriteList()
}, [searchData])
//获取列表
const [list, setList] = useState([])
const {fetchData: fetchDataList} = FavoriteListApi()
const getFavoriteList = async () => {
let res = await fetchDataList(getFilterData({name: searchData}))
setList(() => res.data.list)
}
//创建收藏夹
const [collectioinShow, setCollectioinShow] = useState(false)
const closeCollection = useCallback(() => {
setCollectioinShow(false)
}, [])
const creatShow = () => {
setCollectioinShow(true)
setInitData(() => ({ remark: '',name: '', id:0}))
}
//新增
const {fetchData} = CreateFavoriteApi()
const onCreate = async (submitData) => {
if(!submitData.name) return alert.none('请输入收藏夹名称!')
let res = await fetchData({...submitData})
if(res.success) {
alert.success('创建成功')
getFavoriteList()
} else {
alert.error('创建失败')
}
}
//更多编辑
const [initData, setInitData] = useState({
remark: '',
name: '',
id:0
})
const selectInfo = useRef<any>(null)
const [updateShow, setUpdateShow] = useState(false)
const closeUpdate = useCallback(() => {
setUpdateShow(false)
}, [])
const moreUpdate = (item,e) => {
e.stopPropagation()
selectInfo.current = item
console.log('item:::', item)
setInitData((e) =>({ ...e, remark:item.remark , name: item.name, id: item.id}))
setUpdateShow(true)
}
//删除改收藏夹
const {fetchData: delFetchData} = DelFavoriteApi()
const onDeleteCollect = useCallback(() => {
if(!selectInfo.current.id) return alert.error('参数不正确!')
if(selectInfo.current.id == 1) return alert.none('删除失败,该文件夹不能删除!')
Taro.showModal({
content: '确认删除该文件夹?',
success: async function (res) {
if (res.confirm) {
let res = await delFetchData({id: selectInfo.current.id})
if(res.success) {
alert.success('删除成功')
getFavoriteList()
} else {
alert.error('删除失败')
}
} else if (res.cancel) {
console.log('用户点击取消')
}
}
})
closeUpdate()
}, [])
//编辑
const {fetchData: updateFavoriteFetchData} = UpdateFavoriteApi()
const onUpdateShow = useCallback(() => {
setCollectioinShow(true)
}, [])
const onUpdate = async (submitData) => {
if(!submitData.name) return alert.none('请输入收藏夹名称!')
let res = await updateFavoriteFetchData({...submitData})
if(res.success) {
alert.success('编辑成功')
getFavoriteList()
closeUpdate()
} else {
alert.error('编辑失败')
}
}
const onBatchManagement = useCallback(() => {
goLink('/pages/collection/collectionClass/index', {id: initData.id})
closeUpdate()
}, [initData])
//操作文件夹
const onCreatSuccess = (submitData) => {
if (!initData.id) {
onCreate(submitData)
} else {
onUpdate({...submitData, id: initData.id})
}
setCollectioinShow(false)
}
return (
<View className={styles.collection_main}>
<View className={styles.search}>
<Search style={{width: '100%'}} debounceTime={300} changeOnSearch={onSearch} placeholder="请输入面料关键词" />
<View className={styles.miconfont_con} onClick={creatShow}><Text className={classnames(styles.miconfont, 'iconfont icon-jia')}></Text></View>
</View>
<View className={styles.class_list}>
{list?.map((item:any) => <View className={styles.class_item}>
<View key={item.id} className={styles.class_title} onClick={() => changeOpenCon(item)}>
<Text className={classnames(styles.miconfont_left, 'iconfont icon-a-moreback', item.openStatus?styles.miconfont_open:styles.miconfont_close)}></Text>
<View className={styles.title}>{item.name}
{item.product_color_list&&<><Text className={styles.fg}>·</Text><Text className={styles.num}>{item.product_color_list.length}</Text></>}
</View>
<View className={styles.more} onClick={(e) => moreUpdate(item,e)}></View>
</View>
<View className={styles.class_con} style={item.openStatus?{maxHeight: 10*260 + 'rpx'}:{maxHeight: 0}} >
<Product productList={item.product_color_list||[]}/>
</View>
</View>)}
</View>
<UpdatePopup show={updateShow} onClose={closeUpdate} onDelete={onDeleteCollect} onUpdate={onUpdateShow} onBatchManagement={onBatchManagement}/>
<CreatePopup defaultValue={initData} show={collectioinShow} onClose={closeCollection} onSuccess={onCreatSuccess}/>
</View>
)
}

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '公司资料',
enableShareAppMessage: true,
}

View File

@ -1,44 +0,0 @@
.company{
display: flex;
flex-direction: column;
.save-button{
width: 668px;
height: 82px;
background: #007aff;
border-radius: 40px;
font-size: 32px;
font-weight: 400;
color: #ffffff;
display: flex;align-items: center;justify-content: center;
margin: 320px auto 0;
}
.form-radio{
display: flex;
flex-wrap: wrap;align-items: center;
}
.form-radio view{
height: 54px;
background: #f0f0f0;
border-radius: 28px;
font-size: 24px;
font-weight: 400;
color: #707070;
padding: 10px 28px;
box-sizing: border-box;
display: flex;align-items: center;justify-content: center;
margin: 10px;
border: 2px solid #f0f0f0;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
}
.form-radio .form-radio-active{
background: #ecf5ff;
border: 2px solid #cde5ff;
}
}

View File

@ -1,150 +0,0 @@
import Address from "@/components/address"
import FromList from "@/components/FromList"
import { Button, Input, Text, Textarea, View } from "@tarojs/components"
import Taro, { getCurrentPages, useRouter } from "@tarojs/taro"
import { useEffect, useState } from "react"
import { alert, retrieval } from "@/common/common";
import { companyDetailApi, companyUpdateApi } from "@/api/company"
import "./index.scss"
import useLogin from "@/use/useLogin"
export default ()=>{
useLogin()
const [showSiteModal, setShowSiteModal] = useState(false);
const handleSelectSite = ()=>{
setShowSiteModal(true);
}
// 获取公司信息
const {fetchData: getFromData} = companyDetailApi();
const getData = async ()=>{
const result = await getFromData();
console.log(result.data,"===");
setFormData({
...result.data,
});
}
useEffect(()=>{
getData();
},[])
// 保存
const [formData, setFormData] = useState({
address_detail: "",
city_id: 0,
company_id: 0,
company_long_name: "",
company_name: "",
company_type: [
0
],
director: "",
district_id: 0,
phone: "",
province_id: 0,
site:"",
siteArray: []
})
const rules = {
company_name: [{
message: "请输入公司名称"
}],
company_long_name: [{
message: "请输入公司全称"
}],
director: [{
message: "请输入联系人"
}],
phone: [{
message: "请输入正确的电话号码", regex: /^1[3|5|6|9|2|8|7]\d{9}$/
}],
district_id: [{
message: "请选择地址"
}],
address_detail: [{
message: "请输入详细地址"
}],
}
const {fetchData: saveFetch} = companyUpdateApi();
const handleSave = ()=>{
retrieval(formData, rules).then(async ()=>{
const result = await saveFetch({
address_detail: formData.address_detail,
city_id: formData.city_id,
company_id: formData.company_id,
company_long_name: formData.company_long_name,
company_name: formData.company_name,
company_type: formData.company_type,
director: formData.director,
district_id: formData.district_id,
phone: formData.phone,
province_id: formData.province_id
});
if(result.success){
Taro.eventCenter.trigger('company:detail')
Taro.navigateBack();
alert.success("保存成功");
}else{
alert.error(result.msg);
}
}).catch(message=>{
alert.none(message)
})
Taro.navigateBack();
}
// 单选
const radioData = ['布行','二批','制衣厂'];
const [radioActive, setRadioActive] = useState(0);
const handleActiveRadio = (index:number)=>{
setRadioActive(index);
}
// 设置选择地址
const handleSetSite = (ev:any)=>{
if(ev.length>=3){
setFormData({
...formData,
siteArray: ev,
site: ev.map(item=>item.name+" "),
province_id: ev[0]?.id,
city_id: ev[1]?.id,
district_id: ev[ev.length-1]?.id,
})
}else{
alert.error("请选择完整地址");
}
}
// 监听表单完善
const [hozon, setHozon] = useState(false);
useEffect(()=>{
if(retrieval){
retrieval(formData).then(()=>setHozon(true)).catch(()=>setHozon(false))
}
},[formData])
return (
<View className="company">
<FromList onInput={(ev:any)=>setFormData({...formData,company_name:ev.detail.value})} value={formData["company_name"]} label="公司名称" placeholder="请输入公司名称"/>
<FromList onInput={(ev:any)=>setFormData({...formData,company_long_name:ev.detail.value})} value={formData["company_long_name"]} label="公司全称" placeholder="请输入公司全称"/>
<FromList value={formData["company_type"]} label="公司类型">
<View className="form-radio">
{
radioData.map((item,index)=>{
return <View onClick={()=>handleActiveRadio(index)} className={radioActive==index?'form-radio-active':''} key={index}>{item}</View>
})
}
</View>
</FromList>
<FromList onInput={(ev:any)=>setFormData({...formData,director:ev.detail.value})} value={formData["director"]} label="联系人" placeholder="请输入联系人"/>
<FromList onInput={(ev:any)=>setFormData({...formData,phone:ev.detail.value})} value={formData["phone"]} label="联系方式" placeholder="请输入联系方式"/>
<FromList value={formData["site"]} onClick={handleSelectSite} label="收货地址" type="select" placeholder="请选择/省/市/区"/>
<FromList onInput={(ev:any)=>setFormData({...formData,address_detail:ev.detail.value})} value={formData["address_detail"]} label="详细地址" type="textarea" placeholder="请输入详细地址(街道、门牌号等)"/>
<Button style={{"background": hozon?'#007aff':''}} hoverClass="none" className="save-button" onClick={handleSave}></Button>
{/* <Address addressOnClose={()=>setShowSiteModal(false)} show={showSiteModal}/> */}
<Address addressOnSelect={handleSetSite} defaultValue={[ {name: "广东省", id: 193, level: 2}, {name: "佛山市", id: 202, level:3}, {name: "高明区", id: 204, level:4}]} addressOnClose={()=>setShowSiteModal(false)} show={showSiteModal}/>
</View>
)
}

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '授信额度',
enableShareAppMessage: true,
}

View File

@ -1,92 +0,0 @@
.credit-line{
height: 100vh;
background-color: #f3f3f3;
canvas{
width: 238px;
height: 238px;
}
.credit-line-card{
width: 702px;
background: #ffffff;
border-radius: 20px;
margin: 20px auto 0;
padding: 0 30px;
box-sizing: border-box;
}
.credit-line-card-top{
display: flex;align-items: flex-end;
padding: 30px 20px;
border-bottom: 1px solid #f6f6f6;
position: relative;
}
.credit-line-card-top-info{
text-align: center;
flex: 1;
}
.credit-line-card-top-info-title{
font-size: 24px;
font-weight: 700;
color: #000000;
margin-bottom: 16px;
}
.credit-line-card-top-info-price{
font-size: 44px;
font-weight: 700;
color: #007aff;
margin-bottom: 48px;
}
.credit-line-card-top-info-price text{
font-size: 20px;
}
.credit-line-card-top-info-date{
font-size: 22px;
font-weight: 400;
color: #ababab;
}
.credit-line-card-top-status{
padding: 0 20px;
height: 38px;
background: #ebfaea;
font-size: 22px;
font-weight: 400;
color: #07c160;
display: flex;align-items: center;justify-content: center;
border-top-right-radius: 20px;
border-bottom-left-radius: 20px;
position: absolute;right: 0;top: 30px;
}
.credit-line-card-bottom{
padding: 30px 0;
display: grid;
grid-template-columns: repeat(2, 1fr);
text-align: center;
}
.credit-line-card-bottom-item-title{
font-size: 24px;
font-weight: 700;
color: #000000;
display: flex;
align-items: center;justify-content: center;
margin-bottom: 15px;
line-height: 38px;
}
.credit-line-card-bottom-item-title text{
font-size: 40px;
margin-right: 10px;
color: #007AFF;
}
.credit-line-card-bottom-item-title .miconfont{
color: #ccc;
}
.credit-line-card-bottom-item:nth-child(2) .credit-line-card-bottom-item-title text{
font-size: 28px;
}
.credit-line-card-bottom-item-price{
font-size: 40px;
font-weight: 400;
color: #ababab;
}
.credit-line-card-bottom-item-price text{
font-size: 20px;
}
}

View File

@ -1,252 +0,0 @@
import AddressList from "@/components/AddressList"
import { Button, Canvas, Navigator, ScrollView, Text, View } from "@tarojs/components"
import Taro, { useReady } from "@tarojs/taro"
import { useEffect, useState } from "react"
import {creditInfoApi} from "@/api/creditLine"
import "./index.scss"
import { useSelector } from "@/reducers/hooks";
import { formatDateTime, formatPriceDiv } from "@/common/fotmat"
import Message from "@/components/Message"
import useLogin from "@/use/useLogin"
export default ()=>{
useLogin()
const userInfo = useSelector(state => state.userInfo);
useEffect(()=>{
getData()
}, [])
const {fetchData, state} = creditInfoApi();
const [data, setData] = useState({
credit_quota_used_line: [0,"00"],
credit_quota_line: [0,"00"],
credit_quota_available_line: [0,"00"],
progress: 0,
create_time: "",
quota_status_name: "",
quota_status: "",
credit_quota_start_time: "",
credit_quota_end_time: ""
});
const [style, setStyle]= useState({
type: {},
cir: {
color: "",
background: {start: [], end: []}
},
available: {},
bottomTitle: {}
});
// 获取数据
const getData = async ()=>{
const result = await fetchData();
const credit_quota_used_line = convertPrice(formatPriceDiv(result.data.credit_quota_used_line));
const credit_quota_line = convertPrice(formatPriceDiv(result.data.credit_quota_line));
const credit_quota_available_line = convertPrice(formatPriceDiv(result.data.credit_quota_available_line));
const progress = credit_quota_available_line[0]==0&&credit_quota_line[0]==0?100:((credit_quota_available_line[0]??0) / (credit_quota_line[0]??0) * 100).toFixed(0);
switch(Number(result.data.quota_status)){
case 0://暂未开通
setStyle({
type: {background: "#e4e4ff",color: "#1818B4" },
cir: {
color: "#707070",
background: {start: ["#727272", "#CDCDCD"] as any, end: ["#CDCDCD", "#EEEEEE"] as any}
},
available: {color: "#707070", textDecoration: "line-through"},
bottomTitle: {color: "#cccccc"}
})
break;
case 1://申请中
setStyle({
type: {background: "#cde5ff",color: "#007AFF" },
cir: {
color: "#707070",
background: {start: ["#727272", "#CDCDCD"] as any, end: ["#CDCDCD", "#EEEEEE"] as any}
},
available: {color: "#707070", textDecoration: "line-through"},
bottomTitle: {color: "#cccccc"}
})
break;
case 2://生效中
setStyle({
type: {background: "#cde5ff",color: "#007AFF" },
cir: {
color: "#007aff",
background: {start: ["#047CFF", "#51A4FF"] as any, end: ["#87C0FF", "#57A8FF"] as any}
},
available: {color: "#007aff"},
bottomTitle: {color: "#007AFF"}
})
break;
case 3://已失效
setStyle({
type: {background: "#f6f6f6",color: "#ABABAB" },
cir: {
color: "#707070",
background: {start: ["#727272", "#CDCDCD"] as any, end: ["#CDCDCD", "#EEEEEE"] as any}
},
available: {color: "#707070", textDecoration: "line-through"},
bottomTitle: {color: "#cccccc"}
})
break;
case 4://失效待还款
setStyle({
type: {background: "#FFE6CE",color: "#EE7500" },
cir: {
color: "#707070",
background: {start: ["#EF7907", "#FAC897"] as any, end: ["#FAC897", "#FFE6CE"] as any}
},
available: {color: "#EE7500"},
bottomTitle: {color: "#007AFF"}
})
break;
}
setData({
...result.data,
progress,
credit_quota_used_line,
credit_quota_line,
credit_quota_available_line,
credit_quota_start_time: formatDateTime(result.data?.credit_quota_start_time, "YYYY-MM-DD"),
credit_quota_end_time: formatDateTime(result.data?.credit_quota_end_time, "YYYY-MM-DD"),
})
}
const convertPrice = (data)=>{
var t = data.toString().split(".");
t[1] = t[1]?t[1].padEnd(2,0):"00";
return t;
}
return (
<View className="credit-line">
<Message text="暂不支持线上申请授权,请联系平台客服。"/>
<View className="credit-line-card">
<View className="credit-line-card-top">
<View><Progress progress={data.progress} style={style} /></View>
<View className="credit-line-card-top-info">
<View className="credit-line-card-top-info-title"></View>
<View className="credit-line-card-top-info-price" style={style.available}><Text>¥</Text>{Number(data.credit_quota_available_line[0])?.toLocaleString()}<Text>.{data.credit_quota_available_line[1]}</Text></View>
<View className="credit-line-card-top-info-date">: {data?.credit_quota_start_time} {data?.credit_quota_end_time}</View>
</View>
<View className="credit-line-card-top-status" style={style.type}>{data.quota_status_name}</View>
</View>
<View className="credit-line-card-bottom">
<View className="credit-line-card-bottom-item">
<View className="credit-line-card-bottom-item-title">
<Text style={style.bottomTitle} className="iconfont icon-yucunkuan"></Text>
<View></View>
</View>
<View className="credit-line-card-bottom-item-price"><Text>¥</Text>{Number(data.credit_quota_line[0])?.toLocaleString()}<Text>.{data.credit_quota_line[1]}</Text></View>
</View>
<Navigator hoverClass="none" url="/pages/creditUsed/index" className="credit-line-card-bottom-item">
<View className="credit-line-card-bottom-item-title">
<Text style={style.bottomTitle} className="iconfont icon-tick-pressed"></Text>
<View></View>
<Text className="iconfont icon-a-moreback miconfont"></Text>
</View>
<View className="credit-line-card-bottom-item-price"><Text>¥</Text>{Number(data?.credit_quota_used_line[0])?.toLocaleString()}<Text>.{data.credit_quota_used_line[1]}</Text></View>
</Navigator>
</View>
</View>
</View>
)
}
const Progress = (props)=>{
useEffect(()=>{
if(props.progress!=0){
getCanvas();
}
},[props.progress])
const getCanvas = ()=>{
// const percentage = props.progress??0;
const percentage = props.progress||0;
const query = Taro.createSelectorQuery();
query.select("#myCanvas").fields({ node: true, size: true }).exec((res) => {
const canvas = res[0]?.node;
if(canvas){
const ctx = canvas.getContext('2d');
const { windowHeight, windowWidth } = Taro.getSystemInfoSync();
const dpr = 750 / windowWidth;
canvas.width = res[0].width * dpr;
canvas.height = res[0].height * dpr;
const r = canvas.width / 2;
ctx.translate(r,r);
// 白色大圆
ctx.beginPath();
ctx.fillStyle = "white";
ctx.shadowBlur = 20;
ctx.shadowColor = "#cde5ff";
ctx.arc(0,0,100,0,2*Math.PI, false);
ctx.fill();
// 刻度
const my_minute = Math.PI*2/60;
const my_second = Math.PI*2/60;
ctx.strokeStyle="#F59F5D";
ctx.lineWidth=2;
ctx.beginPath();
for(let i=0;i<15;i++){
ctx.save();
ctx.rotate(i*4*my_minute);
ctx.moveTo(r-45,0);
ctx.lineTo(r-40,0);
ctx.stroke();
ctx.restore();
}
// 白色小圆
ctx.beginPath();
ctx.fillStyle = "white";
ctx.shadowBlur = 20;
ctx.shadowColor = "rgba(204,204,204,0.50)";
ctx.arc(0,0,74,0,2*Math.PI, false);
ctx.fill();
// 文字
ctx.beginPath();
ctx.restore();
ctx.fillStyle = props.style?.cir?.color// "#007aff";
ctx.font="42px Cambria, Cambria-Bold";
ctx.textAlign="center";
ctx.textBaseline="middle";
ctx.fillText(percentage+"%", 0,0);
// 蓝色的圆
if(percentage>0){
ctx.beginPath();
ctx.lineWidth = 25;
ctx.lineCap = "round";
const gad = ctx.createLinearGradient(100,0,0,100);
gad.addColorStop(0, props.style?.cir?.background?.start[0]);
gad.addColorStop(1, props.style?.cir?.background?.start[1]);
ctx.strokeStyle = gad;
ctx.arc(0,0,104,-Math.PI*0.5,2*Math.PI/100*((percentage<50?percentage:50)-25), false);
ctx.stroke();
}
if(percentage>50){
ctx.beginPath();
const gad2 = ctx.createLinearGradient(0,-100,0,0);
gad2.addColorStop(0, props.style?.cir?.background?.end[0]);
gad2.addColorStop(1, props.style?.cir?.background?.start[1]);
ctx.strokeStyle = gad2;
ctx.arc(0,0,104,Math.PI*0.4,2*Math.PI/100*(percentage-25), false);
ctx.stroke();
}
}else{
getCanvas();
}
});
}
useReady(()=>{
getCanvas();
})
return <Canvas type="2d" id="myCanvas"/>
}

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '已用额度',
enableShareAppMessage: true,
}

View File

@ -1,44 +0,0 @@
.credit-used{
height: 100vh;
background-color: #f3f3f3;
.credit-used-list{
background-color: white;
padding: 30px 25px;
border-bottom: 1px solid #f6f6f6;
}
.credit-used-list-top{
display: flex;justify-content: space-between;
margin-bottom: 20px;
}
.credit-used-list-type{
font-size: 26px;
font-weight: 400;
color: #000000;
}
.credit-used-list-price{
font-size: 28px;
font-weight: 400;
}
.credit-used-list-price-add{
color: red;
}
.credit-used-list-bottom{
display: flex;justify-content: space-between;
}
.credit-used-list-date{
font-size: 24px;
font-weight: 400;
color: #ababab;
}
.credit-used-list-orderno{
font-size: 20px;
font-weight: 400;
color: #ababab;
}
.green{
color: #07C160;
}
.red{
color: #FF0000;
}
}

View File

@ -1,175 +0,0 @@
import InfiniteScrollPaging from "@/components/InfiniteScrollPaging"
import { Button, Canvas, ScrollView, Text, View } from "@tarojs/components"
import Taro, { useReady } from "@tarojs/taro"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import {creditListApi} from "@/api/creditLine"
import "./index.scss"
import classnames from "classnames";
import { formatDateTime, formatPriceDiv, toDecimal2 } from "@/common/fotmat"
import { dataLoadingStatus, getFilterData } from "@/common/util";
import useLogin from "@/use/useLogin"
export default ()=>{
useLogin()
const {fetchData, state} = creditListApi();
// 渲染(数据)
const [data, setData] = useState({
list: [],
total: 0
});
const handleChange = useCallback((result)=>{
setData({
list: result.data.list,
total: result.data.total
})
}, [])
return (
<View className="credit-used">
<InfiniteScrollPaging fetchData={fetchData} change={handleChange}>
{
(data as any)?.list?.map((item,index)=>{
return (
<View key={index} className="credit-used-list">
<View className="credit-used-list-top">
<View className="credit-used-list-type">{item.quota_order_status_name}</View>
<View className={classnames(`credit-used-list-price`, item.trans_type==1?`credit-used-list-price-add`:`green`)}>
{item.trans_type==2?"-":"+"}{toDecimal2(formatPriceDiv(item.amount)).toLocaleString()}
</View>
</View>
<View className="credit-used-list-bottom">
<View className="credit-used-list-date">{formatDateTime(item.order_pay_time)}</View>
<View className="credit-used-list-orderno">{item.order_no}</View>
</View>
</View>
)
})
}
{/* {data.length>0&&<View className="credit-used-list"></View>} */}
<View className="credit-used-list"></View>
</InfiniteScrollPaging>
</View>
)
}
// export default ()=>{
// useEffect(()=>{
// refreshDataRef.current = refreshData;
// dataRef.current = data;
// getData({
// moreStatus: true
// },{
// moreStatus: true
// });
// }, [])
// const {fetchData, state} = creditListApi();
// const getData = async (startStatus, endStatus)=>{
// const tRefreshDataRef = refreshDataRef.current as any;
// setRefreshData({
// ...tRefreshDataRef,
// ...startStatus
// })
// const result = await fetchData({
// page: tRefreshDataRef.page,
// size: tRefreshDataRef.size,
// });
// if(result.success){
// if(result.data.total<=0){
// setRefreshData({
// ...tRefreshDataRef,
// ...endStatus
// })
// }else{
// setData({
// list: result.data.list,
// // list: tRefreshDataRef.page>1?(dataRef.current as any).list.concat(result.data.list):result.data.list,
// total: result.data.total
// })
// setRefreshData({
// ...tRefreshDataRef,
// refreshStatus: false,
// moreStatus: false
// })
// }
// }
// }
// // 加载刷新数据
// const [refreshData, setRefreshData] = useState({
// refreshStatus: false,
// moreStatus: false,
// page: 1,
// size: 10
// })
// const refreshDataRef = useRef({});
// // 渲染(数据)
// const [data, setData] = useState({
// list: [],
// total: 0
// });
// const dataRef = useRef({});
// // 下拉刷新
// const handleRefresh = async ()=>{
// let tRefreshData = refreshDataRef.current as any;
// setRefreshData({
// ...tRefreshData,
// page: 1,
// size: 10,
// })
// getData({
// refreshStatus: true,
// moreStatus: false
// },{
// refreshStatus: false,
// moreStatus: true
// });
// }
// // 加载更多
// const handleMoreLoad = async ()=>{
// let t = (dataRef.current as any);
// let tRefreshData = refreshDataRef.current as any;
// if(t.list.length<t.total){
// setRefreshData({
// ...tRefreshData,
// page: ++tRefreshData.page,
// size: ++tRefreshData.page*tRefreshData.size,
// })
// getData({
// moreStatus: true
// },{
// moreStatus: true
// });
// }
// }
// //数据加载状态
// const statusMore = useMemo(() => {
// return dataLoadingStatus({list:data.list, total: data.total, status: refreshData.moreStatus})
// }, [data])
// return (
// <View className="credit-used">
// <InfiniteScroll refresherEnabled={true} refresherTriggered={refreshData.refreshStatus} moreStatus={refreshData.moreStatus}
// selfOnRefresherRefresh={handleRefresh} selfonScrollToLower={handleMoreLoad} statusMore={statusMore}>
// {
// (data as any)?.list?.map((item,index)=>{
// return (
// <View key={index} className="credit-used-list">
// <View className="credit-used-list-top">
// <View className="credit-used-list-type">下单</View>
// <View className={`credit-used-list-price ${item.amount>0?'green':item.amount<0?'red':''}`}>{item.amount.toLocaleString()}</View>
// </View>
// <View className="credit-used-list-bottom">
// <View className="credit-used-list-date">{formatDateTime(item.order_pay_time)}</View>
// <View className="credit-used-list-orderno">订单号:{item.order_no}</View>
// </View>
// </View>
// )
// })
// }
// {/* {data.length>0&&<View className="credit-used-list"></View>} */}
// <View className="credit-used-list"></View>
// </InfiniteScroll>
// </View>
// )
// }

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '预存款',
enableShareAppMessage: true,
}

View File

@ -1,88 +0,0 @@
.deposit-beforehand{
height: 100vh;
background-color: #f3f3f3;
display: flex;
flex-direction: column;
.deposit-beforehand-card{
width: 702px;
background: #ffffff;
border-radius: 20px;
margin: 30px auto;
padding: 30px;
box-sizing: border-box;
}
.deposit-beforehand-balance{
display: flex;flex-direction: column;align-items: center;
}
.deposit-beforehand-balance-title{
font-size: 28px;
font-weight: 400;
color: #000000;
margin-bottom: 35px;
}
.deposit-beforehand-balance-price{
font-size: 40px;
font-weight: 700;
color: #000000;
margin-bottom: 70px;
}
.deposit-beforehand-balance-button{
width: 276px;
height: 74px;
background: #007aff;
border-radius: 38px;
display: flex;align-items: center;justify-content: center;
color: white;
margin-bottom: 10px;
}
.deposit-beforehand-info-title{
display: flex;justify-content: space-between;
margin-bottom: 50px;
}
.deposit-beforehand-info-title-left{
font-size: 28px;
font-weight: 700;
color: #000000;
}
.deposit-beforehand-info-title-copy{
font-size: 24px;
font-weight: 400;
color: #007aff;
}
.deposit-beforehand-info-list{
display: flex;align-items: center;
margin-bottom: 38px;
}
.deposit-beforehand-info-list-left{
width: 160px;
font-size: 24px;
font-weight: 400;
color: #3c3c3c;
border-right: 1px solid #dddddd;
margin-right: 25px;
}
.deposit-beforehand-info-list-right{
font-size: 26px;
font-weight: 400;
color: #000000;
}
.deposit-beforehand-particulars{
display: flex;align-items: center;justify-content: space-between;
}
.deposit-beforehand-particulars-left{
font-size: 28px;
font-weight: 700;
color: #000000;
}
.deposit-beforehand-particulars-right{
font-size: 24px;
font-weight: 400;
color: #ababab;
}
.deposit-beforehand-particulars-right text{
font-size: 28px;
}
}

View File

@ -1,69 +0,0 @@
import { Button, Canvas, Navigator, ScrollView, Text, View } from "@tarojs/components"
import "./index.scss"
import { depositInfoApi } from "@/api/deposit"
import { useEffect } from "react";
import { formatPriceDiv, toDecimal2 } from "@/common/fotmat";
import { setClipboardData } from "@tarojs/taro";
import Message from "@/components/Message";
import useLogin from "@/use/useLogin";
export default ()=>{
useLogin()
const {fetchData, state} = depositInfoApi();
const getData = async ()=>{
fetchData();
}
useEffect(() => {
getData();
}, []);
// 复制
const handleCopy = ()=>{
setClipboardData({data: state.data?.transfer_remittance_account})
}
return (
<View className="deposit-beforehand">
<Message text="汇款成功后1-5分钟自动到账。"/>
<View className="deposit-beforehand-card">
<View className="deposit-beforehand-balance">
<View className="deposit-beforehand-balance-title"> ()</View>
<Text className="deposit-beforehand-balance-price">{toDecimal2(formatPriceDiv(state.data?.amount)).toLocaleString()}</Text>
<View className="deposit-beforehand-balance-button"></View>
</View>
</View>
<View className="deposit-beforehand-card">
<View className="deposit-beforehand-info">
<View className="deposit-beforehand-info-title">
<View className="deposit-beforehand-info-title-left"><Text></Text> </View>
<View className="deposit-beforehand-info-title-copy" onClick={handleCopy}></View>
</View>
<View className="deposit-beforehand-info-content">
<View className="deposit-beforehand-info-list">
<View className="deposit-beforehand-info-list-left"></View>
<View className="deposit-beforehand-info-list-right">{state.data?.account_name}</View>
</View>
<View className="deposit-beforehand-info-list">
<View className="deposit-beforehand-info-list-left"></View>
<View className="deposit-beforehand-info-list-right">{state.data?.bank_of_deposit}</View>
</View>
<View className="deposit-beforehand-info-list">
<View className="deposit-beforehand-info-list-left"></View>
<View className="deposit-beforehand-info-list-right">{state.data?.transfer_remittance_account}</View>
</View>
</View>
</View>
</View>
<View className="deposit-beforehand-card">
<View className="deposit-beforehand-particulars">
<View className="deposit-beforehand-particulars-left"></View>
<Navigator hoverClass="none" url="/pages/depositList/index" className="deposit-beforehand-particulars-right">
<Text className="iconfont icon-a-moreback"></Text>
</Navigator>
</View>
</View>
</View>
)
}

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '交易详情',
enableShareAppMessage: true,
}

View File

@ -1,156 +0,0 @@
.deposit-detail{
// height: 100vh;
// background-color: #f3f3f3;
.deposit-detail-tips{
width: 100%;
height: 66px;
background: #FFE6CE;
border: 2px solid #ffe6ce;
padding: 0 30px;
display: flex;align-items: center;
font-size: 24px;
font-weight: 400;
color: #EE7500;
margin: 0;
}
.deposit-detail-tips text{
margin-right: 10px;
font-size: 30px;
}
&>view{
padding: 30px 0;
margin: 0 25px;
border-bottom: 1px solid #F6F6F6;
}
&>view:last-child{
border-bottom: 0;
}
.deposit-amount{
text-align: center;
}
.deposit-type{
font-size: 28px;
font-weight: 400;
color: #000000;
margin-bottom: 35px;
}
.deposit-price{
font-size: 40px;
font-weight: 700;
color: #000000;
}
.deposit-status{
display: flex;
}
.deposit-status-title{
font-size: 24px;
font-weight: 400;
color: #707070;
margin-right: 105px;
}
.deposit-voucher-title{
font-size: 24px;
font-weight: 400;
color: #707070;
margin-bottom: 28px;
}
.deposit-voucher-title::before{
content: "*";
color: #007AFF;
}
.deposit-voucher-content{
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 30px;
height: 98px;
}
.deposit-voucher-content image{
width: 100%;
height: 100%;
object-fit: cover;
}
.deposit-info-list{
display: flex;
margin-bottom: 20px;
}
.deposit-info-list-title{
width: 140px;
font-size: 24px;
font-weight: 400;
color: #707070;
border-right: 1px solid #F0F0F0;
}
.deposit-info-list-content{
width: 468px;
font-size: 24px;
font-weight: 400;
color: #000000;
padding-left: 25px;
box-sizing: border-box;
}
.deposit-info-list-copy{
font-size: 20px;
font-weight: 400;
color: #ababab;
padding-left: 18px;
border-left: 1px solid #F0F0F0;
}
.deposit-timeline{
}
.deposit-timeline-item{
display: flex;
margin-left: 50px;
height: 100px;
}
.deposit-timeline-item-title{
font-size: 24px;
font-weight: 400;
color: #3c3c3c;
}
.deposit-timeline-item-date{
font-size: 24px;
font-weight: 400;
color: #ababab;
}
.deposit-timeline-item-left{
position: relative;
margin-right: 55px;
width: 12px;
}
.deposit-timeline-item-left::before{
content: " ";
width: 12px;
height: 12px;
background: #007aff;
border-radius: 50%;
display: block;
margin-top: 10px;
}
.deposit-timeline-item-left::after{
content: " ";
border-right: 1px dashed #007aff;
position: absolute;top: 25px;bottom: -8px;
left: 50%;transform: translateX(-50%);
}
.deposit-timeline-item-success,.deposit-timeline-item-error{
position: relative;
margin-right: 55px;
width: 12px;
}
.deposit-timeline-item-error Text,.deposit-timeline-item-success Text{
display: inline-block;
width: 38px;
height: 38px;
background: #007aff;
border-radius: 50%;
position: absolute;left: 50%;transform: translateX(-50%);
color: white;
font-size: 30px;
display: flex;align-items: center;justify-content: center;
}
.deposit-timeline-item-error Text{
background: #cccccc;
}
}

View File

@ -1,87 +0,0 @@
import AddressList from "@/components/AddressList"
import InfiniteScroll from "@/components/infiniteScroll"
import { Button, Canvas, Image, ScrollView, Text, View } from "@tarojs/components"
import Taro, { useReady } from "@tarojs/taro"
import { useEffect, useState } from "react"
import {creditListApi} from "@/api/creditLine"
import "./index.scss"
import useLogin from "@/use/useLogin"
export default ()=>{
useLogin()
return (
<View className="deposit-detail">
<View className="deposit-detail-tips">
<Text className="iconfont icon-zhuyi"></Text>
</View>
<View className="deposit-amount">
<View className="deposit-type"> ()</View>
<View className="deposit-price">999,999.20</View>
</View>
<View className="deposit-status">
<View className="deposit-status-title"></View>
<TimeLine/>
</View>
<View className="deposit-voucher">
<View className="deposit-voucher-title"></View>
<View className="deposit-voucher-content">
<Image src="https://seopic.699pic.com/photo/40216/8643.jpg_wh1200.jpg"/>
<Image src="https://seopic.699pic.com/photo/40216/8643.jpg_wh1200.jpg"/>
</View>
</View>
<View className="deposit-info">
<View className="deposit-info-list">
<View className="deposit-info-list-title"></View>
<View className="deposit-info-list-content">2278204399678121212121288</View>
<View className="deposit-info-list-copy"></View>
</View>
<View className="deposit-info-list">
<View className="deposit-info-list-title"></View>
<View className="deposit-info-list-content"></View>
</View>
<View className="deposit-info-list">
<View className="deposit-info-list-title"></View>
<View className="deposit-info-list-content"></View>
<View className="deposit-info-list-copy"></View>
</View>
<View className="deposit-info-list">
<View className="deposit-info-list-title"></View>
<View className="deposit-info-list-content"></View>
</View>
<View className="deposit-info-list">
<View className="deposit-info-list-title"></View>
<View className="deposit-info-list-content"></View>
</View>
</View>
</View>
)
}
const TimeLine = ()=>{
return(
<View className="deposit-timeline">
<View className="deposit-timeline-item">
<View className="deposit-timeline-item-left"></View>
<View className="deposit-timeline-item-right">
<View className="deposit-timeline-item-title"></View>
<View className="deposit-timeline-item-date">2022-04-24 16:10:11</View>
</View>
</View>
<View className="deposit-timeline-item">
<View className="deposit-timeline-item-left"></View>
<View className="deposit-timeline-item-right">
<View className="deposit-timeline-item-title"></View>
</View>
</View>
<View className="deposit-timeline-item">
<View className="deposit-timeline-item-success">
<Text className="iconfont icon-tick" />
</View>
<View className="deposit-timeline-item-right">
<View className="deposit-timeline-item-title"></View>
<View className="deposit-timeline-item-date">2022-04-24 16:10:11</View>
</View>
</View>
</View>)
}

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '收支明细',
enableShareAppMessage: true,
}

View File

@ -1,49 +0,0 @@
.credit-used{
height: 100vh;
background-color: #f3f3f3;
.credit-used-list{
background-color: white;
padding: 30px 25px;
border-bottom: 1px solid #f6f6f6;
display: flex;justify-content: space-between;
}
.credit-used-list-left{
}
.credit-used-list-type{
font-size: 26px;
font-weight: 400;
color: #000000;
margin-bottom: 20px;
}
.credit-used-list-price{
font-size: 28px;
font-weight: 400;
}
.credit-used-list-right{
display: flex;align-items: center;
}
.credit-used-list-right-price view{
display: flex;align-items: center;
}
.credit-used-list-right text{
font-size: 30px;
margin-left: 10px;
}
.credit-used-list-date{
font-size: 24px;
font-weight: 400;
color: #ababab;
}
.credit-used-list-orderno{
font-size: 20px;
font-weight: 400;
margin-top: 20px;
color: #ababab;
}
.green{
color: #07C160;
}
.red{
color: #FF0000;
}
}

View File

@ -1,59 +0,0 @@
import AddressList from '@/components/AddressList'
import InfiniteScrollPaging from '@/components/InfiniteScrollPaging'
import { Button, Canvas, ScrollView, Text, View } from '@tarojs/components'
import Taro, { useReady } from '@tarojs/taro'
import { useCallback, useEffect, useState } from 'react'
import { depositListApi } from '@/api/deposit'
import './index.scss'
import { formatDateTime, formatPriceDiv } from '@/common/fotmat'
import useLogin from '@/use/useLogin'
export default () => {
useLogin()
const { fetchData, state } = depositListApi()
// 渲染(数据)
const [data, setData] = useState({
list: [],
total: 0,
})
// 数据更新
const handleChange = useCallback((result) => {
setData({
list: result.data.list,
total: result.data.total,
})
}, [])
return (
<View className='credit-used'>
<InfiniteScrollPaging fetchData={fetchData} change={handleChange}>
{data.list?.map((item, index) => {
let res: any = item
return (
res.amount_received_this_time != 0 && (
<View key={index} className='credit-used-list'>
<View className='credit-used-list-left'>
<View className='credit-used-list-type'>{res.type_name}</View>
<View className='credit-used-list-date'>{formatDateTime(res.create_time)}</View>
</View>
<View className='credit-used-list-right'>
<View className='credit-used-list-right-price'>
<View
className={`credit-used-list-price ${[1, 2, 3].includes(res.type as never) ? 'red' : 'green'}`}>
{[1, 2, 3].includes(res.type as never) ? '+' : '-'}
{formatPriceDiv(res.amount_received_this_time)}
</View>
{/* <View className="credit-used-list-orderno">处理中</View> */}
</View>
<Text className='iconfont icon-a-moreback'></Text>
</View>
</View>
)
)
})}
{/* {data.length>0&&<View className="credit-used-list"></View>} */}
<View className='credit-used-list'></View>
</InfiniteScrollPaging>
</View>
)
}

View File

@ -1,46 +0,0 @@
.main{
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
.plus{
color: $color_main;
width: 46px;
height: 46px;
text-align: center;
line-height: 43px;
font-size: 50px;
background-color: $color_main;
color: #fff;
border-radius: 8px;
}
.reduce {
font-size: 50px;
width: 46px;
height: 46px;
text-align: center;
line-height: 43px;
color:#007AFF;
}
.input{
display: flex;
align-items: flex-end;
background-color: #fff;
padding: 5px 10px;
box-sizing: border-box;
width: 106px;
border-radius: 10px;
input{
font-size: $font_size_medium;
text-align: right;
padding-right: 10px;
}
}
.unit{
font-size: $font_size_min;
color: $color_font_two;
}
}

View File

@ -1,113 +0,0 @@
import { Input, View } from "@tarojs/components"
import { useEffect, useMemo, useRef, useState } from "react"
import Big from 'big.js'
import styles from "./index.module.scss"
type params = {
minNum?: number, //最小值
maxNum?: number, //最大值
step?: number, //步长
defaultNum?: number, //默认值
digits?: number //多少位小数
onChange?:(val: number, obj?: any) => void,
onBlue?:(val:number, obj?: any) => void, //失去焦点触发
onClickBtn?:(val:number, obj?: any) => void,
unit?: string,
otherData?: any
}
export default ({minNum = 0, maxNum = 100, step=1, digits = 0, defaultNum = 0, onChange, onBlue, onClickBtn, unit = '', otherData}: params) => {
const [value, setValue] = useState<any>({count:defaultNum})
const onPlus = () => {
let {count} = value
let num_res = Big(count).add(step).toNumber()
num_res = num_res >= maxNum?maxNum:num_res
num_res = formatDigits(num_res)
setValue({...value, count:num_res})
onChange?.(parseFloat(num_res), otherData)
onClickBtn?.(parseFloat(num_res), otherData)
}
const minus = () => {
let {count} = value
let num_res = Big(count).minus(step).toNumber()
num_res = num_res < minNum?0:num_res
setValue({...value, count:num_res})
onChange?.(parseFloat(num_res), otherData)
onClickBtn?.(parseFloat(num_res), otherData)
}
//保留小数
const formatDigits = (num) => {
num = num + ''
if(num.includes('.')&&digits > 0) {
console.log('num::',num.includes('.'))
let res = num.split('.')
let last_num = res[1].substr(0, digits)
return res[0] + '.' + last_num
}
return parseFloat(num)
}
//检查数据
const checkData = (val) => {
let num = parseFloat(val)
if(num > maxNum) return maxNum
if(num < minNum) return minNum
return val
}
const onInputEven = (e) => {
let res = e.detail.value
if(res === '') {
setValue({...value, count:minNum})
onChange?.(minNum, otherData)
}
else if(!isNaN(Number(res))) {
let count = formatDigits(res)
count = checkData(count)
setValue({...value, count})
onChange?.(parseFloat(count as string), otherData)
} else {
let num = parseFloat(res)
if(!isNaN(num)) {
let count = formatDigits(num)
count = checkData(count)
setValue({...value, count})
onChange?.(count as number, otherData)
} else {
setValue({...value, count:defaultNum})
onChange?.(defaultNum, otherData)
}
}
}
const onBluerEven = () => {
let num = parseFloat(value.count)
if(!isNaN(num)) {
let count = formatDigits(num)
count = checkData(count)
setValue({...value, count})
onBlue?.(count as number, otherData)
} else {
setValue({...value, count:defaultNum})
onBlue?.(defaultNum, otherData)
}
}
return (
<View className={styles.main}>
<View className={styles.reduce} onClick={() => minus()}>-</View>
<View className={styles.input}>
<Input
value={String(value.count)}
onInput={onInputEven}
onBlur={onBluerEven}
type='digit'
/>
<View className={styles.unit}>{unit}</View>
</View>
<View className={styles.plus} onClick={() => onPlus()}>+</View>
</View>
)
}

View File

@ -1,176 +0,0 @@
.shop_cart_main{
.popup_con{
height: 80vh;
display: flex;
flex-direction: column;
}
.header{
color: $color_font_one;
font-size: 32px;
font-weight: 700;
padding: 20px;
}
.colorFind{
padding: 10px 20px;
display: flex;
align-items: center;
.search{
flex:1;
}
.text{
font-size: $font_size_medium;
color: $color_main;
}
}
.search{
display: flex;
align-items: center;
padding: 20px;
.search_title{
font-size: $font_size;
color: #000;
width: 160px;
}
.search_list{
display: flex;
justify-content: space-between;
flex:1;
}
.search_item{
width: 148px;
height: 55px;
text-align: center;
line-height: 55px;
color: $color_font_two;
font-size: $font_size_medium;
background-color: #f0f0f0;
border-radius: 50px;
}
.search_item_select{
border: 2px solid $color_main;
background-color: #ecf5ff;
color: $color_main;
width: 144px;
height: 51px;
}
}
.colorNum{
display: flex;
justify-content: space-between;
padding: 20px;
.title{
font-size: 26px;
}
.miconfont{
font-size: 36px;
color: $color_font_two;
}
}
.product_color_con{
flex:1;
height: 0;
padding-bottom:151px;
}
.color_con{
.virtual_list{
padding-bottom: 300px;
}
.item {
display: flex;
justify-content: space-between;
padding: 0 20px;
margin-bottom: 40px;
.item_color{
width: 156.5px;
height: 156.5px;
border-radius: 20px;
}
.item_con{
flex:1;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 20px 0 20px 20px;
.title{
font-size: $font_size_big;
font-weight: 700;
}
.num{
font-size: $font_size;
color: $color_main;
}
.priceText{
font-size: $font_size_big;
Text{
font-size: $font_size_min;
}
}
}
.btn_con{
display: flex;
align-items: flex-end;
.btn{
width: 116px;
height: 64px;
background-color: $color_main;
border-radius: 40px 0px 16px 0px;
font-size: $font_size_medium;
text-align: center;
line-height: 64px;
color: #fff;
}
.btn_count{
width: 235px;
height: 64px;
background-color: #ECF5FF;
border-radius: 40px 0px 16px 0px;
padding: 0 20px;
display: flex;
align-items: center;
}
}
}
}
.noData{
width:100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
color: $color_font_three;
font-size: $font_size_medium;
}
.buy_btn{
width: 100%;
padding: 0 40px;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
box-sizing: border-box;
position: fixed;
bottom:0;
font-size: $font_size_medium;
color: $color_font_two;
background-color: #fff;
box-shadow: 6px 0px 12px 0px rgba(0,0,0,0.16);
.buy_btn_con{
display: flex;
justify-content: space-between;
align-items: center;
height: 151px;
}
.add_cart{
width: 260px;
height: 90px;
font-size: $font_size_big;
text-align: center;
line-height: 90px;
border-radius: 50px;
color: #fff;
background: linear-gradient(38deg,#5cabff, #7cbcfc 100%, #99ccff 100%);
}
.select_add_cart{
background: linear-gradient(38deg,#007aff, #4fa6ff 100%, #68b4ff 100%);
}
}
}

View File

@ -1,333 +0,0 @@
import { View, Text } from '@tarojs/components'
import Popup from '@/components/popup'
import LoadingCard from '@/components/loadingCard'
import Search from '@/components/search'
import Counter from '../counter'
import Big from 'big.js'
import classnames from 'classnames'
import styles from './index.module.scss'
import { memo, useCallback, useEffect, useRef, useState } from 'react'
import { useSelector } from '@/reducers/hooks'
import { GetColorList } from '@/api/materialColor'
import { AddShoppingCartApi } from '@/api/shopCart'
import Taro, { useRouter } from '@tarojs/taro'
import UseLogin from '@/use/useLogin'
import { formatHashTag, formatPriceDiv } from '@/common/fotmat'
import { getFilterData } from '@/common/util'
import LabAndImg from '@/components/LabAndImg'
import VirtualList from '@tarojs/components/virtual-list'
import useCommonData from '@/use/useCommonData'
import LabAndImgShow from '@/components/LabAndImgShow'
type param = {
show?: true | false
onClose?: () => void
title?: string
productId?: number
}
export default memo(({ show = false, onClose, title = '', productId = 0 }: param) => {
const { adminUserInfo } = useSelector((state) => state.userInfo)
const [selectList, _] = useState([
{ id: 0, step: 1, digits: 0, maxNum: 100000, defaultNum: 1, title: '大货', unit: '条', eunit: 'kg', priceField: 'bulk_price' },
{ id: 1, step: 1, digits: 2, maxNum: 9.99, defaultNum: 1, title: '剪板', unit: '米', eunit: 'm', priceField: 'length_cut_price' },
{ id: 2, step: 1, digits: 2, minNum: 3, maxNum: 100000, defaultNum: 3, title: '散剪', unit: '米', eunit: 'kg', priceField: 'weight_cut_price' },
])
const [selectIndex, setSelectIndex] = useState(0)
const selectProduct = (index: number) => {
setSelectIndex(() => index)
}
//重置数据
useEffect(() => {
const newList = initList(list)
setList([...newList])
condition.current.code_or_name = null
setSearchShow(false)
}, [selectIndex])
//获取面料颜色列表
const { fetchData: colorFetchData, state: colorState } = GetColorList()
const [list, setList] = useState<any[]>([])
const condition = useRef({ physical_warehouse: adminUserInfo?.physical_warehouse, sale_mode: selectIndex, product_id: 0, code_or_name: null })
const getColorList = async () => {
let { data } = await colorFetchData(getFilterData(condition.current))
let lists = initList(data.list)
setList(() => [...lists])
}
const [showPopup, setShowPopup] = useState(false)
//显示获取
useEffect(() => {
if (show) {
setSelectIndex(0)
condition.current.code_or_name = null
setSearchShow(false)
condition.current.product_id = productId
getColorList()
}
setShowPopup(show)
}, [show])
//初始化列表数据
const initList = useCallback((list) => {
const newList = list.map((item) => {
item.count = 0
item.show = false
return item
})
return newList
}, [])
//卸载数据
useEffect(() => {
return () => {
setList([])
}
}, [])
//popup关闭
const closePopup = () => {
onClose?.()
setShowPopup(false)
setList([])
}
//计算总数量和总米/件数
const [selectCount, setSelectCount] = useState<{ sumCount: number; kindCount: number; color_list: any[] }>({
sumCount: 0,
kindCount: 0,
color_list: [],
})
useEffect(() => {
let sumCount = 0,
kindCount = 0,
color_list: any[] = []
let color_list_info = {}
list.map((item) => {
if (item.count > 0) {
sumCount = Big(sumCount).add(item.count).toNumber()
kindCount++
color_list_info = selectIndex == 0 ? { product_color_id: item.id, roll: item.count } : { product_color_id: item.id, length: item.count * 100 }
color_list.push(color_list_info)
}
})
setSelectCount({ ...selectCount, sumCount, kindCount, color_list })
}, [list])
//计数组件
const getInputValue = useCallback(
(num, item) => {
item.count = parseFloat(num)
if (num == 0) item.show = false
setList(() => [...list])
},
[list],
)
const onAdd = (item) => {
item.show = true
item.count = selectList[selectIndex].defaultNum
setList((list) => [...list])
}
//搜索显示与隐藏
const [searchShow, setSearchShow] = useState(false)
const changeSearchShow = () => {
setSearchShow(true)
}
//添加购物车
const { getShopCount } = useCommonData()
const { getSelfUserInfo } = UseLogin()
const { fetchData: addFetchData } = AddShoppingCartApi()
const addShopCart = async () => {
try {
await getSelfUserInfo()
} catch (msg) {
Taro.showToast({
icon: 'none',
title: '授权失败,请求完善授权',
})
return false
}
if (selectCount.sumCount == 0) {
Taro.showToast({
icon: 'none',
title: '请选择面料颜色!',
})
return false
}
const state = await addFetchData({
sale_mode: selectIndex,
color_list: selectCount.color_list,
})
if (state.success) {
Taro.showToast({
title: '添加成功',
})
getShopCount()
onClose?.()
} else {
Taro.showToast({
icon: 'none',
title: state.msg,
})
}
}
//筛选数据
const searchInput = useCallback((e) => {
condition.current.code_or_name = e
getColorList()
}, [])
//清空搜索内容
const searchRef = useRef<any>(null)
const clearSearch = () => {
searchRef.current.clearInput()
setSearchShow(false)
}
//格式化金额
const formatPrice = useCallback(
(item) => {
const price = Number(formatPriceDiv(item[selectList[selectIndex].priceField]))
return (
<View className={styles.priceText}>
<Text>¥</Text>
{price}
<Text> /{selectList[selectIndex].eunit}</Text>
</View>
)
},
[selectIndex],
)
//显示图片弹窗
const [showLabImage, setShowLabImage] = useState(false)
const [labImageValue, setLabImageValue] = useState()
const getLabAndImg = useCallback((val) => {
setShowLabImage(() => true)
setLabImageValue(val)
}, [])
const closeLabImgShow = useCallback(() => {
setShowLabImage(() => false)
}, [])
//虚拟滚动
const Rows = memo(({ id, index, style, data }: any) => {
let item = data[index]
return (
<>
{(item && (
<View className={styles.item} key={item.id}>
<View className={styles.item_color}>
<LabAndImg value={{ lab: item.lab, rgb: item.rgb, texture_url: item.texture_url, title: item.code }} showStatus={false} onClick={getLabAndImg} />
</View>
<View className={styles.item_con}>
<View className={styles.title}>{formatHashTag(item.code, item.name)}</View>
<View className={styles.num}>{formatPrice(item)}</View>
</View>
<View className={styles.btn_con}>
{(!item.show && (
<View className={styles.btn} onClick={() => onAdd(item)}>
</View>
)) || (
<View className={styles.btn_count}>
<Counter
otherData={item}
onBlue={getInputValue}
defaultNum={item.count}
step={selectList[selectIndex].step}
digits={selectList[selectIndex].digits}
onClickBtn={getInputValue}
unit={selectList[selectIndex].unit}
minNum={selectList[selectIndex].minNum}
maxNum={selectList[selectIndex].maxNum}
/>
</View>
)}
</View>
</View>
)) || <View className={styles.item}></View>}
</>
)
})
return (
<View className={styles.shop_cart_main}>
<Popup showTitle={false} show={showPopup} onClose={() => closePopup()}>
<View className={styles.popup_con}>
<View className={styles.header}>{title}</View>
<View className={styles.search}>
<View className={styles.search_title}>:</View>
<View className={styles.search_list}>
{selectList.map((item, index) => {
return (
<View
key={index}
onClick={() => selectProduct(index)}
className={classnames(styles.search_item, selectIndex == index && styles.search_item_select)}>
{item.title}
</View>
)
})}
</View>
</View>
{searchShow && (
<View className={styles.colorFind}>
<View className={styles.search}>
<Search placeIcon='out' ref={searchRef} changeOnSearch={searchInput} debounceTime={400} />
</View>
<View className={styles.text} onClick={() => clearSearch()}>
</View>
</View>
)}
<View className={styles.colorNum}>
<View className={styles.title}> ({list.length})</View>
{!searchShow && <View className={classnames('iconfont icon-sousuo', styles.miconfont)} onClick={() => changeSearchShow()}></View>}
</View>
<View className={styles.product_color_con}>
{list.length <= 0 && colorState.loading && <LoadingCard />}
{list.length > 0 && !colorState.loading && (
<View className={styles.color_con}>
<VirtualList
className={styles.virtual_list}
height={400} /* 列表的高度 */
width='100%' /* 列表的宽度 */
itemData={list} /* 渲染列表的数据 */
itemCount={list.length + 1} /* 渲染列表的长度 */
itemSize={100} /* 列表单项的高度 */
overscanCount={1}>
{Rows}
</VirtualList>
<View className='common_safe_area_y'></View>
</View>
)}
{list.length <= 0 && !colorState.loading && <View className={styles.noData}></View>}
</View>
<View className={styles.buy_btn}>
<View className={styles.buy_btn_con}>
<View className={styles.count}>
{selectCount.kindCount}{selectCount.sumCount}
{selectList[selectIndex].unit}
</View>
<View className={classnames(styles.add_cart, selectCount.kindCount && styles.select_add_cart)} onClick={() => addShopCart()}>
</View>
</View>
</View>
</View>
<View className='common_safe_area_y'></View>
</Popup>
<View>
<LabAndImgShow value={labImageValue} show={showLabImage} onClose={closeLabImgShow} />
</View>
</View>
)
})

View File

@ -1,45 +0,0 @@
.main{
position: fixed;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
background-color: rgba(0,0,0, 0.8);
display: flex;
justify-content: center;
align-items: flex-start;
z-index: 999;
.con{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
width: 100%;
height: 60vh;
margin-top: 100px;
padding: 20px;
box-sizing: border-box;
.rgb{
width: 600px;
height: 600px;
border-radius: 20px;
}
image{
width:100%;
border-radius: 10px;
}
.name {
width: 488px;
height: 72px;
color: #fff;
text-align: center;
font-size: 26px;
border-radius: 20px;
line-height: 72px;
margin-top: 10px;
background-color: rgba(0,0,0, 0.5);
padding: 0 10px;
@include common_ellipsis(1);
}
}
}

View File

@ -1,23 +0,0 @@
import { View } from "@tarojs/components"
import { useMemo } from "react"
import styles from './index.module.scss'
export type colorParams = {
value?: { backgroundColor: string; }|null,
show?: false|true
onClose?: () => void
}
export default ({value, show = false, onClose}: colorParams) => {
return (
<>
{show&&<View className={styles.main} catch-move="true" onClick={() => onClose?.()}>
<View className={styles.con}>
<View className={styles.rgb} style={value!}></View>
<View className={styles.name}>{'颜色'}</View>
</View>
</View>}
</>
)
}

View File

@ -1,28 +0,0 @@
.swiper{
height: 450px;
width: 100%;
position: relative;
.swiper_item{
height: 100%;
width: 100%;
}
.image_item{
width: 100%;
height: 100%;
image{
width: 100%;
height: 100%;
display: block;
}
}
.page{
font-size: $font_size_min;
padding: 5px 20px;
background-color: rgba(0,0,0,0.3);
color: #fff;
border-radius: 50px;
position: absolute;
bottom: 20px;
right: 20px;
}
}

View File

@ -1,49 +0,0 @@
import { formatImgUrl } from "@/common/fotmat"
import { Image, Swiper, SwiperItem, View } from "@tarojs/components"
import { useMemo, useRef, useState } from "react"
import Taro from '@tarojs/taro'
import styles from './index.module.scss'
type item = {title:string, img:string, url:string, id:number}
type params = {
list?: item[]
}
export default ({list = []}: params) => {
const [pageIndex, setPageIndex] = useState(1)
const pageRef = useRef<any>(null)
const pageCount = useMemo(() => {
return list.length
},[list])
const formatImages = useMemo(() => {
return list?.map(item => formatImgUrl(item, '!w800'))
}, [list])
const swiperChange = (e) => {
setPageIndex(e.detail.current + 1)
}
const onShowImage = () => {
Taro.previewImage({
current: formatImages[0],
urls: formatImages
})
}
return (
<View className={styles.swiper}>
{list.length > 0 && <Swiper className={styles.swiper_item} circular={true} onAnimationFinish={(e) => swiperChange(e)}>
{list?.map((item) => {
return <SwiperItem >
<View className={styles.image_item} onClick={onShowImage}>
<Image mode="aspectFill" src={formatImgUrl(item, '!w400')}></Image>
</View>
</SwiperItem>
})}
</Swiper>}
{(list.length > 0)&&<View className={styles.page} ref={pageRef}>{pageIndex+'/'+pageCount}</View>}
</View>
)
}

View File

@ -1,6 +0,0 @@
export default {
navigationBarTitleText: '详情',
enablePullDownRefresh: true,
backgroundTextStyle: 'dark',
enableShareAppMessage: true
}

View File

@ -1,174 +0,0 @@
.main{
min-height: 100%;
background-color: $color_bg_one;
padding-bottom: 100px;
.product_header{
padding: 0 20px;
display: flex;
align-items: center;
height: 163.57px;
background-color: #fff;
.title{
flex:1;
.name{
font-size: 32px;
font-weight: 700;
color: $color_font_one;
@include common_ellipsis(1);
}
.des{
font-size: $font_size_medium;
color: $color_font_three;
@include common_ellipsis(1);
margin-top: 20px;
}
}
.share, .collect {
width: 76px;
font-size: $font_size_min;
text-align: center;
color: $color_font_three;
position: relative;
.text{
margin-top: 10px;
font-size: $font_size_medium;
}
}
.shareBtn {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.miconfont{
font-size: 45px;
}
.collected{
color: #FFC300;
}
}
.des_data{
background-color: #fff;
padding: 20px;
margin-top: 16px;
.title{
font-size: $font_size;
font-weight: 700;
color: $color_font_one;
margin-bottom: 20px;
}
.con{
display: grid;
grid-template-columns: 260px auto;
font-size: $font_size_medium;
color: $color_font_three;
.des_text{
display: flex;
margin-bottom: 16px;
text{
flex:1;
@include common_ellipsis(1);
}
}
}
}
.product_color{
background-color: #fff;
margin-top: 16px;
padding: 30px 20px 0;
color: $color_font_one;
font-size: $font_size_medium;
.title{
}
.list{
margin-top: 30px;
display: grid;
grid-template-columns: 210px 210px 210px ;
justify-content: space-between;
.item {
width:210px;
margin-bottom: 20px;
.item_color{
width:210px;
height: 210px;
border-radius: 20px;
image{
width: 100%;
height: 100%;
border-radius: 20px;
}
}
.item_name{
text-align: center;
margin-top: 10px;
}
}
}
}
.product_detail{
// padding: 20px;
background-color: #fff;
margin-top: 16px;
}
.product_buy{
display: flex;
justify-content: space-between;
align-items: center;
height:95px;
width: 100vw;
position: fixed;
bottom: 0;
left: 0;
background-color: #fff;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
.buy_cart{
width: 150px;
color: $color_font_three;
text-align: center;
position: relative;
.text{
font-size: $font_size_min;
}
.miconfont{
font-size: 36px;
}
.product_num{
position: absolute;
font-size: 23px;
background-color: red;
color: #fff;
height: 36px;
line-height: 36px;
padding: 0 6px;
border-radius: 72px;
min-width: 25px;
text-align: center;
top: 0;
right: 20px;
}
}
.buy_btn{
display: flex;
justify-content: center;
align-items: center;
width: 297px;
height: 100%;
background-color: $color_main;
font-size: $font_size;
color: #fff;
position: relative;
.phoneBtn{
background-color: rgba(0, 0, 0, 0);
position: absolute;
width: 100%;
height: 100%;
}
}
}
}

View File

@ -1,253 +0,0 @@
import { Button, RichText, Text, View } from '@tarojs/components'
import Taro, { useDidShow, usePullDownRefresh, useRouter } from '@tarojs/taro'
import classnames from 'classnames'
import DesSwiper from './components/swiper'
import OrderCount from './components/orderCount'
import ShopCart from '@/components/shopCart'
import styles from './index.module.scss'
import { useCallback, useEffect, useMemo, useState } from 'react'
import { formatHashTag, formatImgUrl } from '@/common/fotmat'
import { GetProductDetailApi } from '@/api/material'
import useLogin from '@/use/useLogin'
import { AnalysisShortCodeApi, GetShortCodeApi } from '@/api/share'
import { SHARE_SCENE } from '@/common/enum'
import useUserInfo from '@/use/useUserInfo'
import LabAndImg from '@/components/LabAndImg'
import { alert } from '@/common/common'
import AddCollection from '@/components/addCollection'
import { AddFavoriteApi, DelFavoriteProductApi } from '@/api/favorite'
import useCommonData from '@/use/useCommonData'
import { IMG_CND_Prefix } from '@/common/constant'
type item = { title: string; img: string; url: string; id: number }
type Params = {
list?: item[]
swiperOnClick?: (val: item) => void
style?: Object
}
export default (props: Params) => {
const { getPhoneNumber, userInfo } = useLogin()
//获取参数(有两种参数1.商品id, 2.页面分享)
const router = useRouter()
const [params, setParams] = useState({ id: '', share: null })
//判断是否是分享过来的参数
const judgeParam = async () => {
if (router.params.id) {
setParams({ ...params, id: router.params.id })
} else if (router.params.share) {
analysisShortCode()
}
}
//解析短码参数
const { fetchData: fetchDataAnalysisShortCode } = AnalysisShortCodeApi()
const analysisShortCode = async () => {
let res = await fetchDataAnalysisShortCode({ md5_key: router.params.share })
setParams({ id: res.data.product_id, share: res.data })
}
//获取购物车数据数量
const { getShopCount, commonData } = useCommonData()
useDidShow(() => {
judgeParam()
setShowCart(false)
getShopCount()
})
useEffect(() => {
if (params.id) {
getProductDetail()
}
}, [params])
//获取数据
const [productInfo, setProductInfo] = useState<any>({})
const { fetchData } = GetProductDetailApi()
const getProductDetail = async () => {
let { data } = await fetchData({ id: params.id })
setProductInfo(data)
Taro.stopPullDownRefresh()
}
useEffect(() => {
if (productInfo.code) {
getShortCode()
setCollectStatus(() => productInfo.is_favorite)
}
}, [productInfo])
//面料名称
const productName = useMemo(() => {
return formatHashTag(productInfo.code, productInfo.name)
}, [productInfo])
const [showCart, setShowCart] = useState(false)
const [showOrderCount, setShowOrderCount] = useState(false)
// const html = `
// <img style="width:100%" src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic24.nipic.com%2F20121021%2F10910884_100200815001_2.jpg&refer=http%3A%2F%2Fpic24.nipic.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1652257920&t=9353dda34f18ae2fe6803f3da35954bb">
// `
const html = ``
const { setSortCode, userInfo: userObj } = useUserInfo()
//详情页获取分享短码
const { ShareDetail } = SHARE_SCENE
const { fetchData: fetchDataShortCode } = GetShortCodeApi()
const getShortCode = async () => {
const { data: resDetail } = await fetchDataShortCode({
share_user_id: userObj.adminUserInfo.user_id,
type: ShareDetail.value,
product_id: parseInt(params.id),
})
const img = formatImgUrl(productInfo.texture_url || '/mall/share_img_01.png', '!w400')
setSortCode({ ...userObj.sort_code, shareShortDetail: { title: productName as string, code: resDetail.md5_key, img: img } })
}
//授权手机号和下单
const placeOrder = async (status = 'to_phone', e: any = {}) => {
if (!productInfo.id) return false
if (status == 'to_phone') {
if (!e.detail.code) return alert.error('请授权手机号')
try {
await getPhoneNumber(e.detail.code)
} catch (msg) {
Taro.showToast({
icon: 'none',
title: msg,
})
return false
}
}
setShowOrderCount(true)
}
//收藏功能
const [collectStatus, setCollectStatus] = useState(false)
const [collectionShow, setCollectionShow] = useState(false)
const { fetchData: addFavoritefetchData } = AddFavoriteApi()
const openCollection = () => {
if (productInfo.is_favorite) {
delFavoriteProduct()
} else {
setCollectionShow(true)
}
}
const onAdd = useCallback(
async (val) => {
let res = await addFavoritefetchData({ favorite_id: val.id, product_id: Number(params.id) })
if (res.success) {
alert.success('添加成功')
setCollectStatus(true)
getProductDetail()
} else {
alert.none(res.msg)
}
setCollectionShow(false)
},
[params],
)
const closeCollection = useCallback(() => {
setCollectionShow(false)
}, [])
//取消收藏
const { fetchData: delFavoriteProductFetchData } = DelFavoriteProductApi()
const delFavoriteProduct = async () => {
let res = await delFavoriteProductFetchData({ favorite_id: productInfo.favorite_id, product_id: [productInfo.id] })
if (res.success) {
setCollectStatus(false)
getProductDetail()
alert.none('已取消收藏')
}
}
//页面下拉刷新
usePullDownRefresh(() => {
getProductDetail()
})
return (
<View className={styles.main}>
<DesSwiper list={productInfo.texture_url ? productInfo.texture_url.toString().split(',') : []} />
<View className={styles.product_header}>
<View className={styles.title}>
{productInfo.code && <View className={styles.name}>{productName}</View>}
<View className={styles.des}>{productInfo.describe}</View>
</View>
<View className={styles.share}>
<View className={classnames('iconfont icon-fenxiang', styles.miconfont)}></View>
<View className={styles.text}></View>
<Button open-type='share' className={styles.shareBtn}></Button>
</View>
<View className={styles.collect} onClick={openCollection}>
<View
className={classnames(
`iconfont ${collectStatus ? 'icon-shoucang-pressed' : 'icon-shoucang'}`,
styles.miconfont,
collectStatus && styles.collected,
)}></View>
<View className={styles.text}></View>
</View>
</View>
<View className={styles.des_data}>
<View className={styles.title}></View>
<View className={styles.con}>
<View className={styles.des_text}>
<Text>{productInfo.code}</Text>
</View>
<View className={styles.des_text}>
<Text>{productInfo.width}</Text>
</View>
<View className={styles.des_text}>
<Text>{productInfo.weight_density}</Text>
</View>
<View className={styles.des_text}>
<Text>{productInfo.component}</Text>
</View>
</View>
</View>
<View className={styles.product_color}>
<View className={styles.title}> ({productInfo?.product_color_list?.length})</View>
<View className={styles.list}>
{productInfo?.product_color_list?.map((item) => {
return (
<View key={item.id} className={styles.item}>
<View className={styles.item_color}>
<LabAndImg value={{ lab: item.lab, rgb: item.rgb, texture_url: item.texture_url, title: item.code }} showStatus={true} />
</View>
<View className={styles.item_name}>{item.code}</View>
</View>
)
})}
</View>
</View>
<View className={styles.product_detail}>
<RichText nodes={html}></RichText>
</View>
<View className={styles.product_buy}>
<View className={styles.buy_cart} onClick={() => setShowCart(true)}>
<View className={classnames('iconfont icon-gouwuche', styles.miconfont)}></View>
<View className={styles.text}></View>
{commonData.shopCount > 0 && <View className={styles.product_num}>{commonData.shopCount > 99 ? '99+' : commonData.shopCount}</View>}
</View>
{(!userInfo.adminUserInfo?.is_authorize_phone && (
<View className={styles.buy_btn}>
<Button className={styles.phoneBtn} open-type='getPhoneNumber' onGetPhoneNumber={(e) => placeOrder('to_phone', e)}></Button>
</View>
)) || (
<View className={styles.buy_btn} onClick={() => placeOrder('to_order')}>
</View>
)}
</View>
<OrderCount show={showOrderCount} onClose={() => setShowOrderCount(false)} title={productName} productId={productInfo.id} />
<ShopCart show={showCart} onClose={() => setShowCart(false)} />
<AddCollection show={collectionShow} onAdd={onAdd} onClose={closeCollection} />
<View className='common_safe_area_y'></View>
</View>
)
}

View File

@ -1,33 +0,0 @@
.order_title{
display: flex;
align-items: center;
padding: 20px 30px;
box-sizing: border-box;
background-color: #fff;
height: 116px;
border-radius: 20px;
margin-top: 20px;
text{
flex:1;
font-size: $font_size;
font-weight: 700;
}
.order_status{
background-color: #F0F0F0;
width: 148px;
height: 55px;
color: $color_font_three;
text-align: center;
line-height: 55px;
font-size: $font_size_medium;
border-radius: 30px;
&:nth-last-child(1) {
margin-left: 20px;
}
}
.order_status_selected{
color: $color_main;
border: 1px solid $color_main;
}
}

View File

@ -1,32 +0,0 @@
import { Text, View } from "@tarojs/components"
import styles from './index.module.scss'
import classnames from "classnames";
import { memo, useEffect, useRef, useState } from "react";
type Param = {
onSelect?:(val:number) => void
defaultValue?: 0|1|2
}
export default memo(({onSelect, defaultValue = 0}: Param) => {
//收货方法 0:没选择, 1:自提2物流
const shipmentMode = useRef([
{value:1, label:'上门自提', selected:false},
{value:2, label:'物流', selected:false}
])
const [selectValue, setSelectValue] = useState<number>()
useEffect(() => {
setSelectValue(defaultValue)
}, [defaultValue])
const selectShipmentMode = (value) => {
setSelectValue(() => value)
onSelect?.(value)
}
return (
<View className={styles.order_title}>
<Text></Text>
{shipmentMode.current.map(item => {
return <View className={classnames(styles.order_status, (selectValue == item.value)&&styles.order_status_selected)} onClick={() => selectShipmentMode(item.value)}>{item.label}</View>
})}
</View>
)
})

View File

@ -1,6 +0,0 @@
export default {
navigationBarTitleText: '修改地址',
enablePullDownRefresh: true,
backgroundTextStyle: 'dark',
enableShareAppMessage: true,
}

View File

@ -1,120 +0,0 @@
.order_edit_main{
min-height: 100%;
background-color:$color_bg_one;
padding-top: 20px;
display: flex;
flex-direction: column;
box-sizing: border-box;
.title_msg{
display: flex;
align-items: center;
padding: 20px;
background-color: #fff;
margin: 0 20px;
border-radius: 20px;
.miconfont{
font-size: 50px;
color: $color_main;
}
.title_msg_con{
font-size: 23px;
display: flex;
flex-direction: column;
margin-left: 30px;
text{
&:nth-child(1) {
color: $color_main;
}
&:nth-child(2) {
color: $color_font_three;
}
}
}
}
.shipmentMode_con{
margin: 0 20px;
}
.old_address{
display: flex;
flex-direction: column;
padding: 30px 20px 60px 20px;
box-sizing: border-box;
.old_address_text{
font-weight: 700;
&:nth-of-type(1) {
padding-bottom: 30px;
font-size: $font_size_big;
}
&:nth-of-type(2) {
padding-bottom: 30px;
font-size: $font_size;
}
}
.userInfo{
display: flex;
font-size: $font_size;
color: $color_font_three;
align-items: center;
.userInfo_text{
font-size: $font_size;
&:nth-child(2) {
padding-left: 20px;
}
}
}
}
.select_address_con{
flex:1;
display: flex;
flex-direction: column;
align-items: center;
background-color: #fff;
border-radius: 30px 30px 0px 0px;
position: relative;
.title{
font-size: $font_size;
font-weight: 700;
margin-top: 30px;
}
.address_list{
flex:1;
height: 0;
margin-top: 50px;
}
.submitBtn{
display: flex;
font-size: $font_size_big ;
justify-content: center;
height: 82px;
margin-bottom: 20px;
position: absolute;
bottom:0;
.addressBtn{
flex:1;
text-align: center;
height: 100%;
border: 3px solid #cde5ff;
width: 348px;
justify-content: center;
align-items: center;
}
.addAddress{
border-right: 0;
display: flex;
border-radius: 50px 0px 0px 50px;
color: $color_main;
background-color: #fff;
}
.submitUpdate{
display: flex;
justify-content: center;
align-items: center;
border-radius: 0px 50px 50px 0px;
background-color: $color_main;
color: #fff;
}
}
}
}

View File

@ -1,94 +0,0 @@
import { Text, View } from "@tarojs/components"
import styles from './index.module.scss'
import classnames from "classnames";
import { useCallback, useMemo, useRef, useState } from "react";
import ShipmentMode from "./components/shipmentMode";
import AddressList from "@/components/AddressList";
import { alert, goLink } from "@/common/common";
import { getParam } from "@/common/system";
import {EditSaleOrderAddressApi, EditSaleOrderShipmentModeApi} from "@/api/order";
import Taro from "@tarojs/taro";
import useLogin from "@/use/useLogin";
export default () => {
useLogin()
//获取临时传递的数据
const params = getParam()
const [paramsData, setParamsData] = useState<any>(params)
//提交的数据
const [submitData, setSubmitData] = useState({
address_id:0,
id:params.id,
shipment_mode: params.shipment_mode
})
//格式化地址
const address = useMemo(() => {
return paramsData.province_name+' '+paramsData.city_name+' '+paramsData.district_name+' '+paramsData.address_detail
}, [paramsData])
//获取收货方法
const getShipmentMode = useCallback((num) => {
setSubmitData((val) => ({...val, shipment_mode:num}))
}, [])
//获取地址
const getSelectAddress = useCallback((e) => {
setSubmitData((val) => ({...val, address_id:e.id}))
}, [])
//修改请求
const {fetchData: addressFetchData} = EditSaleOrderAddressApi()
const {fetchData: shipmentFetchData} = EditSaleOrderShipmentModeApi()
const editData = async () => {
if(submitData.address_id) {
let res = await addressFetchData(submitData)
if(!res.success) {
alert.error(res.msg)
return false
}
}
let res = await shipmentFetchData(submitData)
if(!res.success) {
alert.error(res.msg)
return false
}
Taro.navigateBack()
}
return (
<View className={styles.order_edit_main}>
<View className={classnames(styles.title_msg)}>
<Text className={classnames(styles.miconfont, 'iconfont icon-zhuyi')}></Text>
<View className={styles.title_msg_con}>
<Text></Text>
<Text></Text>
</View>
</View>
<View className={styles.shipmentMode_con}>
<ShipmentMode onSelect={getShipmentMode} defaultValue={paramsData.shipment_mode}/>
</View>
<View className={styles.old_address}>
<Text className={styles.old_address_text}>:</Text>
<Text className={styles.old_address_text}>{address}</Text>
<View className={styles.userInfo}>
<Text className={styles.userInfo_text}>{paramsData.name}</Text>
<Text className={styles.userInfo_text}>{paramsData.phone}</Text>
</View>
</View>
<View className={styles.select_address_con}>
<View className={styles.title}></View>
<View className={styles.address_list}>
<AddressList focusBorderEnabled={true} addButtonEnabled={false} onSelect={getSelectAddress}/>
</View>
<View className={styles.submitBtn}>
<View onClick={() => goLink('/pages/addressAdd/index', {type:'add'})} className={classnames(styles.addAddress, styles.addressBtn)}></View>
<View className={classnames(styles.submitUpdate, styles.addressBtn)} onClick={() => editData()}></View>
</View>
</View>
<View className="common_safe_area_y"></View>
</View>
)
}

View File

@ -1,79 +0,0 @@
.products_list{
padding: 0 20px 20px 20px;
box-sizing: border-box;
height: 100%;
}
.products_item{
width: 100%;
background-color: #fff;
border-radius: 20px;
padding: 20px;
box-sizing: border-box;
display: flex;
justify-content: space-between;
&:nth-child(n+2){
margin-top: 16px;
}
.item_img{
width: 198px;
height: 198px;
position: relative;
image{
width: 100%;
height: 100%;
border-radius: 10px;
}
.num{
width: 100px;
height: 36px;
font-size: $font_size_min;
position: absolute;
right:0;
bottom: 0;
background: rgba($color: #fff, $alpha: 0.3);
border-radius: 36px 0px 10px 0px;
color: #fff;
text-align: center;
line-height: 36px;
}
}
.item_con{
padding-left: 15px;
font-size: $font_size;
flex:1;
.title{
font-size: $font_size;
color: #707070;
text{
color: $color_font_one;
font-weight: bold;
}
}
.tag_list{
display: flex;
margin-top: 16px;
.tag{
padding: 3px 10px;
background-color: #CDE5FF;
font-size: $font_size_min;
border-radius: 5px;
color: $color_main;
&:nth-child(2) {
margin-left: 10px;
}
}
}
.introduce{
font-size: $font_size_medium;
color: $color_font_two;
margin-top: 16px;
}
.des{
font-size:$font_size_medium;
color: #707070;
margin-top: 16px;
@include common_ellipsis($params:2);
}
}
}

View File

@ -1,27 +0,0 @@
import { Image, View } from "@tarojs/components"
import styles from './index.module.scss'
export default () => {
return (
<View className={styles.products_list}>
{new Array(10).fill('').map(item => {
return <View className={styles.products_item}>
<View className={styles.item_img}>
<Image src="https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.jj20.com%2Fup%2Fallimg%2Ftp01%2F1ZZQ214233446-0-lp.jpg&refer=http%3A%2F%2Fimg.jj20.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1651827249&t=b2fc2a3672dc8ced9e0f37ce7e2ff901"/>
<View className={styles.num}>230</View>
</View>
<View className={styles.item_con}>
<View className={styles.title}><text>0770#</text>21S单面平纹()</View>
<View className={styles.tag_list}>
<View className={styles.tag}>160cm</View>
<View className={styles.tag}>110g</View>
</View>
<View className={styles.introduce}>67.6%24%6.4%</View>
<View className={styles.des}></View>
</View>
</View>
})}
</View>
)
}

View File

@ -1,3 +0,0 @@
import React from "react";
export const ParamsContext = React.createContext<any>(null)

View File

@ -0,0 +1,3 @@
export default {
navigationBarTitleText: '首页',
}

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '首页',
enableShareAppMessage: true,
}

View File

@ -1,33 +0,0 @@
.main{
background-color: $color_bg_one;
height: 100vh;
display: flex;
flex-direction: column;
.search{
width: 100%;
display: flex;
justify-content: space-between;
padding: 20px 20px 30px 20px;
box-sizing: border-box;
align-items: center;
.search_collect{
font-size: 26px;
border: 2px solid #007AFF;
color: #007AFF;
border-radius: 50px;
width: 132px;
height: 44px;
text-align: center;
line-height: 44px;
}
.search_input{
flex:1;
margin-left: 20px;
}
}
.products{
flex:1;
height: 0;
}
}

0
src/pages/index/index.ts Normal file
View File

View File

@ -1,116 +0,0 @@
import { View } from '@tarojs/components'
import Banner from '@/components/banner'
import Search from '@/components/search'
import SideBar from '@/components/sideBar'
import Product from '@/components/product'
import MoveBtn from '@/components/moveBtn'
import ShopCart from '@/components/shopCart'
import { goLink } from '@/common/common'
import styles from './index.module.scss'
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import Taro, { Events, useDidShow, usePullDownRefresh } from '@tarojs/taro'
import { GetProductKindListApi, GetProductListApi } from '@/api/material'
import useLogin from '@/use/useLogin'
import { dataLoadingStatus } from '@/common/util'
export default () => {
useLogin()
useEffect(() => {
categoryList()
}, [])
//获取面料种类
const [kindData, setKindData] = useState<any>({ list: [], defaultId: 0 })
const { fetchData } = GetProductKindListApi()
const categoryList = async () => {
const res = await fetchData()
if (res.data?.list) {
setKindData({ ...kindData, list: res.data.list, defaultId: res.data.list[0].id })
setFiltrate({ ...filtrate, product_kind_id: res.data.list[0].id })
}
}
//获取面料列表
const [productData, setProductData] = useState({ list: [], total: 0 })
const [hasMore, setHasMore] = useState(true)
const [filtrate, setFiltrate] = useState({ product_kind_id: 0, size: 5, page: 1 })
const pageNum = useRef({ size: filtrate.size, page: filtrate.page })
const { fetchData: productFetchData, state: productState } = GetProductListApi()
//获取数据方法
const getProductList = async () => {
const { data, total } = await productFetchData(filtrate)
setProductData({ ...productData, list: data.list, total })
setRefresherTriggeredStatus(() => false)
}
//监听查询条件
useEffect(() => {
if (filtrate.product_kind_id) getProductList()
}, [filtrate])
//点击面料类型
const getProductKindId = useCallback((e) => {
pageNum.current.page = 1
setProductData({ list: [], total: 0 })
setFiltrate((list) => ({ ...list, size: 5, product_kind_id: e.id }))
}, [])
//上拉加载数据
const getScrolltolower = useCallback(() => {
if (productData.list.length >= productData.total) {
setHasMore(false)
} else {
pageNum.current.page++
const newSize = pageNum.current.size * pageNum.current.page
setFiltrate((e) => ({ ...e, size: newSize }))
}
}, [productData])
const [showShopCart, setShowShopCart] = useState(false)
//列表下拉刷新
const [refresherTriggeredStatus, setRefresherTriggeredStatus] = useState(false)
const getRefresherRefresh = async () => {
pageNum.current.page = 1
setFiltrate({ ...filtrate, size: 5 })
setHasMore(true)
setRefresherTriggeredStatus(true)
}
//数据加载状态
const statusMore = useMemo(() => {
return dataLoadingStatus({ list: productData.list, total: productData.total, status: productState.loading })
}, [productData, productState.loading])
return (
<MoveBtn onClick={() => setShowShopCart(!showShopCart)}>
<View className={styles.main}>
<Banner />
<View className={styles.search}>
<View className={styles.search_collect} onClick={() => goLink('/pages/collection/index')}>
</View>
<View className={styles.search_input} onClick={() => goLink('/pages/searchList/search')}>
<Search disabled={true} style={{ width: '263rpx' }} />
</View>
</View>
<View className={styles.products}>
<SideBar
list={kindData.list}
height='100%'
defaultValue={kindData.defaultId}
hasMore={hasMore}
statusMore={statusMore}
selfOnScrolltolower={getScrolltolower}
sideBarOnClick={getProductKindId}
heightItem={150}
refresherTriggered={refresherTriggeredStatus}
selfOnRefresherRefresh={() => getRefresherRefresh()}>
<Product productList={productData.list} />
</SideBar>
</View>
<View className='common_safe_area_y'></View>
<ShopCart show={showShopCart} onClose={() => setShowShopCart(false)} />
</View>
</MoveBtn>
)
}

View File

@ -1,4 +0,0 @@
export default {
navigationBarTitleText: '确认订单',
enableShareAppMessage: true,
}

View File

@ -1,132 +0,0 @@
.order_main {
min-height: 100%;
background-color: $color_bg_one;
padding: 20px;
padding-bottom: 190px;
box-sizing: border-box;
.order_title {
display: flex;
align-items: center;
padding: 20px 30px;
box-sizing: border-box;
background-color: #fff;
height: 116px;
border-radius: 20px;
margin-top: 20px;
text {
flex: 1;
font-size: $font_size;
font-weight: 700;
}
.order_status {
background-color: #f0f0f0;
width: 148px;
height: 55px;
color: $color_font_three;
text-align: center;
line-height: 55px;
font-size: $font_size_medium;
border-radius: 30px;
&:nth-last-child(1) {
margin-left: 20px;
}
}
.order_status_selected {
color: $color_main;
border: 1px solid $color_main;
}
}
.order_desc {
display: flex;
align-items: center;
background-color: #fff;
padding: 20px;
min-height: 116px;
border-radius: 20px;
margin-top: 20px;
box-sizing: border-box;
.order_desc_con {
width: 150px;
font-size: $font_size;
font-weight: 700;
}
.order_desc_text,
.order_desc_text_hint {
font-size: $font_size_medium;
margin-right: 10px;
flex: 1;
}
.order_desc_text_hint {
text-align: right;
color: $color_font_two;
}
.miconfont {
font-size: 20px;
color: $color_font_two;
}
}
.submit_order {
display: flex;
position: fixed;
bottom: 0;
left: 0;
justify-content: space-between;
width: 100%;
height: 175px;
align-items: center;
background-color: #fff;
box-shadow: 6px 0px 12px 0px rgba(0, 0, 0, 0.16);
padding: 20px 50px;
box-sizing: border-box;
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
.submit_order_number {
padding: 20px 0;
}
.order_btn {
width: 250px;
height: 90px;
opacity: 0.6;
background: linear-gradient(38deg, #007aff, #4fa6ff 100%, #68b4ff 100%);
border-radius: 46px;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
}
.ok_order_btn {
opacity: 1;
}
.order_number_desc {
font-size: $font_size_medium;
color: $color_font_two;
}
}
.order_info {
background-color: #fff;
margin-top: 20px;
border-radius: 20px;
padding: 20px;
.order_info_title {
font-size: $font_size;
font-weight: 700;
margin-bottom: 20px;
}
.order_num {
display: flex;
justify-content: space-between;
align-items: center;
.order_num_btn {
font-size: $font_size_medium;
padding: 5px 10px;
border: 2px solid #007cf7;
border-radius: 10px;
color: $color_main;
}
}
text {
font-size: $font_size;
}
}
}

View File

@ -1,209 +0,0 @@
import { SaleOrderPreViewApi, SaleOrderApi } from '@/api/order'
import { formatPriceDiv } from '@/common/fotmat'
import Popup from '@/components/popup'
import { View } from '@tarojs/components'
import Taro, { useDidShow, usePullDownRefresh } from '@tarojs/taro'
import classnames from 'classnames'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import KindList from './components/kindList'
import Remark from './components/remark'
import styles from './comfirm.module.scss'
import { getParam } from '@/common/system'
import { alert, goLink } from '@/common/common'
import SubmitOrderBtn from './components/submitOrderBtn'
import AddressInfoDetail from './components/addressInfoDetail'
import { SubscriptionMessageApi } from '@/api/user'
import { SUBSCRIPTION_MESSAGE_SCENE } from '@/common/enum'
import { UseSubscriptionMessage } from '@/use/useCommon'
import { throttle } from '@/common/util'
export default () => {
const [showDesc, setShowDesc] = useState(false)
//下单信息
type OrderParams = { address_id?: number; remark?: string; sale_mode?: number; shipment_mode?: number; list?: any[] }
const [submitOrderData, setSubmitOrderData] = useState<OrderParams>()
//获取购物车传过来的id
type orderPreParam = {
shopping_cart_product_color_list: { shopping_cart_product_color_id: number }[]
sale_mode: number
}
const param = getParam()
const idsAndSaleModel = useRef<orderPreParam>({ shopping_cart_product_color_list: [], sale_mode: 0 })
useDidShow(async () => {
idsAndSaleModel.current = { shopping_cart_product_color_list: [], sale_mode: 0 } //初始化
idsAndSaleModel.current.sale_mode = Number(param?.sale_mode)
param?.ids?.split('-')?.map((item) => {
return idsAndSaleModel.current.shopping_cart_product_color_list?.push({
shopping_cart_product_color_id: Number(item),
})
})
getSaleOrderPreView()
setSubmitOrderData((val) => ({ ...val, sale_mode: param?.sale_mode }))
})
//获取销售预览订单
const [preViewOrder, setPreViewOrder] = useState<any>() //获取到的原始数据
const { fetchData } = SaleOrderPreViewApi()
const getSaleOrderPreView = async () => {
if (idsAndSaleModel.current.shopping_cart_product_color_list?.length > 0) {
let res = await fetchData(idsAndSaleModel.current)
setPreViewOrder(res.data)
}
}
//监听获取到的数据
useEffect(() => {
if (preViewOrder) {
formatData()
getDataList()
setSubmitOrderData((val) => ({
...val,
address_id: preViewOrder.default_address.id,
shipment_mode: preViewOrder.shipment_mode || 2,
}))
}
}, [preViewOrder])
//格式化数据格式
const [formatPreViewOrder, setFormatPreViewOrder] = useState<any>() //格式化后的数据
const formatData = () => {
setFormatPreViewOrder({
estimate_amount: preViewOrder.estimate_amount, //预估金额
sale_mode: preViewOrder.sale_mode,
sale_mode_name: preViewOrder.sale_mode_name,
total_colors: preViewOrder.total_colors, //总颜色数量
total_number: preViewOrder.total_number, //总数量
total_fabrics: preViewOrder.total_fabrics, //面料数量
unit: preViewOrder.sale_mode == 0 ? '条' : 'm', //单位
list: preViewOrder.product_list,
total_should_collect_money: preViewOrder.total_should_collect_money, //应收金额
total_sale_price: preViewOrder.total_sale_price, //合计金额
})
}
const formatPreViewOrderMemo = useMemo(() => {
return formatPreViewOrder
}, [formatPreViewOrder])
//格式化初始地址
const defaultAddress = useMemo(() => {
const address = preViewOrder?.default_address
return {
province_name: address?.province_name,
city_name: address?.city_name,
district_name: address?.district_name,
address_detail: address?.address_detail,
id: address?.id,
target_user_name: address?.name,
target_user_phone: address?.phone,
shipment_mode: address?.shipment_mode,
take_goods_address: preViewOrder?.take_goods_address,
take_goods_phone: preViewOrder?.take_goods_phone,
}
}, [preViewOrder])
//获取提交格式数据列表
const getDataList = () => {
let list: { shopping_cart_product_color_id: number }[] = []
preViewOrder.product_list?.map((item) => {
item.product_colors?.map((colorItem) => {
list.push({ shopping_cart_product_color_id: colorItem.id })
})
})
setSubmitOrderData((val) => ({ ...val, list }))
}
//获取地址
const getAddress = (e) => {
setSubmitOrderData((val) => ({ ...val, address_id: e.id }))
}
const selectShipmentMode = useCallback((value) => {
setSubmitOrderData((val) => ({ ...val, shipment_mode: value }))
}, [])
//获取备注
const getRemark = useCallback((e) => {
setSubmitOrderData((val) => ({ ...val, remark: e }))
setShowDesc(() => false)
}, [])
//提交按钮是否可用
const btnStatus = useMemo(() => {
return submitOrderData?.shipment_mode == 1 || (submitOrderData?.shipment_mode == 2 && submitOrderData?.address_id)
}, [submitOrderData])
//数量格式
const numText = useMemo(() => {
if (formatPreViewOrder) {
let total_number = formatPreViewOrder?.sale_mode == 0 ? formatPreViewOrder?.total_number : formatPreViewOrder?.total_number / 100
return `${formatPreViewOrder?.total_fabrics} 种面料,${formatPreViewOrder?.total_colors} 种颜色,共 ${total_number} ${formatPreViewOrder?.unit}`
}
}, [formatPreViewOrder])
//订阅消息
const { SubmitOrder } = SUBSCRIPTION_MESSAGE_SCENE
const { openSubscriptionMessage } = UseSubscriptionMessage()
//提交订单
const { fetchData: saleOrderFetchData } = SaleOrderApi()
const submitOrderEven = throttle(async () => {
if (!submitOrderData?.shipment_mode) {
alert.error('请选择收货方式')
return false
}
if (!submitOrderData?.address_id && submitOrderData?.shipment_mode == 2) {
alert.error('请选择地址')
return false
}
let showModalRes = await Taro.showModal({
title: '确定提交订单?',
content: `发货方式为${submitOrderData?.shipment_mode == 1 ? '自提' : '物流'}`,
confirmText: '确定',
cancelText: '取消',
})
if (showModalRes.confirm) {
await openSubscriptionMessage({ scenes: SubmitOrder.value })
const res = await saleOrderFetchData(submitOrderData)
if (res.success) {
goLink('/pages/order/index', { id: res.data.id }, 'redirectTo')
} else {
alert.none(res.msg)
}
}
}, 800)
//页面下拉刷新
usePullDownRefresh(() => {
getSaleOrderPreView()
})
return (
<View className={styles.order_main}>
<AddressInfoDetail orderInfo={defaultAddress} onSelect={getAddress} onChangeShipmentMode={selectShipmentMode} status={1} />
<KindList order={formatPreViewOrderMemo} comfirm={true} />
<View className={styles.order_desc} onClick={() => setShowDesc(true)}>
<View className={styles.order_desc_con}></View>
{(submitOrderData?.remark && <View className={styles.order_desc_text}>{submitOrderData?.remark}</View>) || <View className={styles.order_desc_text_hint}></View>}
<View className={classnames(styles.miconfont, 'iconfont icon-a-moreback')}></View>
</View>
<View className={styles.submit_order}>
<View className={styles.submit_order_number}>
<SubmitOrderBtn
style={{ color: '#007AFF' }}
number={(preViewOrder?.sale_mode == 1 ? formatPreViewOrder?.total_should_collect_money : formatPreViewOrder?.estimate_amount) / 100}
priceTitle={preViewOrder?.sale_mode == 1 ? '合计金额' : '预估金额'}
/>
<View className={styles.order_number_desc}>{numText}</View>
</View>
<View className={classnames(styles.order_btn, btnStatus && styles.ok_order_btn)} onClick={() => submitOrderEven()}>
</View>
</View>
<Popup show={showDesc} showTitle={false} onClose={() => setShowDesc(false)}>
<Remark defaultValue={submitOrderData?.remark} onSave={(e) => getRemark(e)} />
</Popup>
<View className='common_safe_area_y'></View>
</View>
)
}

View File

@ -1,71 +0,0 @@
.order_address{
height: 178px;
background: #ffffff;
border-radius: 20px;
display: flex;
align-items: center;
padding: 30px;
box-sizing: border-box;
margin-top: 20px;
.order_address_icon{
font-size: 76px;
color: $color_main;
}
.order_address_text_con{
flex:1;
padding: 0 30px;
box-sizing: border-box;
.order_address_text_title{
font-size: $font_size_medium;
margin-top: 10px;
@include common_ellipsis;
}
.order_address_text_name{
align-items: center;
text{
&:nth-child(1) {
color: #000;
font-weight: 700;
font-size: $color_font_one;
margin-right: 40px;
}
&:nth-child(2) {
color: $color_font_one;
font-size: $font_size_medium;
}
}
}
}
.updateBtn{
font-size: $font_size_medium;
color: $color_font_three;
width: 96px;
height: 52px;
border: 2px solid #dddddd;
border-radius: 28px;
text-align: center;
line-height: 52px;
}
.order_address_text_no{
flex: 1;
font-size: $font_size;
font-weight: 700;
margin-left: 30px;
}
.order_address_more_icon{
color: $color_font_three;
font-size: $font_size;
}
}
.order_address_list {
height: 900px;
.order_address_title{
font-size: $font_size;
font-weight: 700;
width: 100%;
text-align: center;
padding: 20px 0 30px 0;
}
}

View File

@ -1,76 +0,0 @@
import AddressList from "@/components/AddressList";
import Popup from "@/components/popup";
import { Text, View } from "@tarojs/components"
import classnames from "classnames";
import { memo, useCallback, useEffect, useMemo, useState } from "react";
import styles from './index.module.scss'
export type AddressInfoParam = {
province_name: string,
city_name: string,
district_name: string,
address_detail: string,
id?: number,
name: string,
phone: string
}
type Param = {
onSelect?: (val:any) => void, //选择
defaultValue?: AddressInfoParam|null //默认值
disabled?: false|true //true禁用后只用于展示
}
export default memo(({onSelect, defaultValue = null, disabled = false}: Param) => {
const [showAddressList, setShowAddressList] = useState(false)
useEffect(() => {
setUserInfo(() => defaultValue)
}, [defaultValue])
//选择地址
const [userInfo, setUserInfo] = useState<any>()
const getAddress = useCallback((val) => {
setShowAddressList(() => false)
setUserInfo(() => val)
onSelect?.(val)
}, [])
//地址格式
const formatAddress = useMemo(() => {
if(userInfo)
return userInfo.province_name + userInfo.city_name + userInfo.district_name + userInfo.address_detail
}, [userInfo])
const changeShow = () => {
if(!disabled)
setShowAddressList(() => true)
}
return (
<View>
<View className={styles.order_address} onClick={() => changeShow()}>
<View className={classnames(styles.order_address_icon, 'iconfont icon-daohang')}></View>
{!userInfo&&
<>
<View className={styles.order_address_text_no}></View>
<View className={classnames(styles.order_address_more_icon, 'iconfont icon-a-moreback')}></View>
</>
||<>
<View className={styles.order_address_text_con}>
<View className={styles.order_address_text_name}>
<Text>{userInfo?.name}</Text>
<Text>{userInfo?.phone}</Text>
</View>
<View className={styles.order_address_text_title}>{formatAddress}</View>
</View>
<View className={styles.updateBtn}></View>
</>}
</View>
{!disabled&&<Popup show={showAddressList} showTitle={false} onClose={() => setShowAddressList(false)}>
<View className={styles.order_address_list}>
<View className={styles.order_address_title}></View>
<AddressList onSelect={(item) => getAddress(item)}/>
</View>
</Popup>}
</View>
)
})

View File

@ -1,139 +0,0 @@
.order_address{
background: #ffffff;
border-radius: 20px;
display: flex;
align-items: center;
padding: 30px;
box-sizing: border-box;
margin-top: 20px;
position: relative;
.order_address_icon{
font-size: 50px;
color: $color_main;
position: absolute;
top: 35px;
left: 20px;
}
.order_address_text_con{
flex:1;
padding-left: 50px;
box-sizing: border-box;
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
.order_address_text_title{
font-size: $font_size_medium;
margin-top: 10px;
display: flex;
justify-content: space-between;
.moreIconfont{
font-size: 20px;
padding-top: 10px;
}
.address_text{
word-break:break-all;
}
.address_text_no{
font-weight: 700;
padding-left: 20px;
}
}
.order_address_text_name{
margin-top: 30px;
align-items: center;
text{
&:nth-child(1) {
color: #000;
font-weight: 700;
font-size: $color_font_one;
margin-right: 40px;
}
&:nth-child(2) {
color: $color_font_one;
font-size: $font_size_medium;
}
}
}
}
.updateBtn{
width:200px;
font-size: $font_size_min;
background-color: #F0F0F0;
height: 64px;
border-radius: 24px;
color: $color_font_two;
position: absolute;
bottom: 10px;
right: 10px;
z-index: 999;
.updateBtn_list{
position: absolute;
display: flex;
z-index: 5;
width: 100%;
.updateBtn_item_select{
color: #fff;
}
}
.updateBtn_item{
flex:1;
text-align: center;
line-height: 64px;
}
.updateBtn_select{
color: #fff;
background-color: $color_main;
border-radius: 24px;
position: absolute;
width: 100px;
height: 61px;
z-index: 1;
transition: all 0.3s ease-in-out;
}
}
.logisticsBtn{
width: 152px;
height: 72px;
background: #ffffff;
border: 2px solid #007AFF;
border-radius: 38px;
position: absolute;
bottom: 10px;
right: 10px;
z-index: 999;
font-size: 28px;
color: #007AFF;
text-align: center;
line-height: 72px;
}
.order_address_text_no{
flex: 1;
font-size: $font_size;
font-weight: 700;
margin-left: 30px;
}
.order_address_more_icon{
color: $color_font_three;
font-size: $font_size;
}
}
.order_address_list {
height:80vh;
.order_address_title{
font-size: $font_size;
font-weight: 700;
width: 100%;
text-align: center;
padding: 20px 0 30px 0;
height: 100px;
}
.addressList_con{
padding-bottom: 20px;
height: calc(100% - 160px);
}
}

View File

@ -1,219 +0,0 @@
import { GetAddressListApi } from '@/api/addressList'
import { addressListApi } from '@/api/addressManager'
import { EditSaleOrderAddressApi, EditSaleOrderShipmentModeApi } from '@/api/order'
import { alert, goLink } from '@/common/common'
import { ORDER_STATUS } from '@/common/enum'
import { debounce, throttle } from '@/common/util'
import AddressList from '@/components/AddressList'
import Popup from '@/components/popup'
import { Text, View } from '@tarojs/components'
import classnames from 'classnames'
import { forwardRef, memo, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react'
import Taro from '@tarojs/taro'
import styles from './index.module.scss'
type Param = {
onSelect?: (val: any) => void //选择地址
disabled?: false | true //true禁用后只用于展示
onChangeShipmentMode?: (val: number) => void //返回收货方式
onLogistics?: () => void //查看物流
status?: 1 | 2 //1确认订单时使用 2订单流程
orderInfo?: {
id?: number //订单id
shipment_mode?: 1 | 2 //1自提 2物流
status?: number //订单状态
province_name: string
city_name: string
district_name: string
address_detail: string
take_goods_address: string
take_goods_phone: string
target_user_name: string
target_user_phone: string
}
}
//订单状态
const {
SaleorderstatusWaitingPrePayment,
SaleOrderStatusBooking,
SaleOrderStatusArranging,
SaleOrderStatusArranged,
SaleOrderStatusWaitingPayment,
SaleOrderStatusWaitingReceipt,
SaleOrderStatusAlreadyReceipt,
SaleOrderStatusComplete,
SaleOrderStatusRefund,
SaleOrderStatusCancel,
} = ORDER_STATUS
export default memo(
forwardRef(({ onSelect, onChangeShipmentMode, orderInfo, status = 2, disabled = false, onLogistics }: Param, ref) => {
const [addressInfo, setAddressInfo] = useState<any>()
useEffect(() => {
if (orderInfo) {
setReceivingStatus(() => orderInfo.shipment_mode || 2)
setAddressInfo(() => orderInfo)
}
}, [orderInfo])
//打开地址列表
const [showAddressList, setShowAddressList] = useState(false)
const changeShow = () => {
if (receivingStatus == 2 && !logisticsShow && limitEdit()) setShowAddressList(() => true)
}
//把内部方法提供给外部
useImperativeHandle(ref, () => ({
changeShow,
}))
//收货方法,1:自提2物流
const [receivingStatus, setReceivingStatus] = useState(2)
const { fetchData: shipmentModeFetchData } = EditSaleOrderShipmentModeApi()
const onReceivingStatus = async (value, e) => {
e.stopPropagation()
if (limitEdit()) changeReceivingStatus(value)
}
//当没有地址时获取地址列表中的第一个数据
const { fetchData: addressListFetchData } = addressListApi()
const getAddressListOne = async () => {
if (orderInfo?.address_detail) return true
let res = await addressListFetchData()
if (res.data.list && res.data.list?.length > 0) {
let info = res.data.list[0]
await addressFetchData({ id: orderInfo?.id, address_id: info.id })
setAddressInfo((e) => ({ ...e, ...info, target_user_name: info.name, target_user_phone: info.phone }))
return true
} else {
Taro.showModal({
content: '您还没有地址,请前去新增地址',
success: function (res) {
if (res.confirm) {
goLink('/pages/addressManager/index')
} else if (res.cancel) {
console.log('用户点击取消')
}
},
})
return false
}
}
const changeReceivingStatus = debounce(async (value) => {
if (!orderInfo || value == receivingStatus) return false
if (status == 1) {
onChangeShipmentMode?.(value)
setReceivingStatus(value)
return false
}
if (value == 2) {
let res = await getAddressListOne()
if (!res) return false
}
alert.loading('正在修改')
const res = await shipmentModeFetchData({ id: orderInfo.id, shipment_mode: value })
if (res.success) {
alert.success('收货方式修改成功')
onChangeShipmentMode?.(value)
setReceivingStatus(() => value)
} else {
alert.none(res.msg)
}
}, 300)
//修改地址
const [addressId, setAddressId] = useState(0)
const { fetchData: addressFetchData } = EditSaleOrderAddressApi()
const getAddress = async (value) => {
if (!orderInfo) return false
if (status == 1) {
setShowAddressList(() => false)
setAddressId(value.id)
setAddressInfo((e) => ({ ...e, ...value, target_user_name: value.name, target_user_phone: value.phone }))
onSelect?.(value)
return false
}
alert.loading('正在修改')
const res = await addressFetchData({ id: orderInfo.id, address_id: value.id })
if (res.success) {
alert.success('地址修改成功')
onSelect?.(value)
setShowAddressList(() => false)
setAddressId(value.id)
setAddressInfo((e) => ({ ...e, ...value, target_user_name: value.name, target_user_phone: value.phone }))
} else {
alert.none(res.msg)
}
}
//根据订单状态判断是否可修改
const limitEdit = () => {
let res = [SaleorderstatusWaitingPrePayment.value, SaleOrderStatusBooking.value, SaleOrderStatusArranging.value, SaleOrderStatusArranged.value, SaleOrderStatusWaitingPayment.value].includes(
orderInfo?.status as number,
)
if (!res && status != 1) alert.none('该订单状态不能修改地址!')
return status == 1 ? true : res
}
//根据订单状态判断是否显示物流
const logisticsShowList = [SaleOrderStatusWaitingReceipt.value, SaleOrderStatusAlreadyReceipt.value, SaleOrderStatusComplete.value, SaleOrderStatusRefund.value]
const logisticsShow = useMemo(() => {
return logisticsShowList.includes(orderInfo?.status as number)
}, [orderInfo])
//地址格式
const formatAddress = useMemo(() => {
if (receivingStatus == 2) {
return addressInfo?.address_detail ? addressInfo.province_name + addressInfo.city_name + addressInfo.district_name + addressInfo.address_detail : ''
} else {
return addressInfo?.take_goods_address
}
}, [receivingStatus, addressInfo])
return (
<View>
<View className={styles.order_address} onClick={() => changeShow()}>
<View className={classnames(styles.order_address_icon, 'iconfont', receivingStatus == 2 ? 'icon-daohang' : 'icon-fahuo')}></View>
<View className={styles.order_address_text_con}>
<View className={styles.order_address_text_title}>
<Text className={classnames(styles.address_text, styles.address_text_no)}>{formatAddress || '请选择收货地址及信息'}</Text>
{receivingStatus == 2 && !logisticsShow && <Text className={classnames(styles.moreIconfont, 'iconfont icon-a-moreback')}></Text>}
</View>
<View className={styles.order_address_text_name}>
<Text>{receivingStatus == 1 ? '谭先生' : addressInfo?.target_user_name}</Text>
<Text>{receivingStatus == 1 ? addressInfo?.take_goods_phone : addressInfo?.target_user_phone}</Text>
</View>
</View>
{(!logisticsShow && (
<View className={styles.updateBtn}>
<View className={styles.updateBtn_list}>
<View className={classnames(styles.updateBtn_item, receivingStatus == 1 && styles.updateBtn_item_select)} onClick={(e) => onReceivingStatus(1, e)}>
</View>
<View className={classnames(styles.updateBtn_item, receivingStatus == 2 && styles.updateBtn_item_select)} onClick={(e) => onReceivingStatus(2, e)}>
</View>
</View>
<View style={{ transform: receivingStatus == 1 ? 'translateX(0)' : 'translateX(100%)' }} className={classnames(styles.updateBtn_select)}></View>
</View>
)) ||
(orderInfo?.status != SaleOrderStatusRefund.value && (
<View className={styles.logisticsBtn} onClick={onLogistics}>
</View>
))}
</View>
<Popup show={showAddressList} showTitle={false} onClose={() => setShowAddressList(false)}>
<View className={styles.order_address_list}>
<View className={styles.order_address_title}></View>
<View className={styles.addressList_con}>
<AddressList onSelect={getAddress} id={addressId} />
</View>
</View>
</Popup>
</View>
)
}),
)

View File

@ -1,64 +0,0 @@
.advance_main{
width:100%;
height: 238px;
background-color: #007AFF;
border-radius: 20px;
display: flex;
align-items: center;
font-size: 24px;
color: #dddddd;
position: relative;
.time_con{
padding-left: 30px;
.times{
margin-bottom: 25px;
display: flex;
align-items: center;
.text{
margin-right: 15px;
}
.num{
width: 46px;
height: 50px;
background: #0063ce;
border-radius: 10px;
line-height: 50px;
text-align: center;
font-weight: 700;
color: #fff;
}
.separate{
padding: 0 10px;
}
}
}
.cardIcon{
width: 238px;
height: 178px;
position: absolute;
right: 0;
bottom: 0;
.image{
width:100%;
height: 100%;
}
}
.refresh{
position: absolute;
top: 23px;
right: 20px;
display: flex;
color: #dddddd;
display: flex;
align-items: center;
.mconfont{
font-size: 36px;
}
.refresh_text{
font-size: 25px;
}
}
}

Some files were not shown because too many files have changed in this diff Show More