✨ feat:初始化
This commit is contained in:
parent
76dca1ef45
commit
74144ad820
@ -5,11 +5,11 @@ const versions =
|
||||
encoding: 'utf8',
|
||||
}) != 'HEAD\n'
|
||||
? childProcess.execSync('git rev-parse --abbrev-ref HEAD', {
|
||||
encoding: 'utf8',
|
||||
})
|
||||
encoding: 'utf8',
|
||||
})
|
||||
: childProcess.execSync('git describe --tags --abbrev=0', {
|
||||
encoding: 'utf8',
|
||||
})
|
||||
encoding: 'utf8',
|
||||
})
|
||||
const CURRENT_GITHASH = childProcess.execSync('git rev-parse --short HEAD', {
|
||||
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 = {
|
||||
projectName: 'EShop',
|
||||
date: '2022-4-6',
|
||||
@ -42,7 +29,6 @@ const config = {
|
||||
},
|
||||
sourceRoot: 'src',
|
||||
outputRoot: 'dist',
|
||||
plugins: [['@tarojs/plugin-mini-ci', CIPluginOpt]],
|
||||
defineConstants: {
|
||||
CURRENT_VERSION: JSON.stringify(CURRENT_VERSION),
|
||||
CURRENT_GITHASH: JSON.stringify(CURRENT_GITHASH),
|
||||
|
||||
@ -28,10 +28,7 @@
|
||||
"dev:jd": "npm run build:jd -- --watch",
|
||||
"dev:quickapp": "npm run build:quickapp -- --watch",
|
||||
"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",
|
||||
"buildo:weapp:open": "taro build --type weapp --open",
|
||||
"build:weapp:upload": "taro build --type weapp --upload",
|
||||
"build:weapp:preview": "taro build --type weapp --preview"
|
||||
"dev:weapp:pre": "cross-env NODE_ENV=pre npm run build:weapp -- --watch"
|
||||
},
|
||||
"browserslist": [
|
||||
"last 3 versions",
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
{
|
||||
"miniprogramRoot": "dist/",
|
||||
"projectname": "EShop",
|
||||
"projectname": "Mall-lymarket",
|
||||
"description": "项目配置文件,详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
|
||||
"appid": "wx68d92d7cbf0b6963",
|
||||
"appid": "wxa41b2eda1c6b557a",
|
||||
"setting": {
|
||||
"urlCheck": true,
|
||||
"es6": false,
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
export default {
|
||||
pages: [
|
||||
'pages/index/index',
|
||||
'pages/order/index',
|
||||
'pages/user/index',
|
||||
],
|
||||
window: {
|
||||
@ -15,14 +16,20 @@ export default {
|
||||
{
|
||||
pagePath: 'pages/index/index',
|
||||
text: '首页',
|
||||
iconPath: './styles/tabbar/home.png',
|
||||
selectedIconPath: './styles/tabbar/home_selected.png',
|
||||
iconPath: './styles/tabbar/list.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',
|
||||
text: '我的',
|
||||
iconPath: './styles/tabbar/my.png',
|
||||
selectedIconPath: './styles/tabbar/my_selected.png',
|
||||
selectedIconPath: './styles/tabbar/my_on.png',
|
||||
}
|
||||
],
|
||||
'color': '#707070',
|
||||
@ -31,156 +38,7 @@ export default {
|
||||
'borderStyle': 'white'
|
||||
},
|
||||
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",
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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%);
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '地址管理',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
.address-manager{
|
||||
height: 100vh;
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
})
|
||||
@ -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>
|
||||
)
|
||||
})
|
||||
@ -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>
|
||||
)
|
||||
})
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
})
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '申请售后',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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>}
|
||||
</>
|
||||
)
|
||||
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '邀请码',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
})
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '认证信息',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
|
||||
)
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '分类标题'
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '收藏详情',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
})
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
})
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '我的收藏',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '公司资料',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '授信额度',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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"/>
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '已用额度',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
// )
|
||||
// }
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '预存款',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '交易详情',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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>)
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '收支明细',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -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%);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
})
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>}
|
||||
</>
|
||||
)
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -1,6 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '详情',
|
||||
enablePullDownRefresh: true,
|
||||
backgroundTextStyle: 'dark',
|
||||
enableShareAppMessage: true
|
||||
}
|
||||
@ -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%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
})
|
||||
@ -1,6 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '修改地址',
|
||||
enablePullDownRefresh: true,
|
||||
backgroundTextStyle: 'dark',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -1,3 +0,0 @@
|
||||
import React from "react";
|
||||
|
||||
export const ParamsContext = React.createContext<any>(null)
|
||||
3
src/pages/index/index.cofig.ts
Normal file
3
src/pages/index/index.cofig.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export default {
|
||||
navigationBarTitleText: '首页',
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '首页',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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
0
src/pages/index/index.ts
Normal 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>
|
||||
)
|
||||
}
|
||||
@ -1,4 +0,0 @@
|
||||
export default {
|
||||
navigationBarTitleText: '确认订单',
|
||||
enableShareAppMessage: true,
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
})
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
@ -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>
|
||||
)
|
||||
}),
|
||||
)
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user