Authored by htoooth

add form

... ... @@ -4,7 +4,7 @@ import {
} from 'store/yoho/types';
import {createApp} from './app';
import {createApi} from 'create-api';
import {Style, Toast, Dialog} from 'cube-ui'; //eslint-disable-line
import {Style, Toast, Dialog, DatePicker} from 'cube-ui'; //eslint-disable-line
import {get} from 'lodash';
import Lazy from 'vue-lazyload';
import yoho from 'common/yoho';
... ... @@ -26,6 +26,7 @@ window._router = get(store, 'state.yoho.context.route');
Vue.prop('yoho', yoho);
Vue.use(Toast);
Vue.use(DatePicker);
Vue.use(Dialog);
Vue.prop('api', createApi());
Vue.use(Lazy, {error: ''});
... ...
<template>
<CInput :label="label">
<slot>
<div class="wrapper">
<div style="width: 67%; display: inline-block;">
<div>
<input class="input-wrapper" style="width: 40%;" placeholder="选择开始时间" @focus="onFocusStartTime" @blur="onBlurStartTime">
<span style="display: inline-block; width: 5%;">-</span>
<input class="input-wrapper" style="width: 40%;" placeholder="选择结束时间" @focus="onFocusEndTime" @blur="onBlurEndTime">
</div>
</div>
<div style="display: inline-block;">
<Radio :label="{text: '无固定期限', value: 1}"></Radio>
</div>
</div>
</slot>
</CInput>
</template>
<script>
import Input from './input';
import Radio from './radio';
import {DatePicker} from 'cube-ui';
export default {
name: 'CUpload',
props: {
label: {
type: String
}
},
methods: {
onFocusStartTime() {
if (!this.startDatePicker) {
this.startDatePicker = this.$createDatePicker({
title: '选择开始时间',
min: new Date(2008, 7, 8),
max: new Date(2020, 9, 20),
value: new Date(),
onSelect: null,
onCancel: null
});
}
this.startDatePicker.show();
},
onBlurStartTime() {
},
onFocusEndTime() {
if (!this.endDatePicker) {
this.endDatePicker = this.$createDatePicker({
title: '选择结束时间',
min: new Date(2008, 7, 8),
max: new Date(2020, 9, 20),
value: new Date(),
onSelect: null,
onCancel: null
});
}
this.endDatePicker.show();
},
onBlurEndTime() {
},
},
components: {
CInput: Input,
DatePicker,
Radio
}
};
</script>
<style lang="scss" scoped>
.wrapper {
width: 100%;
font-size: 28px;
}
.input-wrapper {
display: inline-block;
}
</style>
... ...
<template>
<div class="fixed-bottom">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'fixed-bottom'
}
</script>
<style lang="scss" scoped>
.fixed-bottom {
position: fixed;
bottom: 0;
width: 100%;
z-index: 3;
}
</style>
... ...
<template>
<div class="form-item">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'FormItem'
};
</script>
<style lang="scss" scoped>
.form-item {
border-bottom: 2px solid #eee;
padding: 36px 0;
}
</style>
... ...
<template>
<div class="form">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'Form',
};
</script>
<style lang="scss" scoped>
</style>
... ...
<template>
<div class="input-class">
<div class="wrapper-label" v-if="label">
<label class="input-label"> {{label}} </label>
<span class="error"></span>
</div>
<slot>
<input class="wrapper-input" :placeholder="placeHolder" />
</slot>
</div>
</template>
<script>
export default {
name: 'Input',
props: {
value: {
type: [String, Number],
default() {
return '';
}
},
label: {
type: String,
default() {
return '';
}
},
placeHolder: {
type: String,
default() {
return '';
}
}
}
};
</script>
<style lang="scss" scoped>
.input-label {
font-size: 36px;
display: block;
}
.wrapper-label {
margin-bottom: 30px;
}
.wrapper-input {
font-size: 28px;
width: 100%;
}
</style>
... ...
<template>
<div class="radio-group">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'Radio-Group',
props: {
value: {
type: [String, Number]
}
},
data() {
return {
labelList: []
};
},
methods: {
getLabels() {
return this.$children.forEach(i => i.$options.name === 'Radio');
},
updateLabel() {
}
}
};
</script>
<style lang="scss" scoped>
.radio-group {
display: flex;
}
</style>
... ...
<template>
<label class="container" @click="onClickLabel">
<span :class="classes"></span>
<span :class="labelClasses">{{label.text}}</span>
</label>
</template>
<script>
export default {
name: 'Radio',
props: {
value: {
type: [String, Number],
default() {
return '';
}
},
label: {
type: Object,
default() {
return {text: '', value: 'radio1'};
}
}
},
data() {
return {
checked: false
};
},
methods: {
updateLabel() {
this.updateStatus();
},
onClickLabel() {
this.$emit('input', this.label.value);
},
updateStatus() {
if (this.value === this.label.value) {
this.checked = true;
} else {
this.checked = false;
}
}
},
computed: {
classes() {
return ['checkmark', {
'cubeic-round-border': !this.checked,
'cubeic-right': this.checked
}];
},
labelClasses() {
return ['radio-label', {
active: this.checked
}];
}
},
watch: {
value() {
this.updateStatus();
}
},
created() {
// this.updateLabel();
this.updateStatus();
}
};
</script>
<style lang="scss" scoped>
.container {
position: relative;
font-size: 28px;
display: flex;
align-content: center;
}
.checkmark {
font-size: 40px;
}
.radio-label {
display: inline-block;
height: 55px;
font-size: 28px;
line-height: 55px;
margin-left: 20px;
color: #999;
&.active {
color: black;
}
}
</style>
... ...
<template>
<CInput :label="label">
<slot>
<Upload></Upload>
</slot>
</CInput>
</template>
<script>
import Input from './input';
import {Upload} from 'cube-ui';
export default {
name: 'CUpload',
props: {
label: {
type: String
}
},
components: {
CInput: Input,
Upload
}
};
</script>
<style lang="scss" scoped>
.cube-upload {
/deep/ .cube-upload-btn {
margin: 0 0;
}
/deep/ .cube-upload-btn-def {
background-color: #eee;
}
}
</style>
... ...
<template>
<LayoutApp>
<div class="pane-body">
<div class="title">营业执照认证</div>
<p class="desc">UFO平台将严格保密您的认证信息,请按照种类分别填写以下信息,保证上传的图片文字清晰可见,认证成功后我们将会第一时间通知您。</p>
<RadioGroup class="wrapper-radio">
<Radio :label="{text: '个体工商户', value: 1}" style="flex: 0 1 50%;" v-model="model.type"></Radio>
<Radio :label="{text: '企业', value: 2}" style="flex: 0 1 50%;" v-model="model.type"></Radio>
</RadioGroup>
<Form v-if="model.type === 1">
<FormItem>
<CInput label="个体工商户名称" place-holder="请填写个体工商户名称"></CInput>
</FormItem>
<FormItem>
<CInput label="统一社会信用代码" place-holder="请填写统一社会信用代码"></CInput>
</FormItem>
<FormItem>
<CInput label="经营者姓名" place-holder="请填写认证姓名"></CInput>
</FormItem>
<FormItem>
<CInput label="经营者身份证号" place-holder="请填写个体身份证号"></CInput>
</FormItem>
<FormItem>
<CDatePick label="营业执照有效期"></CDatePick>
</FormItem>
<FormItem>
<CUpload label="个体工商户营业执照正本照片"></CUpload>
</FormItem>
<FormItem>
<CUpload label="个体工商户营业执照副本照片"></CUpload>
</FormItem>
<FormItem>
<CUpload label="上传个人身份证正面照片"></CUpload>
</FormItem>
<FormItem>
<CUpload label="上传个人身份证反面照片"></CUpload>
</FormItem>
</Form>
<Form v-else>
<FormItem>
<CInput label="企业名称" place-holder="请填写企业名称"></CInput>
</FormItem>
<FormItem>
<CInput label="统一社会信用代码" place-holder="请填写统一社会信用代码"></CInput>
</FormItem>
<FormItem>
<CInput label="法人姓名" place-holder="请填写法人姓名"></CInput>
</FormItem>
<FormItem>
<CInput label="法人身份证号" place-holder="请填写法人身份证号"></CInput>
</FormItem>
<FormItem>
<CDatePick label="营业执照有效期"></CDatePick>
</FormItem>
<FormItem>
<CUpload label="企业营业执照正本照片"></CUpload>
</FormItem>
<FormItem>
<CUpload label="企业营业执照副本照片"></CUpload>
</FormItem>
<FormItem>
<CUpload label="上传法人身份证正面照片"></CUpload>
</FormItem>
<FormItem>
<CUpload label="上传法人身份证反面照片"></CUpload>
</FormItem>
</Form>
<div class="footer active">确认提交</div>
</div>
</LayoutApp>
</template>
<script>
import LayoutApp from '../../components/layout/layout-app';
import FixedBottom from '../components/fixed-bottom';
import Radio from '../components/radio';
import RadioGroup from '../components/radio-group';
import Form from '../components/form';
import FormItem from '../components/form-item';
import Input from '../components/input';
import Upload from '../components/upload';
import DatePick from '../components/date-pick';
export default {
data() {
return {
model: {
type: 1,
businessName: '',
code: '',
name: '',
id: '',
start_time: '',
end_time: '',
is_limit: false,
licence_image_side: [],
licence_image_other_side: [],
id_image_side: [],
id_image_other_side: []
},
};
},
methods: {
},
components: {
LayoutApp,
FixedBottom,
RadioGroup,
Form,
FormItem,
Radio,
CInput: Input,
CUpload: Upload,
CDatePick: DatePick
}
};
</script>
<style lang="scss" scoped>
.title {
font-size: 68px;
}
.footer {
width: 100%;
height: 120px;
text-align: center;
line-height: 120px;
font-size: 28px;
margin: 40px 0;
color: white;
background-color: #ccc;
&.active {
background-color: #002b47;
}
}
.pane-body {
height: 100%;
overflow: scroll;
padding-left: 40px;
padding-right: 40px;
}
.desc {
font-size: 24px;
line-height: 1.5;
color: #999;
}
.wrapper-radio {
margin: 60px 0;
}
</style>
... ...
import Form from './form.vue';
export default Form;
... ...
export default [{
path: '/mapp/auth/form.html',
name: 'form',
component: () => import(/* webpackChunkName: "auth" */ './form')
}, {
path: '/mapp/auth/status.html',
name: 'status',
component: () => import(/* webpackChunkName: "auth" */ './status')
}];
... ...
import Status from './status.vue';
export default Status;
... ...
<template>
<LayoutApp>
<div class="wrapper">
<template v-if="value === 1">
<div class="image waiting"></div>
<div class="pane-body">
<h1>审核中</h1>
<p class="desc">您的资料已提交审核,认证成功后我们将会第一时间通知您。</p>
</div>
<div class="footer" @click="onFinishClick">返回</div>
</template>
<template v-if="value === 2">
<div class="image fail"></div>
<div class="pane-body">
<h1>审核不通过</h1>
<p class="desc">您提交的姓名和身份证不匹配。</p>
</div>
<div class="footer" @click="onRepeatClick">重新提交</div>
</template>
<template v-if="value === 3">
<div class="pane-body">
<div class="image success"></div>
<h1>审核通过</h1>
<p class="desc">您的资料已审核通过,现您可以商家入驻。</p>
</div>
<div class="footer" @click="onCashClick">商家入驻</div>
</template>
</div>
</LayoutApp>
</template>
<script>
import LayoutApp from '../../components/layout/layout-app';
import FixedBottom from '../components/fixed-bottom';
export default {
props: {
value: {
type: Number,
default() {
return 1;
}
}
},
data() {
return { };
},
methods: {
onFinishClick() {
this.$yoho.finishPage({});
},
onRepeatClick() {
var url = window.location.protocol + '//m.yohobuy.com/mapp/auth/form.html';
this.$yoho.goNewPage({url});
},
onCashClick() {
}
},
components: {
LayoutApp,
FixedBottom
}
};
</script>
<style lang="scss" scoped>
h1 {
font-size: 40px;
margin: 20px 0;
}
.footer {
position: absolute;
bottom: 40%;
width: 600px;
height: 100px;
color: white;
text-align: center;
line-height: 100px;
font-size: 32px;
background-color: #002b47;
}
.pane-body {
height: 100%;
overflow: scroll;
text-align: center;
}
.image {
width: 120px;
height: 120px;
margin: 40px auto;
&.success {
background-image: url("~statics/image/auth/success.png");
background-size: 100% 100%;
}
&.waiting {
background-image: url("~statics/image/auth/waiting.png");
background-size: 100% 100%;
}
&.fail {
background-image: url("~statics/image/auth/fail.png");
background-size: 100% 100%;
}
}
.desc {
font-size: 28px;
line-height: 1.5;
}
.wrapper {
padding: 100px 76px 0;
text-align: center;
}
</style>
... ...
import Order from './order';
import Auth from './auth';
export default [...Order];
export default [...Order, ...Auth];
... ...
import * as Types from './types';
const TYPE = {notuse: 'notuse', use: 'use', overtime: 'overtime'};
export default {
async fetchYohoList({commit, state}, {type, filter = 0, refresh = false}) {
commit(Types.FETCH_YOHO_COUPON_REQUEST);
if (!refresh) {
if (state.yohoList[type].page > state.yohoList[type].pageNum) {
return false;
}
}
const fetchPage = refresh ? 1 : state.yohoList[type].page + 1;
// 下一页的数据
const result = await this.$api.get('/api/coupon/yoho/list', {
type,
filter,
limit: 10,
page: fetchPage
});
if (result && result.code === 200) {
const data = {
type,
couponList: result.data.couponList ? result.data.couponList.map((i) => _handleCoupon(i, type)) : [],
pageNum: result.data.pageNum,
pageSize: result.data.pageSize,
total: result.data.total,
filterId: filter,
page: fetchPage,
refresh
};
if (type === TYPE.notuse) {
data.filter = result.data.filters;
}
commit(Types.FETCH_YOHO_COUPON_SUCCESS, data);
} else {
commit(Types.FETCH_YOHO_COUPON_FAILED);
}
return result.data.couponList ? result.data.couponList.length !== 0 : false;
},
async fetchYohoNum({commit}) {
commit(Types.FETCH_YOHO_COUPON_REQUEST);
const result = await this.$api.get('/api/coupon/yoho/num', {});
if (result && result.code === 200) {
commit(Types.FETCH_YOHO_COUPON_NUM_SUCCESS, result.data);
} else {
commit(Types.FETCH_YOHO_COUPON_FAILED);
}
},
async fetchUfoList({commit}) {
commit(Types.FETCH_YOHO_COUPON_REQUEST);
const result = await this.$api.get('/api/coupon/ufo/list');
if (result && result.code === 200) {
commit(Types.FETCH_UFO_COUPON_SUCCESS, {
list: result.data.map(_handleUfoCoupon)
});
} else {
commit(Types.FETCH_YOHO_COUPON_FAILED);
}
},
async getCouponCode({commit}, {code}) {
commit(Types.FETCH_YOHO_COUPON_REQUEST);
const result = await this.$api.post('/api/coupon/yoho/getcoupon', {
coupon_code: code
});
if (result && result.code === 200) {
commit(Types.FETCH_YOHO_COUPON_CODE_SUCCESS);
} else {
commit(Types.FETCH_YOHO_COUPON_FAILED);
}
return result || {};
}
};
... ...
import actions from './actions';
import mutations from './mutations';
function handleNum(n) {
return n > 99 ? '99+' : n;
}
export default function() {
return {
namespaced: true,
state: {
fetching: false,
},
actions,
mutations
};
}
... ...
import * as Types from './types';
export default {
[Types.FETCH_YOHO_COUPON_REQUEST](state) {
state.fetching = true;
},
[Types.FETCH_YOHO_COUPON_SUCCESS](state, {couponList, filter, type, pageNum, pageSize, total, filterId, page, refresh}) {
state.fetching = false;
const typeData = state.yohoList[type];
const list = typeData.couponList;
const newCouponList = refresh ? couponList : list.concat(couponList);
typeData.couponList = newCouponList;
typeData.pageNum = pageNum;
typeData.pageSize = pageSize;
typeData.total = total;
typeData.filterId = filterId;
typeData.page = page;
if (filter) {
state.filterList = filter;
}
},
[Types.FETCH_YOHO_COUPON_FAILED](state) {
state.fetching = false;
},
[Types.FETCH_YOHO_COUPON_NUM_SUCCESS](state, data) {
state.num = data;
},
[Types.FETCH_UFO_COUPON_SUCCESS](state, {list = []}) {
state.fetching = false;
state.ufoList = list;
}
};
... ...
export const FETCH_YOHO_COUPON_REQUEST = 'FETCH_YOHO_COUPON_REQUEST';
export const FETCH_YOHO_COUPON_FAILED = 'FETCH_YOHO_COUPON_FAILED';
export const FETCH_YOHO_COUPON_SUCCESS = 'FETCH_YOHO_COUPON_SUCCESS';
export const FETCH_YOHO_COUPON_NUM_SUCCESS = 'FETCH_YOHO_COUPON_NUM_SUCCESS';
export const FETCH_YOHO_COUPON_CODE_SUCCESS = 'FETCH_YOHO_COUPON_CODE_SUCCESS';
export const FETCH_UFO_COUPON_SUCCESS = 'FETCH_UFO_COUPON_SUCCESS';
... ...
import storeList from './auth';
export default function() {
return {
namespaced: true,
modules: {
auth: storeList()
}
};
}
... ...
... ... @@ -7,5 +7,11 @@ module.exports = [
},
{
route: /mapp\/coupon\/yoho/,
},
{
route: /mapp\/auth\/form.html/,
},
{
route: /mapp\/auth\/status.html/,
}
];
... ...
... ... @@ -45,6 +45,10 @@ exports.createApp = async(app) => {
app.use(devtools());
}
app.use((req, res, next) => {
req.isApmReport = _.get(req.app.locals, 'wap.open.bughd', false);
next();
});
// 添加请求上下文
app.use(global.yoho.httpCtx());
... ...