Commit 9fdc4cd3 by 姜雷

Merge branch 'test'

parents 2766a416 82d47d8c
const path = require('path');
const config = {
projectName: 'wx-school-app',
date: '2019-2-20',
......@@ -5,32 +7,35 @@ const config = {
deviceRatio: {
'640': 2.34 / 2,
'750': 1,
'828': 1.81 / 2
'828': 1.81 / 2,
},
sourceRoot: 'src',
outputRoot: 'dist',
alias: {
'@': path.resolve(__dirname, '..', 'src'),
},
plugins: {
babel: {
sourceMap: true,
presets: [
['env', {
modules: false
}]
[
'env',
{
modules: false,
},
],
],
plugins: [
'transform-decorators-legacy',
'transform-class-properties',
'transform-object-rest-spread'
]
}
},
defineConstants: {
'transform-object-rest-spread',
],
},
},
defineConstants: {},
copy: {
patterns: [
],
options: {
}
patterns: [],
options: {},
},
weapp: {
module: {
......@@ -38,34 +43,28 @@ const config = {
autoprefixer: {
enable: true,
config: {
browsers: [
'last 3 versions',
'Android >= 4.1',
'ios >= 8'
]
}
browsers: ['last 3 versions', 'Android >= 4.1', 'ios >= 8'],
},
},
pxtransform: {
enable: true,
config: {
}
config: {},
},
url: {
enable: true,
config: {
limit: 10240 // 设定转换尺寸上限
}
limit: 10240, // 设定转换尺寸上限
},
},
cssModules: {
enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
config: {
namingPattern: 'module', // 转换模式,取值为 global/module
generateScopedName: '[name]__[local]___[hash:base64:5]'
}
}
}
}
generateScopedName: '[name]__[local]___[hash:base64:5]',
},
},
},
},
},
h5: {
publicPath: '/',
......@@ -75,28 +74,24 @@ const config = {
autoprefixer: {
enable: true,
config: {
browsers: [
'last 3 versions',
'Android >= 4.1',
'ios >= 8'
]
}
browsers: ['last 3 versions', 'Android >= 4.1', 'ios >= 8'],
},
},
cssModules: {
enable: false, // 默认为 false,如需使用 css modules 功能,则设为 true
config: {
namingPattern: 'module', // 转换模式,取值为 global/module
generateScopedName: '[name]__[local]___[hash:base64:5]'
}
}
}
}
}
}
generateScopedName: '[name]__[local]___[hash:base64:5]',
},
},
},
},
},
};
module.exports = function (merge) {
module.exports = function(merge) {
if (process.env.NODE_ENV === 'development') {
return merge({}, config, require('./dev'))
return merge({}, config, require('./dev'));
}
return merge({}, config, require('./prod'))
}
return merge({}, config, require('./prod'));
};
......@@ -4,13 +4,13 @@
"private": true,
"description": "",
"scripts": {
"build:weapp": "npx @tarojs/cli build --type weapp",
"build:weapp": "cross-env NODE_ENV=product npx @tarojs/cli build --type weapp",
"build:swan": "npx @tarojs/cli build --type swan",
"build:alipay": "npx @tarojs/cli build --type alipay",
"build:tt": "npx @tarojs/cli build --type tt",
"build:h5": "npx @tarojs/cli build --type h5",
"build:rn": "npx @tarojs/cli build --type rn",
"dev:weapp": "npm run build:weapp -- --watch",
"dev:weapp": "npx @tarojs/cli build --type weapp -- --watch",
"dev:swan": "npm run build:swan -- --watch",
"dev:alipay": "npm run build:alipay -- --watch",
"dev:tt": "npm run build:tt -- --watch",
......@@ -55,6 +55,7 @@
"babel-plugin-transform-jsx-stylesheet": "^0.6.5",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.1",
"cross-env": "^5.2.0",
"eslint": "^4.19.1",
"eslint-config-taro": "1.2.13",
"eslint-plugin-import": "^2.12.0",
......
import { baseFetch } from './index';
import { baseFetch, ResponseDataEntity } from './index';
export const fetchAllArea = () =>
export type Area = {
id: number;
areaName: string;
initial?: string;
};
export const fetchAllArea = (): Promise<ResponseDataEntity<Area[]>> =>
baseFetch({
url: '/area/queryAreaList',
});
import { CustomerBeanAccountVo, AccountParams } from './baseClass';
import { CustomerBeanAccountVo } from './baseClass';
import { customerFetch, ResponseDataEntity } from '.';
type Params = {
areaId: number;
/** 会员电话 */
customerPhone: string;
/** 会员id */
id: number;
/** 服务id */
serviceIdList: string[];
};
export const fetchBeanCount = (
data: AccountParams,
data: Params,
): Promise<ResponseDataEntity<CustomerBeanAccountVo[]>> =>
customerFetch({
url: '/customerAccount/queryAccount',
......
import { customerFetch } from '.';
import { customerFetch, ResponseDataEntity } from '.';
export class LoginParams {
/** 登陆标识 */
......@@ -35,7 +35,16 @@ export const changePwdByCellphone = (data: PwdParams) =>
data: data,
});
type RegisiterPramas = {};
type RegisiterPramas = {
code: string;
areaId: number;
areaName: string;
customerName: string;
customerPhone: string;
customerSex: string;
password: string;
verificationCode: string;
};
// type RegisiterReponseData = {};
export const wxUserRegister = (entity: RegisiterPramas) =>
......@@ -78,3 +87,8 @@ export const fetchFeedback = (entity: CustomerParam) =>
method: 'POST',
data: entity,
});
export const refreshCodeBar = (): Promise<ResponseDataEntity<string>> =>
customerFetch({
url: '/dcxy/wechat/applet/flush/idbar',
});
import Taro, { request } from '@tarojs/taro';
import store from '../store/index';
import {
OLD_BASE_SERVER_URL,
BASE_SERVER_URL,
CUSTOMER_SERVER_URL,
SCHOOL_MAIN_URL,
LogoutCode,
SuccessCode,
} from '../constants/index';
export type ResponseDataEntity<T> = {
......@@ -27,15 +28,24 @@ const createFetch = (basePath: string) => {
header: token
? {
token: token,
reqSource: 'wxmini',
}
: {},
: {
reqSource: 'wxmini',
},
url: basePath + entity.url,
}).then(({ data }: ResponseEntity) => {
if (data.code === 1000) {
if (data.code === SuccessCode) {
return data;
}
if (data.code === LogoutCode) {
Taro.redirectTo({
url: '/pages/Login/Login',
});
throw data;
}
Taro.showToast({
title: data.msg,
title: data.msg || '网络错误',
icon: 'none',
});
throw data;
......@@ -43,7 +53,6 @@ const createFetch = (basePath: string) => {
};
};
export const oldBaseFetch = createFetch(OLD_BASE_SERVER_URL);
export const baseFetch = createFetch(BASE_SERVER_URL);
export const customerFetch = createFetch(CUSTOMER_SERVER_URL);
export const schoolMainFetch = createFetch(SCHOOL_MAIN_URL);
......
import { baseFetch } from '.';
type ImageVcodePramas = {
effective?: number;
loginName: string;
codeNum?: number;
};
export const getImageVcode = (data: ImageVcodePramas) =>
baseFetch({
url: `/common/getCode?loginName=${data.loginName}&codeNum=4`,
method: 'POST',
data: data,
});
type VcodePramas = {
cellphone: string;
};
export const getVcode = (entity: VcodePramas) =>
baseFetch({
url: `/common/sendMsgCode?cellphone=${entity.cellphone}&codeNum=6`,
method: 'POST',
data: entity,
});
import { oldBaseFetch, baseFetch, ResponseDataEntity } from './index';
import { UserState } from '../store/rootReducers/userinfo';
type LoginPramas = {
code: string;
};
type LoginReponseData = {
register: boolean;
wxToken: string;
} & UserState;
export interface LoginReponse extends ResponseDataEntity<LoginReponseData> {
data: LoginReponseData;
}
export const login = (data: LoginPramas) =>
oldBaseFetch({
url: '/wx/api/user/login2',
data: data,
});
export const fetchValidateCode = () =>
oldBaseFetch({
url: '/wx/api/getValidateCode',
});
type ImageVcodePramas = {
effective?: number;
loginName: string;
codeNum?: number;
};
export const getImageVcode = (data: ImageVcodePramas) =>
baseFetch({
url: `/common/getCode?loginName=${data.loginName}&codeNum=4`,
method: 'POST',
data: data,
});
export const getVcode = entity =>
oldBaseFetch({
url: '/wx/api/getValidateCode',
method: 'POST',
data: entity,
});
type RegisiterPramas = {};
// type RegisiterReponseData = {};
export const fetchWxUserRegister = (entity: RegisiterPramas) =>
baseFetch({
url: '/dcxy/wechat/applet/register/',
method: 'POST',
data: entity,
});
......@@ -38,6 +38,7 @@ class App extends Component {
'pages/Order/OrderDetail/OrderDetail',
'pages/SelectCampus/SelectCampus',
'pages/Content/Content',
'pages/WebPage/WebPage',
],
window: {
backgroundTextStyle: 'light',
......
......@@ -20,6 +20,9 @@ interface Modal {
class Modal extends Component {
static externalClasses = ['body-class'];
static options = {
addGlobalClass: true,
};
static defaultProps = {
visiabled: false,
title: '提示',
......
import { ComponentClass } from 'react';
import Taro, { Component } from '@tarojs/taro';
import { View, Input, Canvas } from '@tarojs/components';
import { getVcode, getImageVcode } from '../../api/wx';
import { getVcode, getImageVcode } from '../../api/vcode';
import Modal from '../Modal/Modal';
import './Vcode.scss';
import { ResponseDataEntity } from 'src/api';
......@@ -66,7 +66,7 @@ class Vcode extends Component {
this.setState({
showImgBox: true,
});
this.renderImg(1234);
// this.renderImg(1234);
} else {
Taro.showToast({
title: '输入正确的手机号',
......@@ -76,7 +76,7 @@ class Vcode extends Component {
}
}
closeImageBox() {
const ctx = Taro.createCanvasContext('Vcode', this);
const ctx = Taro.createCanvasContext('Vcode', this.$scope);
ctx.setFillStyle('#6180f4');
ctx.fillRect(0, 0, 73, 38);
ctx.draw();
......@@ -86,7 +86,7 @@ class Vcode extends Component {
}
renderImg(vcode: number) {
const ctx = Taro.createCanvasContext('Vcode', this);
const ctx = Taro.createCanvasContext('Vcode', this.$scope);
ctx.setFillStyle('#6180f4');
ctx.fillRect(0, 0, 73, 38);
ctx.font = '26px arial';
......@@ -102,7 +102,7 @@ class Vcode extends Component {
const { cellphone } = this.props;
getVcode({
tel: cellphone,
cellphone: cellphone,
})
.then(res => {
this.countStart();
......
export const APP_ID = 'wxf5912b79bba23663';
export const SuccessCode = 1000;
export const LogoutCode = -2;
export const NotRegisterCode = 1005;
export const OLD_BASE_SERVER_URL = 'https://ex-dev-selfbase.168cad.top';
export const BASE_SERVER_URL = 'https://ex-dev-dcxy-base-app.168cad.top';
export const BASE_SERVER_URL = 'https://ex-test-dcxy-base-app.168cad.top';
export const CUSTOMER_SERVER_URL =
'https://ex-dev-dcxy-customer-app.168cad.top';
export const SCHOOL_MAIN_URL = 'https://internal-dev-school-main.168cad.top';
export const ANN_LINK_URL = 'https://ex-dev-wx.168cad.top/announcement/';
'https://ex-test-dcxy-customer-app.168cad.top';
export const SCHOOL_MAIN_URL =
'https://internal-test-school-home-bg.168cad.top';
export const ANN_LINK_URL = 'https://ex-test-wx.168cad.top/announcement/';
......@@ -26,8 +26,13 @@
margin-right: 16px;
}
.Announcement-item-title {
height: 40px;
line-height: 40px;
flex: 1;
font-size: 32px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.Announcement-item-date {
margin-top: 10px;
......
......@@ -5,13 +5,12 @@ import { View, ScrollView, Image, Text, WebView } from '@tarojs/components';
import AnnIcon from '../../images/icon/ann_tongzhi_icon@2x.png';
import { fetchAllAnn, AnnItem } from '../../api/announcement';
import { connect } from '@tarojs/redux';
import { UserState } from '../../store/rootReducers/userinfo';
import './Announcement.scss';
import { ANN_LINK_URL } from '../../constants';
import { Customer } from '@/types/Customer/Customer';
type PageStateProps = {
userinfo: UserState;
userinfo: Customer;
};
type PageOwnProps = {};
type PageState = {
......@@ -56,7 +55,7 @@ class Announcement extends Component {
console.log(err);
});
}
geAnnDetail(id: number, title: string) {
geAnnDetail(id: number) {
Taro.navigateTo({
url: `/pages/Content/Content?id=${id}`,
});
......@@ -70,7 +69,7 @@ class Announcement extends Component {
<View
key={annItem.id}
className='Announcement-item'
onClick={() => this.geAnnDetail(annItem.id, annItem.title)}>
onClick={() => this.geAnnDetail(annItem.id)}>
<Image
className='Announcement-item-img'
src={annItem.linkUrls[0]}
......
page {
background-color: #eee;
}
.BarCode {
.OrderBox {
box-sizing: border-box;
......@@ -13,9 +16,9 @@
}
.BarCodeBox {
position: relative;
background-color: #fff;
width: 100%;
height: 260px;
overflow: hidden;
transition: all 0.28s;
display: flex;
}
......@@ -28,7 +31,6 @@
flex: 1;
margin: 26px 52px 46px;
background-color: #fff;
overflow: hidden;
transition: all 0.28s;
}
.BarCodeImgBig {
......@@ -36,26 +38,39 @@
}
.BarCodeBox-refresh {
position: absolute;
right: 4px;
width: 32px;
height: 52px;
right: 44px;
bottom: -58px;
width: 176px;
height: 96px;
}
.BarCodeCav {
display: none;
width: 100%;
height: 100%;
}
.BarCodeCav.show {
display: block;
}
.toggleBtn {
position: absolute;
right: 0;
bottom: 4px;
background-color: #6180f4;
display: flex;
justify-content: center;
align-items: center;
left: 50%;
bottom: 0;
transform: translate(-50%, 40px);
background-color: #fff;
box-sizing: border-box;
width: 82px;
height: 40px;
line-height: 40px;
padding-left: 20px;
border-radius: 20px 0 0 20px;
font-size: 24px;
color: #fff;
width: 136px;
height: 45px;
border-radius: 0 0 20px 20px;
.arricon {
width: 24px;
height: 24px;
transition: all 400ms ease-in-out;
}
.rever {
transform: rotate(180deg);
}
}
}
import Taro, { Component } from '@tarojs/taro';
import { ComponentClass } from 'react';
import { View, Canvas, Image } from '@tarojs/components';
import BarCodeBoxBg from '../../images/barcode/tiaoxingma-1.png';
import BarCodeBoxBigBg from '../../images/barcode/tiaoxingma-2.png';
import RefreshIcon from '../../images/barcode/icon_shuaxin@2x.png';
import RefreshIcon from '../../images/barcode/pic_shuaxin@2x.png';
import ArrIcon from '../../images/barcode/icon_fangda@2x.png';
import wxbarcode from 'wxbarcode';
import './BarCode.scss';
import { UserState } from '../../store/rootReducers/userinfo';
import { UserState, updateUserInfo } from '../../store/rootReducers/userinfo';
import { connect } from '@tarojs/redux';
import {
fetchPayOrder,
fetchOrderDetailAndPay,
fetchDeductionInfo,
} from '../../api/order';
import { fetchPayOrder, fetchOrderDetailAndPay } from '../../api/order';
import OrderInfo from '../Order/components/OrderInfo/OrderInfo';
import OrderTitle from '../Order/components/OrderTitle/OrderTitle';
import OrderPayway from '../Order/components/OrderPayway/OrderPayway';
import {
ConsumeOrder,
PaymentAndActiveInfo,
CustomerBeanAccountVo,
} from '../../api/baseClass';
import { Customer } from '../../types/Customer/Customer';
import { refreshCodeBar } from '../../api/customer';
import Order from '@/types/Order/Order';
type PageStateProps = {
userinfo: UserState;
userinfo: Customer;
};
type PageDispatchProps = {
updateUserInfo: (e: UserState) => void;
};
type PageOwnProps = {};
type PageState = {
ScreenBrightness: number;
showPayOrder: boolean;
showBig: boolean;
accounts: CustomerBeanAccountVo[];
orderInfo: ConsumeOrder;
orderInfo: Order;
payInfos: {
paymentAndActiveInfos: PaymentAndActiveInfo[];
paymentConfId: number;
......@@ -49,37 +53,45 @@ type PageState = {
};
};
type IProps = PageStateProps & PageOwnProps;
type IProps = PageStateProps & PageOwnProps & PageDispatchProps;
interface BarCode {
props: IProps;
state: PageState;
}
@connect(({ userinfo }) => ({
userinfo,
}))
@connect(
({ userinfo }) => ({
userinfo,
}),
dispatch => ({
updateUserInfo(entity: UserState) {
dispatch(updateUserInfo(entity));
},
}),
)
class BarCode extends Component {
constructor(props: PageOwnProps) {
super(props);
this.state = {
ScreenBrightness: 1,
showPayOrder: false,
showBig: false,
accounts: [],
orderInfo: {
actualMoney: undefined,
areaId: undefined,
actualMoney: 0,
areaId: 0,
areaName: '',
consumeType: '',
createAt: '',
customerCellphone: '',
customerId: undefined,
customerId: 0,
customerName: '',
deductionBean: undefined,
deductionMoney: undefined,
deductionBean: 0,
deductionMoney: 0,
equipmentNum: '',
equipmentPosition: '',
id: undefined,
operateId: undefined,
id: 0,
operateId: 0,
operateName: '',
operationMode: '',
orderName: '',
......@@ -87,10 +99,10 @@ class BarCode extends Component {
orderState: '',
outTradeNo: '',
payType: '',
payableMoney: undefined,
serviceId: undefined,
payableMoney: 0,
serviceId: 0,
serviceName: '',
thirdDiscountMoney: undefined,
thirdDiscountMoney: 0,
thirdTradeNumber: '',
updateDate: '',
},
......@@ -122,12 +134,39 @@ class BarCode extends Component {
this.fetchOrder(res.data[0].id);
this.setState({ showPayOrder: true });
} else {
this.drawBarCode(false);
this.drawBarCode();
}
})
.catch(err => {
console.log(err);
});
console.log('调整亮度');
Taro.getScreenBrightness()
.then(({ value }) => {
console.log(value);
this.setState({
ScreenBrightness: value,
});
Taro.setScreenBrightness({
value: 1,
});
})
.catch(err => {
console.log(err);
Taro.setScreenBrightness({
value: 1,
});
});
}
componentWillUnmount() {
console.log('调整亮度');
const { ScreenBrightness } = this.state;
console.log(ScreenBrightness);
Taro.setScreenBrightness({
value: ScreenBrightness,
});
}
fetchOrder(id: number) {
......@@ -148,32 +187,46 @@ class BarCode extends Component {
}
payDoneHandle() {
const { showBig } = this.state;
this.setState(
{
showPayOrder: false,
},
() => {
this.drawBarCode(showBig);
this.drawBarCode();
},
);
}
drawBarCode(showBig: boolean) {
drawBarCode() {
const { userinfo } = this.props;
if (showBig) {
wxbarcode.barcode('BarCode', userinfo.idBar, 646, 188);
} else {
wxbarcode.barcode('BarCode', userinfo.idBar, 700, 364);
}
let idBar = userinfo.idBar.substring(0, userinfo.idBar.length - 2) + '04';
wxbarcode.barcode('BarCode', idBar, 646, 188);
wxbarcode.barcode('BarCodeBig', idBar, 700, 364);
}
toggleBigBarCode() {
const { showBig } = this.state;
this.drawBarCode(showBig);
this.setState({
showBig: !showBig,
});
}
refreshCodeBar() {
const { updateUserInfo } = this.props;
refreshCodeBar()
.then(res => {
console.log(res);
const data = res.data;
updateUserInfo({
idBar: data,
});
this.drawBarCode();
})
.catch(err => {
Taro.showToast({
title: err.msg || '获取失败',
icon: 'none',
});
});
}
render() {
const { userinfo } = this.props;
......@@ -198,21 +251,28 @@ class BarCode extends Component {
className={`BarCodeBox ${showPayOrder ? 'blur' : ''} ${
showBig ? 'BarCodeBoxBig' : ''
}`}>
{showBig ? (
<Image className='bg' src={BarCodeBoxBigBg} />
) : (
<Image className='bg' src={BarCodeBoxBg} />
<Image
className='BarCodeBox-refresh'
src={RefreshIcon}
onClick={this.refreshCodeBar}
/>
{showPayOrder ? null : (
<View className={`BarCodeImg ${showBig ? 'BarCodeImgBig' : ''}`}>
<Canvas
className={`BarCodeCav ${showBig ? 'show' : ''}`}
canvasId='BarCodeBig'
/>
<Canvas
className={`BarCodeCav ${showBig ? '' : 'show'}`}
canvasId='BarCode'
/>
</View>
)}
{!showBig && (
<Image className='BarCodeBox-refresh' src={RefreshIcon} />
)}
<View className={`BarCodeImg ${showBig ? 'BarCodeImgBig' : ''}`}>
{showPayOrder ? null : (
<Canvas className='BarCodeCav' canvasId='BarCode' />
)}
</View>
<View className='toggleBtn' onClick={this.toggleBigBarCode}>
{showBig ? '缩小' : '放大'}
<Image
className={`arricon ${showBig ? 'rever' : ''}`}
src={ArrIcon}
/>
</View>
</View>
</View>
......
.checkTelephone {
width: 100%;
height: 100%;
overflow: hidden;
// background: url('../../images/login/bg@2x.png') center;
background-size: cover;
}
.loginBox {
width: 634px;
height: 538px;
margin: 180px auto 0;
background-color: rgba(255, 255, 255, 0.5);
border-radius: 8px;
padding: 50px 40px 0;
line-height: 88px;
.loginBox-input {
box-sizing: border-box;
background-color: #fff;
width: 100%;
height: 88px;
padding: 0 20px;
font-size: 30px;
margin-bottom: 50px;
border-radius: 8px;
color: #ff9000;
}
.loginBox-input::-webkit-input-placeholder {
/* WebKit browsers */
color: #d9a842;
}
.loginBox-button {
font-size: 28px;
width: 100%;
height: 88px;
background-color: #ff9000;
color: #fff;
border: none;
outline: none;
border-radius: 8px;
}
.loginBox-button.big {
font-size: 34px;
}
.loginBox-button.fetching {
background-color: #ccc;
}
.loginBox-vcodeBox {
display: flex;
}
.vcodeBox-input-wrap {
flex: 1;
margin-right: 20px;
}
.vcodeBox-button-wrap {
text-align: center;
width: 200px;
height: 88px;
}
.countDownText {
color: #ff9000;
font-size: 30px;
}
}
.imgVcodeBox-wrap {
.imgVcodeBox-content {
width: 380px;
height: 332px;
}
.imgVcodeBox {
display: flex;
margin-bottom: 60px;
justify-content: space-between;
}
.imgVcodeBox-item {
width: 180px;
height: 88px;
background-color: #ffebcc;
border-radius: 8px;
}
.loginBox-input {
background-color: #ffebcc;
color: #d9a842;
}
}
import { ComponentClass } from 'react';
import Taro, { Component } from '@tarojs/taro';
import { View, Text, Button, Input } from '@tarojs/components';
import './CheckTelephone.scss';
type PageOwnProps = {};
type PageState = {
count: number;
timer: null;
fetching: boolean;
tel: string;
code: string;
sending: boolean;
vcode: string;
imgCode: string;
imgVcode: string;
dialogVisible: boolean;
};
interface CheckTelephone {
state: PageState;
}
class CheckTelephone extends Component {
constructor(props) {
super(props);
this.state = {
timer: null,
fetching: false,
tel: '',
code: '',
count: 60,
sending: false,
vcode: '',
imgCode: '',
imgVcode: '',
dialogVisible: false,
};
}
fetchImageVcode = () => {
console.log('in fetchImageVcode');
};
registerUser = () => {
Taro.navigateTo({
url: '/pages/Register/Register',
});
};
render() {
const { sending, count } = this.state;
return (
<View className='checkTelephone'>
<View className='loginBox'>
<Input
className='loginBox-input'
type='text'
placeholder='输入您的手机号'
/>
<View className='loginBox-vcodeBox'>
<View className='vcodeBox-input-wrap'>
<Input
className='loginBox-input'
type='text'
placeholder='请输入短信验证码'
/>
</View>
<View className='vcodeBox-button-wrap'>
{sending && <Text className='countDownText'>{{ count }}s</Text>}
<Button
v-else
className='loginBox-button'
onClick={this.fetchImageVcode}>
获取验证码
</Button>
</View>
</View>
<Button className='loginBox-button big' onClick={this.registerUser}>
登 录
</Button>
{/* // <ks-Dialog
// class="imgVcodeBox-wrap"
// :visible.sync="dialogVisible"
// top="180px"
// >
// <View class="imgVcodeBox-content">
// <View class="imgVcodeBox">
// <View class="imgVcodeBox-item">
// <input
// class="loginBox-input"
// type="text"
// v-model="imgCode"
// maxlength="6"
// />
// </View>
// <CodeView class="imgVcodeBox-item" :value="imgVcode"></CodeView>
// </View>
// <button v-if="fetching" class="loginBox-button big fetching">
// 确认
// </button>
// <button v-else class="loginBox-button big" @click="fetchVcode">
// 确认
// </button>
// </View>
// </ks-Dialog> */}
</View>
</View>
);
}
}
export default CheckTelephone as ComponentClass<PageOwnProps, PageState>;
......@@ -3,7 +3,6 @@ import Taro, { Component, Config } from '@tarojs/taro';
import { View, Textarea, Button } from '@tarojs/components';
import { fetchFeedback } from '../../api/customer';
import { connect } from '@tarojs/redux';
import { UserState } from 'src/store/rootReducers/userinfo';
import './Feedback.scss';
......@@ -43,7 +42,7 @@ class Feedback extends Component<PageProps, PageState> {
feedbackHandle() {
Taro.showLoading();
const { feedbackContent } = this.state;
if (feedbackContent && feedbackContent.length > 5) {
if (feedbackContent && feedbackContent.length >= 5) {
const {
areaId,
areaName,
......
......@@ -175,6 +175,14 @@
font-size: 32px;
color: #fff;
font-weight: bold;
.Home-Announcement-Content-title {
height: 40px;
line-height: 40px;
flex: 1;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ContentDate {
font-size: 24px;
font-weight: normal;
......
......@@ -16,28 +16,45 @@ import UserHeaderF from '../../images/home/img_girl_touxiang@2x.png';
import './Home.scss';
import { connect } from '@tarojs/redux';
import { UserState } from '../../store/rootReducers/userinfo';
import {
UserState,
updateUserInfo,
INITIAL_STATE as userINitState,
} from '../../store/rootReducers/userinfo';
import { fetchBeanCount } from '../../api/bean';
import { fetchAnn, SectionItem } from '../../api/announcement';
import { appLogout } from '../../api/customer';
import { Customer } from '@/types/Customer/Customer';
type PageStateProps = {
userinfo: UserState;
userinfo: Customer;
};
type PageDispatchProps = {
updateUserInfo: (e: UserState) => void;
};
type PageState = {
barMenuVisiable: boolean;
commBean: number;
hairDryerBean: number;
annItem: SectionItem;
};
type IProps = PageStateProps & PageDispatchProps;
interface Home {
props: PageStateProps;
props: IProps;
state: PageState;
}
@connect(({ userinfo }) => ({
userinfo,
}))
@connect(
({ userinfo }) => ({
userinfo,
}),
dispatch => ({
updateUserInfo(entity: UserState) {
dispatch(updateUserInfo(entity));
},
}),
)
class Home extends Component {
constructor(props) {
super(props);
......@@ -63,7 +80,29 @@ class Home extends Component {
componentWillMount() {
this.getInitData();
}
componentDidShow() {
this.getBeanCountData();
}
getInitData() {
this.getBeanCountData();
const { userinfo } = this.props;
fetchAnn({
campusId: userinfo.areaId,
customerId: userinfo.customerId,
})
.then(res => {
if (res) {
this.setState({
annItem: res,
});
}
})
.catch(err => {
console.error(err);
});
}
getBeanCountData() {
const { userinfo } = this.props;
fetchBeanCount({
id: userinfo.customerId,
......@@ -74,7 +113,7 @@ class Home extends Component {
.then(res => {
const data = res.data;
let commBeanItem = data.find(item => item.serviceId === '1');
let hairDryerBeanItem = data.find(item => item.serviceId === '1');
let hairDryerBeanItem = data.find(item => item.serviceId === '4');
let commBean = commBeanItem ? commBeanItem.money : 0.0;
let hairDryerBean = hairDryerBeanItem ? hairDryerBeanItem.money : 0.0;
this.setState({
......@@ -83,65 +122,6 @@ class Home extends Component {
});
})
.catch(console.error);
fetchAnn({
campusId: userinfo.areaId,
customerId: userinfo.customerId,
})
.then(res => {
if (res) {
this.setState({
annItem: res,
});
}
})
.catch(err => {
// this.setState({
// annItem: {
// id: 896,
// styleType: 'ANNOUNCEMENT',
// name: '公告1',
// titleTypeRemark: '无',
// titleType: 'NONE',
// titleContent: '',
// sort: 3,
// updateTime: 1528770103000,
// itemsCount: 10,
// items: [
// {
// id: 301070,
// title: 'ASFDSGSD大苏打',
// multiImageType: 'SINGLE',
// source: '关机开不开地方',
// linkUrls: ['sqwerqwerqwefsf'],
// linkType: 'DEFAULT',
// jumpUrl: '',
// urlParameters: {},
// sort: 1,
// loadAd: false,
// mandatoryPrompt: false,
// createTime: '2018-06-01 10:41:11',
// updateTime: '2019-01-25 09:43:17',
// },
// {
// id: 301073,
// title: '啊实打实的阿斯顿',
// multiImageType: 'SINGLE',
// source: '个撒大',
// linkUrls: ['sqwerqwerqwefsf'],
// linkType: 'DEFAULT',
// jumpUrl: '',
// urlParameters: {},
// sort: 2,
// loadAd: false,
// mandatoryPrompt: false,
// createTime: '2018-06-12 10:52:15',
// updateTime: '2019-01-25 09:47:39',
// },
// ],
// },
// });
console.error(err);
});
}
goSetting() {
......@@ -155,9 +135,9 @@ class Home extends Component {
url: '/pages/Feedback/Feedback',
});
}
goAnn() {
goAnn(id: number) {
Taro.navigateTo({
url: '/pages/Announcement/Announcement?sectionId=896',
url: '/pages/Announcement/Announcement?sectionId=' + id,
});
}
......@@ -179,19 +159,21 @@ class Home extends Component {
}));
}
logoutHandle() {
const { updateUserInfo } = this.props;
appLogout()
.then(() => {
updateUserInfo(userINitState);
Taro.redirectTo({
url: '/pages/index/index',
});
})
.catch(console.log);
}
formatePhone = phone => {
formatePhone = (phone: string) => {
let newPhone = phone.replace(/([0-9]{3})([0-9]{4})([0-9]{4})/, '$1****$3');
return newPhone;
};
geAnnDetail(id: number, title: string) {
geAnnDetail(id: number) {
console.log(id);
Taro.navigateTo({
url: `/pages/Content/Content?id=${id}`,
......@@ -247,12 +229,16 @@ class Home extends Component {
<View className='Home-UserBox-BeanItem'>
<Image className='Home-UserBox-BeanIcon' src={HBeanIcon} />
<Text>吹风豆:</Text>
<Text className='Home-UserBox-BeanCount'>{hairDryerBean}</Text>
<Text className='Home-UserBox-BeanCount'>
{hairDryerBean.toFixed(2)}
</Text>
</View>
<View className='Home-UserBox-BeanItem'>
<Image className='Home-UserBox-BeanIcon' src={TBeanIcon} />
<Text>通用豆:</Text>
<Text className='Home-UserBox-BeanCount'>{commBean}</Text>
<Text className='Home-UserBox-BeanCount'>
{commBean.toFixed(2)}
</Text>
</View>
</View>
<View className='Home-UserBox-Order'>
......@@ -275,7 +261,9 @@ class Home extends Component {
<Image className='bg' src={AnnouncementBg} />
<View className='Home-Announcement-title'>
<Text>最新公告</Text>
<View className='Home-Announcement-more' onClick={this.goAnn}>
<View
className='Home-Announcement-more'
onClick={() => this.goAnn(annItem.id)}>
更多
<Image className='more-icon' src={MoreIcon} />
</View>
......@@ -283,10 +271,10 @@ class Home extends Component {
{annItem.items.length && (
<View
className='Home-Announcement-Content'
onClick={() =>
this.geAnnDetail(annItem.items[0].id, annItem.items[0].title)
}>
<Text>{annItem.items[0].title}</Text>
onClick={() => this.geAnnDetail(annItem.items[0].id)}>
<Text className='Home-Announcement-Content-title'>
{annItem.items[0].title}
</Text>
<Text className='ContentDate'>
{annItem.items[0].updateTime}
</Text>
......
......@@ -5,14 +5,16 @@ import { View, Button, Input, Navigator } from '@tarojs/components';
import './Login.scss';
import { appLogin } from '../../api/customer';
import { connect } from '@tarojs/redux';
import { updateUserInfo } from '../../store/rootReducers/userinfo';
import { LoginInfoVo } from '../../api/baseClass';
import { updateUserInfo, UserState } from '../../store/rootReducers/userinfo';
import { NotRegisterCode } from '../../constants/index';
type PageDispatchProps = {
updateUserInfo: (e: LoginInfoVo) => void;
userinfo: UserState;
updateUserInfo: (e: UserState) => void;
};
type PageState = {
fetching: boolean;
account: string;
pwd: string;
};
......@@ -23,9 +25,9 @@ interface Login {
}
@connect(
() => ({}),
({ userinfo }) => ({ userinfo }),
dispatch => ({
updateUserInfo(data: LoginInfoVo) {
updateUserInfo(data: UserState) {
dispatch(updateUserInfo(data));
},
}),
......@@ -38,6 +40,7 @@ class Login extends Component {
constructor(props) {
super(props);
this.state = {
fetching: false,
account: '',
pwd: '',
};
......@@ -63,22 +66,48 @@ class Login extends Component {
}
loginHandle(): void {
if (this.state.fetching) return;
if (this.validataLoginData()) {
this.setState({
fetching: true,
});
const { updateUserInfo, userinfo } = this.props;
const { account, pwd } = this.state;
console.log('in loginHandle');
appLogin({
loginAccount: account,
password: pwd,
code: userinfo.code,
})
.then(res => {
const data = res.data;
console.log(data);
this.props.updateUserInfo(data);
Taro.navigateTo({
updateUserInfo(data);
Taro.reLaunch({
url: '/pages/Home/Home',
});
})
.catch(console.error);
.catch(err => {
console.log(err);
if (err.code && err.code === NotRegisterCode) {
updateUserInfo({
customerPhone: account,
});
setTimeout(() => {
this.setState({
fetching: false,
});
Taro.navigateTo({
url: '/pages/Register/Register',
});
}, 2000);
} else {
this.setState({
fetching: false,
});
}
});
}
}
......@@ -94,6 +123,7 @@ class Login extends Component {
placeholder='请输入账号手机号'
type='number'
value={account}
maxLength={11}
onInput={({ detail: { value } }) => {
this.setState({
account: value,
......@@ -107,6 +137,7 @@ class Login extends Component {
password
placeholder='请输入密码'
value={pwd}
maxLength={20}
onInput={({ detail: { value } }) => {
this.setState({
pwd: value,
......
......@@ -118,6 +118,7 @@ class OrderDetail extends Component {
equipmentNum,
equipmentPosition,
deductionMoney,
thirdDiscountMoney,
} = this.state;
const payTypeName = getPayType(payType);
return (
......@@ -140,7 +141,7 @@ class OrderDetail extends Component {
</View>
{deductionBean ? (
<View className='OrderDetail-payinfo'>
<Text>通用豆抵扣</Text>
<Text>{serviceName ? serviceName : ''}豆抵扣</Text>
<Text className='deduction'>{deductionBean.toFixed(2)}</Text>
</View>
) : null}
......@@ -150,6 +151,12 @@ class OrderDetail extends Component {
<Text className='deduction'>{deductionMoney.toFixed(2)}</Text>
</View>
) : null}
{thirdDiscountMoney ? (
<View className='OrderDetail-payinfo'>
<Text>三方抵扣</Text>
<Text className='deduction'>{thirdDiscountMoney.toFixed(2)}</Text>
</View>
) : null}
<View className='OrderDetail-payinfo'>
<Text>支付方式</Text>
......
......@@ -15,13 +15,12 @@ import {
} from './actions';
import { StoreState } from './store';
import { fetchAllOrder, fetchPayOrder } from '../../../api/order';
import { UserState } from '../../../store/rootReducers/userinfo';
import { ConsumeOrder } from '../../../api/baseClass';
import Order, { AllOrderItem } from '../../../types/Order/Order';
import { Customer } from '@/types/Customer/Customer';
type PageStateProps = {
orderList: StoreState;
userinfo: UserState;
userinfo: Customer;
};
type PageDispatchProps = {
toggleOrderState: (state: String) => void;
......@@ -33,8 +32,13 @@ type PageOwnProps = {};
type PageProps = PageStateProps & PageDispatchProps & PageOwnProps;
type PageState = {
needRefresh: boolean;
};
interface OrderList {
props: PageProps;
state: PageState;
}
@connect(
......@@ -52,7 +56,7 @@ interface OrderList {
updateAllOrder(data) {
dispatch(updateAllOrderList(data));
},
})
}),
)
class OrderList extends Component {
config: Config = {
......@@ -61,10 +65,21 @@ class OrderList extends Component {
};
constructor(props: PageProps) {
super(props);
this.state = {
needRefresh: false,
};
}
componentWillMount() {
this.getPayOrderHandle();
this.getAllOrderHandle();
}
componentDidShow() {
const { needRefresh } = this.state;
if (needRefresh) {
this.getPayOrderHandle();
this.getAllOrderHandle();
}
}
onPullDownRefresh() {
......@@ -95,7 +110,7 @@ class OrderList extends Component {
: {
customerId: userinfo.customerId,
pageSize: 10,
}
},
)
.then(res => {
console.log(res);
......@@ -119,7 +134,7 @@ class OrderList extends Component {
: {
customerId: customerId,
pageSize: 10,
}
},
)
.then(res => {
console.log(res);
......@@ -129,12 +144,18 @@ class OrderList extends Component {
}
goPayPage(data) {
this.setState({
needRefresh: true,
});
this.$preload({ id: data.id });
Taro.navigateTo({
url: '/pages/Order/OrderPay/OrderPay',
});
}
goDetail(data) {
this.setState({
needRefresh: false,
});
this.$preload(data);
Taro.navigateTo({
url: '/pages/Order/OrderDetail/OrderDetail',
......@@ -187,14 +208,12 @@ class OrderList extends Component {
<View className='Tab'>
<Text
className={`Tab-item ${orderState === '1' ? 'active' : ''}`}
onClick={() => this.toggleStateHandle('1')}
>
onClick={() => this.toggleStateHandle('1')}>
待付款
</Text>
<Text
className={`Tab-item ${orderState === 'all' ? 'active' : ''}`}
onClick={() => this.toggleStateHandle('all')}
>
onClick={() => this.toggleStateHandle('all')}>
全部
</Text>
</View>
......@@ -206,8 +225,7 @@ class OrderList extends Component {
upperThreshold={-100}
lowerThreshold={70}
scrollWithAnimation
scrollTop={0}
>
scrollTop={0}>
{orderState === '1'
? payList.map(order => (
<OrderItem
......
......@@ -4,20 +4,20 @@ import { View } from '@tarojs/components';
import OrderTitle from '../components/OrderTitle/OrderTitle';
import OrderInfo from '../components/OrderInfo/OrderInfo';
import { fetchOrderDetailAndPay, fetchDeductionInfo } from '../../../api/order';
import { fetchOrderDetailAndPay } from '../../../api/order';
import './OrderPay.scss';
import {
ConsumeOrder,
CustomerBeanAccountVo,
PaymentAndActiveInfo,
} from '../../../api/baseClass';
import { connect } from '@tarojs/redux';
import { UserState } from 'src/store/rootReducers/userinfo';
import OrderPayway from '../components/OrderPayway/OrderPayway';
import Order from '@/types/Order/Order';
import { Customer } from '@/types/Customer/Customer';
type PageStateProps = {
userinfo: UserState;
userinfo: Customer;
};
type PageProps = {
id?: number;
......@@ -25,7 +25,7 @@ type PageProps = {
type PageState = {
prePay: boolean;
accounts: CustomerBeanAccountVo[];
orderInfo: ConsumeOrder;
orderInfo: Order;
payInfos: {
paymentAndActiveInfos: PaymentAndActiveInfo[];
paymentConfId: number;
......@@ -48,20 +48,20 @@ class OrderPay extends Component {
prePay: true,
accounts: [],
orderInfo: {
actualMoney: undefined,
areaId: undefined,
actualMoney: 0,
areaId: 0,
areaName: '',
consumeType: '',
createAt: '',
customerCellphone: '',
customerId: undefined,
customerId: 0,
customerName: '',
deductionBean: undefined,
deductionMoney: undefined,
deductionBean: 0,
deductionMoney: 0,
equipmentNum: '',
equipmentPosition: '',
id: undefined,
operateId: undefined,
id: 0,
operateId: 0,
operateName: '',
operationMode: '',
orderName: '',
......@@ -69,10 +69,10 @@ class OrderPay extends Component {
orderState: '',
outTradeNo: '',
payType: '',
payableMoney: undefined,
serviceId: undefined,
payableMoney: 0,
serviceId: 0,
serviceName: '',
thirdDiscountMoney: undefined,
thirdDiscountMoney: 0,
thirdTradeNumber: '',
updateDate: '',
},
......@@ -116,7 +116,9 @@ class OrderPay extends Component {
const { orderInfo, payInfos, accounts } = this.state;
return (
<View className='OrderPay topBr'>
<OrderTitle price={orderInfo.payableMoney} />
<OrderTitle
price={orderInfo.payableMoney ? orderInfo.payableMoney : 0}
/>
<OrderInfo orderInfo={orderInfo} />
<View className='OrderPay-line' />
<OrderPayway
......
.OrderDetail-info,
.OrderDetail-payinfo {
.OrderDetail-info {
display: flex;
height: 60px;
line-height: 60px;
justify-content: space-between;
font-size: 28px;
color: #666;
.OrderDetail-info-title {
width: 120px;
}
.OrderDetail-info-content {
text-align: right;
flex: 1;
}
}
......@@ -47,28 +47,32 @@ class OrderInfo extends Component {
return (
<View>
<View className='OrderDetail-info'>
<Text>商品说明</Text>
<Text>{serviceName ? serviceName : ''}</Text>
<Text className='OrderDetail-info-title'>商品说明</Text>
<Text className='OrderDetail-info-content'>
{serviceName ? serviceName : ''}
</Text>
</View>
<View className='OrderDetail-info'>
<Text>消费时间</Text>
<Text>{createAt}</Text>
<Text className='OrderDetail-info-title'>消费时间</Text>
<Text className='OrderDetail-info-content'>{createAt}</Text>
</View>
<View className='OrderDetail-info'>
<Text>订单号</Text>
<Text>{orderNumber}</Text>
<Text className='OrderDetail-info-title'>订单号</Text>
<Text className='OrderDetail-info-content'>{orderNumber}</Text>
</View>
<View className='OrderDetail-info'>
<Text>所属区域</Text>
<Text>{areaName}</Text>
<Text className='OrderDetail-info-title'>所属区域</Text>
<Text className='OrderDetail-info-content'>{areaName}</Text>
</View>
<View className='OrderDetail-info'>
<Text>设备编号</Text>
<Text>{equipmentNum}</Text>
<Text className='OrderDetail-info-title'>设备编号</Text>
<Text className='OrderDetail-info-content'>{equipmentNum}</Text>
</View>
<View className='OrderDetail-info'>
<Text>设备位置</Text>
<Text>{equipmentPosition ? equipmentPosition : ''}</Text>
<Text className='OrderDetail-info-title'>设备位置</Text>
<Text className='OrderDetail-info-content'>
{equipmentPosition ? equipmentPosition : ''}
</Text>
</View>
</View>
);
......
......@@ -19,6 +19,9 @@
border: 6px solid #c8c8c8;
border-radius: 50%;
}
.OrderPay-check.disabled {
background-color: #c8c8c8;
}
.checked {
border-color: #ffd506;
background-color: #ffd506;
......@@ -48,7 +51,7 @@
.OrderPay-DeductionInfo::before {
content: '';
position: absolute;
top: -12px;
top: -10px;
left: 120px;
border-bottom: 12px solid #ffe4e4;
border-left: 11px solid transparent;
......
import Taro, { Component } from '@tarojs/taro';
import { ComponentClass } from 'react';
import { Button, View, Image, Text } from '@tarojs/components';
import { UserState } from '../../../../store/rootReducers/userinfo';
import {
PaymentAndActiveInfo,
CustomerBeanAccountVo,
ConsumeOrder,
} from '../../../../api/baseClass';
import { confirmPay, fetchDeductionInfo } from '../../../../api/order';
......@@ -20,11 +18,13 @@ import Utf8 from 'crypto-js/enc-utf8';
import ECBmode from 'crypto-js/mode-ecb';
import PaddingPkcs7 from 'crypto-js/pad-pkcs7';
import { getPayType } from '../../../../utils/payType';
import Order from '../../../../types/Order/Order';
import { Customer } from '../../../../types/Customer/Customer';
type PageOwnProps = {
onPayDoneCallback: () => void;
userinfo: UserState;
orderInfo: ConsumeOrder;
userinfo: Customer;
orderInfo: Order;
accounts: CustomerBeanAccountVo[];
payInfos: {
paymentAndActiveInfos: PaymentAndActiveInfo[];
......@@ -67,9 +67,34 @@ class OrderPayway extends Component {
paymentAndActiveInfos: [],
paymentConfId: 0,
},
orderInfo: {
actualMoney: 0,
areaId: 0,
areaName: '',
consumeType: '',
createAt: '',
customerCellphone: '',
customerId: 0,
customerName: '',
deductionBean: 0,
deductionMoney: 0,
equipmentNum: '',
equipmentPosition: '',
id: 0,
operateId: 0,
operateName: '',
operationMode: '',
orderName: '',
orderNumber: '',
orderState: '',
outTradeNo: '',
payType: '',
payableMoney: 0,
serviceId: 0,
serviceName: '',
thirdDiscountMoney: 0,
thirdTradeNumber: '',
updateDate: '',
},
};
constructor(props: PageOwnProps) {
......@@ -146,8 +171,10 @@ class OrderPayway extends Component {
const { payWay } = this.state;
confirmPay({
orderId: id,
payType: payWay.payType,
[payWay.activeId ? 'activeId' : 'notUse']: payWay.activeId,
payType: payWay ? payWay.payType : '',
[payWay && payWay.activeId ? 'activeId' : 'notUse']: payWay
? payWay.activeId
: 0,
returnUrl: '',
callType: '3',
paymentConfId: payInfos.paymentConfId,
......@@ -163,24 +190,23 @@ class OrderPayway extends Component {
}).toString(Utf8),
);
console.log(payData);
Taro.requestPayment({
timeStamp: payData.msg.timeStamp.toString(),
nonceStr: payData.msg.nonceStr,
package: payData.msg.package,
signType: payData.msg.signType,
paySign: payData.msg.paySign,
success(res) {
})
.then(res => {
console.log(res);
onPayDoneCallback();
},
fail(res) {
})
.catch(err => {
Taro.showToast({
title: res.msg || '发起支付失败',
title: err.msg || '发起支付失败',
icon: 'none',
});
},
});
});
} else {
onPayDoneCallback();
}
......@@ -207,9 +233,6 @@ class OrderPayway extends Component {
item.payType === '7' ||
item.payType === '8',
);
const payInfo = prePay
? null
: payInfoList.find(item => item.payType === payWay.payType);
const useAmi = accountsInfo && accountsInfo['6'] >= orderInfo.payableMoney;
const useCom = accountsInfo && accountsInfo['8'] >= orderInfo.payableMoney;
const useBean = accountsInfo && accountsInfo['7'] >= orderInfo.payableMoney;
......@@ -244,9 +267,9 @@ class OrderPayway extends Component {
<Image className='OrderPay-icon' src={payWayAimiLogo} />
<Text className='OrderPay-text'>
{getPayType(payway.payType)}(余额:
{accountsInfo &&
accountsInfo['6'] &&
accountsInfo['6'].toFixed(2)}
{accountsInfo && accountsInfo['6']
? accountsInfo['6'].toFixed(2)
: '0.00'}
)
</Text>
<View
......@@ -254,7 +277,7 @@ class OrderPayway extends Component {
payWay && payWay.payType === payway.payType
? 'checked'
: ''
}`}
} ${useAmi ? '' : 'disabled'}`}
/>
</View>
) : payway.payType === '7' ? (
......@@ -264,7 +287,7 @@ class OrderPayway extends Component {
onClick={() => this.changePayWay(payway, !useBean)}>
<Image className='OrderPay-icon' src={payWayHairLogo} />
<Text className='OrderPay-text'>
{getPayType(payway.payType)}(余额:
{orderInfo.serviceName}(余额:
{accountsInfo && accountsInfo['7']
? accountsInfo['7'].toFixed(2)
: '0.00'}
......@@ -275,7 +298,7 @@ class OrderPayway extends Component {
payWay && payWay.payType === payway.payType
? 'checked'
: ''
}`}
} ${useBean ? '' : 'disabled'}`}
/>
</View>
) : payway.payType === '8' ? (
......@@ -296,7 +319,7 @@ class OrderPayway extends Component {
payWay && payWay.payType === payway.payType
? 'checked'
: ''
}`}
} ${useCom ? '' : 'disabled'}`}
/>
</View>
) : null,
......
......@@ -17,15 +17,19 @@ import agreeNotIcon from '../../images/login/icon_zhuce_nor@2x.png';
import { connect } from '@tarojs/redux';
import { UserState, updateUserInfo } from '../../store/rootReducers/userinfo';
import { wxUserRegister } from '../../api/customer';
import { replaceIllegalPwd } from '../../utils/pwd';
import { Customer } from '@/types/Customer/Customer';
import { ANN_LINK_URL } from '@/constants';
type PageStateProps = {
userinfo: UserState;
userinfo: Customer;
};
type PageDispatchProps = {
updateUserInfo: (e: UserState) => void;
};
type PageState = {
fetching: boolean;
name: string;
cellphone: string;
vcode: string;
......@@ -60,9 +64,11 @@ class Register extends Component {
constructor(props: IProps) {
super(props);
const { customerPhone } = props.userinfo;
this.state = {
fetching: false,
name: '',
cellphone: '',
cellphone: customerPhone,
vcode: '',
pwd: '',
checkPwd: '',
......@@ -78,32 +84,17 @@ class Register extends Component {
sex: value,
});
}
getVcode() {
const { cellphone } = this.state;
if (cellphone.length == 11) {
// getVcode({
// tel: cellphone,
// })
// .then(res => {
// console.log(res);
// Taro.showToast({
// title: res.msg,
// mask: true,
// });
// })
// .catch(console.error);
this.refs.Vcode.countStart();
} else {
Taro.showToast({
title: '输入正确的手机号',
icon: 'none',
mask: true,
});
}
setPwdValue(key: string, value: string) {
let val = replaceIllegalPwd(value);
this.setState({
[key]: val,
});
return val;
}
validateRegisterEntity(): boolean {
const { name, cellphone, pwd, checkPwd } = this.state;
const { name, cellphone, vcode, pwd, checkPwd } = this.state;
const {
userinfo: { areaId },
} = this.props;
......@@ -121,14 +112,21 @@ class Register extends Component {
});
return false;
}
if (!pwd) {
if (!vcode || vcode.length !== 6) {
Taro.showToast({
title: '请输入码',
title: '请输入6位验证码',
icon: 'none',
});
return false;
}
if (!checkPwd) {
if (!pwd || pwd.length < 6) {
Taro.showToast({
title: '请输入大于6位密码',
icon: 'none',
});
return false;
}
if (!checkPwd || checkPwd.length < 6) {
Taro.showToast({
title: '请输入确认密码',
icon: 'none',
......@@ -137,7 +135,7 @@ class Register extends Component {
}
if (pwd != checkPwd) {
Taro.showToast({
title: '请输入确认密码',
title: '两次密码不一致',
icon: 'none',
});
return false;
......@@ -153,34 +151,48 @@ class Register extends Component {
}
getRegister() {
if (this.state.fetching) return;
if (this.validateRegisterEntity()) {
this.setState({
fetching: true,
});
const { name, cellphone, pwd, sex, vcode } = this.state;
const {
userinfo: { areaId, areaName },
updateUserInfo,
} = this.props;
wxUserRegister({
areaId: areaId,
areaName: areaName,
customerName: name,
customerPhone: cellphone,
customerSex: sex,
password: pwd,
verificationCode: vcode,
})
.then(res => {
const { register, wxToken, ...userInfo } = res.data;
updateUserInfo({
...userInfo,
token: wxToken,
});
Taro.showToast({
title: '注册成功',
});
setTimeout(() => {
Taro.redirectTo({
url: '/pages/Home/Home',
Taro.login()
.then(res => res.code)
.then(code => {
wxUserRegister({
code: code,
areaId: areaId,
areaName: areaName,
customerName: name,
customerPhone: cellphone,
customerSex: sex,
password: pwd,
verificationCode: vcode,
})
.then(res => {
const data = res.data;
console.log(data);
updateUserInfo(data);
Taro.showToast({
title: '注册成功',
});
setTimeout(() => {
Taro.reLaunch({
url: '/pages/Home/Home',
});
}, 2000);
})
.catch(err => {
console.log(err);
this.setState({
fetching: false,
});
});
}, 2000);
})
.catch(console.log);
}
......@@ -210,6 +222,15 @@ class Register extends Component {
}));
}
goAgreementPage(e) {
e.stopPropagation();
Taro.navigateTo({
url:
'/pages/WebPage/WebPage?url=' +
encodeURIComponent(ANN_LINK_URL + '/agreement.html'),
});
}
render() {
const {
name,
......@@ -311,12 +332,9 @@ class Register extends Component {
placeholder='密码由6-20位组成'
maxLength={20}
value={pwd}
onInput={({ detail: { value } }) => {
this.setState({
pwd: value,
});
return value;
}}
onInput={({ detail: { value } }) =>
this.setPwdValue('pwd', value)
}
/>
<Image
className='registerBox-pwdIcon'
......@@ -332,12 +350,9 @@ class Register extends Component {
placeholder='确认密码'
maxLength={20}
value={checkPwd}
onInput={({ detail: { value } }) => {
this.setState({
checkPwd: value,
});
return value;
}}
onInput={({ detail: { value } }) =>
this.setPwdValue('checkPwd', value)
}
/>
<Image
className='registerBox-pwdIcon'
......@@ -364,7 +379,9 @@ class Register extends Component {
<Image className='registerBox-agreeCheck' src={agreeNotIcon} />
)}
<Text>同意条款</Text>
<Text className='service-deal'>《多彩校园服务协议》</Text>
<Text className='service-deal' onClick={this.goAgreementPage}>
《多彩校园服务协议》
</Text>
</View>
{agree ? (
<Button className='registerBox-button' onClick={this.getRegister}>
......
......@@ -8,6 +8,7 @@ import ToastBox from '../../components/ToastBox/ToastBox';
import './ResetPwd.scss';
import { changePwdByCellphone } from '../../api/customer';
import { replaceIllegalPwd } from '../../utils/pwd';
type PageOwnProps = {};
type PageState = {
......@@ -31,7 +32,7 @@ class ResetPwd extends Component {
constructor(props: PageOwnProps) {
super(props);
this.state = {
cellphone: '18108096099',
cellphone: '',
vcode: '',
pwd: '',
checkPwd: '',
......@@ -40,6 +41,14 @@ class ResetPwd extends Component {
};
}
setPwdValue(key: string, value: string) {
let val = replaceIllegalPwd(value);
this.setState({
[key]: val,
});
return val;
}
togglePwdBox() {
this.setState(({ showPwd }: PageState) => ({
showPwd: !showPwd,
......@@ -62,7 +71,7 @@ class ResetPwd extends Component {
}
if (!vcode || vcode.length !== 6) {
Taro.showToast({
title: '请输入验证码',
title: '请输入6位验证码',
icon: 'none',
});
return false;
......@@ -76,7 +85,7 @@ class ResetPwd extends Component {
}
if (!checkPwd || checkPwd.length < 6) {
Taro.showToast({
title: '请输入大于6位密码',
title: '请输入确认密码',
icon: 'none',
});
return false;
......@@ -111,7 +120,14 @@ class ResetPwd extends Component {
}
}
render() {
const { cellphone, vcode, showPwd, pwd,showCheckPwd, checkPwd } = this.state;
const {
cellphone,
vcode,
showPwd,
pwd,
showCheckPwd,
checkPwd,
} = this.state;
return (
<View className='ResetPwd'>
<ToastBox ref='ToastBox' />
......@@ -162,12 +178,9 @@ class ResetPwd extends Component {
placeholder='输入6-20位新密码'
maxLength={20}
value={pwd}
onInput={({ detail: { value } }) => {
this.setState({
pwd: value,
});
return value;
}}
onInput={({ detail: { value } }) =>
this.setPwdValue('pwd', value)
}
/>
<Image
className='registerBox-pwdIcon'
......@@ -183,12 +196,9 @@ class ResetPwd extends Component {
placeholder='确认6-20位新密码'
maxLength={20}
value={checkPwd}
onInput={({ detail: { value } }) => {
this.setState({
checkPwd: value,
});
return value;
}}
onInput={({ detail: { value } }) =>
this.setPwdValue('checkPwd', value)
}
/>
<Image
className='registerBox-pwdIcon'
......
......@@ -88,4 +88,7 @@
border-bottom: 2px solid #ebebeb;
word-break: break-all;
}
.locationItem:last-child {
border-bottom: none;
}
}
......@@ -5,17 +5,11 @@ import { connect } from '@tarojs/redux';
import { View, Text, Input, Image, ScrollView } from '@tarojs/components';
import SearchIcon from '../../images/login/icon_search@2x.png';
import { fetchAllArea } from '../../api/area';
import { fetchAllArea, Area } from '../../api/area';
import { UserState, updateUserInfo } from '../../store/rootReducers/userinfo';
import './SelectCampus.scss';
type Area = {
id: number;
areaName: string;
initial?: string;
};
type AreaList = Array<{
firstPin: string;
children: Array<Area>;
......@@ -80,6 +74,34 @@ class SelectCampus extends Component {
fetchAllArea()
.then(res => {
console.log(res);
let initialList = [
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
];
let campusIndexArr: Array<string> = [];
let campusList: AreaList = [];
res.data.map((area: Area) => {
......@@ -89,11 +111,12 @@ class SelectCampus extends Component {
if (index > -1) {
campusList[index].children.push(area);
} else {
campusIndexArr.push(firstPin);
campusList.push({
let index = initialList.indexOf(firstPin);
campusIndexArr[index] = firstPin;
campusList[index] = {
firstPin: firstPin,
children: [area],
});
};
}
}
});
......@@ -190,14 +213,16 @@ class SelectCampus extends Component {
</View>
</View>
<View className='infoBar'>
{pinList.map(item => (
<View
key={item}
className='infoItem'
onClick={() => this.showToastHandle(item)}>
{item}
</View>
))}
{pinList.map(item =>
item ? (
<View
key={item}
className='infoItem'
onClick={() => this.showToastHandle(item)}>
{item}
</View>
) : null,
)}
</View>
<View className={showToast ? 'show br8 infoToast' : 'br8 infoToast'}>
{localText}
......@@ -207,22 +232,24 @@ class SelectCampus extends Component {
className='locationList'
scrollIntoView={localText}
scrollWithAnimation>
{filterList.map(campusItem => (
<View key={campusItem.firstPin} className='locationArea'>
<View id={campusItem.firstPin} className='locationTitle'>
{campusItem.firstPin}
</View>
{campusItem.children.map(campus => (
<View
key={campus.id}
className='locationItem'
data-campus={campus}
onClick={this.bindCampus}>
{campus.areaName}
{filterList.map(campusItem =>
campusItem ? (
<View key={campusItem.firstPin} className='locationArea'>
<View id={campusItem.firstPin} className='locationTitle'>
{campusItem.firstPin}
</View>
))}
</View>
))}
{campusItem.children.map(campus => (
<View
key={campus.id}
className='locationItem'
data-campus={campus}
onClick={this.bindCampus}>
{campus.areaName}
</View>
))}
</View>
) : null,
)}
</ScrollView>
</View>
);
......
......@@ -36,6 +36,7 @@
font-size: 32px;
color: #333;
}
.UserSetting-placeholder,
.UserSetting-ContentItem.Disabled {
color: #999;
}
......
......@@ -11,14 +11,23 @@ import radioIcon from '../../images/login/pc_nor_icon@2x.png';
import radioCheckIcon from '../../images/login/pc_sel_icon@2x.png';
import './UserSetting.scss';
import { connect } from '@tarojs/redux';
import { UserState, updateUserInfo } from '../../store/rootReducers/userinfo';
import { updateUserInfo } from '../../store/rootReducers/userinfo';
import { perfectionUserInfo } from '../../api/customer';
import { Customer } from '../../types/Customer/Customer';
type UpdateParams = {
customerId: number;
customerName: string;
customerSex: string;
birthDay: string;
studentNo: string;
entranceDate: string;
};
type PageStateProps = {
userinfo: UserState;
userinfo: Customer;
};
type PageDispatchProps = {
updateUserInfo: (e: UserState) => void;
updateUserInfo: (e: UpdateParams) => void;
};
type PageOwnProps = {};
type PageState = {
......@@ -40,10 +49,10 @@ interface UserSetting {
userinfo,
}),
dispatch => ({
updateUserInfo(entity: UserState) {
updateUserInfo(entity: UpdateParams) {
dispatch(updateUserInfo(entity));
},
})
}),
)
class UserSetting extends Component {
config: Config = {
......@@ -63,12 +72,12 @@ class UserSetting extends Component {
},
} = props;
this.state = {
birthDay: birthDay,
customerHead: customerHead,
customerName: customerName,
customerSex: customerSex,
entranceDate: entranceDate,
studentNo: studentNo,
birthDay: birthDay ? birthDay.split(' ')[0] : '',
customerHead: customerHead ? customerHead : '',
customerName: customerName ? customerName : '',
customerSex: customerSex ? customerSex : '',
entranceDate: entranceDate ? entranceDate.split(' ')[0] : '',
studentNo: studentNo ? studentNo : '',
};
}
......@@ -171,8 +180,7 @@ class UserSetting extends Component {
this.setState({
customerSex: '2',
})
}
>
}>
{customerSex === '2' ? (
<Image className='sexBox-icon' src={radioCheckIcon} />
) : (
......@@ -186,8 +194,7 @@ class UserSetting extends Component {
this.setState({
customerSex: '1',
})
}
>
}>
{customerSex === '1' ? (
<Image className='sexBox-icon' src={radioCheckIcon} />
) : (
......@@ -206,9 +213,14 @@ class UserSetting extends Component {
this.setState({
birthDay: value,
})
}
>
<View>{birthDay}</View>
}>
{birthDay ? (
<View>{birthDay}</View>
) : (
<View className='UserSetting-placeholder'>
{'请选择出生日期'}
</View>
)}
</Picker>
</View>
<View className='UserSetting-ContentItem Disabled'>
......@@ -233,6 +245,8 @@ class UserSetting extends Component {
<Input
className='UserSetting-ContentItem-input'
value={studentNo}
placeholderClass='UserSetting-placeholder'
placeholder='请输入学号'
onInput={({ detail: { value } }) => {
this.setState({
studentNo: value.trim(),
......@@ -250,9 +264,14 @@ class UserSetting extends Component {
this.setState({
entranceDate: value,
})
}
>
<View>{entranceDate}</View>
}>
{entranceDate ? (
<View>{entranceDate}</View>
) : (
<View className='UserSetting-placeholder'>
{'请选择入学日期'}
</View>
)}
</Picker>
</View>
</View>
......
import { Component } from '@tarojs/taro';
import { ComponentClass } from 'react';
import { WebView } from '@tarojs/components';
type PageState = {
linkUrl: string;
};
interface WebPage {
state: PageState;
}
class WebPage extends Component {
constructor(props) {
super(props);
this.state = {
linkUrl: '',
};
}
componentWillMount() {
console.log(this.$router.params);
const { url } = this.$router.params;
if (url) {
this.setState({
linkUrl: url,
});
}
}
render() {
const { linkUrl } = this.state;
return linkUrl && <WebView src={linkUrl} />;
}
}
export default WebPage as ComponentClass<any, PageState>;
......@@ -3,7 +3,6 @@ import Taro, { Component, Config } from '@tarojs/taro';
import { View } from '@tarojs/components';
import './index.scss';
import { LoginReponse } from '../../api/wx';
import { connect } from '@tarojs/redux';
import { updateUserInfo, UserState } from '../../store/rootReducers/userinfo';
......@@ -67,35 +66,25 @@ class Index extends Component {
Taro.login()
.then(res => {
console.log(res);
const code = res.code;
updateUserInfo({
code,
});
appLogin({
code: res.code,
})
.then((res: LoginReponse) => {
const { register, wxToken, ...userInfo } = res.data;
console.log(wxToken);
if (register) {
updateUserInfo({
...userInfo,
token: wxToken,
});
Taro.redirectTo({
url: '/pages/Home/Home',
});
} else {
updateUserInfo({
token: wxToken,
});
Taro.hideLoading();
Taro.redirectTo({
url: '/pages/Login/Login',
});
}
.then(res => {
const data = res.data;
updateUserInfo(data);
Taro.redirectTo({
url: '/pages/Home/Home',
});
})
.catch(err => {
console.log(err);
this.setState({
errorText: err.msg,
Taro.hideLoading();
Taro.redirectTo({
url: '/pages/Login/Login',
});
});
})
......
......@@ -3,8 +3,9 @@ import thunkMiddleware from 'redux-thunk';
import rootReducer from './reducers';
const composeEnhancers =
typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
typeof window === 'object' &&
(window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
// Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
})
: compose;
......
type INITIAL_STATE = {
type ConstantState = {
APP_ID: string;
};
const INITIAL_STATE = {
APP_ID: 'wxf5912b79bba23663',
};
export default function counter(state = INITIAL_STATE) {
export default function counter(state: ConstantState = INITIAL_STATE) {
return state;
}
import Action from '../../types/Store/Actions';
import { Customer } from '../../types/Customer/Customer';
export class UserState {
login?: boolean;
areaId: number;
areaName?: string;
birthDay?: string;
createAt?: string;
createLoginDate?: string;
customerHead?: string;
customerId: number;
customerName?: string;
customerPhone?: string;
customerSex?: string;
customerType?: string;
email?: string;
entranceDate?: string;
hardwareAccount?: string;
hardwarePwd?: string;
hardwareState?: string;
hardwarelastDate?: string;
idBar: string;
idCard?: string;
isFirstRecharge?: number;
lastLoginDate?: string;
loginAccount?: string;
loginPwd?: string;
loginPwdSalt?: string;
loginState?: string;
state?: string;
studentNo?: string;
token?: string;
updateAt?: string;
updateLoginDate?: string;
version?: string;
}
export type UserState = StoreState<Customer & { code: string }>;
const INITIAL_STATE = {
login: false,
areaId: undefined,
export const INITIAL_STATE = {
code: '',
areaId: 0,
areaName: '',
birthDay: '',
createAt: '',
createLoginDate: '',
customerHead: '',
customerId: undefined,
customerId: 0,
customerName: '',
customerPhone: '',
customerSex: '',
......@@ -56,7 +24,7 @@ const INITIAL_STATE = {
hardwarelastDate: '',
idBar: '',
idCard: '',
isFirstRecharge: undefined,
isFirstRecharge: 0,
lastLoginDate: '',
loginAccount: '',
loginPwd: '',
......@@ -76,9 +44,9 @@ export const updateUserInfo = (entity: UserState): Action => ({
});
export default function userinfo(
state: UserState = INITIAL_STATE,
state: Customer = INITIAL_STATE,
actions: Action,
): UserState {
): Customer {
switch (actions.type) {
case 'UPDATE_USERINFO':
return {
......
export type Customer = {
areaId: number;
areaName: string;
birthDay: string;
createAt: string;
createLoginDate: string;
customerHead: string;
customerId: number;
customerName: string;
customerPhone: string;
customerSex: string;
customerType: string;
email: string;
entranceDate: string;
hardwareAccount: string;
hardwarePwd: string;
hardwareState: string;
hardwarelastDate: string;
idBar: string;
idCard: string;
isFirstRecharge: number;
lastLoginDate: string;
loginAccount: string;
loginPwd: string;
loginPwdSalt: string;
loginState: string;
state: string;
studentNo: string;
token: string;
updateAt: string;
updateLoginDate: string;
version: string;
};
......@@ -15,6 +15,7 @@ type Order = {
operateId: number;
operateName: string;
operationMode: string;
orderName: string;
orderNumber: string;
orderState: string;
outTradeNo: string;
......
type StoreState<T> = { [P in keyof T]?: T[P] };
export const replaceIllegalPwd = (val: string) =>
val.replace(/[^a-zA-Z0-9]+/g, '');
......@@ -15,16 +15,14 @@
"sourceMap": true,
"baseUrl": ".",
"rootDir": ".",
"paths": {
"@/*": ["./src/*"]
},
"jsx": "preserve",
"jsxFactory": "Taro.createElement",
"allowJs": true,
"typeRoots": [
"node_modules/@types"
]
"typeRoots": ["node_modules/@types"]
},
"exclude": [
"node_modules",
"dist"
],
"exclude": ["node_modules", "dist"],
"compileOnSave": false
}
......@@ -2003,6 +2003,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4:
safe-buffer "^5.0.1"
sha.js "^2.4.8"
cross-env@^5.2.0:
version "5.2.0"
resolved "http://registry.npm.taobao.org/cross-env/download/cross-env-5.2.0.tgz#6ecd4c015d5773e614039ee529076669b9d126f2"
dependencies:
cross-spawn "^6.0.5"
is-windows "^1.0.0"
cross-spawn@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-3.0.1.tgz#1256037ecb9f0c5f79e3d6ef135e30770184b982"
......@@ -2018,7 +2025,7 @@ cross-spawn@^5.0.1, cross-spawn@^5.1.0:
shebang-command "^1.2.0"
which "^1.2.9"
cross-spawn@^6.0.0:
cross-spawn@^6.0.0, cross-spawn@^6.0.5:
version "6.0.5"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
dependencies:
......@@ -3868,7 +3875,7 @@ is-utf8@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
is-windows@^1.0.2:
is-windows@^1.0.0, is-windows@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment