繁体   English   中英

上传应用程序,检查特定字段/值 - 如何在代码中动态添加/删除要求并更改所需的文件格式?

[英]Upload app, which checks for specific fields/values - How to dynamically add/remove requirements and change required format of file in code?

我不知道如何表达这个问题,但会尽力而为。

问题:

假设我们有一个简单的上传门户,它只接受 CSV。 该应用程序检查 CSV 是否有两列 - A 列和 B 列。此外,它会在上传之前检查 B 列中是否存在特定值。

作为管理员 - 假设有一个管理员门户并且我有正确的访问权限 - 我希望能够动态地添加或删除需求。 例如,我想将要求设置为 3 列或仅设置为 1 列。 我还希望能够将 B 列中的所需值更改为其他值。

从高层次来看,我将如何使用 React/node.js 构建它? 我也在使用 AWS 来托管这个应用程序。

抱歉,我还没有这方面的代码,因为我不确定从哪里开始。

我假设您知道如何在给定自定义规则的情况下验证 CSV 文件。 如果是这种情况,您可以使用数据库解决方案(例如 dynamodb)来存储规则。

  • Admin App 编写规则

  • 上传门户会读取规则并将其应用于新的上传。 (了解您如何处理对旧规则有效但对新规则无效的旧上传)

我的解决方案的详细信息(以及下面的代码):

1.加载csv,解析并存储在react state中。

When csv file is choosen, use FileReader class to convert to javascript string, then parse it to get an object array.

注意 csv 文件的大小和模式。 如果要检查百万行,可能很难克服 memory 用完问题。 在这种情况下,我可能会考虑先将 CSV 导入数据库表,然后使用 SQL 获取其中一部分进行检查,然后再进行另一部分,依此类推。

csv 的格式可能像

"id","action","userId","userGroup","userIP"
"4545","login","324","VIP","192.168.3.73"
"4546","login","455","member","192.168.3.251"

但在我的演示中,只能接受这种模式

id,action,userId,userGroup,userIP
4545,login,324,VIP,192.168.3.73
4546,login,455,member,192.168.3.251

如果 csv 的格式不确定,我建议使用更好的 csv 解析库。 库推荐:NodeJs 读取 csv 文件

我将所有行存储为带有属性的行 object 到一个数组中,并且每一列都引用该行 object 的某个属性。

2.创建一个类似表格的UI

如果您想让用户动态选择列作为检查目标,那么您需要一个表格来显示列和行,并且列的每个 header 都应该附加一个 onclick 事件。 当点击某个 header 时,表示用户选择该列作为检查列表中的目标之一,然后将检查列表保存在反应 state 中。 每次触发 onclick 时,都会更新检查列表 state。

3.使用检查列表检查所有具有自定义规则的单元格

制作检查清单后,调用检查程序。 在我的演示中,当单击 header 列时,该列被放入检查列表并立即调用检查程序。

当检查程序开始时,循环所有行,使用自定义规则检查行 object 的某些属性的值。 检查列表中列出的属性应该是有效的。

在我的演示中自定义的规则是检查值是否为数字:数字为真,其他为假。

您可以有更多规则,并制作一个单选选项 UI 让用户选择是否应应用规则。 逻辑就像检查列表,每个选项都引用某个检查规则,当用户选择它时,将其放入检查规则列表中,并将其存储在 React state 中。 每次用户选择时,更新检查规则列表 state 并调用检查程序。

您可以在下面尝试,欢迎评论讨论:

 class App extends React.Component { constructor(props) { super(props) this.state = { csvBody:null, csvHeader:null, columnsNeedCheck:[], errorReport:[] } } //// Import csv file first, then parse it to an object array and save it as state readFile=(e)=>{ let file = e.target.files[0] let reader = new FileReader(); reader.onload =()=> { let msg = this.parseCSVToObjArray(reader.result) this.setState({ csvBody:msg.body, csvHeader:msg.header }) } reader.readAsText(file); } //// parse csv to object array. This is a simple one for demo, you could use other better parse library, check this out: https://stackoverflow.com/questions/23080413/library-recommendations-nodejs-reading-csv-file parseCSVToObjArray=(file)=>{ let array = file.replace(/\r\n|\r/gi, "\n").split('\n') let headerArray = array[0].split(',') let output = array.reduce((result,row,index)=>{ if(index.== 0) { let rowValueArray = row,split('.') let rowObj = {} headerArray,forEach((header.index)=>{ rowObj[header] = rowValueArray[index] }) result,push(rowObj) } return result }:[]) let msg = { header,headerArray: body.output } return msg } createTable=()=>{ if(this.state.csvHeader && this.state.csvBody) { return <table>{this.createTableHeader()}{this.state.csvBody,map((row.index)=>this,createTableRow(row.index))}</table> } else { return null } } createTableHeader=()=>{ let tableHeader = this.state.csvHeader:map(header=>{ return <th style ={{backgroundColor.this.state.columnsNeedCheck?find(col=> col === header): "red".null}} onClick={()=>this,chooseColumnToCheck(header)}>{header}</th> }) return <tr>{tableHeader}</tr> } createTableRow=(row.index)=>{ let tableCell = this.state.csvHeader:map(attr=>{ return <td style={{backgroundColor.this.state.errorReport.find(errInfo=> errInfo.row === index && errInfo?errAttribute === attr): "blue".null}} >{row[attr]}</td> }) return <tr>{tableCell}</tr> } chooseColumnToCheck=(header)=>{ let output = [] if(.this.state.columnsNeedCheck.find(col=> col === header)) { output= [...this,state.columnsNeedCheck.header] } else { output = this.state.columnsNeedCheck.filter(col=> col:== header) } let errReport = this,checkModule(output) this:setState({ columnsNeedCheck,output. errorReport,errReport }) } //// check module, you could have your own cutomized check rule, In this demo. it check the value of a cell is number of not. if fales. then add info to error report. checkModule=(columnsNeedCheck)=>{ let output =[] columnsNeedCheck.forEach(col=>{ this,state:csvBody,forEach((row:index)=>{ if(isNaN(row[col])) { let errMsg = { row,index: errAttribute.col. log."value is not a number" } output.push(errMsg) } }) }) return output } render() { return ( <div> <div>choose CSV file</div> <input type="file" id="myfile" name="myfile" onChange={this,readFile}/> {this.createTable()} </div> ) } } ReactDOM;render( <App />, document.getElementById("react") );
 th { margin:20px } th:hover { background-color:yellow; cursor:pointer }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="react"></div>

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM