版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、<p> Web程序設(shè)計說明書</p><p> 姓名 LL </p><p> 專業(yè) 計算機科學(xué)與技術(shù) </p><p> 考號 0901051319 </p><p><b> 1 需求分析</b></p>
2、<p><b> 1.1 功能需求</b></p><p> 本系統(tǒng)實現(xiàn)如下功能:</p><p><b> 用戶管理</b></p><p> 用戶分為管理員和普通用戶</p><p> 普通用戶擁有創(chuàng)建并管理書架、上傳并管理圖書,評論、收藏、舉報圖書等功能。</p&
3、gt;<p> 管理員除了擁有普通用戶的所有功能外,還可以管理系統(tǒng)圖書分類、舉報信息和用戶信息。</p><p> 管理員登錄后,可以在管理中心中封鎖、解鎖用戶。</p><p><b> 分類管理</b></p><p> 添加分類:管理員可以添加小說分類,分類不可以重名。</p><p> 修
4、改分類:管理員可以修改分類的名字,分類不可以重名。</p><p> 刪除分類:管理員可以刪除分類,當(dāng)分類下有小說存在時,無法成功刪除分類。</p><p><b> 書架管理</b></p><p> 添加書架:用戶登錄后可以添加書架,書架的名字可以重名。</p><p> 修改書架:用戶登錄后可以修改自己創(chuàng)建
5、的書架,書架名字可以重名。</p><p> 刪除書架:用戶登錄后可以刪除自己創(chuàng)建的書架,當(dāng)書架下有小說存在時,無法成功刪除書架。</p><p> 訂閱書架:用戶登錄后可以訂閱網(wǎng)站上的任意一個書架。</p><p><b> 小說管理</b></p><p> 上傳小說:用戶登錄后可以上傳TXT格式的小說,小說
6、不得大于5M,并且需要有固定格式的章節(jié)信息,比如“第X卷 第X章 XXXX”。小說上傳成功后會自動生成小說章節(jié)索引,方便用戶按章節(jié)閱讀小說。如果上傳小說時用戶沒有指定小說摘要,則會自動以小說前六章的章節(jié)標(biāo)題組成摘要。</p><p> 修改小說:用戶登錄后可以修改自己上傳的小說信息,更改小說的所屬分類和書架等信息。</p><p> 刪除小說:用戶登錄后可以刪除自己上傳的小說,小說刪除
7、時,會連帶刪除小說的評論等信息。</p><p> 收藏小說:用戶登錄后可以收藏網(wǎng)站上的任意一部小說。</p><p> 舉報小說:用戶可以舉報自己認(rèn)為有不良信息或者不合法信息的小說,管理員會及時處理舉報信息。</p><p> 評論小說:用戶登錄后可以對網(wǎng)站上的任意一部小說發(fā)表評論。</p><p><b> 統(tǒng)計信息&l
8、t;/b></p><p> 統(tǒng)計小說閱讀量:網(wǎng)站會對小說的閱讀次數(shù)進行統(tǒng)計,以作為熱門小說的排名依據(jù)。</p><p> 統(tǒng)計小說評論量:網(wǎng)站會對小說的評論次數(shù)進行統(tǒng)計,以作為熱門小說的排名依據(jù)。</p><p> 統(tǒng)計小說收藏量:網(wǎng)站會對小說的收藏次數(shù)進行統(tǒng)計,以作為熱門小說的排名依據(jù)。</p><p> 統(tǒng)計書架小說數(shù):網(wǎng)
9、站會對各個書架中小說的數(shù)量進行統(tǒng)計。</p><p> 統(tǒng)計分類小說數(shù):網(wǎng)站會對各個分類中小說的數(shù)量進行統(tǒng)計。</p><p> 1.2 數(shù)據(jù)庫需求分析</p><p> 不管對數(shù)據(jù)庫設(shè)計還是對系統(tǒng)設(shè)計來說,需求分析都是第一步。需求的目的就是搞清楚用戶要做什么,如果需求做的仔細,可以在后面的設(shè)計和實現(xiàn)中少做很多無用功,其重要性是不言自明的。做需求分析需要有點心
10、理學(xué)的知識,要能充分的跟客戶進行交流,能抓住問題的關(guān)鍵所在,最終能夠快速的搞清楚系統(tǒng)所要實現(xiàn)的業(yè)務(wù)。</p><p> 需求分析的方法在軟件工程中都有說明,不管哪種方法,最重要的都是與用戶的溝通和交流,引導(dǎo)用戶正確的確認(rèn)問題。用戶需求具體體現(xiàn)在各種信息的提供、保存、更新和查詢,這就要求數(shù)據(jù)庫結(jié)構(gòu)能充分滿足各種信息的輸出和輸入。</p><p> 根據(jù)用戶的需求設(shè)計數(shù)據(jù)庫如下:</
11、p><p> 用戶:編號,郵箱,昵稱,密碼,頭像,角色,注冊日期,狀態(tài),書架數(shù),小說數(shù)。</p><p> 分類:編號,名稱,小說數(shù)。</p><p> 小說:編號,書名,作者,大小,細節(jié),狀態(tài),分類編號,書架編號,文件路徑,上傳日期,上傳用戶,閱讀量,評論量,收藏量。</p><p> 書架:編號,名稱,創(chuàng)建者,創(chuàng)建日期,小說數(shù)。<
12、;/p><p><b> 3 數(shù)據(jù)庫設(shè)計</b></p><p> 3.1 數(shù)據(jù)庫概念結(jié)構(gòu)設(shè)計</p><p> 在需求分析的基礎(chǔ)上,設(shè)計出能夠滿足用戶需求的各種實體以及它們之間的關(guān)系,現(xiàn)將各實體及實體之間的E-R圖描述如下:</p><p><b> ?。?)分類實體:</b></p>
13、;<p> 圖3.2 分類實體圖</p><p><b> ?。?)用戶實體:</b></p><p> 圖3.3 用戶實體圖</p><p><b> ?。?)書架實體:</b></p><p> 圖3.4 書架實體圖</p><p><b>
14、 ?。?)小說實體:</b></p><p><b> 、</b></p><p> 圖3.5 小說實體圖</p><p><b> ?。?)總體ER圖:</b></p><p> 圖3-6 ER圖總圖</p><p> 3.2 數(shù)據(jù)庫邏輯結(jié)構(gòu)設(shè)計<
15、;/p><p> 現(xiàn)在把數(shù)據(jù)庫概念設(shè)計的E-R圖轉(zhuǎn)化為關(guān)系數(shù)據(jù)。在關(guān)系數(shù)據(jù)庫中,數(shù)據(jù)關(guān)系由數(shù)據(jù)表組成的,而表的結(jié)構(gòu)體現(xiàn)在表的字段上。具體為:確定數(shù)據(jù)庫中數(shù)據(jù)表的組成;確定數(shù)據(jù)表中字段的構(gòu)成,主鍵字段和有關(guān)字段的約束條件;依據(jù)表中主鍵字段建立數(shù)據(jù)表之間的關(guān)系。數(shù)據(jù)的合理性問題:數(shù)據(jù)表內(nèi)記錄不重復(fù);數(shù)據(jù)字段不可分割,具有最小數(shù)據(jù)單位的特點;數(shù)據(jù)表內(nèi)字段或字段之間互不依賴。具體結(jié)構(gòu)如下圖所示:</p>&l
16、t;p><b> 1. 用戶表</b></p><p><b> 表3-1 用戶表</b></p><p><b> 2. 分類表</b></p><p> 表3-2 小說分類表</p><p><b> 3. 小說表</b><
17、/p><p><b> 表3-3 小說表</b></p><p><b> 4.書架表</b></p><p><b> 表3-4 書架表</b></p><p><b> 5.書架訂閱表</b></p><p> 表3-5
18、 書架訂閱表</p><p><b> 6.小說評論表</b></p><p> 表3-6 小說評論表</p><p><b> 7.小說收藏表</b></p><p> 表3-7 小說收藏表</p><p><b> 8.小說舉報表</b>&
19、lt;/p><p> 表3-8 小說舉報表</p><p><b> 9小說閱讀表</b></p><p><b> 表3-9閱讀表</b></p><p> 4 界面描述和代碼實現(xiàn)</p><p><b> 4.1 用戶管理</b></p&
20、gt;<p> 用戶管理模塊主要包括用戶注冊、登錄及信息修改。</p><p> 用戶注冊:用戶填寫注冊信息并通過校驗后可以成功注冊成為會員,其中郵箱作為登錄名,不能重復(fù)。</p><p> 圖4-1 用戶注冊頁面</p><p> 以Ajax的方式進行注冊校驗,成功后方才跳轉(zhuǎn)頁面,如果出錯,則在不刷新的情況下在當(dāng)前頁面提示錯誤信息。</
21、p><p> public String signup() throws Exception {</p><p> result = new HashMap<String, Object>();</p><p> Map<String, Object> errors = new HashMap<String, Object>()
22、;</p><p> // Validate email address</p><p> if (!ValidatorUtil.validEmail(user.getEmail())) {</p><p> errors.put("user.email", "郵箱格式不正確");</p><p>
23、; // If the email has been taken</p><p> } else if (userDao.findByEmail(user.getEmail()) != null) {</p><p> errors.put("user.email", "郵箱已經(jīng)被占用");</p><p><b&
24、gt; }</b></p><p> // Validate username</p><p> if (!ValidatorUtil.validUsername(user.getName())) {</p><p> errors.put("user.name", "用戶名格式不正確");</p&g
25、t;<p> // Validate password</p><p> if (!ValidatorUtil.validPassword(user.getPass()))</p><p> errors.put("user.pass", "密碼格式不正確");</p><p><b> }&l
26、t;/b></p><p> logger.info(String.format("signing up user[name=%s, email=%s]", </p><p> user.getName(), user.getEmail()));</p><p> // Add the user</p><p>
27、; if (!errors.isEmpty()) {</p><p> result.put("approved", false);</p><p> result.put("message", "注冊失敗,請檢查注冊信息是否填寫正確");</p><p> result.put("err
28、ors", errors);</p><p> } else if (!userDao.insert(user)) {</p><p> result.put("approved", false);</p><p> result.put("message", "注冊失敗,服務(wù)器正忙,請稍后再試&qu
29、ot;);</p><p><b> } else {</b></p><p> result.put("approved", true);</p><p> result.put("message", "注冊成功,正在中轉(zhuǎn)頁面");</p><p>&l
30、t;b> }</b></p><p> return SUCCESS;</p><p><b> }</b></p><p> 用戶登錄:用戶填寫登錄信息后點擊登錄,進行Ajax校驗,成功后跳轉(zhuǎn)到個人頁面。</p><p> 圖4-2 用戶登錄頁面</p><p>
31、用戶登錄的前臺相關(guān)代碼:</p><p><b> /**</b></p><p> * Script to implement user related works, such as signin, signup, validation and..</p><p><b> *</b></p><
32、;p> * @author GreatGhoul</p><p> * @version 1.0 2010-04-25 22:35</p><p> * @require</p><p> * : jquery.1.3.2.min.js</p><p> * : status-1.0.3.js</p>&
33、lt;p><b> */</b></p><p> $(function() {</p><p> var signupForm = $('#signup-form');</p><p> var signinForm = $('#signin-form');</p><p>
34、; function signup() {</p><p><b> $.ajax({ </b></p><p> url: 'dosignup.do', </p><p> data: signupForm.serialize(), </p><p> type: 'POST'
35、, </p><p> dataType: 'json',</p><p> error: function() {</p><p> signupForm.lock(false, '注冊失敗,請檢查您的網(wǎng)絡(luò)連接');</p><p><b> },</b></p>
36、<p> success: function(data) {</p><p> signupForm.lock(false, data.result.message);</p><p> if (data.result.approved) {</p><p> setTimeout(function() {</p><p>
37、 window.location = 'signin.do';</p><p><b> }, 3000);</b></p><p><b> } else {</b></p><p> signupForm.errs(data.result.errors);</p><p>
38、;<b> }</b></p><p><b> }</b></p><p><b> });</b></p><p> signupForm.lock(true, '正在提交注冊信息...');</p><p> return false;</
39、p><p><b> }</b></p><p> function signin() {</p><p><b> $.ajax({ </b></p><p> url: 'dosignin.do', </p><p> data: signinFor
40、m.serialize(), </p><p> type: 'POST', </p><p> dataType: 'json',</p><p> error: function() {</p><p> signinForm.lock(false, '登錄失敗,請檢查您的網(wǎng)絡(luò)連接'
41、);</p><p><b> },</b></p><p> success: function(data) {</p><p> signinForm.lock(false, data.result.message);</p><p> if (data.result.approved) {</p>
42、;<p> setTimeout(function() {</p><p> window.location = 'home.do';</p><p><b> }, 1000);</b></p><p><b> }</b></p><p><b>
43、 }</b></p><p><b> });</b></p><p> signinForm.lock(true, '正在提交注冊信息...');</p><p> return false;</p><p><b> }</b></p><
44、;p> signupForm.submit(signup);</p><p> signinForm.submit(signin);</p><p><b> });</b></p><p> 用戶信息修改:提供原始密碼后,用戶可以修改昵稱或者使用新的密碼。</p><p> 圖4.3 用戶信息修改頁面&
45、lt;/p><p><b> 4.2 分類管理</b></p><p> 管理員有權(quán)利對系統(tǒng)的小說分類管理,小說的分類名不能重復(fù)。管理員可以添加分類、修改分類、刪除分類,要刪除含有小說的分類,需要先轉(zhuǎn)移分類中的小說,否則不能成功刪除分類。</p><p> 圖4-4 分類管理頁面</p><p> 以下這段代碼用于更
46、新分類,用于返回更新信息的JSON格式的結(jié)構(gòu)是固定的,在書架,小說管理中都遵循這一格式,統(tǒng)一了操作接口。</p><p> public String update() {</p><p> logger.info(String.format("updating cate[id=%d] ==> cate[name=%s]",</p><p&
47、gt; cate.getId(), cate.getName()));</p><p> result = new HashMap<String, Object>();</p><p> List<String> errors = new ArrayList<String>();</p><p> result.put(&
48、quot;approved", false);</p><p> result.put("message", "更新分類失敗");</p><p> if (cate == null || cate.getId() == null) {</p><p> errors.add("分類不存在"
49、);</p><p> } else if (!ValidatorUtil.validCateName(cate.getName())) {</p><p> errors.add("分類名的長度應(yīng)該在1到20個字體之間,不能含有空格");</p><p><b> } else {</b></p>&l
50、t;p> Cate cate1 = cateDao.findById(cate.getId());</p><p> if (cate1 == null) {</p><p> errors.add("要修改的分類不存在");</p><p> } else if (cate1.getName().equals(cate.getNa
51、me())) {</p><p> errors.add("分類名已經(jīng)存在");</p><p> } else if (!cateDao.update(cate)) {</p><p> errors.add("服務(wù)器正忙,請稍候再試");</p><p><b> } else {
52、</b></p><p> result.put("approved", true);</p><p> result.put("message", "更新分類成功");</p><p><b> }</b></p><p><b>
53、 }</b></p><p> result.put("errors", errors);</p><p> return SUCCESS;</p><p><b> }</b></p><p><b> 4.3 書架管理</b></p>&l
54、t;p> 用戶登錄后可以創(chuàng)建書架,并可以編輯或刪除自己創(chuàng)建的書架。在“我的書架”頁面會羅列當(dāng)前用戶的所有書架,如圖:</p><p> 圖4-5 書架列表頁面</p><p> (1) 添加書架:點擊書架列表中的“添加書架”,可以打開添加書架窗口,填寫書架名稱后點擊確認(rèn)按鈕即可添加一個書架。</p><p><b> 圖4-6 添加書架<
55、;/b></p><p> (2) 修改書架:點擊要修改的書架名后面的“修改”即可打開書架修改窗口,填寫新的名稱后點擊確認(rèn)按鈕,即可修改書架的名稱。</p><p><b> 圖4-7 修改書架</b></p><p> (3) 刪除書架:點擊要刪除的書架后面的“刪除”會提示是否確認(rèn)刪除,如果點擊“是”,且書架中書架數(shù)為0,則可以成
56、功刪除書架,否則不會刪除書架。</p><p> 刪除書架的代碼如下:</p><p> public String delete() {</p><p> User user = (User) getSessionMap().get("curUser");</p><p> if (user == null) r
57、eturn "signin";</p><p> if (bookDao.findByShelf(shelf).size() > 0) {</p><p> addActionMessage("要刪除書架,請先清空書架中的小說");</p><p> return ERROR;</p><p&g
58、t; } else if (!shelfDao.delete(shelf)) {</p><p> addActionMessage("刪除書架失敗,服務(wù)器正忙,請稍候再試。");</p><p> return ERROR;</p><p><b> } else {</b></p><p>
59、; return SUCCESS;</p><p><b> }</b></p><p><b> }</b></p><p><b> 4.4小說管理</b></p><p> 用戶可以上傳小說,并對自己上傳的小說進行管理。在首頁、個人頁面、書架展示等頁面會羅列出用
60、戶上傳的小說,點擊即可查看詳情。</p><p> 網(wǎng)站的首頁會羅列出所有小說分類,熱門的書架、小說等,點擊鏈接即可查看相關(guān)條目。</p><p><b> 圖4-8 網(wǎng)站首頁</b></p><p> 個人頁面會羅列出用戶最近上傳的小說和創(chuàng)建的所有書架。</p><p><b> 圖4-9 用戶首頁&
61、lt;/b></p><p> (1) 上傳小說:點擊頂端導(dǎo)航中的“上傳小說”,在打開的頁面中填寫相關(guān)信息,并選定要上傳的文件(文件要求txt格式,小于5M,而且章節(jié)目錄比較標(biāo)準(zhǔn) )。其中小說簡介可以選填,如果用戶不填寫,則自動以前6章的章節(jié)標(biāo)題拼接成簡介。</p><p> 圖4-10 小說上傳頁面</p><p> 上傳小說的相關(guān)代碼:</p&
62、gt;<p> public String execute() throws IOException {</p><p> User user = (User) getSessionMap().get("curUser");</p><p> if (user == null) {</p><p> return "
63、;signin";</p><p><b> }</b></p><p> if (book.getAuthor() == null || book.getAuthor().trim().isEmpty()){</p><p> book.setAuthor("未知");</p><p
64、><b> }</b></p><p> if (book.getDesc() != null && book.getAuthor().length() > 200) {</p><p> book.setDesc(book.getDesc().substring(0, 199));</p><p><b
65、> }</b></p><p> if (upload == null || !upload.exists()) {</p><p> addActionMessage("只能上傳txt類型的文件,且文件不能超過5M。");</p><p> return ERROR;</p><p><b
66、> } else {</b></p><p> if (book.getName() == null || book.getName().trim().isEmpty()) {</p><p> addActionMessage("請?zhí)顚懶≌f名稱");</p><p><b> }</b></
67、p><p> if (book.getShelf() == null) {</p><p> addActionMessage("請為小說指定一個書架");</p><p><b> }</b></p><p> if (getActionMessages().isEmpty()) {</p
68、><p> String toPath = "/uploads/" + System.currentTimeMillis() + "-" + uploadFileName;</p><p> File toFile = new File(ServletActionContext.getServletContext()</p><p
69、> .getRealPath(toPath));</p><p> FileUtils.copyFile(upload, toFile);</p><p> book.setUploadFile(toPath);</p><p> book.setSize(toFile.length());</p><p><b>
70、 try {</b></p><p> BookParser.parseDetail(toFile, book);</p><p> } catch (IOException e) {</p><p> addActionMessage("未能生成索引");</p><p> book.setDetai
71、l("[]");</p><p><b> }</b></p><p> book.setUploadUser(user);</p><p> if (bookDao.insert(book)) {</p><p> cateDao.countBooks(book.getCate());<
72、;/p><p> shelfDao.countBooks(book.getShelf());</p><p> return SUCCESS;</p><p><b> } else {</b></p><p> addActionMessage("服務(wù)器錯誤,上傳文件失敗");</p>
73、;<p> return ERROR;</p><p><b> }</b></p><p><b> } else {</b></p><p> return ERROR;</p><p><b> }</b></p><p>
74、<b> }</b></p><p><b> }</b></p><p> Struts2配置:</p><p> <action name="doBookUpload" class="bookUploadAction"></p><p>
75、; <interceptor-ref name="fileUpload"></p><p> <param name="maximumSize">5242880</param></p><p> <param name="allowedTypes">text/plain<
76、/param></p><p> </interceptor-ref></p><p> <interceptor-ref name="basicStack" /></p><p> <result name="signin" type="redirect">
77、signin.do</result></p><p> <result name="success">/WEB-INF/views/book-upload-success.jsp</result></p><p> <result name="error">/WEB-INF/views/error.
78、jsp</result></p><p><b> </action></b></p><p> 生成索引的相關(guān)代碼:</p><p> public static void parseDetail(File file, Book book) throws IOException {</p><
79、p> JSONArray detail = new JSONArray();</p><p> StringBuilder desc = new StringBuilder();</p><p> InputStreamReader istream = new InputStreamReader(new FileInputStream(file), "GBK"
80、;);</p><p> BufferedReader stream = new BufferedReader(istream);</p><p> //RandomAccessFile stream = new RandomAccessFile(file, "r");</p><p> int headLineNumber = 1,
81、tailLineNumber = 1; // 初始行號為1</p><p> int lineNumber = 0;</p><p> String chapterTitle = "前言";</p><p> String line = null;</p><p> int chapterCount = 0;<
82、;/p><p> while ((line = stream.readLine()) != null) {</p><p> lineNumber++;</p><p> if (line.matches(CHAPTER_RE)) {</p><p> if (chapterCount <= 6) {</p><
83、p> desc.append(line);</p><p> desc.append("\r\n");</p><p><b> }</b></p><p> chapterCount++;</p><p> tailLineNumber = lineNumber - 1;</p
84、><p> JSONObject chapter = new JSONObject();</p><p> chapter.put("title", chapterTitle);</p><p> chapter.put("head", headLineNumber);</p><p> chapt
85、er.put("tail", tailLineNumber);</p><p> detail.add(chapter);</p><p> chapterTitle = line;</p><p> headLineNumber = tailLineNumber;</p><p><b> }</
86、b></p><p><b> }</b></p><p> tailLineNumber = lineNumber;</p><p> JSONObject chapter = new JSONObject();</p><p> chapter.put("title", chapte
87、rTitle);</p><p> chapter.put("head", headLineNumber);</p><p> chapter.put("tail", tailLineNumber);</p><p> detail.add(chapter);</p><p> stream.c
88、lose();</p><p> istream.close();</p><p> book.setDetail(detail.toString());</p><p> if (book.getDesc() != null && book.getDesc().trim().isEmpty()) {</p><p>
89、 book.setDesc(desc.toString());</p><p><b> }</b></p><p><b> }</b></p><p> (2) 修改小說信息:點擊書架展示頁面中小說名稱后面的“修改”,即可跳轉(zhuǎn)到小說信息修改頁面,可以重新填寫小說的名稱,作者,簡介,分類及書架信息。</p&g
90、t;<p> 圖4-11 小說修改頁面</p><p> (3) 小說查看:點擊小說名稱的鏈接可以打開小說查看頁面,在該頁面上可以看到小說的基本信息和評論列表,在評論框中輸入評論后點擊提交可以發(fā)表評論。</p><p> 圖4-12小說查看頁面</p><p> (3) 小說閱讀:點擊小說查看頁面的“閱讀小說”鏈接可以打開小說閱讀器,如果是第一
91、次閱讀該小說,則會從第一章開始閱讀,如果以前已經(jīng)閱讀過該小說,則會自動載入上次閱讀的章節(jié)。</p><p> 圖4-13說閱讀頁面</p><p> 后臺獲取章節(jié)內(nèi)容的相關(guān)代碼:</p><p> public static String getChapterDetail(File file, ReadDetail detail) throws IOExcep
92、tion {</p><p> InputStreamReader istream = new InputStreamReader(new FileInputStream(file), "GBK");</p><p> BufferedReader stream = new BufferedReader(istream);</p><p>
93、 int lineNumber = 0;</p><p> StringBuilder sb = new StringBuilder();</p><p> String line = null;</p><p> while ((line = stream.readLine()) != null) {</p><p> lineNu
94、mber++;</p><p> if (lineNumber >= detail.getHead() && lineNumber <= detail.getTail()) {</p><p> sb.append("<p>" + line + "</p>");</p><p
95、><b> }</b></p><p><b> }</b></p><p> stream.close();</p><p> istream.close();</p><p> return sb.toString();</p><p><b>
96、 }</b></p><p> 前臺載入閱讀頁面的相關(guān)代碼:</p><p> <script type="text/javascript"></p><p> function escapeXML(xml) {</p><p> var text = xml;</p>&l
97、t;p> text = text.replace(/</g, '<');</p><p> text = text.replace(/>/g, '>');</p><p> text = text.replace(/&/g, '&');</p><
98、p> text = text.replace(/\t/g, ' ');</p><p> text = text.replace(/\s/g, ' ');</p><p> return text;</p><p><b&
99、gt; }</b></p><p> function readChapter(chapter) {</p><p> Status.show('正在加載章節(jié) ' + chapter.title);</p><p><b> $.ajax({</b></p><p> url:
100、39;bookChapter.do',</p><p><b> data: {</b></p><p> 'book.id': ${book.id},</p><p> 'detail.title': chapter.title,</p><p> 'detail
101、.head': chapter.head,</p><p> 'detail.tail': chapter.tail</p><p><b> },</b></p><p> type: 'POST',</p><p> dataType: 'json',&
102、lt;/p><p> error: function() {</p><p> Status.show('讀取章節(jié)失敗,請檢查您的網(wǎng)絡(luò)連接');</p><p><b> },</b></p><p> success: function(data) {</p><p> S
103、tatus.show(data.result.message);</p><p> if (data.result.approved) {</p><p> $('#main-head').html(chapter.title);</p><p> $('#main-body').html(data.chapterContent
104、);</p><p><b> }</b></p><p><b> }</b></p><p><b> });</b></p><p><b> }</b></p><p> function showChpater(
105、node, head, tail) {</p><p> readChapter({</p><p> title: node.innerHTML,</p><p> head: head,</p><p> tail: tail</p><p><b> });</b></p&g
106、t;<p><b> }</b></p><p> $(function() {</p><p> // 在目錄中添加一個章節(jié)</p><p> function appendChapter(chapter) {</p><p> var chapterNode = document.create
107、Element('LI');</p><p> chapterNode.innerHTML = '<a href="#" '</p><p> + 'onclick="showChpater(this, ' + head + ', ' + tail + ')">&
108、#39; </p><p> + escapeXML(trim(chapter)) + '</a>';</p><p> menu.appendChild(chapterNode);</p><p><b> }</b></p><p> var chapterList = $(
109、9;#chapter-list');</p><p> var chapters = eval('(' + '${book.detail}' + ')');</p><p> var curChapter = eval('(' + '${read.detail==null?"null":
110、read.detail}' + ')')</p><p> // building chapters.</p><p> Status.show("正在生成章節(jié)列表...");</p><p> for (var i = 0; i < chapters.length; i++) {</p><
111、;p> var chapter = chapters[i];</p><p> chapterList.append($('<li><a href="javascript:;" onclick="showChpater(this, ' + chapter.head + ', ' + chapter.tail + ')
112、;">'</p><p> + escapeXML($.trim(chapter.title)) + '</a></li>'));</p><p><b> }</b></p><p> Status.hide();</p><p> if (!c
113、urChapter || !curChapter.title) {</p><p> curChapter = chapters[0];</p><p><b> }</b></p><p> readChapter(curChapter);</p><p> $('.font-ctrl').cl
114、ick(function() {</p><p> var mainBody = $('#main-body');</p><p> var fontSize = parseInt(mainBody.css('font-size'));</p><p> var action = $(this).html();</p>
115、;<p> switch (action) {</p><p> case 'A+':</p><p> fontSize++;</p><p><b> break;</b></p><p> case 'A-':</p><p> fo
116、ntSize--;</p><p><b> break;</b></p><p><b> case 'A':</b></p><p> fontSize = 16;</p><p><b> break;</b></p><p&g
117、t;<b> default:</b></p><p><b> }</b></p><p> if (fontSize < 12) fontSize = 12;</p><p> if (fontSize > 20) fontSize = 20;</p><p> mainB
118、ody.css('font-size', '' + fontSize + 'px');</p><p><b> });</b></p><p><b> });</b></p><p><b> </script></b></p
119、><p> (4) 刪除小說:點擊小說列表中小說后面的“刪除”會彈出小說刪除確認(rèn)框,如果點擊是則會刪除該小說,刪除小說會連帶刪除小說的評論、閱讀記錄等信息。</p><p> 刪除小說的相關(guān)代碼:</p><p> User user = (User) getSessionMap().get("curUser");</p><
120、;p> if (user == null) return "signin";</p><p> Book book1 = bookDao.findById(book.getId());</p><p> if (book1 == null) {</p><p> addActionMessage("該小說可能已經(jīng)刪除了。&
121、quot;);</p><p><b> } else {</b></p><p> Cate cate = book1.getCate();</p><p> Shelf shelf = book1.getShelf();</p><p> if (!bookDao.delete(book)) {</p&
122、gt;<p> addActionMessage("刪除小說錯誤,服務(wù)器正忙,請稍后再試");</p><p><b> } else {</b></p><p> cateDao.countBooks(cate);</p><p> shelfDao.countBooks(shelf);</p&
123、gt;<p> return SUCCESS;</p><p><b> }</b></p><p><b> }</b></p><p> return ERROR;</p><p><b> }</b></p><p> 4
124、.5統(tǒng)一的錯誤頁面</p><p> 站使用統(tǒng)一的錯誤頁面展示出錯信息,給用戶更好的使用體驗。</p><p> 圖4-13說閱讀頁面</p><p><b> 5 體 會</b></p><p> 通過本次畢業(yè)設(shè)計,我對MVC結(jié)構(gòu)有了更深入的理解,對軟件工程方法有更客觀的認(rèn)識,對Struts2、Spring、
125、Hibernate有了更進一步的掌握??偨Y(jié)起來有以下幾點:</p><p> 需求分析很重要。設(shè)計之初做了全面的需求分析,對應(yīng)用的功能進行了完整的分析,但是因為沒有考慮時間問題,導(dǎo)致許多需要都沒有實現(xiàn),需求是個無底洞,以后做設(shè)計時,我一定綜合開發(fā)成本確認(rèn)需求方案。</p><p> 功能考慮不夠全面。在做軟件功能設(shè)計時,因為缺乏開發(fā)經(jīng)驗,許多細節(jié)都沒有關(guān)注到,比如用戶注冊的確認(rèn)問題,看
126、著雖然是個不怎么上進心眼的功能,但一旦出錯,直接關(guān)系一個用戶的去留,我沒有在這方面下功夫,是不正確的。</p><p> 單元測試:因為時間緊迫,我并沒有對各位模塊進行完整的單元測試,雖然真初有進行過一些嘗試,但最后還是放棄了,這必然對系統(tǒng)埋下了隱患。使得我面對一些恑異的錯誤時,變得手足無措,浪費了一些不必要的時間?;仡櫰饋?,還是因為開發(fā)計劃混亂所至,如果起初就制定嚴(yán)格的開發(fā)計劃,并貫徹實施,就不會在這方面栽跟
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 課程設(shè)計說明書
- 課程設(shè)計說明書
- 前門課程設(shè)計說明書
- javaweb課程設(shè)計說明書
- 后蓋課程設(shè)計說明書
- 鍋爐課程設(shè)計說明書
- 空調(diào)課程設(shè)計說明書
- 蝸輪課程設(shè)計說明書
- 采礦課程設(shè)計說明書
- 機床課程設(shè)計說明書
- caxa課程設(shè)計說明書
- 化工課程設(shè)計說明書
- vb課程設(shè)計說明書
- 課程設(shè)計說明書.doc
- 課程設(shè)計說明書.doc
- 課程設(shè)計說明書.doc
- 課程設(shè)計說明書.doc
- 課程設(shè)計說明書.doc
- 課程設(shè)計說明書.doc
- 課程設(shè)計說明書.doc
評論
0/150
提交評論