[保险人管理]是这个APP最重要的功能,用于保存保险客户的数据,给后面的功能提供数据支撑。
简单说说[保险人管理]功能:主要就是增、删、改、查四个功能,在新增和修改的时候不仅可以保存保险人的姓名、身份证等基本信息,还可以保存保险人购买的保险信息(保险名称、保险公司、保险期限等)。(上传图片文件功能还没实现,这个正在想办法)
- 数据库设计
所有数据库初始化语句还是在DBHelper的onUpgrade中完成。
主表是insurer_info(保险人基本信息)、从表insurances(保险人保单信息,与主表保持多对一的关系)。
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { ...... if(oldVersion < 4 && newVersion >= 4){ StringBuilder insurer_info = new StringBuilder(); insurer_info.append("CREATE TABLE IF NOT EXISTS \"insurer_info\" ("); insurer_info.append("\"id\" INTEGER NOT NULL,"); insurer_info.append("\"name\" varchar(99),"); insurer_info.append("\"sex\" INTEGER,"); insurer_info.append("\"birthday\" varchar(32),"); insurer_info.append("\"id_number\" varchart(99),"); insurer_info.append("\"mobile_phone\" varchar(32),"); insurer_info.append("\"email\" varchar(99),"); insurer_info.append("\"fax\" varchar(99),"); insurer_info.append("\"address\" varchart(999),"); insurer_info.append("\"marital_status\" INTEGER,"); insurer_info.append("\"education\" INTEGER,"); insurer_info.append("\"delete_flag\" INTEGER,"); insurer_info.append("\"update_time\" varchart(99),"); insurer_info.append("PRIMARY KEY (\"id\")"); insurer_info.append(");"); db.execSQL(insurer_info.toString()); StringBuilder image_info = new StringBuilder(); image_info.append("CREATE TABLE IF NOT EXISTS \"image_info\" ("); image_info.append("\"id\" INTEGER NOT NULL,"); image_info.append("\"table_name\" varchart(99),"); image_info.append("\"table_id\" INTEGER,"); image_info.append("\"image_type\" INTEGER,"); image_info.append("\"image_value\" varchart(3000),"); image_info.append("\"image_index\" INTEGER,"); image_info.append("PRIMARY KEY (\"id\")"); image_info.append(");"); db.execSQL(image_info.toString()); StringBuilder insurances = new StringBuilder(); insurances.append("CREATE TABLE IF NOT EXISTS \"insurances\" ("); insurances.append("\"id\" INTEGER NOT NULL,"); insurances.append("\"insurer_info_id\" INTEGER NOT NULL,"); insurances.append("\"insurance_name\" varchart(99),"); insurances.append("\"insurance_company\" varchart(99),"); insurances.append("\"insurance_date\" varchart(99),"); insurances.append("\"year_period\" INTEGER,"); insurances.append("\"year_cost\" varchart(99),"); insurances.append("\"insurance_comment\" varchart(3000),"); insurances.append("\"delete_flag\" INTEGER,"); insurances.append("\"update_time\" varchart(99),"); insurances.append("\"remind_time\" varchart(99),"); insurances.append("PRIMARY KEY (\"id\")"); insurances.append(");"); db.execSQL(insurances.toString()); } if(oldVersion < 5 && newVersion >= 5){ db.execSQL("ALTER TABLE insurer_info ADD qq_number varchart(99)"); } if(oldVersion < 6 && newVersion >= 6){ StringBuilder insurance_company = new StringBuilder(); insurance_company.append("CREATE TABLE IF NOT EXISTS \"insurance_company\" ("); insurance_company.append("\"id\" INTEGER NOT NULL,"); insurance_company.append("\"name\" varchart(99),"); insurance_company.append("\"delete_flag\" INTEGER,"); insurance_company.append("\"index_sort\" INTEGER,"); insurance_company.append("\"comment\" varchart(3000),"); insurance_company.append("PRIMARY KEY (\"id\")"); insurance_company.append(");"); db.execSQL(insurance_company.toString()); } if(oldVersion < 7 && newVersion >= 7){ String initSQL = "INSERT INTO insurance_company(id,name,delete_flag,index_sort,comment) VALUES('1','未知','"+Enums.DeleteEnum.AVAILABLE.getKey()+"','1','初始化设置');"; String updateSQL = "UPDATE insurances SET insurance_company='1'"; db.execSQL(initSQL); db.execSQL(updateSQL); } if(oldVersion < 8 && newVersion >= 8){ db.execSQL("ALTER TABLE insurances ADD end_date varchart(99)"); db.execSQL("ALTER TABLE insurances ADD remind_type INTEGER"); db.execSQL("ALTER TABLE insurer_info ADD remind_time varchart(99)"); } ...... }
中间有很多版本变化,因为是在开发过程中不断完善的。
下面是用到的表对应的JavaBean。
public class InsurerInfo extends BasePO { private static final long serialVersionUID = 6953325446546926866L; private Long id; private String name; private Integer sex; private String birthday; private String id_number; private String mobile_phone; private String qq_number; private String email; private String fax; private String address; private Integer marital_status; private Integer education; private Integer delete_flag; private String update_time; private String remind_time; ...... }
public class Insurances extends BasePO { private static final long serialVersionUID = 3329436852215192933L; private Long id; private Long insurer_info_id; //外键关联保险人基础信息表 private String insurance_name; //保险名称 private String insurance_company; //保险单位 private String insurance_date; //投保日期 private String end_date; //结束日期 private String year_period; //年期 private String year_cost; //年保费 private String insurance_comment; //备注说明 private Integer delete_flag; //删除标识 private String update_time; //更新时间 private int remind_type; //是否提醒 private String remind_time; //上次提醒时间 ...... }
- 开发过程
------>新增/修改页面
这个页面效果图如下。
默认加载[基本信息]页签,可以录入保险人的个人基本资料
[投保信息]页签记录保险人购买的保险,结构是上半部分为已购买保险列表,下半部分为已购保险新增和修改。
点击保险列表某一项即可自动回填在下方表单内,支持删除修改操作。
(PS:投保信息页面我承认设计很失败,应该用dialog来录入保险信息的,主要原因是最初我不知道怎么动态调用dialog,- -||)
下面是整个页面的HTML代码,[基本信息]和[投保信息]的代码都在同一个页面,通过javascript动态隐藏、显示对应模块。
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"> <title> </title> </head> <body> <div data-role="page" id="insurer_edit_page"> <div data-theme="b" data-role="header" data-position="fixed"> <a data-role="button" data-rel="back" href="#" class="ui-btn-left" data-icon="back"> 返回 </a> <h3> 保险人信息 </h3> <a data-role="button" data-theme="b" href="#" id="a_save" data-icon="check" data-iconpos="left" class="ui-btn-right"> 保存 </a> </div> <div data-role="navbar" data-iconpos="top"> <ul> <li> <a href="#" data-transition="slide" id="a_basic_info" class="ui-btn-active"> 基本信息 </a> </li> <li> <a href="#" data-transition="slide" id="a_insure_info"> 投保信息 </a> </li> </ul> </div> <div data-role="content"> <div style="color:red" id="msg"></div> <input type="hidden" id="id" name="id" > <div id="div_basic_info"> <div class="ui-field-contain" data-controltype="textinput"> <label for="name"> 姓名 </label> <input name="name" id="name" value="" type="text"> </div> <div id="sex" class="ui-field-contain" data-controltype="radiobuttons"> <fieldset data-role="controlgroup" data-type="horizontal"> <legend> 性别 </legend> <input id="mail" name="sex" value="1" type="radio" checked="checked"> <label for="mail"> 男 </label> <input id="femail" name="sex" value="2" type="radio"> <label for="femail"> 女 </label> </fieldset> </div> <div class="ui-field-contain" data-controltype="dateinput"> <label for="birthday"> 生日 </label> <input name="birthday" id="birthday" placeholder="出生日期..." value="" type="date"> </div> <div class="ui-field-contain" data-controltype="textinput"> <label for="id_number"> 身份证号 </label> <input name="id_number" id="id_number" placeholder="身份证号码..." value="" type="text"> </div> <div class="ui-field-contain" data-controltype="textinput"> <label for="mobile_phone"> 移动电话 </label> <input name="mobile_phone" id="mobile_phone" placeholder="手机号码..." value="" type="tel"> </div> <div class="ui-field-contain" data-controltype="textinput"> <label for="email"> 电子邮箱 </label> <input name="email" id="email" placeholder="E-Mail地址..." value="" type="email"> </div> <div class="ui-field-contain" data-controltype="textinput"> <label for="qq_number"> QQ </label> <input name="qq_number" id="qq_number" placeholder="QQ号码..." value="" type="text"> </div> <div class="ui-field-contain" data-controltype="textinput"> <label for="fax"> 传真 </label> <input name="fax" id="fax" placeholder="传真号码..." value="" type="text"> </div> <div class="ui-field-contain" data-controltype="textarea"> <label for="address"> 联系地址 </label> <textarea name="address" id="address" placeholder="你的直接联系地址..."></textarea> </div> <div id="marital_status" class="ui-field-contain" data-controltype="radiobuttons"> <fieldset data-role="controlgroup" data-type="horizontal"> <legend> 婚姻状况 </legend> <input id="unmarried" name="marital_status" value="1" type="radio" checked="checked"> <label for="unmarried"> 未婚 </label> <input id="married" name="marital_status" value="2" type="radio"> <label for="married"> 已婚 </label> <input id="divorce" name="marital_status" value="3" type="radio"> <label for="divorce"> 离婚 </label> </fieldset> </div> <div class="ui-field-contain" data-controltype="selectmenu"> <label for="education"> 学历 </label> <select id="education" name="education"> <option value="2"> 高中及以下 </option> <option value="3"> 专科 </option> <option value="4"> 本科 </option> <option value="5"> 硕士 </option> <option value="6"> 博士 </option> </select> </div> <div class="ui-field-contain" data-controltype="fileinput"> <label for="images"> 图片 </label> <input type="file" name="images" id="images"> </div> </div> <div id="div_insure_info"> <div data-role="collapsible" id="collapsible" data-collapsed="false"> <h3 class="h3">已保存保单列表</h3> <ul data-role='listview' id="collapsible_listview"> </ul> </div> <hr> <h4>新增或修改保单信息</h4> <div style="color:red" id="insurance_error"></div> <input type="hidden" name="insurance_id"> <div class="ui-field-contain" data-controltype="textinput"> <label for="insurance_name"> 险种 </label> <input name="insurance_name" value="" type="text"> </div> <div class="ui-field-contain" data-controltype="selectmenu"> <label for="insurance_company"> 投保公司 </label> <select id="insurance_company" name="insurance_company"> </select> </div> <div class="ui-field-contain" data-controltype="dateinput"> <label for="insurance_date"> 投保日期 </label> <input name="insurance_date" value="" type="date"> </div> <div class="ui-field-contain" data-controltype="textinput"> <label for="insurance_year"> 年期(年) </label> <input name="year_period" value="" type="number"> </div> <div class="ui-field-contain" data-controltype="textinput"> <label for="insurance_cost"> 年保费(元) </label> <input name="year_cost" value="" type="number"> </div> <div class="ui-field-contain" data-controltype="textarea"> <label for="insurance_comment"> 备注 </label> <textarea name="insurance_comment" placeholder=""></textarea> </div> <a href="javascript:void(0);" data-role="button" id="btn_insurance_save" data-inline="true" data-theme="e">新增</a> <a href="javascript:void(0);" data-role="button" style="display:none" id="btn_insurance_delete" data-inline="true" data-theme="b">删除</a> <a href="javascript:void(0);" data-role="button" id="btn_insurance_cancel" data-inline="true">取消</a> </div><!-- end of div_insure_info --> </div><!-- end of content --> </div> </body> </html>
页签切换时执行的事件:
$(document).on("pageinit", "#insurer_edit_page", function() { $("#insurer_edit_page").find("#div_basic_info").show(); $("#insurer_edit_page").find("#div_insure_info").hide(); $("#insurer_edit_page").find("#a_basic_info").click(function(){ $("#insurer_edit_page").find("#div_basic_info").show(); $("#insurer_edit_page").find("#div_insure_info").hide(); }); $("#insurer_edit_page").find("#a_insure_info").click(function(){ $("#insurer_edit_page").find("#div_basic_info").hide(); $("#insurer_edit_page").find("#div_insure_info").show(); }); ...... });
[投保信息]页面新增、删除、取消三个按钮点击事件处理逻辑如下。
最重要的是新增操作,它会提取录入的数据并且放到上方的ListView中,保存前还通过js做了一些输入有效性验证。
删除操作只是从ListView中临时删除那条数据,如果不点击右上方的[保存]按钮的话,不会生效。
function init_div_insure_info_event(){ $("#insurer_edit_page").find("#btn_insurance_save").unbind("click").bind("click",function(){ var DOM = $("#insurer_edit_page").find("#div_insure_info"); var isNew = false; var insurance_id = DOM.find("input[name='insurance_id']").val(); if( $.isNull(insurance_id) ){ insurance_id = javascriptUser.getUUID(); isNew = true; } var insurance_name = DOM.find("input[name='insurance_name']").val(); if($.isNull(insurance_name)){ DOM.find("#insurance_error").html("险种不能为空"); return; } var insurance_company = DOM.find("select[name='insurance_company']").val(); var insurance_date = DOM.find("input[name='insurance_date']").val(); if(!$.isNull(insurance_date)){ if(!$.isDate(insurance_date)){ DOM.find("#insurance_error").html("投保日期不是正确的日期格式:年-月-日"); return; } } var year_period = DOM.find("input[name='year_period']").val(); if(!$.isNull(year_period)){ if(!$.isNumber(year_period)){ DOM.find("#insurance_error").html("年期不是数字类型"); return; } } var year_cost = DOM.find("input[name='year_cost']").val(); if(!$.isNull(year_cost)){ if(!$.isNumber(year_cost)){ DOM.find("#insurance_error").html("年保费不是数字类型"); return; } } var insurance_comment = DOM.find("textarea[name='insurance_comment']").val(); DOM.find("#insurance_error").html(" ");//清空错误提示 if(isNew){ var html = "<li name=\"views\" id=\""+insurance_id+"\">"; html += "<input type=\"hidden\" name=\"h_id\" value=\""+insurance_id+"\" >"; html += "<input type=\"hidden\" name=\"h_isNew\" value=\""+isNew+"\" >"; html += "<input type=\"hidden\" name=\"h_insurance_name\" value=\""+insurance_name+"\" >"; html += "<input type=\"hidden\" name=\"h_insurance_date\" value=\""+insurance_date+"\" >"; html += "<input type=\"hidden\" name=\"h_insurance_company\" value=\""+insurance_company+"\" >"; html += "<input type=\"hidden\" name=\"h_year_period\" value=\""+year_period+"\" >"; html += "<input type=\"hidden\" name=\"h_year_cost\" value=\""+year_cost+"\" >"; html += "<input type=\"hidden\" name=\"h_insurance_comment\" value=\""+insurance_comment+"\" >"; html += "<input type=\"hidden\" name=\"h_remind_time\" value=\"0\" >"; html += "<a href=\"#\" onclick=\"init_div_insure_info_form('"+insurance_id+"')\" >"; html += ("<p name=\"p_insurance_name\">"+insurance_name+"<p>"); html += ("<p name=\"p_insurance_company\">"+$.parseJSON(javascriptUser.getCompanyById(insurance_company)).name+"<p>"); html += ("<p name=\"p_insurance_date\">"+insurance_date+"<p>"); html += ("<p name=\"p_year_period\">"+year_period+"年 "+year_cost+"元/年<p>"); html += ("<p name=\"p_insurance_comment\">"+insurance_comment+"<p>"); html += "</a>"; html += "</li>"; DOM.find("#collapsible_listview").prepend(html); }//end of isNew else{ DOM.find("#"+insurance_id).find("input[name='h_insurance_name']").val(insurance_name); DOM.find("#"+insurance_id).find("input[name='h_insurance_company']").val(insurance_company); DOM.find("#"+insurance_id).find("input[name='h_insurance_date']").val(insurance_date); DOM.find("#"+insurance_id).find("input[name='h_year_period']").val(year_period); DOM.find("#"+insurance_id).find("input[name='h_year_cost']").val(year_cost); DOM.find("#"+insurance_id).find("input[name='h_insurance_comment']").val(insurance_comment); DOM.find("#"+insurance_id).find("p[name='p_insurance_name']").html(insurance_name); DOM.find("#"+insurance_id).find("p[name='p_insurance_company']").html($.parseJSON(javascriptUser.getCompanyById(insurance_company)).name); DOM.find("#"+insurance_id).find("p[name='p_insurance_date']").html(insurance_date); DOM.find("#"+insurance_id).find("p[name='p_year_period']").html(year_period+"年 "+year_cost+"元/年"); DOM.find("#"+insurance_id).find("p[name='p_insurance_comment']").html(insurance_comment); } reset_div_insure_info_form(); DOM.find("#collapsible_listview").listview("refresh"); DOM.find("#collapsible_listview").focus(); });//end of click /** * 取消 */ $("#insurer_edit_page").find("#btn_insurance_cancel").unbind("click").bind("click",function(){ reset_div_insure_info_form(); }); /** * 删除 */ $("#insurer_edit_page").find("#btn_insurance_delete").unbind("click").bind("click",function(){ if(confirm("确定临时删除保单吗?(保存后会完全删除)")){ var id = $("#insurer_edit_page").find("#div_insure_info").find("input[name='insurance_id']").val(); $("#insurer_edit_page").find("#collapsible_listview").find("#"+id).remove(); $("#insurer_edit_page").find("#collapsible_listview").listview("refresh"); $("#insurer_edit_page").find("#collapsible_listview").focus(); reset_div_insure_info_form(); } }); }
右上角[保存]按钮执行最终的保存操作。
因为保单信息可以是多条ListView,而调用Android后台方法是不能传List的,所以我是将数据转换成字符串,在后台通过split转回成数组。
$(document).on("pageinit", "#insurer_edit_page", function() { ...... $("#insurer_edit_page").find("#a_save").unbind("click").bind("click",insurer_edit_save); ...... }); function insurer_edit_save(){ var DOM = $("#insurer_edit_page"); var insurerInfo = new Object(); insurerInfo.id = DOM.find("#id").val(); insurerInfo.name = DOM.find("#name").val(); insurerInfo.sex = DOM.find('input[name="sex"]:checked').val(); insurerInfo.birthday = DOM.find("#birthday").val(); insurerInfo.id_number = DOM.find("#id_number").val(); insurerInfo.mobile_phone = DOM.find("#mobile_phone").val(); insurerInfo.email = DOM.find("#email").val(); insurerInfo.qq_number = DOM.find("#qq_number").val(); insurerInfo.fax = DOM.find("#fax").val(); insurerInfo.address = DOM.find("#address").val(); insurerInfo.marital_status = DOM.find('input[name="marital_status"]:checked').val(); insurerInfo.education = DOM.find("#education").val(); var insurancesString = ""; var listView = DOM.find("#collapsible_listview").children(); if(listView != undefined && listView.length > 0){ listView.each(function(i,n){ var view = $(n) var insurances = new Object(); insurances.id = view.find("input[name='h_id']").val(); insurances.insurance_name = view.find("input[name='h_insurance_name']").val(); insurances.insurance_date = view.find("input[name='h_insurance_date']").val(); insurances.insurance_company = view.find("input[name='h_insurance_company']").val(); insurances.year_period = view.find("input[name='h_year_period']").val(); insurances.year_cost = view.find("input[name='h_year_cost']").val(); insurances.insurance_comment = view.find("input[name='h_insurance_comment']").val(); if(!$.isNull(view.find("input[name='h_update_time']").val())){ insurances.update_time = view.find("input[name='h_update_time']").val(); } insurances.remind_time = view.find("input[name='h_remind_time']").val(); insurances.isNew = view.find("input[name='h_isNew']").val(); insurancesString += $.objectToString(insurances)+"#LIST#" }); } var imageInfo = new Object(); var result = javascriptUser.saveOrUpdateInsurer($.objectToString(insurerInfo),insurancesString,$.objectToString(imageInfo)); if(result == "true"){ $.mobile.changePage("insurer_list.html",{transition: "slide"}); }else{ $("#msg").html(result); } }
Android后台执行保存操作,这里主要是接收参数,验证输入有效性,封装成对象,最后调用Manager方法执行最终入库逻辑。
public String saveOrUpdateInsurer(String insurerInfoString,String insurancesString,String imageInfoString){ Map<String, String> insurerInfoMap = this.getParams(insurerInfoString); String id = insurerInfoMap.get("id"); String name = insurerInfoMap.get("name"); String sex = insurerInfoMap.get("sex"); String birthday = insurerInfoMap.get("birthday"); String id_number = insurerInfoMap.get("id_number"); String mobile_phone = insurerInfoMap.get("mobile_phone"); String email = insurerInfoMap.get("email"); String qq_number = insurerInfoMap.get("qq_number"); String fax = insurerInfoMap.get("fax"); String address = insurerInfoMap.get("address"); String marital_status = insurerInfoMap.get("marital_status"); String education = insurerInfoMap.get("education"); List<Validator> list = new ArrayList<Validator>(); list.add( new Validator(ValidateUtils.ValidateEnum.EMPTY, "姓名", new Object[]{name}) ); list.add( new Validator(ValidateUtils.ValidateEnum.CHARACTERS, "姓名", new Object[]{name.trim(),"<>'\""}) ); if(StringUtils.isNotBlank(birthday)){ list.add( new Validator(ValidateUtils.ValidateEnum.DATE, "生日", new Object[]{birthday,"yyyy-MM-dd"}) ); } if(StringUtils.isNotBlank(mobile_phone)){ list.add( new Validator(ValidateUtils.ValidateEnum.NUMBER, "移动电话", new Object[]{mobile_phone}) ); } if(StringUtils.isNotBlank(qq_number)){ list.add( new Validator(ValidateUtils.ValidateEnum.NUMBER, "QQ号码", new Object[]{qq_number}) ); } if(StringUtils.isNotBlank(email)){ list.add( new Validator(ValidateUtils.ValidateEnum.EMAIL, "E-Mail", new Object[]{email}) ); } String check = ValidateUtils.validateList(list); if(StringUtils.isNotBlank(check)){ return check; } boolean isEdit = false; if(StringUtils.isNotBlank(id)){ isEdit = true; } Integer delete_flag = Enums.DeleteEnum.AVAILABLE.getKey(); String update_time = DateUtil.date2string(new Date(), DateUtil.yyyy_MM_dd_HH_mm_ss); //保险人基本信息 InsurerInfo insurerInfo = new InsurerInfo( (StringUtils.isNotBlank(id) ? Long.valueOf(id) : InsurerInfo.uuid() ) , name, Integer.valueOf(sex), birthday, id_number, mobile_phone,qq_number,email, fax, address, Integer.valueOf(marital_status), Integer.valueOf(education), delete_flag, update_time); //保险单信息:分新建和更新两种 List<Insurances> newInsurancesList = new ArrayList<Insurances>(); List<Insurances> oldInsurancesList = new ArrayList<Insurances>(); if(StringUtils.isNotBlank(insurancesString)){ String[] insurancesArr = insurancesString.split("#LIST#"); for (String string : insurancesArr) { Map<String, String> insurancesMap = null; Insurances insurances = null; if(StringUtils.isNotBlank(string)){ insurancesMap = this.getParams(string); insurances = new Insurances(); insurances.setId(Long.valueOf(insurancesMap.get("id"))); insurances.setDelete_flag(Enums.DeleteEnum.AVAILABLE.getKey()); insurances.setInsurance_comment(insurancesMap.get("insurance_comment")); insurances.setInsurance_company(insurancesMap.get("insurance_company")); insurances.setInsurance_date(insurancesMap.get("insurance_date")); insurances.setInsurance_name(insurancesMap.get("insurance_name")); insurances.setInsurer_info_id(insurerInfo.getId()); insurances.setRemind_time(insurancesMap.get("remind_time")); insurances.setUpdate_time(insurancesMap.containsKey("update_time")?insurancesMap.get("update_time"):DateUtil.date2string(new Date(), DateUtil.yyyy_MM_dd_HH_mm_ss)); insurances.setYear_cost(insurancesMap.get("year_cost")); insurances.setYear_period(insurancesMap.get("year_period")); insurances.setRemind_type(Enums.RemindTypeEnum.ON.getKey()); if(StringUtils.isNotEmpty(insurances.getInsurance_date()) && StringUtils.isNotEmpty(insurances.getYear_period())){ try { Date start = DateUtil.string2date(insurances.getInsurance_date(),DateUtil.yyyy_MM_dd); Date end = DateUtil.addYear(start, Integer.valueOf(insurances.getYear_period())); insurances.setEnd_date(DateUtil.date2string(end, DateUtil.yyyy_MM_dd)); } catch (ParseException e) { Log.e("common", "日期时间转换错误:"+insurances.getInsurance_date(), e); } } if("true".equals(insurancesMap.get("isNew"))){ newInsurancesList.add(insurances); }else{ oldInsurancesList.add(insurances); } } } } //图片附件功能未做 Map<String, String> imageInfoMap = this.getParams(imageInfoString); try { if(isEdit){ insurerInfoManager.update(insurerInfo, newInsurancesList,oldInsurancesList, null); }else{ insurerInfoManager.save(insurerInfo, newInsurancesList, null); } } catch (Exception e) { Log.e(Enums.LogTagEnum.COMMON.getKey(), "保存保险人信息失败", e); return e.getMessage(); } return "true"; }
最终执行新增、修改操作的是InsurerInfoManager,因为涉及多张表操作,所以这里我做了事务处理,保持数据的一致性。
public void update(InsurerInfo insurerInfo,List<Insurances> newInsurancesList,List<Insurances> oldInsurancesList,List<ImageInfo> imageInfoList){ //开启事务 dbHelper.getWritableDatabase().beginTransaction(); try { //更新保险人基本信息 super.update(insurerInfo); //删除不存在的保险单信息 if(!ObjectUtils.isEmpty(oldInsurancesList)){ String ids = ""; for (Insurances insurances: oldInsurancesList) { //更新已存在的保险单 insurancesManager.update(insurances); ids += insurances.getId().toString()+","; } String delSql = "DELETE FROM insurances WHERE id NOT IN ("+ObjectUtils.removeLastChar(ids, ",")+") AND insurer_info_id = ?"; super.updateBySql(delSql, new Object[]{insurerInfo.getId()}); }else{ String delSql = "DELETE FROM insurances WHERE insurer_info_id = ?"; super.updateBySql(delSql, new Object[]{insurerInfo.getId()}); } if(!ObjectUtils.isEmpty(newInsurancesList)){ for (Insurances insurances: newInsurancesList) { //添加新建的保险单 insurancesManager.save(insurances); } } //提交事务 dbHelper.getWritableDatabase().setTransactionSuccessful(); } catch (Exception e) { Log.e(Enums.LogTagEnum.COMMON.getKey(), "保存保险人信息异常!", e); }finally{ //结束事务 dbHelper.getWritableDatabase().endTransaction(); } }
public void save(InsurerInfo insurerInfo,List<Insurances> insurancesList,List<ImageInfo> imageInfoList){ dbHelper.getWritableDatabase().beginTransaction(); try { super.save(insurerInfo); if(!ObjectUtils.isEmpty(insurancesList)){ for (Insurances insurances: insurancesList) { insurancesManager.save(insurances); } } dbHelper.getWritableDatabase().setTransactionSuccessful(); } catch (Exception e) { Log.e(Enums.LogTagEnum.COMMON.getKey(), "保存保险人信息异常!", e); }finally{ dbHelper.getWritableDatabase().endTransaction(); } }
------>保险人列表
执行保存操作后,会跳转到保险人列表页面。这个页面主要由两个控件组成:查询输入框和ListView列表组件,ListView用于显示所有保险人信息的,查询输入框可根据保险人姓名进行即时条件查询。
这是全部保险人列表
这是根据条件即时查询的保险人列表
HTML页面代码非常简单:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"> <title> </title> </head> <body> <div data-role="page" id="insurer_list_page"> <div data-theme="b" data-role="header" data-position="fixed"> <a data-role="button" data-rel="back" href="#" class="ui-btn-left" data-icon="back"> 返回 </a> <h3> (准)保险人列表 </h3> <a id="a_add" href="#" data-transition="slide" data-role="button" data-theme="b" data-icon="add" data-iconpos="left" class="ui-btn-right"> 新增 </a> </div> <div data-role="content"> <div role="main" class="ui-content"> <div class="ui-field-contain" data-controltype="searchinput"> <input name="searchinput" id="searchinput" placeholder="根据保险人姓名搜索..." value="" type="search" data-clear-btn="true"> </div> <ul data-role="listview" data-inset="true" id="listview"> </ul> </div> </div> </div> </body> </html>
保险人列表页面的pageinit事件主要做两件事:①调用initInsurerListPage()初始化ListView显示全部的保险人;②绑定[新增]按钮和即时查询控件事件。
$(document).on("pageinit", "#insurer_list_page", function() { initInsurerListPage(""); $("#insurer_list_page").find("#a_add").unbind("click").bind("click",function(){ $.changePageInitData("insurer_edit.html"); }); $("#insurer_list_page").find("#searchinput").bind('input propertychange', function(){ initInsurerListPage($("#insurer_list_page").find("#searchinput").val()); }); });
function initInsurerListPage(_name){ var json = javascriptUser.findAllInsurer(_name); var DOM = $("#insurer_list_page").find("#listview"); if(!$.isNull(json)){ DOM.empty(); var list = $.parseJSON(json); for(var i=0 ; i< list.length ; i++){ var insurerInfo_ = list[i]; var li = "<li><a href=\"#\" onclick=\"goToInsurerDetailById('"+insurerInfo_.id+"')\">"; li += "<h3>"+insurerInfo_.name + " " + (insurerInfo_.sex==1?"男":"女") + " " + insurerInfo_.birthday+"</h3>"; li += "<p>"+insurerInfo_.mobile_phone+"</p>"; li += "</a></li>"; DOM.append(li); } DOM.listview("refresh"); }else{ DOM.empty(); DOM.listview("refresh"); } }
Android后台执行的条件查询操作:
public String findAllInsurer(String name){ List<InsurerInfo> infoList = null; try { infoList = this.insurerInfoManager.findInsurerInfoByCondition(name); } catch (Exception e) { Log.e("common", "条件查询异常", e); } if(!ObjectUtils.isEmpty(infoList)){ StringBuilder json = new StringBuilder(); json.append("["); json.append(infoList.get(0).toJSON()); for (int i = 1; i < infoList.size(); i++) { json.append(",").append(infoList.get(i).toJSON()); } json.append("]"); return json.toString(); } return ""; }
public List<InsurerInfo> findInsurerInfoByCondition(String name){ StringBuilder sql = new StringBuilder("SELECT * FROM insurer_info WHERE delete_flag="+Enums.DeleteEnum.AVAILABLE.getKey()); String[] params = null; if(StringUtils.isNotBlank(name)){ sql.append(" AND name LIKE ?"); params = new String[]{"%"+name.trim()+"%"}; } sql.append(" ORDER BY update_time DESC"); return super.findBySql(sql.toString(), params, 0, 0); }
特别需要注意的是SQLite中LIKE语句的写法和参数传递方式。
------>保险人详细信息
在保险人列表页面点击某一个ListView即可进入该保险人的详细信息页面,这个页面显示该保险人所有信息和购买的保险内容,通过最上方的删除操作可以永久删除保险人,也可通过[编辑]操作进入修改页面。
保险人详细信息页面的HTML代码如下:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <meta name="viewport" content="width=device-width, initial-scale=1"> <title> </title> </head> <body> <div data-role="page" id="insurer_detail_page"> <div data-theme="b" data-role="header" data-position="fixed"> <a data-role="button" data-rel="back" href="#" class="ui-btn-left" data-icon="back"> 返回 </a> <h3> 保险人信息 </h3> </div> <div data-role="navbar" data-iconpos="top"> <ul> <li> <a href="#" id="a_delete" data-transition="slide" data-icon="delete"> 删除 </a> </li> <li> <a href="#" id="a_edit" data-transition="slide" data-icon="edit"> 修改 </a> </li> </ul> </div> <div data-role="content" id="insurer_detail_content"> </div> </div> </body> </html>
在[保险人列表]点击ListView时会触发onclick事件,这时会调用进入保险人详细信息页面的逻辑代码。
onclick事件是在[保险人列表]创建ListView时就定义好的,注意看代码var li = "<li><a href=\"#\" onclick=\"goToInsurerDetailById('"+insurerInfo_.id+"')\">";
function initInsurerListPage(_name){ var json = javascriptUser.findAllInsurer(_name); var DOM = $("#insurer_list_page").find("#listview"); if(!$.isNull(json)){ DOM.empty(); var list = $.parseJSON(json); for(var i=0 ; i< list.length ; i++){ var insurerInfo_ = list[i]; var li = "<li><a href=\"#\" onclick=\"goToInsurerDetailById('"+insurerInfo_.id+"')\">"; li += "<h3>"+insurerInfo_.name + " " + (insurerInfo_.sex==1?"男":"女") + " " + insurerInfo_.birthday+"</h3>"; li += "<p>"+insurerInfo_.mobile_phone+"</p>"; li += "</a></li>"; DOM.append(li); } DOM.listview("refresh"); }else{ DOM.empty(); DOM.listview("refresh"); } } function goToInsurerDetailById(id,url){ var html = $.isNull(url)?"insurer_detail.html":url; $.changePageInitData(html,"insurer_detail_page",function(page, data, params){ if(id != null){ var json = javascriptUser.getInsurerById(id); if($.isNull(json)){ alert("该条数据已不存在!"); $.mobile.changePage("insurer_list.html",{transition: "slide"}); }else{ var info = $.parseJSON(json); page.find("#a_edit").unbind("click").bind("click",function(){goToInsurerEditById(info.id)}); page.find("#a_delete").unbind("click").bind("click",function(){ if(confirm("确认永久删除该条数据?")){ javascriptUser.deleteInsurer(info.id); $.mobile.changePage("insurer_list.html",{transition: "slide"}); } }); var content = page.find("#insurer_detail_content"); content.append("<input name='id' id='id' type='hidden' value='"+info.id+"'>"); content.append("<p>姓名:"+info.name+"</p>"); content.append("<p>性别:"+(info.sex==1 ? "男":"女")+"</p>"); content.append("<p>生日:"+info.birthday+"</p>"); content.append("<p>身份证号:"+info.id_number+"</p>"); content.append("<p>移动电话:"+info.mobile_phone+ call_phone_icon(info.mobile_phone,info.name + (info.sex==1 ? "先生":"女士") ) +"</p>"); content.append("<p>QQ号:"+info.qq_number+"</p>"); content.append("<p>电子邮箱:"+info.email+"</p>"); content.append("<p>传真:"+info.fax+"</p>"); content.append("<p>联系地址:"+info.address+"</p>"); content.append("<p>婚姻状况:"+ return_marital_status(info.marital_status) +"</p>"); content.append("<p>学历:"+return_education(info.education)+"</p>"); var insurancesJSON = javascriptUser.getInsurancesByInsurerId(id); if(!$.isNull(insurancesJSON)){ content.append("<hr>"); content.append("<ul id=\"detail_listview\" >"); var insurancesList = $.parseJSON(insurancesJSON); for(var i=0;i<insurancesList.length;i++){ var insurances = insurancesList[i]; var html = "<li>"; html += ("<p name=\"p_insurance_name\"><h3>"+insurances.insurance_name+"</h3><p>"); html += ("<p name=\"p_insurance_company\">"+$.parseJSON(javascriptUser.getCompanyById(insurances.insurance_company)).name+"<p>"); html += ("<p name=\"p_insurance_date\">"+insurances.insurance_date+"<p>"); html += ("<p name=\"p_year_period\">"+insurances.year_period+"年 "+insurances.year_cost+"元/年<p>"); html += ("<p name=\"p_insurance_comment\">"+insurances.insurance_comment+"<p>"); html += "</li>"; content.append(html); } content.append("</ul>"); //page.find("#detail_listview").listview("refresh"); }//end of isNull } } }); }
------>详细到编辑页面
在初始化保险人详细列表时就绑定了[编辑]按钮的事件:
page.find("#a_edit").unbind("click").bind("click",function(){goToInsurerEditById(info.id)});
function goToInsurerEditById(id){ $.changePageInitData("insurer_edit.html","insurer_edit_page",function(page, data, params){ if(id != null){ var json = javascriptUser.getInsurerById(id); if($.isNull(json)){ alert("该条数据已不存在!"); $.mobile.changePage("insurer_list.html",{transition: "slide"}); }else{ var info = $.parseJSON(json); page.find("#id").val(info.id); page.find("#name").val(info.name); $.radioChecked(page.find("input[name='sex']"),info.sex); page.find("#birthday").val(info.birthday); page.find("#id_number").val(info.id_number); page.find("#mobile_phone").val(info.mobile_phone); page.find("#email").val(info.email); page.find("#qq_number").val(info.qq_number); page.find("#fax").val(info.fax); page.find("#address").html(info.address); $.radioChecked(page.find("input[name='marital_status']"),info.sex); page.find("#education").val(info.education).selectmenu("refresh"); var insurancesJSON = javascriptUser.getInsurancesByInsurerId(id); if(!$.isNull(insurancesJSON)){ var insurancesList = $.parseJSON(insurancesJSON); for(var i=0;i<insurancesList.length;i++){ var insurances = insurancesList[i]; //保单ListView var html = "<li name=\"views\" id=\""+insurances.id+"\">"; html += "<input type=\"hidden\" name=\"h_id\" value=\""+insurances.id+"\" >"; html += "<input type=\"hidden\" name=\"h_isNew\" value=\"false\" >"; html += "<input type=\"hidden\" name=\"h_insurance_name\" value=\""+insurances.insurance_name+"\" >"; html += "<input type=\"hidden\" name=\"h_insurance_date\" value=\""+insurances.insurance_date+"\" >"; html += "<input type=\"hidden\" name=\"h_insurance_company\" value=\""+insurances.insurance_company+"\" >"; html += "<input type=\"hidden\" name=\"h_year_period\" value=\""+insurances.year_period+"\" >"; html += "<input type=\"hidden\" name=\"h_year_cost\" value=\""+insurances.year_cost+"\" >"; html += "<input type=\"hidden\" name=\"h_insurance_comment\" value=\""+insurances.insurance_comment+"\" >"; html += "<input type=\"hidden\" name=\"h_remind_time\" value=\""+insurances.remind_time+"\" >"; html += "<a href=\"#\" onclick=\"init_div_insure_info_form('"+insurances.id+"')\" >"; html += ("<p name=\"p_insurance_name\">"+insurances.insurance_name+"<p>"); html += ("<p name=\"p_insurance_company\">"+$.parseJSON(javascriptUser.getCompanyById(insurances.insurance_company)).name+"<p>"); html += ("<p name=\"p_insurance_date\">"+insurances.insurance_date+"<p>"); html += ("<p name=\"p_year_period\">"+insurances.year_period+"年 "+insurances.year_cost+"元/年<p>"); html += ("<p name=\"p_insurance_comment\">"+insurances.insurance_comment+"<p>"); html += "</a>"; html += "</li>"; page.find("#collapsible_listview").append(html); }//end of for page.find("#collapsible_listview").listview("refresh"); } } } }); }
至于[保险人详细页面]的删除操作非常简单,这里就不多说了。
- 注意事项
1、SQLite的Like语句规范稍有特点:SQL语句不能写成"xx like '%?%'",也不能写成"xx like %?%",只能写成"xx like ?",而"%"符号必须以参数的形式传递过去:Cursor cursor = db.rawQuery(sql, new String[]{"%张%"});。这个在[学习系列(5)-SQLite数据库]---[常见问题]中也有说明。
2、监听即时查询框输入变化的事件是input和propertychange,这个是网上找到的,经过测试是有效的。
$("#insurer_list_page").find("#searchinput").bind('input propertychange', function(){ initInsurerListPage($("#insurer_list_page").find("#searchinput").val()); });
3、与其它事务处理不同的是,SQLite的事务没有rollback方法,Sqlite会判定,在beginTransaction和endTransaction中若没有setTransactionSuccessful方法则表示回滚。而且不论事务成功与否,都必须调用entTransaction关闭事务。
dbHelper.getWritableDatabase().beginTransaction(); try { //---CUD事务操作 dbHelper.getWritableDatabase().setTransactionSuccessful(); } catch (Exception e) { //---异常处理 }finally{ dbHelper.getWritableDatabase().endTransaction(); }
4、javascript的List参数想传到Android后台,似乎不能直接以List形式传递,所以我是将List转换成某种格式的字符串,在后台再通过splite转换回来。这种方式其实蛮不规范的,我的建议是最好以JSON的形式进行前后台交互,因为很偷懒,我没有研究怎么用JSON的形式实现代码,这个大家可以自行研究。
5、新增、修改保险人页面的[保单信息]下面的保险公司是从数据库中取的实时数据,我专门做了一个保险公司录入管理功能,无非是增删改查,非常简单,所以就不做详细介绍。这里要说的是在新增、修改页面中的保险公司是一个<select>标签,如果动态录入标签值的话一定要刷新select组件,否则不会有jquerymobile样式效果:
var companyJSON = javascriptUser.findAllCompany(); if(!$.isNull(companyJSON)){ var company = $.parseJSON(companyJSON); var selectDOM = $("#insurer_edit_page").find("#insurance_company"); for(var i=0;i<company.length;i++){ selectDOM.append("<option value='"+company[i].id+"'>"+company[i].name+"</option>"); } selectDOM.selectmenu("refresh"); }
相关推荐
基于 jsp + servlet + jquery + easy-ui + ajax 的学生成绩管理系统 基于 jsp + servlet + jquery + easy-ui + ajax 的学生成绩管理系统 基于 jsp + servlet + jquery + easy-ui + ajax 的学生成绩管理系统 基于 jsp...
Python高校舆情分析监控系统 框架:flask+ html + css + jquery + python + TD-IDF,IDA,NLP算法 +mysql MySQL数据量重置id truncate table tablename python3.9 高校舆情分析监控系统 爬虫三个模块 贴吧 微博
第7课 - 表格与表单 - [精通JavaScript+jQuery] 第8课 - Javascript调试与优化 - [精通JavaScript+jQuery] 第9课 - Ajax - [精通JavaScript+jQuery] jQuery应用 第10课 - jQuery基础 - [精通JavaScript+jQuery] ...
以前不知道哪里找到的一个系统,感觉很不错,使用文档,数据库文件,项目截图全都包括,后台使用Servlet+Jsp,前台用的H-ui+EasyUI+jQuery,很适合新手入门的学习,特别是代码里面许许多多的注释,让我受益匪浅,...
2、本项目适合作为计算机、数学、电子信息等专业的课程设计、期末大作业和毕设项目,作为参考资料学习借鉴。 3、本资源作为“参考资料”如果需要实现其他功能,需要能看懂代码,并且热爱钻研,自行调试。 基于jsp+...
图书的源代部分; 还有由于容量的原因, 视频和web实例图片没有上传. 《jQuery全能权威指南:jQuery Core+jQuery Plugin+...、jQuery UI、jQuery Mobile以及大量第三方的插件库和2800多个应用jQuery技术的网页参考。
jQuery Mobile的设计目标是跨平台兼容,能在iOS、Android、Windows Phone等多款主流移动操作系统上无缝运行。通过使用jQuery Mobile,开发者可以快速构建具有触摸友好的交互和流畅动画的移动应用和网站。 在本书中...
Python高校舆情分析监控...框架:flask+ html + css + jquery + python + TD-IDF,IDA,NLP算法 +mysql MySQL数据量重置id truncate table tablename python3.9 高校舆情分析监控系统 爬虫三个模块 贴吧 微博 新闻
Jquery.Pagination.js + Jquery.Ajax + ASP.NET----无刷新分页Pagination 1.5.1,是在原作者基础上修改的,因为Pagination 1.5.1与它的低版本有很大的区别,所以在此实例中增加了新版的使用方法
【标题】:“Android + PhoneGap + jQuery Mobile” 这个项目标题揭示了一个使用三种技术栈构建的移动应用程序:Android、PhoneGap和jQuery Mobile。Android是Google主导的开源操作系统,主要用于智能手机和平板...
对于想要学习或提升移动Web开发技能的人来说,这是一个很好的实践项目。通过解压并分析"HTM5Demo"中的代码,你可以更直观地了解这两个技术如何协同工作,进而创建出高性能、高交互性的移动Web应用。
ASP.NET、Ajax 和 jQuery 是构建动态网页应用的三个关键技术,它们在实现无刷新用户体验方面扮演着重要角色。本文将深入探讨这些技术如何协同工作,以及如何利用它们来创建一个"顶-踩-无刷新【点赞】"功能的程序。 ...
《jQuery Mobile与Bootstrap主题整合详解》 在Web开发领域,jQuery Mobile和Bootstrap是两种非常流行的前端框架,它们各自为开发者提供了强大的工具和组件,以构建响应式、移动优先的网页应用。当我们谈论"jQuery-...
系统后端基于SpringMVC+Spring+Hibernate框架,前端页面采用JQuery+Bootstrap等主流技术; 流程引擎基于Snaker工作流;表单设计器基于雷劈网WEB表单设计器。 系统主要功能有: >1.系统管理 >>系统管理包含有:基础...
这个压缩包"HTML5+CSS3+JQueryMobile入门-源代码.zip"提供了一套入门级别的学习资源,包含了实际的源代码,帮助初学者通过实践来理解这些技术。 首先,HTML5是超文本标记语言(HyperText Markup Language)的第五个...
jQuery Mobile则是一个轻量级的框架,专门用于简化移动设备上的用户界面开发。 首先,让我们深入了解一下HTML5。HTML5的核心改进在于增强了语义化标签,如`<header>`, `<footer>`, `<article>`, `<section>`等,这...
基于eclipse + easyUi1.2.6+common-fileupload + struts2实现带进度条的文件上传DEMO,具体效果跟思路可见我的博客:http://blog.csdn.net/jun55xiu/article/details/22042279
在实际应用中,`jquery-mobile-theme-174943-0`可能包含了一些预设的样式和布局示例,方便开发者理解和学习如何使用这个主题。例如,可能会有一个设置页面,展示了如何配置不同的主题元素,如按钮、工具栏和列表项。...
jQuery Mobile是一款轻量级的框架,专门用于简化移动设备上的Web开发。它建立在流行的JavaScript库jQuery之上,提供了一套统一的事件处理、动画效果和触控友好的用户界面组件。jQuery Mobile的核心特性包括: 1. **...
**jQuery Mobile 和 Bootstrap 主题整合** `jQuery Mobile` 和 `Bootstrap` 是两个广泛使用的前端开发框架,它们各自在移动和Web应用设计上有着独特的优点。`jQuery Mobile` 专注于提供跨平台、触摸友好的UI组件,...