簡體   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