技术标签: js umijs react React.js andt pro
在config/proxy.ts中
/**
* 在生产环境 代理是无法生效的,所以这里没有生产环境的配置
* The agent cannot take effect in the production environment
* so there is no configuration of the production environment
* For details, please see
* https://pro.ant.design/docs/deploy
*/
export default {
dev: {
'/api': {
target: 'http://*****.cn:9036',
changeOrigin: true,
pathRewrite: {
'^/api': '' },
},
},
};
/** Request 网络请求工具 更详细的 api 文档: https://github.com/umijs/umi-request */
import {
message } from 'antd';
import {
extend } from 'umi-request';
import {
errorHandler, requestOpt, reLogin } from './requestopt';
import {
setToken, getToken } from '@/utils/auth'
/** 配置request请求时的默认参数 */
const request = extend({
errorHandler, // 默认错误处理
credentials: 'include', // 默认请求是否带上cookie
});
// request拦截器, 改变url 或 options.
request.interceptors.request.use((url, options) => {
return requestOpt(url, options)
});
// response拦截器, 处理response
request.interceptors.response.use(async response => {
const data = await response.clone().json();
const token = await response.headers.get('token')
if (token && token != getToken()) {
setToken(token)
}
if (process.env.NODE_ENV === 'development') {
console.log(data)
}
if (data.code !== 200) {
message.error(data.message);
if (data.code === 300) {
reLogin()
}
return data.message
} else {
return response;
}
})
export default request
import {
message } from 'antd';
import {
RequestOptionsInit } from 'umi-request';
import {
getToken } from '@/utils/auth'
import {
getPageQuery } from '@/utils/utils';
import {
history } from 'umi';
import {
stringify } from 'querystring';
import {
removeToken } from '@/utils/auth'
const codeMessage: {
[status: string]: string } = {
200: '服务器成功返回请求的数据。',
201: '新建或修改数据成功。',
202: '一个请求已经进入后台排队(异步任务)。',
204: '删除数据成功。',
400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
401: '用户没有权限(令牌、用户名、密码错误)。',
403: '用户得到授权,但是访问是被禁止的。',
404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
406: '请求的格式不可得。',
410: '请求的资源被永久删除,且不会再得到的。',
422: '当创建一个对象时,发生一个验证错误。',
500: '服务器发生错误,请检查服务器。',
502: '网关错误。',
503: '服务不可用,服务器暂时过载或维护。',
504: '网关超时。',
};
/** 异常处理程序 */
export const errorHandler = (error: {
response: Response }): Response => {
const {
response } = error;
console.log(response)
if (response && response.status) {
const errorText = codeMessage[response.status] || response.statusText;
message.error(errorText);
} else if (!response) {
message.error('您的网络发生异常,无法连接服务器');
}
return response;
};
/**
* request拦截器, 改变url 或 options.
* @returns
*/
export const requestOpt = (url: string, options: RequestOptionsInit): object => {
if (process.env.NODE_ENV === 'development'){
console.log("url==>", url)
if (options.data) {
console.log("options.data==>", JSON.stringify(options.data))
} else if (options.params && Object.keys(options.params).length > 0) {
console.log("options.params==>", options.params)
}
}
if (process.env.NODE_ENV === 'development' && !options.prefix) {
url = '/api' + url
}
const headers = {
'token': getToken(),
};
return {
url: url,
options: {
...options, headers },
};
}
export const reLogin = () => {
const {
redirect } = getPageQuery();
// Note: There may be security issues, please note
if (window.location.pathname !== '/user/login' && !redirect) {
removeToken()
history.replace({
pathname: '/user/login',
search: stringify({
redirect: window.location.href,
}),
});
}
}
import request from '@/utils/request';
import type {
ListParamsType } from '@/services/data'
import type {
AccountInfoType } from './data'
/**
* 列表数据
* @param params
* @returns
*/
export async function getUserList(params: ListParamsType): Promise<any> {
return request('/Admin/UserList', {
method: 'POST',
data: {
...params },
requestType: 'form'
});
}
/**
* 獲取账户信息
* @param params
* @returns
*/
export async function getUserInfo(params: {
id: string }): Promise<any> {
return request('/Admin/UserAdd', {
method: 'GET',
params: {
...params },
requestType: 'form'
});
}
/**
* 用户添加
* @param params
* @returns
*/
export async function userAdd(params: AccountInfoType): Promise<any> {
return request('/Admin/UserAdd', {
method: 'POST',
data: {
...params },
requestType: 'form'
});
}
/**
* 冻结
* @param params
* @returns
*/
export async function userFrozen(params: {
id: string }): Promise<any> {
return request('/Admin/UserFroze', {
method: 'POST',
data: {
...params },
requestType: 'form'
});
}
/**
* 封装后台返回的数据
*/
export type SingleUserListType = {
id: number,
level?: number,
account?: string,
password?: string,
contact_name?: string,
contact_mobile?: string,
remark?: string,
role_id?: number,
is_enable?: number,
ctime?: string,
uptime?: string,
role_name?: string,
ctime_str: string,
}
/**
* 添加编辑账户
*/
export type UserAddType = {
user_id?: number,
account?: string,
account_password?: string,
contact_name?: string,
contact_mobile?: number,
role_id?: number,
};
/**
* 獲取账户信息
*/
export type AccountInfoType = {
user_id?: number,
account?: string,
password?: string,
contact_name?: string,
contact_mobile?: number,
role_id?: number,
id?: number
};
/**
* 獲取账户信息列表
*/
export type AccountRoleListType = {
ctime?: number,
ctime_str?: string,
id?: number,
is_enable?: number,
menu_ids?: string,
role_name?: string,
uptime?: number,
value?:number,
label?:string,
disabled?:boolean
};
import {
Effect, Reducer } from 'umi';
//导入service远端数据请求
import {
getUserList, getUserInfo, userAdd, userFrozen } from './service'
import {
SingleUserListType, AccountInfoType, AccountRoleListType } from './data'
import {
message } from 'antd';
export type AccountListState = {
rows: SingleUserListType[];
total: number;
info: AccountInfoType;
role_list: AccountRoleListType[]
}
interface AccountListModelType {
namespace: string
state: AccountListState;//封装后台返回的数据
effects: {
getRemoteUserList: Effect;
getRemoteUserInfoData: Effect;
postRemoteUserAdd: Effect;
postRemoteUserFrozen: Effect;
};
reducers: {
getUserList: Reducer<AccountListState>,
getUserInfoData: Reducer<AccountListState>,
};
}
const AccountListModel: AccountListModelType = {
namespace: 'accountListData',
state: {
rows: [],
total: 0,
info: {
},
role_list: []
},
effects: {
*getRemoteUserList({
payload }, {
call, put }) {
//从service中获取数据(service主要用于接口请求)
const response = yield call(getUserList, {
...payload })
if (response && response instanceof Object) {
yield put({
type: 'getUserList',//这个是将数据给reducers中哪个方法
payload: response.data //注意这里传递一个数组会出问题,原因待定
})
}
},
//獲取账户信息
*getRemoteUserInfoData({
payload }, {
call, put }) {
const response = yield call(getUserInfo, {
...payload })
if (response && response instanceof Object) {
let {
role_list } = response.data
role_list.forEach((element: AccountRoleListType) => {
element.value = element.id,
element.label = element.role_name,
element.disabled = element.is_enable == 0
})
response.data.role_list = role_list
response.data.info = {
...response.data.info, role_id: (response.data.info.role_id == 0 ? '' : response.data.info.role_id) }
yield put({
type: 'getUserInfoData',
payload: response.data
})
}
},
//用户添加
*postRemoteUserAdd({
payload }, {
call, put }) {
const response = yield call(userAdd, {
...payload })
if (response && response instanceof Object) {
message.success(response.message)
}
},
//冻结
*postRemoteUserFrozen({
payload }, {
call, put }) {
const response = yield call(userFrozen, {
...payload })
if (response && response instanceof Object) {
message.success(response.message)
}
}
},
//同步
reducers: {
getUserList(state, action) {
return {
...state,
...action.payload,
};
},
getUserInfoData(state, action) {
return {
...state,
...action.payload,
};
}
},
}
export default AccountListModel;
import React, {
useRef, FC } from 'react';
import type {
ProColumns, ActionType } from '@ant-design/pro-table';
import {
PageContainer, WaterMark } from '@ant-design/pro-layout';
import {
Card, Space } from 'antd';
import {
connect, Dispatch, AccountListState } from 'umi';
import type {
ListParamsType } from '@/services/data'
import {
SingleUserListType, UserAddType } from './data'
import ProTable from '@ant-design/pro-table'
import './index.less'
import AddAccountModal from './components/addaccountmodal'
/**
* 声明下方 props 类型
*/
type accountListPageProps = {
listData: AccountListState,
dispatch: Dispatch
}
const AccountListPage: FC<accountListPageProps> = (props) => {
//获取从model中来的数据
const {
listData, dispatch } = props
//配置ProTable
const ref = useRef<ActionType>();
/**
* ProTable的网络请求 request
*/
const requestHandler = async (params: ListParamsType) => {
await dispatch({
type: 'accountListData/getRemoteUserList',
payload: params = {
...params }
})
return {
}
}
//提交数据
const onCreateFinish = async (values: UserAddType) => {
await dispatch({
type: 'accountListData/postRemoteUserAdd',
payload: {
...values }
})
ref.current?.reload();
return true
}
/**
* 启用或停用
* @param id
*/
const onAccountTypeClick = async (id: number) => {
await dispatch({
type: 'accountListData/postRemoteUserFrozen',
payload: {
id: id }
})
ref.current?.reload();
}
const columns: ProColumns<SingleUserListType>[] = [
{
title: 'ID',
dataIndex: 'id',
width: 128,
search: false,
align: 'left'
},
{
title: '账号名称',
dataIndex: 'account',
align: 'left',
},
{
title: '状态',
dataIndex: 'is_enable',
search: false,
align: 'left',
render: (text) => <span>{
text == 1 ? `启用` : `停用`}</span>,
},
{
title: '联系人姓名',
dataIndex: 'contact_name',
hideInTable: true,
},
{
title: '创建时间',
dataIndex: 'ctime_str',
search: false,
align: 'left'
},
{
title: '操作',
align: 'center',
render: (text, record) => (
<Space size="middle">
<AddAccountModal
userId={
record.id}
itemInfo={
listData.info}
roleList={
listData.role_list}
dispatch={
dispatch}
showType={
1}
onCreateFinish={
onCreateFinish} />
{
record.is_enable == 0 ? <a className="start-using" onClick={
() => onAccountTypeClick(record.id)}>启用</a> :
<a className="stop-using" onClick={
() => onAccountTypeClick(record.id)}>停用</a>
}
</Space>
),
},
];
return (
<PageContainer title="账号列表">
<Card>
<WaterMark content="地环院内部管理系统">
<ProTable
actionRef={
ref}
request={
requestHandler}
columns={
columns}
dataSource={
listData.rows}
rowKey="id"
search={
{
labelWidth: 'auto',
}}
pagination={
{
showQuickJumper: true,
pageSize: 10,
total: listData.total
}}
form={
{
span: 6
}}
toolBarRender={
() => [
<AddAccountModal
userId={
0}
itemInfo={
listData.info}
roleList={
listData.role_list}
dispatch={
dispatch}
showType={
0}
onCreateFinish={
onCreateFinish} />
]}
/>
</WaterMark>
</Card>
</PageContainer>
)
}
const mapStateToProps = ({
accountListData }: {
accountListData: AccountListState }) => {
return {
listData: accountListData,//这里的usersData就是model中的namespace
}
}
export default connect(mapStateToProps)(AccountListPage)
import React, {
useEffect, FC } from 'react'
import {
Button, Form } from 'antd';
import {
ModalForm,
ProFormText,
ProFormSelect,
} from '@ant-design/pro-form';
import {
PlusOutlined } from '@ant-design/icons';
import type {
UserAddType } from '../data'
import {
Dispatch } from 'umi';
type AddAccountModalProps = {
showType: number
onCreateFinish: (values: UserAddType) => void
dispatch: Dispatch
userId: number
itemInfo: any
roleList: any
}
const AddAccountModal: FC<AddAccountModalProps> = (props) => {
const {
showType, onCreateFinish, dispatch, userId, itemInfo, roleList } = props
useEffect(() => {
form.setFieldsValue({
...itemInfo,
})
}, [itemInfo])
const [form] = Form.useForm();
const layout = {
labelCol: {
span: 5 },
};
//ModalForm状态改变
const onVisibleChange = async (value: boolean) => {
if (value) {
await dispatch({
type: 'accountListData/getRemoteUserInfoData',
payload: {
id: userId }
})
}
}
return (
<ModalForm<{
account: string;
account_password: string;
contact_name: string;
contact_mobile: number;
role_id: number;
user_id: number
}>
width="35%"
{
...layout}
form={
form}
title={
showType === 0 ? `添加账户` : `编辑账户`}
trigger={
showType === 0 ? (
<Button type="primary">
<PlusOutlined />
添加账户
</Button>
) : (
<a>编辑</a>
)
}
onFinish={
async (values) => {
return onCreateFinish(values = {
...values, user_id: userId });
}}
onVisibleChange={
onVisibleChange}
>
<ProFormText name="account"
label="账户名称:"
placeholder="请填写账户名称"
disabled={
showType !== 0}
rules={
[{
required: true, message: '您还没填写账户名称' }]}
/>
<ProFormText name="account_password"
label="账户密码:"
placeholder={
userId == 0 ? `请填写账户密码` : `修改则填写新密码,不修改则不填`}
rules={
[{
required: true, validator: (rule, value = '', callback) => {
if (Object.keys(value).length == 0) {
if (userId) {
return Promise.resolve()
} else {
return Promise.reject('您还没填写账户密码');
}
} else if (!new RegExp(/^(?!^(\d+|[a-zA-Z]+|[~!@#$%^&*?]+)$)^[\w~!@#$%^&*?]{
6,20}$/).test(value)) {
return Promise.reject('必须含有数字、字母、特殊符号三项中间的两项,6到20位')
} else {
return Promise.resolve()
}
}
}]}
/>
<ProFormText name="contact_name"
label="姓名:"
placeholder="请填写姓名"
rules={
[{
required: true, message: '您还没填写姓名' }]}
/>
<ProFormText name="contact_mobile"
label="手机号:"
placeholder="请填写手机号"
rules={
[{
required: true, message: '您还没填写手机号' },
{
pattern: /^((13[0-9])|(14[5,7])|(15[0-3,5-9])|166|(17[0,3,5-8])|(18[0-9])|19[1,8,9]|(147))([0-9]{
8})+$/,
message: '手机号格式不正确',
},]}
/>
<ProFormSelect
options={
roleList}
width="md"
name="role_id"
label="绑定角色:"
placeholder="请选择绑定角色"
rules={
[{
required: true, message: '您还没选择绑定角色' }]}
/>
</ModalForm>
);
};
export default AddAccountModal;
文章浏览阅读331次。第一部分:准备工作1 安装虚拟机2 安装centos73 安装JDK以上三步是准备工作,至此已经完成一台已安装JDK的主机第二部分:准备3台虚拟机以下所有工作最好都在root权限下操作1 克隆上面已经有一台虚拟机了,现在对master进行克隆,克隆出另外2台子机;1.1 进行克隆21.2 下一步1.3 下一步1.4 下一步1.5 根据子机需要,命名和安装路径1.6 ..._创建一个hadoop项目
文章浏览阅读1.7k次。心脏滴血漏洞HeartBleed CVE-2014-0160 是由heartbeat功能引入的,本文从深入码层面的分析该漏洞产生的原因_heartbleed代码分析
文章浏览阅读1.4k次。前言ofd是国家文档标准,其对标的文档格式是pdf。ofd文档是容器格式文件,ofd其实就是压缩包。将ofd文件后缀改为.zip,解压后可看到文件包含的内容。ofd文件分析工具下载:点我下载。ofd文件解压后,可以看到如下内容: 对于xml文件,可以用文本工具查看。但是对于印章文件(Seal.esl)、签名文件(SignedValue.dat)就无法查看其内容了。本人开发一款ofd内容查看器,..._signedvalue.dat
文章浏览阅读1.8w次,点赞29次,收藏313次。整体系统设计本设计主要是对ADC和DAC的使用,主要实现功能流程为:首先通过串口向FPGA发送控制信号,控制DAC芯片tlv5618进行DA装换,转换的数据存在ROM中,转换开始时读取ROM中数据进行读取转换。其次用按键控制adc128s052进行模数转换100次,模数转换数据存储到FIFO中,再从FIFO中读取数据通过串口输出显示在pc上。其整体系统框图如下:图1:FPGA数据采集系统框图从图中可以看出,该系统主要包括9个模块:串口接收模块、按键消抖模块、按键控制模块、ROM模块、D.._基于fpga的信息采集
文章浏览阅读2.5w次。1.背景错误信息:-- [http-nio-9904-exec-5] o.s.c.n.z.filters.post.SendErrorFilter : Error during filteringcom.netflix.zuul.exception.ZuulException: Forwarding error at org.springframework.cloud..._com.netflix.zuul.exception.zuulexception
文章浏览阅读358次。1.介绍图的相关概念 图是由顶点的有穷非空集和一个描述顶点之间关系-边(或者弧)的集合组成。通常,图中的数据元素被称为顶点,顶点间的关系用边表示,图通常用字母G表示,图的顶点通常用字母V表示,所以图可以定义为: G=(V,E)其中,V(G)是图中顶点的有穷非空集合,E(G)是V(G)中顶点的边的有穷集合1.1 无向图:图中任意两个顶点构成的边是没有方向的1.2 有向图:图中..._给定一个邻接矩阵未必能够造出一个图
文章浏览阅读321次。(十二)、WDS服务器安装通过前面的测试我们会发现,每次安装的时候需要加域光盘映像,这是一个比较麻烦的事情,试想一个上万个的公司,你天天带着一个光盘与光驱去给别人装系统,这将是一个多么痛苦的事情啊,有什么方法可以解决这个问题了?答案是肯定的,下面我们就来简单说一下。WDS服务器,它是Windows自带的一个免费的基于系统本身角色的一个功能,它主要提供一种简单、安全的通过网络快速、远程将Window..._doc server2012上通过wds+mdt无人值守部署win11系统.doc
文章浏览阅读219次。python–xlrd/xlwt/xlutilsxlrd只能读取,不能改,支持 xlsx和xls 格式xlwt只能改,不能读xlwt只能保存为.xls格式xlutils能将xlrd.Book转为xlwt.Workbook,从而得以在现有xls的基础上修改数据,并创建一个新的xls,实现修改xlrd打开文件import xlrdexcel=xlrd.open_workbook('E:/test.xlsx') 返回值为xlrd.book.Book对象,不能修改获取sheett_xlutils模块可以读xlsx吗
文章浏览阅读8.2w次,点赞267次,收藏656次。运行Selenium出现'WebDriver' object has no attribute 'find_element_by_id'或AttributeError: 'WebDriver' object has no attribute 'find_element_by_xpath'等定位元素代码错误,是因为selenium更新到了新的版本,以前的一些语法经过改动。..............._unresolved attribute reference 'find_element_by_id' for class 'webdriver
文章浏览阅读198次。一:模态窗口//父页面JSwindow.showModalDialog(ifrmehref, window, 'dialogWidth:550px;dialogHeight:150px;help:no;resizable:no;status:no');//子页面获取父页面DOM对象//window.showModalDialog的DOM对象var v=parentWin..._jquery获取父window下的dom对象
文章浏览阅读1.7w次,点赞15次,收藏129次。算法(algorithm)是解决一系列问题的清晰指令,也就是,能对一定规范的输入,在有限的时间内获得所要求的输出。 简单来说,算法就是解决一个问题的具体方法和步骤。算法是程序的灵 魂。二、算法的特征1.可行性 算法中执行的任何计算步骤都可以分解为基本可执行的操作步,即每个计算步都可以在有限时间里完成(也称之为有效性) 算法的每一步都要有确切的意义,不能有二义性。例如“增加x的值”,并没有说增加多少,计算机就无法执行明确的运算。 _算法
文章浏览阅读1.5k次,点赞18次,收藏26次。网络安全的标准和规范是网络安全领域的重要组成部分。它们为网络安全提供了技术依据,规定了网络安全的技术要求和操作方式,帮助我们构建安全的网络环境。下面,我们将详细介绍一些主要的网络安全标准和规范,以及它们在实际操作中的应用。_网络安全标准规范