Commit 9b63e7d9 authored by 武广's avatar 武广

Merge branch 'master' of git.quantgroup.cn:ui/merchant-manage-ui into feature/group-meal

parents c2eb791a d1c26369
...@@ -5,6 +5,7 @@ import { fakeAccountLogin, getFakeCaptcha } from '@/services/login'; ...@@ -5,6 +5,7 @@ import { fakeAccountLogin, getFakeCaptcha } from '@/services/login';
import { setAuthority } from '@/utils/authority'; import { setAuthority } from '@/utils/authority';
import { getPageQuery } from '@/utils/utils'; import { getPageQuery } from '@/utils/utils';
import localStorage from '@/utils/localStorage'; import localStorage from '@/utils/localStorage';
import sessionStorage from '@/utils/sessionStorage';
const Model = { const Model = {
namespace: 'login', namespace: 'login',
...@@ -18,6 +19,7 @@ const Model = { ...@@ -18,6 +19,7 @@ const Model = {
localStorage.set('token', response.data.accessToken); localStorage.set('token', response.data.accessToken);
localStorage.set('refreshtoken', response.data.refreshToken); localStorage.set('refreshtoken', response.data.refreshToken);
localStorage.set('atExpire', response.data.atExpire); localStorage.set('atExpire', response.data.atExpire);
payload.username && sessionStorage.set('account', payload.username);
yield put({ yield put({
type: 'changeLoginStatus', type: 'changeLoginStatus',
payload: response, payload: response,
......
// queryUsers // queryUsers
import { queryCurrent, homeInfo } from '@/services/user'; import { queryCurrent, homeInfo } from '@/services/user';
import localStorage from '@/utils/localStorage'; import localStorage from '@/utils/localStorage';
import sessionStorage from '@/utils/sessionStorage';
const UserModel = { const UserModel = {
namespace: 'user', namespace: 'user',
...@@ -20,6 +21,9 @@ const UserModel = { ...@@ -20,6 +21,9 @@ const UserModel = {
*fetchCurrent(_, { call, put }) { *fetchCurrent(_, { call, put }) {
const response = yield call(queryCurrent); const response = yield call(queryCurrent);
if (response.code === 2000) { if (response.code === 2000) {
if (response.data && !response.data.name) {
response.data.name = sessionStorage.get('account');
}
localStorage.set('user', JSON.stringify(response.data)); localStorage.set('user', JSON.stringify(response.data));
} }
yield put({ yield put({
......
...@@ -15,7 +15,7 @@ const SendModal = options => { ...@@ -15,7 +15,7 @@ const SendModal = options => {
}); });
}; };
const radioOptions = [{ label: '', value: 1 }, { label: '', value: 0 }]; const radioOptions = [{ label: '单点送', value: 1 }, { label: '单点不送', value: 0 }];
const initialValues = Object.assign({}, options.initialValues); const initialValues = Object.assign({}, options.initialValues);
return ( return (
...@@ -38,14 +38,14 @@ const SendModal = options => { ...@@ -38,14 +38,14 @@ const SendModal = options => {
autoComplete="off" autoComplete="off"
> >
<Form.Item <Form.Item
label="单点不送" label="是否单点不送"
name="isSingleDelivery" name="isSingleDelivery"
rules={[{ required: true, message: '请选择!' }]} rules={[{ required: true, message: '请选择!' }]}
> >
<Radio.Group options={radioOptions} /> <Radio.Group options={radioOptions} />
</Form.Item> </Form.Item>
</Form> </Form>
<div>开启后顾客单点这些商品不可下单</div> <div>选择单点不送后顾客单独点这些商品不可下单</div>
</Modal> </Modal>
); );
}; };
......
...@@ -351,7 +351,7 @@ export async function apiEditStorage(data) { ...@@ -351,7 +351,7 @@ export async function apiEditStorage(data) {
} }
// 分组详情(货架—货架详情) // 分组详情(货架—货架详情)
export async function apiStorageInfo(params) { export async function apiStorageInfo(params) {
return request.post('/api/merchants/products/storageRack/QueryByShopIdAndStorageRackId', { return request.post('/api/merchants/products/storageRack/queryByShopIdAndStorageRackId', {
prefix: goodsApi, prefix: goodsApi,
data: stringify(params), data: stringify(params),
headers, headers,
......
...@@ -45,7 +45,7 @@ const createInitValues = () => ({ ...@@ -45,7 +45,7 @@ const createInitValues = () => ({
detailImageList: [], // 商品图片 detailImageList: [], // 商品图片
stock: '1', // 库存类型 stock: '1', // 库存类型
saleTimeType: 0, // 售卖时间 saleTimeType: 0, // 售卖时间
singleDelivery: 0, // 单点不送 singleDelivery: 1, // 单点不送
list: 1, // 列出商品 list: 1, // 列出商品
label: [], label: [],
minPurchaseNum: 1, minPurchaseNum: 1,
...@@ -817,10 +817,14 @@ const TakeawayGoodsInfo = forwardRef((props, ref) => { ...@@ -817,10 +817,14 @@ const TakeawayGoodsInfo = forwardRef((props, ref) => {
options={tagList} options={tagList}
/> />
</Form.Item> </Form.Item>
<Form.Item name="singleDelivery" label="单点不送" extra="开启后顾客点单则此商品不可下单"> <Form.Item
name="singleDelivery"
label="是否单点不送"
extra="选择单点不送后顾客点该商品不可单独下单"
>
<Radio.Group> <Radio.Group>
<Radio value={0}>是</Radio> <Radio value={1}>单点送</Radio>
<Radio value={1}>否</Radio> <Radio value={0}>单点不送</Radio>
</Radio.Group> </Radio.Group>
</Form.Item> </Form.Item>
<Form.Item name="list" label="列出商品" extra="开启后平台展示商品"> <Form.Item name="list" label="列出商品" extra="开启后平台展示商品">
......
...@@ -163,6 +163,8 @@ const AccountInfo = props => { ...@@ -163,6 +163,8 @@ const AccountInfo = props => {
...fieldsValue, ...fieldsValue,
code, code,
email: email || `${code}@stms.quantgroup.cn`, email: email || `${code}@stms.quantgroup.cn`,
source: 1,
tenantId: 560761,
organization: { organization: {
id: organizationId || orgId, id: organizationId || orgId,
}, },
...@@ -170,7 +172,6 @@ const AccountInfo = props => { ...@@ -170,7 +172,6 @@ const AccountInfo = props => {
delete params.organizationId; delete params.organizationId;
let api = addUser; let api = addUser;
if (id) { if (id) {
console.log(id, 222444);
params.id = id; params.id = id;
api = updateUser; api = updateUser;
} }
......
import React, { useRef, useState } from 'react';
import { Form, Input, Row, Col, Button, message } from 'antd';
import { history } from 'umi';
import { apiSMSCaptcha, fakeAccountLogin } from '@/services/login';
import { getDefaultRule, validatePhone } from '@/utils/validator';
import localStorage from '@/utils/localStorage';
import sessionStorage from '@/utils/sessionStorage';
import styles from '../../style.less';
const FormItem = Form.Item;
const LoginSMS = props => {
const refSearch = useRef(null);
const [second, setSecond] = useState(0);
const [form] = Form.useForm();
const onFinish = async ({ phone, code }) => {
const res = await fakeAccountLogin({
username: phone,
tenantId: 560761,
source: 1,
verifyType: 1,
verifyCode: code,
});
if (res && +res.code === 2000) {
localStorage.set('token', res.data.accessToken);
localStorage.set('refreshtoken', res.data.refreshToken);
localStorage.set('atExpire', res.data.atExpire);
phone && sessionStorage.set('account', phone);
history.replace('/');
} else {
message.error(res.msg);
}
};
// 校验手机号
const checkPhone = v => {
const reg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
return !!v && reg.test(v);
};
const countTimer = () => {
let time = 60;
setSecond(time);
const timer = setInterval(() => {
setSecond(--time);
if (time < 1) {
clearInterval(timer);
}
}, 1000);
};
// 获取验证码
const onGetCaptcha = async e => {
const { phone } = form.getFieldsValue();
if (!checkPhone(phone)) {
message.error('请输入正确的手机号!');
return;
}
const res = await apiSMSCaptcha({
phone,
tenantId: 560761,
source: 1,
});
if (res && +res.code === 2000) {
countTimer();
} else {
message.error(res.msg);
}
};
return (
<Form onFinish={onFinish} form={form} ref={refSearch} name="horizontal_login" layout="inline">
<FormItem
label=""
name="phone"
rules={[
getDefaultRule('请输入手机号!'),
{
validator: validatePhone,
message: '请输入正确的手机号',
},
]}
>
<Input
placeholder="请输入手机号"
prefix="+86"
maxLength={11}
className={styles.txt}
allowClear
/>
</FormItem>
<FormItem label="" name="code" rules={[getDefaultRule('请输入验证码!')]}>
<Row>
<Col span={16}>
<Input placeholder="请输入验证码" maxLength={6} className={styles.txt} allowClear />
</Col>
<Col span={8}>
<Button type="primary" onClick={onGetCaptcha} className={styles.btnCode}>
{second > 0 ? second : '获取验证码'}
</Button>
</Col>
</Row>
</FormItem>
<Button
type="primary"
htmlType="submit"
size="large"
className={styles.btnSubmit}
loading={props.submitting}
>
登录
</Button>
</Form>
);
};
export default LoginSMS;
import { Alert } from 'antd'; import { Alert, Tabs } from 'antd';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'dva'; import { connect } from 'dva';
import LoginComponents from './components/Login'; import LoginComponents from './components/Login';
import styles from './style.less'; import styles from './style.less';
import LoginSMS from './components/Login/LoginSms';
const { UserName, Password, Submit } = LoginComponents; const { UserName, Password, Submit } = LoginComponents;
...@@ -18,7 +19,7 @@ class Login extends Component { ...@@ -18,7 +19,7 @@ class Login extends Component {
const { dispatch } = this.props; const { dispatch } = this.props;
dispatch({ dispatch({
type: 'login/login', type: 'login/login',
payload: { ...values }, payload: { ...values, tenantId: 560761, source: 1 },
}); });
} }
}; };
...@@ -39,44 +40,53 @@ class Login extends Component { ...@@ -39,44 +40,53 @@ class Login extends Component {
const { status } = userLogin; const { status } = userLogin;
return ( return (
<div className={styles.main}> <div className={styles.main}>
<LoginComponents <Tabs defaultActiveKey="1" destroyInactiveTabPane>
onSubmit={this.handleSubmit} <Tabs.TabPane tab="账号密码登录" key="1">
onCreate={form => { <LoginComponents
this.loginForm = form; onSubmit={this.handleSubmit}
}} onCreate={form => {
> this.loginForm = form;
{status === 'error' && }}
!submitting && >
this.renderMessage('账户或密码错误(admin/ant.design)')} {status === 'error' &&
<UserName !submitting &&
name="username" this.renderMessage('账户或密码错误(admin/ant.design)')}
placeholder={`${'用户名'}`} <UserName
rules={[ name="username"
{ placeholder={`${'用户名'}`}
required: true, rules={[
message: '请输入用户名!', {
}, required: true,
]} message: '请输入用户名!',
/> },
<Password ]}
name="password" />
placeholder={`${'密码'}`} <Password
rules={[ name="password"
{ placeholder={`${'密码'}`}
required: true, rules={[
message: '请输入密码!', {
}, required: true,
]} message: '请输入密码!',
onPressEnter={e => { },
e.preventDefault(); ]}
onPressEnter={e => {
e.preventDefault();
if (this.loginForm) { if (this.loginForm) {
this.loginForm.validateFields(this.handleSubmit); this.loginForm.validateFields(this.handleSubmit);
} }
}} }}
/> />
<Submit loading={submitting}>登录</Submit>
</LoginComponents> <Submit loading={submitting}>登录</Submit>
</LoginComponents>
</Tabs.TabPane>
{/* 后端短信模板还没申请下来 先隐藏 */}
{/* <Tabs.TabPane tab="手机号登录" key="2">
<LoginSMS loading={submitting} dispatch={this.props.dispatch} />
</Tabs.TabPane> */}
</Tabs>
</div> </div>
); );
} }
......
...@@ -35,5 +35,50 @@ ...@@ -35,5 +35,50 @@
width: 100%; width: 100%;
margin-top: 24px; margin-top: 24px;
} }
.ant-tabs-tab {
font-size: 16px;
}
.ant-tabs-top > .ant-tabs-nav::before {
border-bottom: 1px solid #ddd;
}
.ant-form-inline .ant-form-item-with-help {
margin-bottom: 0;
}
.ant-form-item-control {
min-height: 65px;
}
.ant-form-item {
width: 100%;
}
.ant-input {
padding-left: 4px !important;
}
} }
} }
.txt {
position: relative;
display: inline-flex;
box-sizing: border-box;
width: 100%;
min-width: 0;
padding: 6.5px 11px;
color: rgba(0, 0, 0, 0.85);
font-size: 16px;
line-height: 1.5715;
background-color: #fff;
background-image: none;
border: 1px solid #d9d9d9;
border-radius: 0;
transition: all 0.3s;
}
.btnCode {
box-sizing: border-box;
width: 100%;
height: 100%;
border: 0;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.btnSubmit {
width: 100%;
}
import { stringify } from 'querystring'; import { stringify } from 'querystring';
import request from '@/utils/request'; import request from '@/utils/request';
/**
* 手机号验证码登录
* http://yapi.quantgroups.com/project/509/interface/api/41776
*/
export async function fakeAccountLogin(params) { export async function fakeAccountLogin(params) {
return request('/v2/oauth/login', { return request('/v2/oauth/login', {
method: 'POST', method: 'POST',
...@@ -11,6 +15,20 @@ export async function fakeAccountLogin(params) { ...@@ -11,6 +15,20 @@ export async function fakeAccountLogin(params) {
export async function getFakeCaptcha(mobile) { export async function getFakeCaptcha(mobile) {
return request(`/v2/user/captcha?mobile=${mobile}`); return request(`/v2/user/captcha?mobile=${mobile}`);
} }
/**
* 获取短信验证码
* http://yapi.quantgroups.com/project/509/interface/api/65044
*/
export function apiSMSCaptcha(params) {
return request('/v2/sms/send', {
method: 'POST',
data: stringify(params),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
});
}
// export async function apiSMSLogin(data) {
// return request.post(`/v2/oauth/login?${stringify(data)}`);
// }
export async function getResFreshToen(token) { export async function getResFreshToen(token) {
return request(`/v2/oauth/refreshtoken?refreshtoken=${token}`); return request(`/v2/oauth/refreshtoken?refreshtoken=${token}`);
} }
......
...@@ -82,7 +82,7 @@ const isTob = searchPrams.source === 'tob'; ...@@ -82,7 +82,7 @@ const isTob = searchPrams.source === 'tob';
// request拦截器, 改变url 或 options. // request拦截器, 改变url 或 options.
request.interceptors.request.use(async (url, options) => { request.interceptors.request.use(async (url, options) => {
const token = getToken(); const token = getToken();
if (!token && !url.includes('/v2/oauth/login')) { if (!token && !url.includes('/v2/oauth/login') && !url.includes('/v2/sms/send')) {
window.location.href = `${window.origin}/user/login`; window.location.href = `${window.origin}/user/login`;
} }
const { headers } = options; const { headers } = options;
......
export default {
get(key) {
let result = sessionStorage.getItem(key);
try {
result = JSON.parse(result);
} catch {
console.log(); // eslint-disable-line no-console
}
return result;
},
set(key, value) {
const { toString } = Object.prototype;
if (toString.call(value) === '[object Array]' || toString.call(value) === '[object Object]') {
value = JSON.stringify(value); // eslint-disable-line no-param-reassign
}
return sessionStorage.setItem(key, value);
},
remove(key) {
return sessionStorage.removeItem(key);
},
clear() {
return sessionStorage.clear();
},
};
...@@ -10,7 +10,7 @@ export const validateRequired = (rule, value, callback) => { ...@@ -10,7 +10,7 @@ export const validateRequired = (rule, value, callback) => {
/* 是否合法IP地址 */ /* 是否合法IP地址 */
export function validateIP(rule, value, callback) { export function validateIP(rule, value, callback) {
if (value === '' || value === 'undefined' || value === null) { if (!value || value === 'undefined') {
callback(); callback();
} else { } else {
const reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/; const reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/;
...@@ -25,7 +25,7 @@ export function validateIP(rule, value, callback) { ...@@ -25,7 +25,7 @@ export function validateIP(rule, value, callback) {
/* 是否手机号码或者固话 */ /* 是否手机号码或者固话 */
export function validatePhoneTwo(rule, value, callback) { export function validatePhoneTwo(rule, value, callback) {
const reg = /^((0\d{2,3}-\d{7,8})|(1[34578]\d{9}))$/; const reg = /^((0\d{2,3}-\d{7,8})|(1[34578]\d{9}))$/;
if (value === '' || value === 'undefined' || value === null) { if (!value || value === 'undefined') {
callback(); callback();
} else if (!reg.test(value) && value !== '') { } else if (!reg.test(value) && value !== '') {
callback(new Error('请输入正确的电话号码或者固话号码')); callback(new Error('请输入正确的电话号码或者固话号码'));
...@@ -36,7 +36,7 @@ export function validatePhoneTwo(rule, value, callback) { ...@@ -36,7 +36,7 @@ export function validatePhoneTwo(rule, value, callback) {
/* 是否固话 */ /* 是否固话 */
export function validateTelphone(rule, value, callback) { export function validateTelphone(rule, value, callback) {
const reg = /0\d{2}-\d{7,8}/; const reg = /0\d{2}-\d{7,8}/;
if (value === '' || value === 'undefined' || value === null) { if (!value || value === 'undefined') {
callback(); callback();
} else if (!reg.test(value) && value !== '') { } else if (!reg.test(value) && value !== '') {
callback(new Error('请输入正确的固话(格式:区号+号码,如010-1234567)')); callback(new Error('请输入正确的固话(格式:区号+号码,如010-1234567)'));
...@@ -47,18 +47,18 @@ export function validateTelphone(rule, value, callback) { ...@@ -47,18 +47,18 @@ export function validateTelphone(rule, value, callback) {
/* 是否手机号码 */ /* 是否手机号码 */
export function validatePhone(rule, value, callback) { export function validatePhone(rule, value, callback) {
const reg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/; const reg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/;
if (value === '' || value === 'undefined' || value === null) { if (!value || value === 'undefined') {
callback(); return Promise.resolve();
} else if (!reg.test(value) && value !== '') {
callback(new Error('请输入正确的电话号码'));
} else {
callback();
} }
if (!reg.test(value) && value !== '') {
return Promise.reject(new Error('请输入正确的电话号码'));
}
return Promise.resolve();
} }
/* 是否身份证号码 */ /* 是否身份证号码 */
export function validateIdNo(rule, value, callback) { export function validateIdNo(rule, value, callback) {
const reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/; const reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
if (value === '' || value === 'undefined' || value === null) { if (!value || value === 'undefined') {
callback(); callback();
} else if (!reg.test(value) && value !== '') { } else if (!reg.test(value) && value !== '') {
callback(new Error('请输入正确的身份证号码')); callback(new Error('请输入正确的身份证号码'));
...@@ -69,7 +69,7 @@ export function validateIdNo(rule, value, callback) { ...@@ -69,7 +69,7 @@ export function validateIdNo(rule, value, callback) {
/* 是否邮箱 */ /* 是否邮箱 */
export function validateEMail(rule, value, callback) { export function validateEMail(rule, value, callback) {
const reg = /^([a-zA-Z0-9]+[-_.]?)+@[a-zA-Z0-9]+.[a-z]+$/; const reg = /^([a-zA-Z0-9]+[-_.]?)+@[a-zA-Z0-9]+.[a-z]+$/;
if (value === '' || value === 'undefined' || value === null) { if (!value || value === 'undefined') {
callback(); callback();
} else if (!reg.test(value)) { } else if (!reg.test(value)) {
callback(new Error('请输入正确的邮箱地址')); callback(new Error('请输入正确的邮箱地址'));
...@@ -80,7 +80,7 @@ export function validateEMail(rule, value, callback) { ...@@ -80,7 +80,7 @@ export function validateEMail(rule, value, callback) {
/* 验证内容是否英文数字以及下划线 */ /* 验证内容是否英文数字以及下划线 */
export function isPassword(rule, value, callback) { export function isPassword(rule, value, callback) {
const reg = /^[_a-zA-Z0-9]+$/; const reg = /^[_a-zA-Z0-9]+$/;
if (value === '' || value === 'undefined' || value === null) { if (!value || value === 'undefined') {
callback(); callback();
} else if (!reg.test(value)) { } else if (!reg.test(value)) {
callback(new Error('密码仅由英文字母,数字以及下划线组成')); callback(new Error('密码仅由英文字母,数字以及下划线组成'));
...@@ -93,7 +93,7 @@ export function isPassword(rule, value, callback) { ...@@ -93,7 +93,7 @@ export function isPassword(rule, value, callback) {
export function checkMaxNumber(rule, value, callback) { export function checkMaxNumber(rule, value, callback) {
const re = /^[1-9][0-9]{0,1}$/; const re = /^[1-9][0-9]{0,1}$/;
const rsCheck = re.test(value); const rsCheck = re.test(value);
if (value === '' || value === 'undefined' || value === null) { if (!value || value === 'undefined') {
callback(); callback();
} else if (rule.isInteger && !rsCheck) { } else if (rule.isInteger && !rsCheck) {
callback(new Error(`请输入[${rule.min}, ${rule.max}]之间的正整数`)); callback(new Error(`请输入[${rule.min}, ${rule.max}]之间的正整数`));
...@@ -435,3 +435,20 @@ export function isCheckPriceTwoDecimal(rule, value, callback) { ...@@ -435,3 +435,20 @@ export function isCheckPriceTwoDecimal(rule, value, callback) {
callback(); callback();
} }
} }
// 获取默认校验规则
export const getDefaultRule = data => {
const isString = typeof data === 'string';
if (isString) {
return {
required: true,
message: data,
};
}
return Object.assign(
{
required: true,
},
data,
);
};
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