国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频

前端 B 端權(quán)限控制

共 44942字,需瀏覽 90分鐘

 ·

2021-07-21 15:38


點(diǎn)擊上方 前端瓶子君,關(guān)注公眾號

回復(fù)算法,加入前端編程面試算法每日一題群


后臺管理平臺內(nèi)部權(quán)限大部分涉及到到兩種方式:資源權(quán)限 & 數(shù)據(jù)權(quán)限

說明:下面的代碼是react + ant design pro的例子。

1. 基本介紹

  • 資源權(quán)限:菜單導(dǎo)航欄 & 頁面 & 按鈕 資源可見權(quán)限。
  • 數(shù)據(jù)權(quán)限:對于頁面上的數(shù)據(jù)操作,同一個人同一個頁面不同的數(shù)據(jù)可能存在不同的數(shù)據(jù)操作權(quán)限。

權(quán)限緯度

  • 角色緯度:大部分的情況為:用戶 => 角色 => 權(quán)限
  • 用戶緯度:用戶 => 權(quán)限

表現(xiàn)形式

  • 基礎(chǔ)表現(xiàn)形式還是樹結(jié)構(gòu)的展現(xiàn)形式,因?yàn)閷?yīng)的菜單-頁面-按鈕是一個樹的從主干到節(jié)點(diǎn)的數(shù)據(jù)流向。

2. 權(quán)限數(shù)據(jù)錄入與展示

采用樹結(jié)構(gòu)進(jìn)行處理。唯一需要處理的是父子節(jié)點(diǎn)的聯(lián)動關(guān)系處理。這里因?yàn)椴煌墓净蛘呦到y(tǒng)可能對于這部分的數(shù)據(jù)錄入方式不同,所以久不貼圖了。

3.用戶資源權(quán)限流程圖

image.png

4 前端權(quán)限控制

前端控制權(quán)限也是分為兩部分,菜單頁面 與 按鈕。因?yàn)榍岸藱?quán)限控制的實(shí)現(xiàn),會因?yàn)楹笈_接口形式有所影響,但是大體方向是相同。還是會分為這兩塊內(nèi)容。這里對于權(quán)限是使用多接口查詢權(quán)限,初始登錄查詢頁面權(quán)限,點(diǎn)擊業(yè)務(wù)頁面,查詢對應(yīng)業(yè)務(wù)頁面的資源code。

4.1 菜單權(quán)限

菜單權(quán)限控制需要了解兩個概念:

  • 一個是可見的菜單頁面 :左側(cè)dom節(jié)點(diǎn)
  • 一個是可訪問的菜單頁面 :系統(tǒng)當(dāng)中路由這一塊

這里說的意思是:我們所說的菜單權(quán)限控制,大多只是停留在菜單是否可見,但是系統(tǒng)路由的頁面可見和頁面上的菜單是否可見是兩回事情。假設(shè)系統(tǒng)路由/path1可見,盡管頁面上的沒有/path1對應(yīng)的菜單顯示。我們直接在瀏覽器輸入對應(yīng)的path1,還是可以訪問到對應(yīng)的頁面。這是因?yàn)橄到y(tǒng)路由那一塊其實(shí)我們是沒有去處理的。

了解了這個之后,我們需要做菜單頁面權(quán)限的時候就需要去考慮兩塊,并且是對應(yīng)的。

4.1.1 路由權(quán)限 【代碼地址[2] demo地址[3]

這里是有兩種做法:

  • 第一種,控制路由的配置,當(dāng)然不是路由配置文件里去配置。而是生效的路由配置里去做。
  • 第二種,完全不做這里的路由控制,而是在路由跳轉(zhuǎn)到?jīng)]有權(quán)限的頁面,寫邏輯校驗(yàn)是否有當(dāng)前的權(quán)限,然后手動跳轉(zhuǎn)到403頁面。

這里還是先用第一種做法來做:因?yàn)檫@里用第一種做了之后,菜單可見權(quán)限自動適配好了。會省去我們很多事情。

a. 路由文件,定義菜單頁面權(quán)限。并且將exception以及404的路由添加notInAut標(biāo)志,這個標(biāo)志說明:這兩個路由不走權(quán)限校驗(yàn)。同理的還有 /user。

export default [
  // user
  {
    path'/user',
    component'../layouts/UserLayout',
    routes: [
      { path'/user'redirect'/user/login' },
      { path'/user/login'component'./User/Login' },
      { path'/user/register'component'./User/Register' },
      { path'/user/register-result'component'./User/RegisterResult' },
    ],
  },
  // app
  {
    path'/',
    component'../layouts/BasicLayout',
    Routes: ['src/pages/Authorized'],
    authority: ['admin''user'],
    routes: [
      // dashboard
      { path'/'redirect'/list/table-list' },
      // forms
      {
        path'/form',
        icon'form',
        name'form',
        code'form_menu',
        routes: [
          {
            path'/form/basic-form',
            code'form_basicForm_page',
            name'basicform',
            component'./Forms/BasicForm',
          },
        ],
      },
      // list
      {
        path'/list',
        icon'table',
        name'list',
        code'list_menu',
        routes: [
          {
            path'/list/table-list',
            name'searchtable',
            code'list_tableList_page',
            component'./List/TableList',
          },
        ],
      },
      {
        path'/profile',
        name'profile',
        icon'profile',
        code'profile_menu',
        routes: [
          // profile
          {
            path'/profile/basic',
            name'basic',
            code'profile_basic_page',
            component'./Profile/BasicProfile',
          },
          {
            path'/profile/advanced',
            name'advanced',
            code'profile_advanced_page',
            authority: ['admin'],
            component'./Profile/AdvancedProfile',
          },
        ],
      },
      {
        name'exception',
        icon'warning',
        notInAuttrue,
        hideInMenutrue,
        path'/exception',
        routes: [
          // exception
          {
            path'/exception/403',
            name'not-permission',
            component'./Exception/403',
          },
          {
            path'/exception/404',
            name'not-find',
            component'./Exception/404',
          },
          {
            path'/exception/500',
            name'server-error',
            component'./Exception/500',
          },
          {
            path'/exception/trigger',
            name'trigger',
            hideInMenutrue,
            component'./Exception/TriggerException',
          },
        ],
      },
      {
        notInAuttrue,
        component'404',
      },
    ],
  },
];

復(fù)制代碼

b. 修改app.js 文件,加載路由

export const dva = {
  config: {
    onError(err) {
      err.preventDefault();
    },
  },
};

let authRoutes = null;

function ergodicRoutes(routes, authKey, authority{
  routes.forEach(element => {
    if (element.path === authKey) {
      Object.assign(element.authority, authority || []);
    } else if (element.routes) {
      ergodicRoutes(element.routes, authKey, authority);
    }
    return element;
  });
}

function customerErgodicRoutes(routes{
  const menuAutArray = (localStorage.getItem('routerAutArray') || '').split(',');

  routes.forEach(element => {
    // 沒有path的情況下不需要走邏輯檢查
    // path 為 /user 不需要走邏輯檢查
    if (element.path === '/user' || !element.path) {
      return element;
    }

    // notInAut 為true的情況下不需要走邏輯檢查
    if (!element.notInAut) {
      if (menuAutArray.indexOf(element.code) >= 0 || element.path === '/') {
        if (element.routes) {
          element.routes = customerErgodicRoutes(element.routes);

          element.routes = element.routes.filter(item => !item.isNeedDelete);
        }
      } else {
        element.isNeedDelete = true;
      }
    }

    /**
     * 后臺接口返回子節(jié)點(diǎn)的情況,父節(jié)點(diǎn)需要溯源處理
     */

    // notInAut 為true的情況下不需要走邏輯檢查
    // if (!element.notInAut) {
    //   if (element.routes) {
    //     // eslint-disable-next-line no-param-reassign
    //     element.routes = customerErgodicRoutes(element.routes);

    //     // eslint-disable-next-line no-param-reassign
    //     if (element.routes.filter(item => item.isNeedSave && !item.hideInMenu).length) {
    //       // eslint-disable-next-line no-param-reassign
    //       element.routes = element.routes.filter(item => item.isNeedSave);
    //       if (element.routes.length) {
    //         // eslint-disable-next-line no-param-reassign
    //         element.isNeedSave = true;
    //       }
    //     }
    //   } else if (menuAutArray.indexOf(element.code) >= 0) {
    //     // eslint-disable-next-line no-param-reassign
    //     element.isNeedSave = true;
    //   }
    // } else {
    //   // eslint-disable-next-line no-param-reassign
    //   element.isNeedSave = true;
    // }

    return element;
  });

  return routes;
}

export function patchRoutes(routes{
  Object.keys(authRoutes).map(authKey =>
    ergodicRoutes(routes, authKey, authRoutes[authKey].authority),
  );

  customerErgodicRoutes(routes);

  /**
   * 后臺接口返回子節(jié)點(diǎn)的情況,父節(jié)點(diǎn)需要溯源處理
   */

  window.g_routes = routes.filter(item => !item.isNeedDelete);

  /**
   * 后臺接口返回子節(jié)點(diǎn)的情況,父節(jié)點(diǎn)需要溯源處理
   */

  // window.g_routes = routes.filter(item => item.isNeedSave);
}

export function render(oldRender{
  authRoutes = '';
  oldRender();
}

復(fù)制代碼

c. 修改login.js,獲取路由當(dāng)中的code便利獲取到,進(jìn)行查詢權(quán)限

import { routerRedux } from 'dva/router';
import { stringify } from 'qs';
import { fakeAccountLogin, getFakeCaptcha } from '@/services/api';
import { getAuthorityMenu } from '@/services/authority';
import { setAuthority } from '@/utils/authority';
import { getPageQuery } from '@/utils/utils';
import { reloadAuthorized } from '@/utils/Authorized';
import routes from '../../config/router.config';

export default {
  namespace'login',

  state: {
    statusundefined,
  },

  effects: {
    *login({ payload }, { call, put }) {
      const response = yield call(fakeAccountLogin, payload);
      yield put({
        type'changeLoginStatus',
        payload: response,
      });
      // Login successfully
      if (response.status === 'ok') {
        // 這里的數(shù)據(jù)通過接口返回菜單頁面的權(quán)限是什么

        const codeArray = [];
        // eslint-disable-next-line no-inner-declarations
        function ergodicRoutes(routesParam{
          routesParam.forEach(element => {
            if (element.code) {
              codeArray.push(element.code);
            }
            if (element.routes) {
              ergodicRoutes(element.routes);
            }
          });
        }

        ergodicRoutes(routes);
        const authMenuArray = yield call(getAuthorityMenu, codeArray.join(','));
        localStorage.setItem('routerAutArray', authMenuArray.join(','));

        reloadAuthorized();
        const urlParams = new URL(window.location.href);
        const params = getPageQuery();
        let { redirect } = params;
        if (redirect) {
          const redirectUrlParams = new URL(redirect);
          if (redirectUrlParams.origin === urlParams.origin) {
            redirect = redirect.substr(urlParams.origin.length);
            if (redirect.match(/^\/.*#/)) {
              redirect = redirect.substr(redirect.indexOf('#') + 1);
            }
          } else {
            window.location.href = redirect;
            return;
          }
        }
        // yield put(routerRedux.replace(redirect || '/'));

        // 這里之所以用頁面跳轉(zhuǎn),因?yàn)槁酚傻闹匦略O(shè)置需要頁面重新刷新才可以生效
        window.location.href = redirect || '/';
      }
    },

    *getCaptcha({ payload }, { call }) {
      yield call(getFakeCaptcha, payload);
    },

    *logout(_, { put }) {
      yield put({
        type'changeLoginStatus',
        payload: {
          statusfalse,
          currentAuthority'guest',
        },
      });
      reloadAuthorized();
      yield put(
        routerRedux.push({
          pathname'/user/login',
          search: stringify({
            redirectwindow.location.href,
          }),
        }),
      );
    },
  },

  reducers: {
    changeLoginStatus(state, { payload }) {
      setAuthority(payload.currentAuthority);
      return {
        ...state,
        status: payload.status,
        type: payload.type,
      };
    },
  },
};

復(fù)制代碼

d. 添加service

import request from '@/utils/request';

// 查詢菜單權(quán)限
export async function getAuthorityMenu(codes{
  return request(`/api/authority/menu?resCodes=${codes}`);
}

// 查詢頁面按鈕權(quán)限
export async function getAuthority(params{
  return request(`/api/authority?codes=${params}`);
}

復(fù)制代碼

4.1.2 路由權(quán)限 菜單可見權(quán)限

參照上面的方式,這里的菜單可見權(quán)限不用做其他的操作。

4.2 按鈕權(quán)限 【代碼地址[4] demo地址[5]

按鈕權(quán)限上就涉及到兩塊,資源權(quán)限數(shù)據(jù)權(quán)限。數(shù)據(jù)獲取的方式不同,代碼邏輯上會稍微有點(diǎn)不同。核心是業(yè)務(wù)組件內(nèi)部的code,在加載的時候就自行累加,然后在頁面加載完成的時候,發(fā)送請求。拿到數(shù)據(jù)之后,自行進(jìn)行權(quán)限校驗(yàn)。盡量減少業(yè)務(wù)頁面代碼的復(fù)雜度。

資源權(quán)限邏輯介紹:

  1. PageHeaderWrapper包含的業(yè)務(wù)頁面存在按鈕權(quán)限
  2. 按鈕權(quán)限通過AuthorizedButton包含處理,需要添加code。但是業(yè)務(wù)頁面因?yàn)槭菃为?dú)頁面發(fā)送當(dāng)前頁面code集合去查詢權(quán)限code,然后在AuthorizedButton進(jìn)行權(quán)限邏輯判斷。
  3. 所以AuthorizedButtoncomponentWillMount生命周期進(jìn)行當(dāng)前業(yè)務(wù)頁面的code累加。累加完成之后,通過PageHeaderWrappercomponentDidMount生命周期函數(shù)發(fā)送權(quán)限請求,拿到權(quán)限code,通過公有g(shù)lobalAuthority model讀取數(shù)據(jù)進(jìn)行權(quán)限邏輯判斷。
  4. 對于業(yè)務(wù)頁面的調(diào)用參考readme進(jìn)行使用。因?yàn)閷τ趶棾隹騼?nèi)部的code,在業(yè)務(wù)列表頁面渲染的時候,組件還未加載,所以通過extencode提前將code累加起來進(jìn)行查詢權(quán)限。

數(shù)據(jù)權(quán)限介紹:

  1. 涉及數(shù)據(jù)權(quán)限,則直接將對應(yīng)的數(shù)據(jù)規(guī)則放進(jìn)AuthorizedButton內(nèi)部進(jìn)行判斷,需要傳入的數(shù)據(jù)則直接通過props傳入即可。因?yàn)閿?shù)據(jù)權(quán)限的規(guī)則不同,這里就沒有舉例子。
  2. 需要注意的邏輯是資源權(quán)限和數(shù)據(jù)權(quán)限是串行的,先判斷資源權(quán)限,然后判斷數(shù)據(jù)權(quán)限。

a. 添加公用authority model

/* eslint-disable no-unused-vars */
/* eslint-disable no-prototype-builtins */
import { getAuthority } from '@/services/authority';

export default {
  namespace'globalAuthority',

  state: {
    hasAuthorityCodeArray: [], // 獲取當(dāng)前具有權(quán)限的資源code
    pageCodeArray: [], // 用來存儲當(dāng)前頁面存在的資源code
  },

  effects: {
    /**
     * 獲取當(dāng)前頁面的權(quán)限控制
     */

    *getAuthorityForPage({ payload }, { put, call, select }) {
      // 這里的資源code都是自己加載的
      const pageCodeArray = yield select(state => state.globalAuthority.pageCodeArray);
      const response = yield call(getAuthority, pageCodeArray);

      if (pageCodeArray.length) {
        yield put({
          type'save',
          payload: {
            hasAuthorityCodeArray: response,
          },
        });
      }
    },

    *plusCode({ payload }, { put, select }) {
      // 組件累加當(dāng)前頁面的code,用來發(fā)送請求返回對應(yīng)的權(quán)限code
      const { codeArray = [] } = payload;
      const pageCodeArray = yield select(state => state.globalAuthority.pageCodeArray);

      yield put({
        type'save',
        payload: {
          pageCodeArray: pageCodeArray.concat(codeArray),
        },
      });
    },

    // eslint-disable-next-line no-unused-vars
    *resetAuthorityForPage({ payload }, { put, call }) {
      yield put({
        type'save',
        payload: {
          hasAuthorityCodeArray: [],
          pageCodeArray: [],
        },
      });
    },
  },

  reducers: {
    save(state, { payload }) {
      return {
        ...state,
        ...payload,
      };
    },
  },
};

復(fù)制代碼

b. 修改PageHeaderWrapper文件【因?yàn)樗械臉I(yè)務(wù)頁面都是這個組件的子節(jié)點(diǎn)】

import React, { PureComponent } from 'react';
import { FormattedMessage } from 'umi/locale';
import Link from 'umi/link';
import PageHeader from '@/components/PageHeader';
import { connect } from 'dva';
import MenuContext from '@/layouts/MenuContext';
import { Spin } from 'antd';
import GridContent from './GridContent';
import styles from './index.less';

class PageHeaderWrapper extends PureComponent {
  componentDidMount() {
    const { dispatch } = this.props;
    dispatch({
      type'globalAuthority/getAuthorityForPage'// 發(fā)送請求獲取當(dāng)前頁面的權(quán)限code
    });
  }

  componentWillUnmount() {
    const { dispatch } = this.props;
    dispatch({
      type'globalAuthority/resetAuthorityForPage',
    });
  }

  render() {
    const { children, contentWidth, wrapperClassName, top, loading, ...restProps } = this.props;

    return (
      <Spin spinning={loading}>
        <div style={{ margin: '-24px -24px 0' }} className={wrapperClassName}>
          {top}
          <MenuContext.Consumer>
            {value => (
              <PageHeader
                wide={contentWidth === 'Fixed'}
                home={<FormattedMessage id="menu.home" defaultMessage="Home" />
}
                {...value}
                key="pageheader"
                {...restProps}
                linkElement={Link}
                itemRender={item => {
                  if (item.locale) {
                    return <FormattedMessage id={item.locale} defaultMessage={item.title} />;
                  }
                  return item.title;
                }}
              />
            )}
          </MenuContext.Consumer>
          {children ? (
            <div className={styles.content}>
              <GridContent>{children}</GridContent>
            </div>
          ) : null}
        </div>
      </Spin>

    );
  }
}

export default connect(({ setting, globalAuthority, loading }) => ({
  contentWidth: setting.contentWidth,
  globalAuthority,
  loading: loading.models.globalAuthority,
}))(PageHeaderWrapper);

復(fù)制代碼

c. 添加AuthorizedButton公共組件

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'dva';

@connect(({ globalAuthority }) => ({
  globalAuthority,
}))
class AuthorizedButton extends Component {
  static contextTypes = {
    isMobile: PropTypes.bool,
  };

  componentWillMount() {
    // extendcode 擴(kuò)展表格中的code還沒有出現(xiàn)的情況
    const {
      dispatch,
      code,
      extendCode = [],
      globalAuthority: { pageCodeArray },
    } = this.props;

    let codeArray = [];

    if (code) {
      codeArray.push(code);
    }

    if (extendCode && extendCode.length) {
      codeArray = codeArray.concat(extendCode);
    }

    // code已經(jīng)存在,證明是頁面數(shù)據(jù)渲染之后或者彈出框的按鈕資源,不需要走dva了
    if (pageCodeArray.indexOf(code) >= 0) {
      return;
    }

    dispatch({
      type'globalAuthority/plusCode',
      payload: {
        codeArray,
      },
    });
  }

  checkAuthority = code => {
    const {
      globalAuthority: { hasAuthorityCodeArray },
    } = this.props;

    return hasAuthorityCodeArray.indexOf(code) >= 0// 資源權(quán)限
  };

  render() {
    const { children, code } = this.props;

    return (
      <span style={{ display: this.checkAuthority(code) ? 'inline' : 'none' }}>{children}</span>
    );
  }
}

export default AuthorizedButton;

復(fù)制代碼

d. 添加AuthorizedButton readme文件
github.com/rodchen-kin…[6]

4.3 按鈕權(quán)限擴(kuò)展-鏈接權(quán)限控制 【代碼地址[7] demo地址[8]

背景:頁面上有需要控制跳轉(zhuǎn)鏈接的權(quán)限,有權(quán)限則可以跳轉(zhuǎn),沒有權(quán)限則不能跳轉(zhuǎn)。

a.公共model添加新的state:codeAuthorityObject

image.png

通過redux-devtool,查看到codeAuthorityObject的狀態(tài)值為:key:code值,value的值為true/false。true代表,有權(quán)限,false代表無權(quán)限。主要用于開發(fā)人員自己做相關(guān)處理。

image.png

b.需要控制的按鈕code,通過其他方式擴(kuò)展進(jìn)行code計算,發(fā)送請求獲取權(quán)限

image.png

c.獲取數(shù)據(jù)進(jìn)行數(shù)據(jù)控制

image.png

4.4 按鈕數(shù)據(jù)權(quán)限

  • demo分支:github.com/rodchen-kin…[9]
  • demo代碼:github.com/rodchen-kin…[10]

背景

數(shù)據(jù)權(quán)限是對于業(yè)務(wù)組件內(nèi)部表格組件的數(shù)據(jù)進(jìn)行的數(shù)據(jù)操作權(quán)限。列表數(shù)據(jù)可能歸屬于不同的數(shù)據(jù)類型,所以具有不同的數(shù)據(jù)操作權(quán)限。對于批量操作則需要判斷選擇的數(shù)據(jù)是否都具有操作權(quán)限,然后顯示是否可以批量操作,如果有一個沒有操作權(quán)限,都不能進(jìn)行操作。

image.png

總體思路

場景:
比如在商品列表中,每條商品記錄后面的“操作”一欄下用三個按鈕:【編輯】、【上架/下架】、【刪除】,而對于某一個用戶,他可以查看所有的商品,但對于某些品牌他可以【上架/下架】但不能【編輯】,則前端需要控制到每一個商品后面的按鈕的可用狀態(tài)。

比如用戶A對于某一條業(yè)務(wù)數(shù)據(jù)(id=1999)有編輯權(quán)限,則這條記錄上的【編輯】按鈕對他來說是可見的(前提是他首先要有【編輯】這個按鈕的資源權(quán)限),但對于另一條記錄(id=1899)是沒有【編輯】權(quán)限,則這條記錄上的【編輯】按鈕對他來說是不可見的。

按鈕【actType】屬性定義

每個數(shù)據(jù)操作的按鈕上加一個屬性 “actType”代表這個按鈕的動作類型(如:編輯、刪除、審核等),這個屬性是資權(quán)限的接口返回的,前端在調(diào)這個接口時將這個屬性記錄下來,或者保存到對應(yīng)的控件中。所以前端可以不用關(guān)于這個屬性的每個枚舉值代表的是什么含義,只需根據(jù)接口的返回值賦值就好。用興趣的同學(xué)也可以參考一下actType取值如下:1 可讀,2 編輯,3 可讀+可寫, 4 可收貨,8 可發(fā)貨,16 可配貨, 32 可審核,64 可完結(jié)

業(yè)務(wù)接口返回權(quán)限類型字段【permissionType】

對于有權(quán)限控制的業(yè)務(wù)數(shù)據(jù),列表接口或者詳情接口都會返回一個“permissionType”的字段,這個字段代表當(dāng)前用戶對于這條業(yè)務(wù)數(shù)據(jù)的權(quán)限類型,如當(dāng) permissionType=2 代表這個用戶對于這條數(shù)據(jù)有【編輯權(quán)限】,permisionType=4 代表這個用戶對于這條業(yè)務(wù)數(shù)據(jù)有收貨的權(quán)限,permisionType=6表示這個用戶對于這條記錄用編輯和發(fā)貨的權(quán)限(6=2+4)

怎么控制按鈕的可用狀態(tài)?

現(xiàn)在列表上有三個按鈕,【編輯】、【收貨】、【完結(jié)】,它們對應(yīng)的“actType”分別為2、4、64,某一條數(shù)據(jù)的permissionType=3,這時這三個按鈕的狀態(tài)怎么判斷呢,permissionType=3 我們可以分解為 1+2,表示這個用戶對于這條記錄有“可讀”+“編輯”權(quán)限,則這三個按鈕中,只有【編輯】按鈕是可用的。那么判斷的公式為:

((data[i].permissionType & obj.actType)==obj.actType)
復(fù)制代碼

前端的js數(shù)據(jù)進(jìn)行&判斷

需要進(jìn)行數(shù)據(jù)轉(zhuǎn)換

  • data.toString(2): 將數(shù)據(jù)進(jìn)行2進(jìn)制轉(zhuǎn)換成二進(jìn)制字符串。
  • parseInt(permissionType,2) : 二進(jìn)制字符串轉(zhuǎn)換成二進(jìn)制數(shù)據(jù)。

代碼修改

接口mock返回數(shù)據(jù)

response = [{
      "type"3,
      "name""創(chuàng)建活動-10001",
      "actType"0,
      "code""10001"
    }, {
      "type"3,
      "name""編輯-10002",
      "actType"2,
      "code""10002"
    }, {
      "type"3,
      "name""配置-10005",
      "actType"4,
      "code""10005"
    }, {
      "type"3,
      "name""訂閱警報-10006",
      "actType"8,
      "code""10006"
    }, {
      "type"3,
      "name""查詢詳情-20001",
      "actType"16,
      "code""20001"
    }, {
      "type"3,
      "name""批量操作-10007",
      "actType"32,
      "code""10007"
    }, {
      "type"3,
      "name""更多操作-10008",
      "actType"64,
      "code""10008"
    }]
復(fù)制代碼

每一個返回的接口權(quán)限會將對應(yīng)的actType一起返回。

getAuthorityForPage代碼修改 簡單修改一下,因?yàn)橹胺祷氐氖莄ode數(shù)組,現(xiàn)在返回的是對象

   /**
     * 獲取當(dāng)前頁面的權(quán)限控制
     */

    *getAuthorityForPage({ payload }, { put, call, select }) {
      // 這里的資源code都是自己加載的
      const pageCodeArray = yield select(state => state.globalAuthority.pageCodeArray);
      const response = yield call(getAuthority, pageCodeArray);
      const hasAuthorityCodeArray = response || [];
      const codeAuthorityObject = {};

      pageCodeArray.forEach((value, index, array) => {
        codeAuthorityObject[value] = hasAuthorityCodeArray.map(item => item.code).indexOf(value) >= 0;
      });

      // debugger
      yield put({
        type'save',
        payload: {
          hasAuthorityCodeArray,
          codeAuthorityObject,
        },
      });
    },
復(fù)制代碼
image.png

修改AuthorizedButton代碼 增加數(shù)據(jù)權(quán)限判斷

/* eslint-disable eqeqeq */
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'dva';

@connect(({ globalAuthority }) => ({
  globalAuthority,
}))
class AuthorizedButton extends Component {
  static contextTypes = {
    isMobile: PropTypes.bool,
  };

  componentWillMount() {
    // extendcode 擴(kuò)展表格中的code還沒有出現(xiàn)的情況
    const {
      dispatch,
      code,
      extendCode = [],
      globalAuthority: { pageCodeArray },
    } = this.props;

    let codeArray = [];

    if (code) {
      codeArray.push(code);
    }

    if (extendCode && extendCode.length) {
      codeArray = codeArray.concat(extendCode);
    }

    // code已經(jīng)存在,證明是頁面數(shù)據(jù)渲染之后或者彈出框的按鈕資源,不需要走dva了
    if (pageCodeArray.indexOf(code) >= 0) {
      return;
    }

    dispatch({
      type'globalAuthority/plusCode',
      payload: {
        codeArray,
      },
    });
  }

  checkAuthority = code => {
    const {
      globalAuthority: { hasAuthorityCodeArray },
    } = this.props;

    return hasAuthorityCodeArray.map(item => item.code).indexOf(code) >= 0 && this.checkDataAuthority(); // 資源權(quán)限
  };


  /**
   * 檢測數(shù)據(jù)權(quán)限
   */

  checkDataAuthority = () => {
    const {
      globalAuthority: { hasAuthorityCodeArray },
      code,                                         // 當(dāng)前按鈕的code
      actType,                                      // 當(dāng)前按鈕的actType的值通過傳遞傳入
      recordPermissionType,                         // 單條數(shù)據(jù)的數(shù)據(jù)操作權(quán)限總和
      actTypeArray
    } = this.props;

    if (recordPermissionType || actTypeArray) {     // 單條數(shù)據(jù)權(quán)限校驗(yàn)
      const tempCode = hasAuthorityCodeArray.filter(item => item.code === code)
      let tempActType = ''

      if (actType) {
        tempActType = actType
      } else if (tempCode.length) {
        tempActType = tempCode[0].actType
      } else {
        return true;                                // 默認(rèn)返回true
      }

      if (actTypeArray) {                           // 批量操作
        return !actTypeArray.some(item => !this.checkPermissionType(item.toString(2), tempActType.toString(2)))
      }

      // 單條數(shù)據(jù)操作
      return this.checkPermissionType(recordPermissionType.toString(2), tempActType.toString(2))
    } 

    return true;                                    // 如果字段沒有值的情況下,證明不需要進(jìn)行數(shù)據(jù)權(quán)限
  }

  /**
   * 二進(jìn)制檢查當(dāng)前當(dāng)前數(shù)據(jù)是否具有當(dāng)前權(quán)限
   * @param {*} permissionType 
   * @param {*} actType
   */

  checkPermissionType = (permissionType, actType) => 
     (parseInt(permissionType,2) & parseInt(actType,2)).toString(2) == actType
  

  render() {
    const { children, code } = this.props;

    return (
      <span style={{ display: this.checkAuthority(code) ? 'inline' : 'none' }}>{children}</span>
    );
  }
}

export default AuthorizedButton;

復(fù)制代碼

調(diào)用方式

單條數(shù)據(jù)操作

<AuthoriedButton code="10005" recordPermissionType={record.permissionType}>
  <a onClick={() => this.handleUpdateModalVisible(true, record)}>配置</a>
</AuthoriedButton>
復(fù)制代碼

批量操作

 <AuthoriedButton code="10007" actTypeArray={getNotDuplicateArrayById(selectedRows, 'permissionType')}>
     <Button>批量操作</Button>
 </AuthoriedButton>
復(fù)制代碼

關(guān)于本文

來源:耳東蝸牛

https://juejin.cn/post/6969799489519353863


最后

歡迎關(guān)注【前端瓶子君】??ヽ(°▽°)ノ?
回復(fù)「算法」,加入前端編程源碼算法群,每日一道面試題(工作日),第二天瓶子君都會很認(rèn)真的解答喲!
回復(fù)「交流」,吹吹水、聊聊技術(shù)、吐吐槽!
回復(fù)「閱讀」,每日刷刷高質(zhì)量好文!
如果這篇文章對你有幫助,在看」是最大的支持
 》》面試官也在看的算法資料《《
“在看和轉(zhuǎn)發(fā)”就是最大的支持
瀏覽 54
點(diǎn)贊
評論
收藏
分享

手機(jī)掃一掃分享

分享
舉報
評論
圖片
表情
推薦
點(diǎn)贊
評論
收藏
分享

手機(jī)掃一掃分享

分享
舉報

感谢您访问我们的网站,您可能还对以下资源感兴趣:

国产秋霞理论久久久电影-婷婷色九月综合激情丁香-欧美在线观看乱妇视频-精品国avA久久久久久久-国产乱码精品一区二区三区亚洲人-欧美熟妇一区二区三区蜜桃视频 久久熟女嫩草成人片免费| 无码久久| 日本韩国无码| 国产一级婬乱片AV片AAA毛片| BBw日本熟妇BBwHD| 2021国产精品视频| 国产精品探花熟女AV| 日韩三区| 日韩成人中文字幕| 91人人草| 欧美日韩视频在线播放| 色色网五月天| 亚洲日韩在线中文字幕| 亚洲福利在线免费观看| 成人午夜视频精品一区| 精品国产一区二区三区性色AV | 欧美精产国品一| np高辣调教视频| 国产AA| 久操视频在线播放| 成人三级视频在线观看| 中文字幕第315页| 青青草精品在线视频| 日韩中文字幕视频在线观看 | 在线观看黄色片| 成人欧美大片黄18| 丰滿人妻一区二区三区| 久久国产黄色视频| 激情五月天黄色| 在线国产福利| 日韩久久精品视频| 在线免费观看成人网站| 大色鬼在线天堂精品| 国产亚洲无码| 成人视频欧美| 欧美级毛片高潮| 国产内射视频| 国产一级在线| 久久精品一区二区三区四区| sesese999| 2018最好看的中文字幕高清电影| 第九色| 三级国产AV| 青青草在线免费视频| 狠狠干天天操| 欧美日韩国产成人综合| 欧美成人免费观看| 亚洲精品在线观看免费| 日韩av无码中文字幕| 三级高清无码视频| 又大又长又粗91| 最新久欠一区二区免费看| 五月天av在线观看| 国产97热人人| 国产av高清| 91午夜福利| 婷婷色色五月天| 熟妇人妻中文字幕无码老熟妇| 中文字幕无码Av在线看| 欧美性猛交XXXX乱大交3| 国产免费一区二区| 91成人一区二区三区| 靠逼免费视频| 国产综合精品久久久久成人AV| 久久久久久高清毛片一级| A片在线观看免费| 一级内射视频| 日韩毛片在线播放| 国产日本在线| 无码人妻中文字幕| 日本丰满老熟妇乱子伦| 看看AV| 一级av片| 小视频+福利| 青青青草视频| 天天添天天干| 欧美群交在线| 黄色片a| 中国熟妇XXXX18| 亚洲成人精品在线观看| 99er热精品视频| 水果派解说在线观看| 精品乱子伦一区二区三区| 欧美成人无码A片免费| 91人妻人人澡| 国产精品无码怀孕软件| 少妇大战黑人46厘米| 爱搞搞就要搞| 大香蕉电影网| 日本操逼在线播放| 色妞一區| 小泽玛利亚一区二区免费| 欧美3P视频| 岛国A视频| 内射黄片| 无码专区av| 伊人大久久| 国产精品999999| 亚洲专区区免费| 人操人操人操| 亚洲精品视频免费观看| 亚洲AV大片| 国产黄色免费视频| 欧美一级大香蕉| 色色国产| 在线中文字幕av| 亚洲www啪成人一区二区麻豆| 欧美成人精品欧美一级乱黄| 91久久精品无码一区二区三区| 五月婷婷丁香| 麻豆MD传媒MD0071| 久久香蕉电影| 1204手机看片| 成人激情四射网| 强伦轩一区二区三区在线观看| 免费在线观看视频黄| 亚洲丁香网| 大地99中文在线观看| 一级特黄AA片| 成人av免费在线观看| 人妻熟女字幕一区二区| 午夜精东影业果冻传媒| 69天堂| 中文字幕日本欧美| 精品视频久久久久久| 91在线无码精品入口电车| 中文资源在线观看| 91国内精品视频| 国产精品成人无码专区| 亚洲精品无码在线观看| 97在线观看视频| 99re在线| 成人婷婷五月| 91麻豆国产在线| 中文字幕免费av| 日本爱爱免费播放视频| 日本少妇做爱| 免费视频一二三区| 亚洲福利片| 一区二区三区久久久| 91无码一区二区三区在线| 欧美喷水视频| 超碰九一| 免费十无码| 天天日天天添| 久久成人精品视频| 999精品视频| 中文字幕视频一区日日骚| 淫色网址| 日韩欧美一| 99久久99久久精品免费看小说。 | AV无码高清| 黄色片免费看| 成人色色视频| 亚洲视频在线观看网站| 黄色一级片免费观看| 久操福利视频| 日韩福利在线| 9久热| 麻豆一区视频| 99热官方网站| 婷婷看片| 色六月婷婷| 第一色影院| 99成人| 国产a一级a毛一级视频| 伊人大香焦网| 国产一a毛一a免费观看| 西西4444WWW无码精品| 久久亚洲成人| 亚洲AV无码成人精品区天堂小说 | 中文字幕欧美在线| 日本一级特黄电影| 精品中文视频| 狠狠色噜噜狠狠狠7777| 国产黄色免费视频| 国产色av| 欧美五月在线网址| 国产看色免费| 69视频在线播放| 97黄片| 国产精品久久久精品| 中国老太卖婬HD播放| 日本一级片中文字幕| 国产精品免费网站| 激情深爱五月| 成人黄色视频网站在线观看| 亚洲日韩成人| www.四虎成人网站| 国产一级影院| 奥门毛片| 日本男人天堂| 开心深爱激情网| 黄色无码av| 亚洲精品人伦一区二区| 在线视频亚洲| 国产精品系列视频| 西西WWW888大胆无码| 欧美操逼图片| 学生妹一级J人片内射视频| 人人操人人爽| 欧洲无码一区二区三区| 久久成人网豆花视频| 牛牛影视av老牛影视av| 国产黄色免费网站| 白丝久久| jizz免费在线观看| 69精品无码成人久久久久久| 国内操逼视频| 玖玖中文字幕| 五月婷婷六月婷婷| 天天日天天干天天干| caoporen| 成年人黄色视频免费观看| 在线免费观看黄色视频网站| 丁香五月婷婷网| 蜜桃av| 国产婷婷五月| 91亚洲精选| 色婷婷一区二区| 秋霞一区二区三区无码| 亚洲美女网站免费观看网址| 91成人看片| 青娱乐超碰在线| 91re| 成人在线综合| 色婷婷亚洲综合| 丁月婷婷五香天日五月天| 精品秘一区性综合三区| 97爱爱爱| 欧美一级性爱| 五月婷婷狠狠爱| 欧美成年人视频| 在线国产小视频| 日本色色网站免费| 男人天堂视频在线| 亚洲AV成人无码精品直播在线| 久久机热| 国产又粗又大又爽| 大香蕉男人天堂| 足浴小少妇-88AX| 国产日韩a| 中文字幕在线视频第一页| 成人av无码| 亚州精品国产精品乱码不99勇敢| 日韩一区二区三区免费视频| 欧美日本在线观看| 国产高清av| 国产精品久久一区二区三区影音先锋| 国产男女啪啪视频| 日韩18禁| 国产亚洲精品久久久波多野结衣 | 一道AV| 国产亚洲精品久久久久动| 中文字幕不卡AV在线观看| 狠狠色五月| 中国老女人操逼视频| 操逼国产| 国产在线看片| aaa在线| 人妻少妇偷人精品无码免费| 18害羞勿进网站国产| 青春草在线观看视频| 日韩操逼一区| 91九色TS另类国产人妖| 高清av在线| 午夜影院操| 欧美一级爱| 亚洲AV第二区国产精品| 91新婚人妻偷拍| 91无码AⅤ在线| 亚洲第一伊人| 精品久久免费一区二区三区| 欧美不卡一区二区三区| 国产日韩欧美综合精品在线观看 | 9l视频自拍九色9l视频成人| 中日韩一级片| 亚洲天堂福利| 欧美激情无码一区二区三区张丽| 亚洲AAA| 日韩成人免费在线| 四川少妇BBBB槡BBBB槡| 好吊视频一区二区三区红桃视频you | 男人天堂成人| 亚洲无码激情视频| 国产91无码精品秘入口新欢| 黄片网址在线观看| 黄色视频免费播放| 欧美激情伊人久久五月天| 无码国产精品一区二区视频| 免费亲子乱婬一级A片| 91丨九色丨蝌蚪丨对白| 精品欧美乱码久久久久久| 免费爱爱视频| 日本黄色免费在线观看| 免费无码一区二区三区| 日韩操逼电影| 91人妻无码| 国产精品自产拍| aaa免费视频| 日韩综合色视频导航| 色播欧美| 依人成人| 亚洲色情在线播放| 免费中文字幕av| 在线小视频| 免费在线a视频| 成人毛片在线播放| 激情性爱五月天| 西西www444无码大胆| 操逼电影网站| 中文字幕激情精品| 久久99精品久久久久婷婷| 日韩久久久久| 日韩AV小电影| 黄片av| 欧美群交videotv群交| 久视频在线| 国产视频97| 成人网站av| 亚洲日韩一区二区三区四区| 午夜天堂精品久久| 五月少妇| JlZZJLZZ亚洲美女18| 国产A片录制现场妹子都很多| 久久久久99精品成人片三人毛片| 国产九色91回来了| 国产成人AV一区二区三区在线观看 | 日批免费视频| 日韩三级在线免费观看| 精品无码一区二区三区的天堂| www.99热| 艹逼在线观看| 在线观看无码| 熟妇熟女一区二区三区| 肏屄视频在线观看| 激情婷婷网| 99视频免费观看| 一区二区三级片| 国产美女高潮| 国产在线观看无码| 人妻无码免费视频| 伊人成人片| 日本黄色视频免费观看| 亚洲天堂一区在线观看| www.91自拍| 亚洲天堂视频网站| 国产做受91| 婷婷五月天电影网| 狠狠操av| 亚洲激色| 91在线精品秘一区二区黄瓜| 777大香蕉| 欧美午夜精品| 综合激情网站| 搞黄免费视频视频| 黑人巨粗进入疼哭A片| 国产熟女一区二区视频网站| 亚洲激情片| 新超碰在线观看| 最近中文字幕在线| 北条麻妃精品青青久久价格| 岛国免费AV| 人妻无码在线观看| 欧美97| 91密臀| 偷拍综合网| 国产A片大全| www.婷婷| 成人欧美精品| 肏少妇女情人大骚逼直播一区二区| 伊人国产视频| 国产女人操逼视频| 国产精品99久久久久久成人| 婷婷好色五月天| 久草热在线| 国产一级特黄大片| 国产黄片在线免费观看| 亚洲成人在线观看视频| 国内毛片毛片毛片毛片毛片毛片毛片毛片毛片毛片毛片毛片 | 欧美污网站| 黄色小说在线播放| 大香蕉69| 日韩欧美国产综合| 高清一区二区| 五月天丁香网| 91国产福利| 日本不卡视频在线| 日韩毛片在线免费观看| 久久午夜夜伦鲁鲁一区二区| 精品视频999| 免费在线观看黄片| 亚洲综合精品| 久久草草热国产精| 免费视频91蜜桃| 在线成人自拍| 一级欧美一级日韩| 蜜臀久久99精品久久久久酒店更新时间 | 成人黄片在线免费观看| 91香蕉在线观看| 免费电影日本黄色| 成人看片33x9.CC| 日韩三级AV| 麻豆精品一区二区三区| 久久久福利视频| 日本黄色A片免费看| 18禁黄网站| 日韩婬乱片A片AAA真人视频| 久久久综合网| 第一色影院| 日韩中文字幕在线人成网站| 五月丁香欧美性爱| 日本激情视频| yjizz国产| 国产在线激情| 无码在线观看免费视频| 亚洲成人无码片| 99久久婷婷国产综合精品电影 | 欧美午夜福利电影| 国产xxxx视频| 亚洲高清无码视频| 国产一区二区三区在线视频| 干B网| 黄色成人18| 99久久99久久精品免费看小说。 | 亚洲日韩精品在线观看| 亚韩在线| 日韩欧美在线视频观看| 久草免费在线观看视频| 性爱AV| 老司机免费视频| 粉嫩小泬粉嫩小泬在线| 国产性爱一级片| 日韩高清中文字幕| 日韩欧美成人片| 男女操逼免费观看| 欧美日韩精品一区二区| 老妇槡BBBB| 天美果冻麻豆国产一区| 日本精品无码a62v在线| 无码精品在线观看| 无码秘蜜桃一区二区| 国产在线视频导航| 亚洲中文字幕日韩精品| 亚洲无码精品视频| 美女91视频| 在线免费观看成人视频| AV在线观看黄| 色婷婷激情| 伊人黄色视频| 黄色网址av| AV三级片在线观看| 日本乱伦网站| 欧美爱爱免费看| 欧美丰满人妻免费视频人| 处破女初破全过免费看| www.啪| 国内久久| 91视频专区| 人人舔人人草| AV你懂得| 午夜看黄片| 91国内精品视频| 国产高清AV无码| 午夜天堂精品久久久久| 精品免费在线观看| 亚洲AV无码成人片在线| 女人A片一级黄色| 亚洲熟女av中文字幕| 免费黄色小视频在线观看| 天天爱夜夜操| 国产中文在线观看| 69自拍视频| 国产一级a毛一级a毛片视频黑人 | 国产午夜在线视频| 国产成人午夜高潮毛片| 亚洲欧美手机在线| 欧美丰满人妻免费视频人| 国产一级婬乱片AV片AAA毛片| 熟女伦乱| 熟女探花精选| 成人自拍视频在线观看| 视色视频在线观看18| 91日韩无码| 99在线免费视频| 伊人88| 91看片看婬黄大片女跟女| 小早川怜子精品一区二区| 17.3c一起起草| 日本伊人大香蕉| 91丨PORN丨国产| 久久久国产一区二区三区| 日韩无码影院| 91免费看片| 69国产精品视频免费观看| 性爱视频亚洲| 超碰乱伦| 99久久99九九九99九他书对| 欧美h在线观看| 大地资源第三页在线观看免费播放最新 | 久操精品| 男人天堂视频网| 欧美熟妇一区二区| 亚洲不卡在线| 亚洲在线| 久久久亚洲| 西西444WWW无码精品| 日逼视频网| 欧美一级黄片免费看| 欧美成人免费| 草逼小视频| 无码人妻一区二区三区免水牛视频| 久久国产高清视频| 朝鲜性感AV在线| 国产无码激情视频| 91麻豆精品无码人妻| 黄色a片在线观看| 久草福利| 思思99热| 国产9熟妇视频网站| 国产成人在线视频免费| 精品乱子伦一区二区三区下载| 亚洲四区| 免费黄色成人视频| www.黄色电影| 9久久精品| 国产人妻人伦精品1国产丝袜| 91探花秘在线播放| 免费V片| 欧美在线成人视频| 久久国产乱子伦精品免费午夜...| 久久天堂一区| 久久亚洲中文字幕乱码| 精品福利视频导航| 1024国产| 北京熟妇搡BBBB搡BBBB| 丰满熟妇高潮呻吟无码| 淫色网址| 欧美性交一区二区| 中文字幕无码在线视频| 日韩av毛片| 人人草在线观看| 国产精品久久久久久久久久久久久久久久 | 天天爽| aaa午夜| 欧美成年人视频| 天堂网中文字幕| 一本色道精品久久一区二区三区| 伊人毛片| 在线观看黄网| 最新中文字幕免费MV第一季歌词 | 去干网欧美| 淫荡人妻视频| 中文字幕精品视频在线观看| 中国a一片一级一片| 日本三级片免费| 日韩精品成人专区无码| 蜜臀色欲AV无码人妻| 最近2021中文字幕免费| 亚洲精品久久久久久久久久久| 99国产精品久久久久久久成人| 91精品国产91久久久久久吃药| 日韩一及| 韩日一级17c| 欧美色图网站| 日韩人妻精品无码制服| 午夜激情四射| 极品美鮑20p| 五月乱伦| 国产精品秘国产精品88| 蜜桃成人久久| 任你爽在线视频| 91超碰在线| 亚洲中文在线播放| 天天做天天爱天天爽| 99黄色| 亚洲无套内射| 久久中文字幕视频| 51妺嘿嘿午夜福利视频| av天堂一区| 蝌蚪窝免费在线视频| 俺来也俺去也www色| 99热免费| 国产97视频| 欧美综合国产| 一级A黄色片| 日本成人久久| 强伦轩人妻一区二区三区四区| www.人人摸| 国产乱伦内射视频| 一级黄色片免费观看| 大学生18一19GAY169| 三级网址大全| 日韩欧AV| 夜夜骚精品人妻av一区| 色妹子综合| 少妇特黄A一区二区三区| 91在线无码精品秘| 蜜桃av秘无码一区二区三欧| 蜜臀av在线观看| 丁香五月婷婷久久| 国产成人无码Av片在线公司 | 强行征服邻居人妻HD高清日本 | 男女啪啪国产| 极品少妇久久久| 日本免费版网站nba| 九九热99视频| 97性爱视频| 久久久久久久久久久亚洲| 欧美肏逼网| 国产精品久久久久久久免牛肉蒲| 欧美日逼超碰| 黄网站在线观看| 国产黄色视频在线| 婷婷国产亚洲精品网站| 天天色天天干天天日| 欧美群交在线| 欧美日韩在线一区| 亚洲综合视频在线| 91亚洲精品乱码久久久久久蜜桃 | 羞羞视频com.入口| 日韩精品一区二区在线观看| 香蕉视频一区| 潮喷在线观看| 久99久视频| 久久九九热| 五月天精品视频| 黄页视频网站| 无码中文一区| 亚洲成人在线观看视频| 国产传媒一区| 操小嫩逼视频| 日韩不卡一区二区三区| 亚洲色图五月天| 青娱乐国产av| 亚洲天堂一区在线观看| 9I成人免费版视频| 成人AV午夜福利| 激情国产精品| 秋霞午夜久久| 欧美精品成人网站| 91大鸡| 大香蕉色视频| 国精产品一区一区三区有限公司杨| 国内自拍欧美| 高清无码视频免费看| 国产18禁网站| 九九亚洲精品| 五月六月丁香| 亚洲免费视频一区| 最新免费一区二区三区| 亚洲日韩免费| 无码在线免费播放| 7799精品视频天天看| 伊人免费在线| 天天干在线观看| 操学生妹| 国产色情视频在线观看| 欧美国产日韩在线观看| 翔田千里無碼破解| 亚洲黄色视频免费看| 天天弄天天操| 欧美日韩在线视频播放| 激情av| 粉粉嫩嫩的18虎白女| 操逼大香蕉| 狠狠撸狠狠干| 超碰乱伦| 久久高清免费视频| 日韩成人精品| 综合导航无码| 狠狠AV| 思思热这里只有精品| 蜜桃传媒在线| 2024男人天堂| 国产一区二区三区四区在线观看| www在线播放| 少妇无码在线| 99精品无码视频| 久草在线播放| 日逼视频免费| 亚洲最大的成人网站| 白嫩外女BBWBBWBBW| 伊人东京热| 午夜无码电影| 丰满人妻一区二区三区| 日本欧美在线观看高清| 欧美日韩在线观看一区| 久久久精品久久| 99视频自拍| 久久久久久久久久久久高清毛片一级| 欧美国产精品一区二区三区| 强伦轩一区二区三区在线观看| 黄色a级片| 婷婷精品国产一区二区三区日韩| 一区二区三区电影| 人人操大香蕉| h片在线| 免费黄色AV| 国产特級黃色大片| 手机毛片在线播放| 国产精品视频久久久久| 日日爱av| 免费无码婬片AAAA片在线蜜芽| 青青草成人在线观看| 欧美性BBB槡BBB槡BBB| 精品人妻午夜一区二区三区四区 | 免费三级网站| 麻豆免费成人传媒| 青草福利视频| 北条麻妃电影九九九| 中文在线最新版天堂8| 一级aa视频| 校园春色亚洲色图| 中文在线无码| 久久久久久久无码| 97视频在线免费观看| 日韩人妻一区二区三区| 色老板在线观看| 男人av网站| 午夜AV福利影院| 日日夜夜综合| 人妻无码久久精品| 蜜桃精品视频在线观看| 中日韩在线视频| 911亚洲精品| 日韩一级黄色片| 四虎影库男人天堂| 精品国产一二三区| 精品成人AV| 大香蕉三级| 国产17c精品视频一二三区| 91在线无码精品秘入口动作 | 夜夜躁狠狠躁| 青青综合网| 欧美囗交大荫蒂免费| 无码看片| 国产性爱在线观看| 黄色成人视频在线观看| 色吧五月| 人人操91| 一插菊花综合视频| AV无码免费一区二区三区不卡| 蜜臀精品| 国产第一页在线观看| 五月天激情爱爱| 手机在线看片av| 国产超碰青青草| 四虎黄色影院| 亲子伦一区二区三区| 久久久九九九| 美日韩在线观看| 三级无码视频在线观看| 免费高清无码| 成人黄色AV| 翔田千里AV在线| 天天色视频| 国产一级性爱视频| 免费在线观看内射| 日本成人高清视频| 亚洲精品人伦一区二区| 日韩天天操| 看90后操B| 无码三级午夜久久人妻| a√免费看| 亚洲专区在线| 黄色www| 久久日韩操| 永久免费叼嘿| 秘亚洲国产精品成人网站| 中文字幕无码视频在线观看| 久久亚洲天堂| 怡春院综合成人社区| 高清毛片AAAAAAAAA郊外| 99国产精品久久久久久久成人 | 青春草在线观看| 天天操天天干麻豆| 欧美三级欧美三级三级| 69国产在线| a在线免费| 熟女一区| 日本性欧美| 亚洲av大全| 亚洲图片欧美另类| 色噜噜狠狠色综无码久久合欧美| 国产最新在线视频| 91亚洲国产成人精品一区二区三| 日韩人妻丝袜中文字幕| www.国产在线观看| 日韩中文字幕在线观看| 北条麻妃无码视频在线| 无码中文在线| 欧美黄色三级片| 黄色免费网站在线观看| 伊人综合色| 午夜免费网站| 无码AV中文字幕| av天天干| 欧美黄色a片| 欧美亚洲国产视频| 奇米狠狠操| 越南小嫩嫩BBWBBw| 污视频在线免费| 中文字幕无码观看| 嫩BBB揍BBB揍BBB| 午夜伊人| 免费啪啪视频| 亚洲视频五区| 69式荫蒂被添全过程频| h片在线免费观看| 日韩av小说| 婷婷俺也去| 日本无码专区| 欧美成人片免费看| 美女91小视频| 91成人无码视频| 波多野结衣无码视频在线观看| 丝袜东京热AV高清| 五月大香蕉| 一区二区三区精品视频| 另类AV| 国产精品AV一区| 超碰人人操人人摸| 91探花在线观看| 色94色.欧美.setu| 一区二区三区Av| 91ThePorn国产在线观看| a在线视频| 日韩无码一卡| 亚洲免费观看高清完整版在线观| 操逼视频在线播放| 国产精品久久久一区二区三区| 91射区| 成人做爰100部免费网站| 免费中文字幕日韩欧美| 色婷婷7777| 91探花秘在线播放偷拍| 色噜噜狠狠色综无码久久合欧美| 西西444WWW无码视频软件| www.日韩一区| 亚洲日韩中文无码| 婷婷开心色四房播播免费| 理论在线视频| 国产学生妹在线播放| 蕉久中文字慕| 国产91在线看| 你懂的网址在线观看| 激情婷婷| 日韩在线99| 可以在线观看的av| 欧美视频一区二区三区| 成年片免费观看网站免费观看,亚洲+欧... | 在线播放国产精品| 91日逼视频| 中字一区人妻水多多| 北条麻妃91人妻互换| 91含羞草www·Com| AV你懂得| 亚洲免费成人电影| 蜜桃av在线播放| 91大神在线资源观看无广告| 天天搞天天干| 欧美性爱一区二区三区| WWW.豆花视频精品| 日韩五码在线| 国产理论| JIZZJIZZ国产精品喷水| 91精品国产乱码香蕉黄瓜草莓| 亚洲狠狠操| 怡红院成人AV| 毛片操逼视频| 亚洲女人被黑人巨大的原因| 成人网站一区二区| 熟女嗷嗷叫高潮合集91| 91香蕉| 阿v视频在线观看| 东京热国产| 午夜亚洲福利视频| 7799精品视频天天看| 久久99久久99久久99国内少妇精品 | 黑人vs亚洲人在线播放| 成人做爰黄A片免费| 中文在线字幕电视剧免费平台| 亚洲国产A片| 中文在线免费看视频| 日韩高清无码一区| 2024无码| 久久久久久久91| 亚洲无码一级电影| 亚洲观看黄色网| 免费观看av| 日韩AV免费在线播放| 日本久久综合| 日韩成人无码| 在线播放国产精品| 黄色AA片| 久久久久久无码精品亚洲日韩麻豆 | 亚洲欧美第一页| 亚洲色图15P| 大吊操|