Commit f19b7121 authored by XieZhiXiong's avatar XieZhiXiong
parents cdd82d9f 6927854a
......@@ -12,7 +12,7 @@
"api": "god-ytt",
"scripts:build": "node scripts/run",
"scripts:build-yxc": "node scripts/run http://yxc-web-demo.shushangyun.com/api",
"start:dev": "umi dev ",
"start:dev": "cross-env NODE_OPTIONS=--max_old_space_size=4096 umi dev",
"start:analyze": "ANALYZE=1 umi dev",
"clean": "rimraf node_modules",
"start": "yarn api && yarn scripts:build && cross-env NODE_OPTIONS=--max_old_space_size=4096 umi dev",
......
import { Popconfirm, PopconfirmProps } from 'antd'
import React from 'react'
export interface PopConfirmControlProps extends Partial<PopconfirmProps> {
visible?: boolean
}
const PopConfirmControl: React.FC<PopConfirmControlProps> = (props) => {
const { visible = true, children, ...restProps } = props
return <Popconfirm
title="确定要执行这个操作?"
okText="是"
cancelText="否"
{ ...restProps }
>
{ children }
</Popconfirm>
}
export default PopConfirmControl
import { useCallback } from "react"
interface ControlTableOptions {
update?: any,
remove?: any,
preview?: any,
changeStatus?: any,
}
const emptyFn = () => {}
const useControlTable = (options: ControlTableOptions) => {
const { update = emptyFn, remove = emptyFn, preview = emptyFn, changeStatus = emptyFn } = options
const handleUpdate = useCallback(() => {
}, [])
const handleRemove = useCallback(() => {
}, [])
const handlePreview = useCallback(() => {
}, [])
const handleChangeStatus = useCallback(() => {
}, [])
return {
handleUpdate,
handleRemove,
handlePreview,
handleChangeStatus
}
}
......@@ -152,7 +152,7 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
minWidth: '1280px',
}
: {}
console.log(currentRouter)
return currentRouter.noLayout ? props.children : (
<ProLayout
pageTitleRender={() => currentRouter ? currentRouter.name : window.location.href}
......@@ -179,6 +179,7 @@ const BasicLayout: React.FC<BasicLayoutProps> = (props) => {
menuData={menuData}
pathname={location.pathname}
collapseState={collapsed}
currentRouter={currentRouter}
changeOpenKeys={(keys: string[]) => setOpenKeys(keys)}
/>}
footerRender={() => defaultFooterDom}
......
......@@ -20,6 +20,7 @@ export interface MenuSliderProps {
currentSelectKey: string[];
openKeys: string[];
changeOpenKeys: Function;
currentRouter: any;
}
const MenuSlider: React.FC<MenuSliderProps> = (props) => {
......
......@@ -13,12 +13,13 @@ const { Sider } = Layout
export interface OuterSiderProps {
menuData: Array<any>;
pathname: string | undefined;
UserStore?: any
currentRouter: any,
UserStore?: any,
}
const OuterSider: React.FC<OuterSiderProps> = observer((props) => {
const { menuData, pathname = "/" } = props
const { menuData, pathname = "/", currentRouter } = props
const authRouters = getRouters()
let defaultSelectedKeys = ""
......@@ -33,14 +34,19 @@ const OuterSider: React.FC<OuterSiderProps> = observer((props) => {
const getSubMenu = () => {
const subHeadMenus: Array<any> = []
menuData.forEach(item => {
if (pathname.indexOf(item.key) > -1) {
defaultSelectedKeys = item.key
// 为适配pass菜单自由组合变更, 使用code进行高亮显示
const code = currentRouter.relationParentCode
console.log(code, item.relationParentCode)
if (code && code === item.relationParentCode) {
defaultSelectedKeys = item.relationParentCode
}
!item.hideInMenu && isAuthPath(item.path) && subHeadMenus.push({
path: item.path,
title: item.name,
icon: item.icon,
key: item.key
key: item.key,
// 新增code属性 用于辨别子菜单是否属于该菜单下的属性
relationParentCode: item.relationParentCode,
})
})
return subHeadMenus
......@@ -60,7 +66,7 @@ const OuterSider: React.FC<OuterSiderProps> = observer((props) => {
<ul className={styles.menuBox}>
{
siderMenu.map(item => (
!item.hideInMenu && <li key={item.key} className={defaultSelectedKeys === item.key ? styles.currentItem : ''}>
!item.hideInMenu && <li key={item.key} className={defaultSelectedKeys === item.relationParentCode ? styles.currentItem : ''}>
<Link to={item.path}>
<CustomIcon type={item.icon} style={{width: 20, height: 20}}/>
<label>{item.title}</label>
......
import { GetProductChannelCommodityGetCommodityUnitPriceResponse } from '@/services';
import { GetProductChannelCommodityGetCommodityUnitPriceResponse } from '@/services/ProductV2Api';
export interface IRole {
key: string;
......@@ -29,4 +29,4 @@ export interface IChannelProductModule {
setTableDataInSetPrice(data: GetProductChannelCommodityGetCommodityUnitPriceResponse[]): void;
setSelectChannel(data: any): void;
setSelectSource(data: number): void;
}
\ No newline at end of file
}
......@@ -9,13 +9,13 @@ import {
EyeOutlined
} from '@ant-design/icons';
import {StandardTable} from 'god'
import {ColumnType} from 'antd/lib/table/interface'
import { IButtonFilter, IFormFilter } from 'god/dist/src/standard-table/TableController';
import { PublicApi } from '@/services/api';
import EyePreview from '@/components/EyePreview';
import StatusSwitch from '@/components/StatusSwitch';
import { STATUS_ENUM } from '@/constants';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import useSysetemTable from './useSystemTable';
// 模拟请求
const fetchData = async (params) => {
......@@ -24,108 +24,18 @@ const fetchData = async (params) => {
}
const UserSystem: React.FC<{}> = () => {
const ref = useRef<any>({})
const addItem = () => {
history.push('/memberCenter/systemSetting/authConfig/userSystem/add')
}
const deleteItem = (record) => {
// 删除该项
PublicApi.postMemberUserDelete({
userId: record.userId
}).then(() => {
ref.current.reload()
})
}
const updateItem = (record) => {
history.push(`/memberCenter/systemSetting/authConfig/userSystem/edit?id=${record.userId}&preview=0`)
}
const handleStatus = (record) => {
PublicApi.postMemberUserUpdatestatus({
userId: record.userId,
status: record.status === 1 ? 0 : 1
}).then(res => {
ref.current.reload()
})
}
const columns: ColumnType<any>[] = [
{
title: '账号',
dataIndex: 'account',
align: 'center',
key: 'account',
className: 'commonPickColor',
render: (text, record) => <EyePreview url={`/memberCenter/systemSetting/authConfig/userSystem/detail?id=${record.userId}&preview=1`}>{text}</EyePreview>
},
{
title: '用户姓名',
dataIndex: 'name',
align: 'center',
key: 'name',
},
{
title: '所属机构',
dataIndex: 'orgName',
align: 'center',
key: 'orgName'
},
{
title: '绑定手机号码',
align: 'center',
dataIndex: 'phone',
key: 'phone',
},
{
title: '所属角色',
align: 'center',
dataIndex: 'roleName',
key: 'roleName',
},
{
title: '最后登录时间',
align: 'center',
dataIndex: 'lastLoginTime',
key: 'lastLoginTime',
},
{
title: '状态',
align: 'center',
dataIndex: 'status',
key: 'status',
render: (text: any, record:any) => <StatusSwitch handleConfirm={() => handleStatus(record)} record={record}/>
},
{
title: '操作',
dataIndex: 'option',
align: 'center',
render: (text:any, record:any) => {
return (
<>
{
record.status === 0 && <Popconfirm
title="确定要执行这个操作?"
onConfirm={() => deleteItem(record)}
okText="是"
cancelText="否"
>
<Button type='link'>删除</Button>
</Popconfirm>
}
<Button type='link' onClick={()=>updateItem(record)}>修改</Button>
</>
)
}
}
];
const {
dataRef,
tableRef,
addItem
} = useSysetemTable()
return (
<PageHeaderWrapper>
<Card className="common-wrapper">
<StandardTable
columns={columns}
currentRef={ref}
columns={dataRef.current.columns}
currentRef={tableRef.current}
fetchTableData={(params:any) => fetchData(params)}
formilyLayouts={{
justify: 'space-between'
......@@ -143,7 +53,7 @@ const UserSystem: React.FC<{}> = () => {
ctx: {
effects: ($) => {
$('onFieldInputChange', 'status').subscribe(() => {
ref.current.reload()
tableRef.current.reload()
})
},
schema: {
......
import React, { useRef } from 'react'
import EyePreview from "@/components/EyePreview";
import StatusSwitch from '@/components/StatusSwitch';
import { Button } from 'antd';
import PopConfirmControl from '@/components/PopConfirmControl';
import { PublicApi } from '@/services/api';
import { history } from 'umi'
const useSysetemTable = () => {
const tableRef = useRef<any>({})
const dataRef = useRef<any>({
columns: [
{
title: '账号',
dataIndex: 'account',
align: 'center',
key: 'account',
className: 'commonPickColor',
render: (text, record) => <EyePreview url={`/memberCenter/systemSetting/authConfig/userSystem/detail?id=${record.userId}&preview=1`}>{text}</EyePreview>
},
{
title: '用户姓名',
dataIndex: 'name',
align: 'center',
key: 'name',
},
{
title: '所属机构',
dataIndex: 'orgName',
align: 'center',
key: 'orgName'
},
{
title: '绑定手机号码',
align: 'center',
dataIndex: 'phone',
key: 'phone',
},
{
title: '所属角色',
align: 'center',
dataIndex: 'roleName',
key: 'roleName',
},
{
title: '最后登录时间',
align: 'center',
dataIndex: 'lastLoginTime',
key: 'lastLoginTime',
},
{
title: '状态',
align: 'center',
dataIndex: 'status',
key: 'status',
render: (text: any, record:any) => <StatusSwitch handleConfirm={() => handleStatus(record)} record={record}/>
},
{
title: '操作',
dataIndex: 'option',
align: 'center',
render: (text:any, record:any) => {
return (
<>
<PopConfirmControl
onConfirm={() => deleteItem(record)}
visible={record.status === 0}
>
<Button type='link'>删除</Button>
</PopConfirmControl>
<Button type='link' onClick={()=>updateItem(record)}>修改</Button>
</>
)
}
}
]
})
const addItem = () => {
history.push('/memberCenter/systemSetting/authConfig/userSystem/add')
}
const deleteItem = (record) => {
// 删除该项
PublicApi.postMemberUserDelete({
userId: record.userId
}).then(() => {
tableRef.current.reload()
})
}
const updateItem = (record) => {
history.push(`/memberCenter/systemSetting/authConfig/userSystem/edit?id=${record.userId}&preview=0`)
}
const handleStatus = (record) => {
PublicApi.postMemberUserUpdatestatus({
userId: record.userId,
status: record.status === 1 ? 0 : 1
}).then(res => {
tableRef.current.reload()
})
}
return {
tableRef,
dataRef,
addItem,
}
}
export default useSysetemTable
@import '~@/global/styles/global.less';
#root {
.loginItem {
flex: 1;
width: 0;
}
.loginCtl {
position: relative;
background: @white;
}
.loginWrap {
padding: 141px 0 102px;
}
.readyLogin {
text-align: center;
margin-top: 24px;
}
.loginMain {
position: relative;
background: @white;
padding: 64px 56px 0;
color: #909399;
&>h2 {
font-size: 32px;
margin-bottom: 32px;
color: #606266;
font-weight: 400;
}
.clickUsernameLogin {
.ab-position(right, top, 8, 8);
font-size: 12px;
color: rgba(107, 119, 140, 1);
}
.clickScanLogin {
// .center-text();
.ab-position(right, top, 8, 8);
width: 32px;
height: 32px;
background: url("../../../mockStatic/qr_code1.png") center center no-repeat;
background-size: cover;
&:hover {
background: url("../../../mockStatic/qr_code2.png") center center no-repeat;
}
}
.scanTips {
.make-center(flex);
font-size: 12px;
color: rgba(107, 119, 140, 1);
.scanIcon {
font-size: 30px;
margin-right: @margin-sm;
}
}
}
.loginDesc {
// background: url("../../../mockStatic/image_ad.png") center center no-repeat;
background-size: cover;
.adBox {
color: @white;
.make-center(text);
& h2 {
margin-top: 20px;
.font-height-color(32, 80, @white);
letter-spacing: 2px;
}
& p {
padding: 10px 60px;
text-indent: 2em;
}
}
}
.thirdLogin {
height: 64px;
background: #FAFBFC;
margin-top: 100px;
& a {
margin-left: 6px;
.make-center(text);
vertical-align: middle;
}
}
.loginVerBtn {
background: #EBF7F2;
}
.scanLoginWrap {
.make-center(text);
&>h2 {
color: #909399;
}
.qrCodeImage {
.make-center(text);
width: 224px;
height: 224px;
.make-center-space(margin, 30, 18);
&>img {
.make-center(block);
width: 100%;
height: 100%;
}
}
}
.mr_t-40 {
margin-top: 40px;
}
.mr_t-24 {
margin-top: 24px;
}
// register
.register {
padding-top: 60px;
// width: 100%;
&>h3 {
padding: 40px 0;
.make-center(text);
font-size: 32px;
margin-bottom: 0;
}
}
.registerForm {
max-width: 335px;
margin: 0px auto;
padding-top: 40px;
}
.registerBox {
width: 100%;
min-height: 700px;
padding-bottom: 40px;
background: #fff;
padding-bottom: 40px;
.stepWrap {
height: 72px;
background: #FAFBFC;
padding: 0 115px;
.make-center(flexAlign);
}
}
.formBoxStep1 {
width: 324px;
.make-center-space(margin, 40, 0);
}
.formBefore {
width: 54px;
.font-height-color(undefined, 40, #606266, #F4F5F7);
.make-center(text);
border: 1px solid #DFE1E6;
border-right: 0;
}
.formBoxStep2 {
width: 704px;
.make-center(margin);
& h3 {
margin-top: 48px;
}
}
.continueButton {
.make-center(block);
width: 340px;
height: 40px;
.make-center-space(margin, 8);
}
.formBoxStep3 {
width: 704px;
.make-center(margin);
.make-center(text);
& .description {
margin-bottom: 40px;
& p {
.font-height-color(14, 20, #606266);
}
}
&.guid {
.font-height-color(14, 22, #909399);
}
& h2 {
font-size: 24px;
color: rgba(23, 43, 77, 1);
margin: 24px 0;
}
& img {
display: block;
.make-center(margin);
}
}
.agreement {
font-size: 12px;
}
.checkTypes {
width: 702px;
.make-center(margin);
}
.margin320 {
width: 320px;
.make-center(margin);
display: block;
}
.default {
width: 148px;
margin-right: 24px;
margin-bottom: 16px;
.make-center(text);
height: 32px;
line-height: 32px;
&:nth-child(2n) {
margin-right: 0;
}
}
.large {
width: 320px;
margin-bottom: 24px;
.make-center(text);
height: 48px;
line-height: 48px;
}
.btnCenter {
width: 320px;
.make-center(margin);
display: block;
}
// policy
.policyBox {
width: 100%;
// height: 100vh;
background-color: #fff;
&>h1 {
.font-height-color(24, 96, #303133, #F4F5F7);
.make-center(text)
}
& article {
padding-bottom: 200px;
h4 {
width: 96px;
.font-height-color(16, 48, #303133);
font-weight: 500;
margin-top: 24px;
}
p {
font-size: 12px;
color: rgba(66, 82, 110, 1);
line-height: 22px;
}
}
}
// get back password
.getBackBox {
position: relative;
padding-top: 60px;
&>h2 {
width: 100%;
.make-center(text);
.font-height-color(24, 120, #303133);
}
.getBackForm {
background-color: @white;
margin-left: auto;
margin-right: auto;
width: 1190px;
padding-bottom: 60px;
.formBox {
width: 320px;
.make-center-space(margin, 40, 40);
.back {
width: 100%;
.make-center(block);
.make-center(text);
color: #909399;
}
}
}
}
}
\ No newline at end of file
@import '~@/global/styles/global.less';
#root {
.loginItem {
flex: 1;
width: 0;
}
.loginCtl {
position: relative;
background: @white;
}
.loginWrap {
padding: 141px 0 102px;
min-height: 560px;
}
.readyLogin {
text-align: center;
margin-top: 24px;
}
.loginMain {
position: relative;
background: @white;
padding: 64px 56px 0;
color: #909399;
&>h2 {
font-size: 32px;
margin-bottom: 32px;
color: #606266;
font-weight: 400;
}
.clickUsernameLogin {
.ab-position(right, top, 8, 8);
font-size: 12px;
color: rgba(107, 119, 140, 1);
}
.clickScanLogin {
// .center-text();
.ab-position(right, top, 8, 8);
width: 32px;
height: 32px;
background: url("../../../mockStatic/qr_code1.png") center center no-repeat;
background-size: cover;
&:hover {
background: url("../../../mockStatic/qr_code2.png") center center no-repeat;
}
}
.scanTips {
.make-center(flex);
font-size: 12px;
color: rgba(107, 119, 140, 1);
.scanIcon {
font-size: 30px;
margin-right: @margin-sm;
}
}
}
.loginDesc {
// background: url("../../../mockStatic/image_ad.png") center center no-repeat;
background-size: cover;
.adBox {
color: @white;
.make-center(text);
& h2 {
margin-top: 20px;
.font-height-color(32, 80, @white);
letter-spacing: 2px;
}
& p {
padding: 10px 60px;
text-indent: 2em;
}
}
}
.thirdLogin {
height: 64px;
background: #FAFBFC;
margin-top: 100px;
& a {
margin-left: 6px;
.make-center(text);
vertical-align: middle;
}
}
.loginVerBtn {
background: #EBF7F2;
}
.scanLoginWrap {
.make-center(text);
&>h2 {
color: #909399;
}
.qrCodeImage {
.make-center(text);
width: 224px;
height: 224px;
.make-center-space(margin, 30, 18);
&>img {
.make-center(block);
width: 100%;
height: 100%;
}
}
}
.mr_t-40 {
margin-top: 40px;
}
.mr_t-24 {
margin-top: 24px;
}
// register
.register {
padding-top: 60px;
// width: 100%;
&>h3 {
padding: 40px 0;
.make-center(text);
font-size: 32px;
margin-bottom: 0;
}
}
.registerForm {
max-width: 335px;
margin: 0px auto;
padding-top: 40px;
}
.registerBox {
width: 100%;
min-height: 700px;
padding-bottom: 40px;
background: #fff;
padding-bottom: 40px;
.stepWrap {
height: 72px;
background: #FAFBFC;
padding: 0 115px;
.make-center(flexAlign);
}
}
.formBoxStep1 {
width: 324px;
.make-center-space(margin, 40, 0);
}
.formBefore {
width: 54px;
.font-height-color(undefined, 40, #606266, #F4F5F7);
.make-center(text);
border: 1px solid #DFE1E6;
border-right: 0;
}
.formBoxStep2 {
width: 704px;
.make-center(margin);
& h3 {
margin-top: 48px;
}
}
.continueButton {
.make-center(block);
width: 340px;
height: 40px;
.make-center-space(margin, 8);
}
.formBoxStep3 {
width: 704px;
.make-center(margin);
.make-center(text);
& .description {
margin-bottom: 40px;
& p {
.font-height-color(14, 20, #606266);
}
}
&.guid {
.font-height-color(14, 22, #909399);
}
& h2 {
font-size: 24px;
color: rgba(23, 43, 77, 1);
margin: 24px 0;
}
& img {
display: block;
.make-center(margin);
}
}
.agreement {
font-size: 12px;
}
.checkTypes {
width: 702px;
.make-center(margin);
}
.margin320 {
width: 320px;
.make-center(margin);
display: block;
}
.default {
width: 148px;
margin-right: 24px;
margin-bottom: 16px;
.make-center(text);
height: 32px;
line-height: 32px;
&:nth-child(2n) {
margin-right: 0;
}
}
.large {
width: 320px;
margin-bottom: 24px;
.make-center(text);
height: 48px;
line-height: 48px;
}
.btnCenter {
width: 320px;
.make-center(margin);
display: block;
}
// policy
.policyBox {
width: 100%;
// height: 100vh;
background-color: #fff;
&>h1 {
.font-height-color(24, 96, #303133, #F4F5F7);
.make-center(text)
}
& article {
padding-bottom: 200px;
h4 {
width: 96px;
.font-height-color(16, 48, #303133);
font-weight: 500;
margin-top: 24px;
}
p {
font-size: 12px;
color: rgba(66, 82, 110, 1);
line-height: 22px;
}
}
}
// get back password
.getBackBox {
position: relative;
padding-top: 60px;
&>h2 {
width: 100%;
.make-center(text);
.font-height-color(24, 120, #303133);
}
.getBackForm {
background-color: @white;
margin-left: auto;
margin-right: auto;
width: 1190px;
padding-bottom: 60px;
.formBox {
width: 320px;
.make-center-space(margin, 40, 40);
.back {
width: 100%;
.make-center(block);
.make-center(text);
color: #909399;
}
}
}
}
}
import {action, computed, observable, runInAction} from 'mobx'
import { IChannelProductModule, IRole, IChannel } from '@/module/channelProductModule';
/**
* 渠道直采商品
*/
class ChannelProductStore implements IChannelProductModule {
// 选择商品区块
@observable public productSourceInStore: number = 1;
@observable public productSelectRowInStore: any = null;
@observable public priceType: number = null;
@observable public productName: string = null;
@observable public tableDataInSetPrice: any[] = null;
@observable public selectedRole: IRole = null;
@observable public selectChannel: any = null;
@observable public selectedSource: number = 1;
@action.bound
public setProductSourceInStore(data: number) {
this.productSourceInStore = data;
}
@action.bound
public setProductSelectRowInStore(data: any) {
this.productSelectRowInStore = data;
}
@action.bound
public setPriceType(data: number){
this.priceType = data;
}
@action.bound
public setProductName(data: string){
this.productName = data;
}
@action.bound
public setTableDataInSetPrice(data: any[]){
this.tableDataInSetPrice = data;
}
@action.bound
public setSelectedRole(data: IRole){
this.selectedRole = data;
}
@action.bound
public setSelectChannel(data: any[]){
this.selectChannel = data
}
@action.bound
public setSelectSource(data: number){
this.selectedSource = data
}
}
export default ChannelProductStore
import {action, computed, observable, runInAction} from 'mobx'
import { IChannelProductModule } from '@/module/channelProductModule';
export interface IRole {
key: string;
value: number;
children: string;
}
export interface IChannel {
name: string;
memberId?: number;
}
/**
* 渠道直采商品
*/
class ChannelProductStore implements IChannelProductModule {
// 选择商品区块
@observable public productSourceInStore: number = 1;
@observable public productSelectRowInStore: any = null;
@observable public priceType: number = null;
@observable public productName: string = null;
@observable public tableDataInSetPrice: any[] = null;
@observable public selectedRole: IRole = null;
@observable public selectChannel: any = null;
@observable public selectedSource: number = 1;
@action.bound
public setProductSourceInStore(data: number) {
this.productSourceInStore = data;
}
@action.bound
public setProductSelectRowInStore(data: any) {
this.productSelectRowInStore = data;
}
@action.bound
public setPriceType(data: number){
this.priceType = data;
}
@action.bound
public setProductName(data: string){
this.productName = data;
}
@action.bound
public setTableDataInSetPrice(data: any[]){
this.tableDataInSetPrice = data;
}
@action.bound
public setSelectedRole(data: IRole){
this.selectedRole = data;
}
@action.bound
public setSelectChannel(data: any[]){
this.selectChannel = data
}
@action.bound
public setSelectSource(data: number){
this.selectedSource = data
}
}
export default ChannelProductStore
import {action, computed, observable, runInAction} from 'mobx'
import { IProductModule, IProductSelectAttribute, IBasicFormParam, IPriceAttributeParam, IOtherParam, IDecsParams, IPage } from '@/module/productModule'; // mobx要用到的数据类型
import { IProductModule, IProductSelectAttribute, IBasicFormParam, IPriceAttributeParam, IOtherParam } from '@/module/productModule'; // mobx要用到的数据类型
export interface IPage {
current: number;
pageSize: number;
}
export interface IDecsParams {
id?: number;
video: string[];
image: string[] ;
word: string[];
}
class ProductStore implements IProductModule {
@observable public attributeLists: any[] = [];
......
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