校园跑腿系统需求
软件能实现跑腿业务的流程管理,其功能主要包括:
(1)用户注册、登录,个人信息管理等,用户既可作为雇佣方,也可以作为被雇方。
(2)雇佣方用户可以选择服务项目,发布所需求跑腿任务,查看/处理所发布任务;查看任务进度;评价被雇方的服务,进行相关数据的统计和分析,等;跑腿业务可以分为代取快递和外卖、代排队、代购、代送,以及服务类等。
(3)被雇方用户可以浏览任务信息,选择适合自己的任务进行接单;可以查看、操作任务单,编辑任务进度,进行相关数据的统计和分析,等。
(4)辅助功能包括:软件设置,后台管理用户,维护跑腿业务相关信息,维护用户信息,跑腿业务经营管理相关数据的统计与分析。
一、使用到的云数据库
采用云数据库Bmob,这里创建了三个表,一个用户表,一个任务表和一个接单者订单消息表。具体如下:
MyUser表
列名 | 类型 | 注释 |
---|---|---|
uid | Number | 用户编号(主键) |
account | String | 用户账号 |
upassword | String | 用户密码 |
uname | String | 用户昵称 |
urealname | String | 用户真实姓名 |
uidentitycard | String | 用户身份证号码 |
usubapplicate | Number | 接单者是否提交申请 |
ucheck | Number | 是否成为接单者 |
sex | String | 性别 |
String | QQ号 | |
phone | String | 电话号码 |
income | String | 收益 |
ureputation | Number | 用户信誉值 |
goodappraisecount | Number | 好评任务数 |
badappraisecout | Number | 差评任务数 |
MyTask表
列名 | 类型 | 注释 |
---|---|---|
tid | Number | 任务编号(主键) |
uid | Number | 发单者编号 |
id | Number | 接单者编号 |
tname | String | 任务标题 |
tkind | String | 任务类型 |
tdetail | String | 任务详情 |
myaddress | String | 本人地址 |
targetaddress | String | 目标地址 |
tphone | Number | 发单者联系电话 |
tprice | Number | 价格 |
tcheck | Number | 任务审核成功标识 |
torder | Number | 接单标识 |
tfinish | Number | 完成订单标识 |
tappfinsh | Number | 评价任务标识 |
tasknotify | Number | 删除通知标识 |
tordercheck | Number | 订单异常标识 |
tappraise | Number | 数字评分 |
tappraisetext | String | 文字评论 |
tcheckerrordetails | String | 审核任务失败通知内容 |
tordercanceldetails | String | 取消订单的详细信息 |
MyOrderRead表
列名 | 类型 | 注释 |
---|---|---|
tid | Number | 订单编号(主键) |
id | Number | 接单者编号 |
tname | String | 订单标题 |
torderread | Number | 接单者者是否已读消息 |
torderreaddetails | String | 异常订单消息详情 |
二、部分功能展示
1.发布任务(包含虚拟支付功能)
支付界面是以弹窗形式进行显示,部分代码如下(示例):
//发布功能实现
fabubutton=findViewById(R.id.fabubutton);
fabubutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (etname.getText().toString().equals("")){
// System.out.println("名字:"+etname.getText().toString());
Toast.makeText(getApplication(), "请填写任务标题" ,
Toast.LENGTH_SHORT).show();
}
else if(etprice.getText().toString().equals("")){
Toast.makeText(getApplication(), "请输入任务价格" ,
Toast.LENGTH_SHORT).show();
}
else if (etphone.getText().toString().equals("")){
Toast.makeText(getApplication(), "请输入联系方式" ,
Toast.LENGTH_SHORT).show();
}
else if(etdetails.getText().toString().equals("")){
Toast.makeText(getApplication(), "请填写任务详细信息" ,
Toast.LENGTH_SHORT).show();
}
else if (etmyadress.getText().toString().equals("")){
Toast.makeText(getApplication(), "请输入任务起始地址" ,
Toast.LENGTH_SHORT).show();
}
else if(ettargetadress.getText().toString().equals("")){
Toast.makeText(getApplication(), "请输入任务目标地址" ,
Toast.LENGTH_SHORT).show();
}
else{
BmobQuery<MyTask> bmobQuery = new BmobQuery<>();
bmobQuery.findObjects(new FindListener<MyTask>(){
@Override
public void done(List<MyTask> list, BmobException e) {//统计任务总数
if (e == null){
int tidend=0;
// System.out.println("任务总数:"+sum);
//插入一条任务数据,如果将插入数据放到外面,就会先执行插入数据,不会先查询,那么tid就永远为0
//获得最后一条数据的id值
for (int i=0;i<list.size();i++){
tidend=list.get(i).getTid();
}
int sum=tidend+1;
// System.out.println("tidend="+tidend+1);
myTask.setTid(sum);
myOrderRead.setTid(sum);
//通过用户的账号查找到用户的uid
BmobQuery<MyUser> bmobQuery = new BmobQuery<>();
String bql = "select uid from MyUser where account = ? ";
bmobQuery.setSQL(bql);
bmobQuery.setPreparedParams(new Object[]{LoginActivity.uaccount});
bmobQuery.doSQLQuery(new SQLQueryListener<MyUser>() {
@Override
public void done(BmobQueryResult<MyUser> bmobQueryResult, BmobException e) {
List<MyUser> list = (List<MyUser>) bmobQueryResult.getResults();
if (list != null && list.size() > 0) {//存在一个匹配的用户
uid = list.get(0).getUid();//获得当前用户的uid
myTask.setUid(uid);
// System.out.println("当前用户的uid:" + uid);
} else {
// System.out.println("不存在当前用户的uid");
}
}
});
myTask.setTname(etname.getText().toString());
myTask.setTkind(kind);
myTask.setTprice(Double.valueOf(etprice.getText().toString()));
myTask.setTphone(Long.valueOf(etphone.getText().toString()));
// System.out.println("Long.valueOf(etphone.getText().toString())="+Long.valueOf(etphone.getText().toString()));
myTask.setTdetail(etdetails.getText().toString());
myTask.setMyaddress(etmyadress.getText().toString());
myTask.setTargetaddress(ettargetadress.getText().toString());
myTask.setTcheck(0);//任务还没有被管理员审核
//此时数据还没有存入任务表
myOrderRead.setTname(etname.getText().toString());
myOrderRead.setTorderread(0);
//此时数据还没有存入接单者消息表
// System.out.println("弹出支付方式");
payTypesDialog.show();
}
}
});
}
}
});
//在取消dialog弹窗时添加一个事件监听
payTypesDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
if (payTypesDialog.getPanduan()==1){//支付成功,刷新界面
Toast.makeText(ReleaseTask.this,"支付成功",Toast. LENGTH_LONG).show();
myTask.save(new SaveListener<String>() {//支付成功后才会将数据存入任务表
@Override
public void done(String objectId, BmobException e) {
if (e == null) {
System.out.println("发布任务成功");
} else {
Log.e("BMOB", e.toString());
System.out.println("发布任务失败");
}
}
});
myOrderRead.save(new SaveListener<String>() {
@Override
public void done(String s, BmobException e) {
if (e == null) {
System.out.println("MyOrederRead数据保存成功");
} else {
Log.e("BMOB", e.toString());
System.out.println("保存失败失败");
}
}
});
Intent intent=new Intent(ReleaseTask.this, ReleaseTask.class);
startActivity(intent);
finish();
}
else {//支付取消,维持当前状态
Toast.makeText(ReleaseTask.this,"支付取消",Toast. LENGTH_LONG).show();
payTypesDialog.cancel();
}
}
});
- 具体效果图,如下所示:
2.评价功能
长按列表,中间显示弹窗,进行评分。部分代码如下:
//获取数据,存储到Map中
SimpleAdapter simpleAdapter;
Map<String, String> mHashMap;
String tempTprice,tempTid,tempTphone,tempTkind;
List<Map<String,String>> mapList=new ArrayList<>();
List<MyTask> list = (List<MyTask>) bmobQueryResult.getResults();//查询结果
for (MyTask myTask:list){
tempTprice=String.valueOf(myTask.getTprice());
tempTid=String.valueOf(myTask.getTid());
tempTphone=String.valueOf(myTask.getTphone());
tempTkind=String.valueOf(myTask.getTkind());
mHashMap=new HashMap<>();
mHashMap.put("tname",myTask.getTname());
mHashMap.put("targetaddress",myTask.getTargetaddress());
mHashMap.put("tprice",tempTprice);
mHashMap.put("tid",tempTid);
mHashMap.put("tdetail",myTask.getTdetail());
mHashMap.put("myaddress",myTask.getMyaddress());
mHashMap.put("tphone",tempTphone);
mHashMap.put("tkind",tempTkind);
mapList.add(mHashMap);
// System.out.println("标题:"+myTask.getTname()+"目标地址:"+myTask.getTargetaddress()+"价格:"+myTask.getTprice());
}
//获取数据显示在列表中
ListView listView=findViewById(R.id.listView);
simpleAdapter=new SimpleAdapter(AppraiseActivity.this,mapList,R.layout.view_task_item_info,
new String[]{"tname","targetaddress","tprice"},
new int[]{R.id.item_tname,R.id.item_targetaddress,R.id.item_tprice});
listView.setAdapter(simpleAdapter);
simpleAdapter.notifyDataSetChanged();
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
//Bmob获取listview中某一行数据
// System.out.println("弹出任务评分");
//传入当前准备评分的任务的tid
starScoreDialog.SetTaskid(mapList.get(position).get("tid"));
starScoreDialog.show();
}
});
- 实现效果图,如下所示:
3.完成订单或取消订单
长按列表弹窗,接单者选择订单完成或取消当前进行中的订单,部分代码如下所示:
//长按订单列表,显示弹窗,选择是否已经完成当前订单,还是有特殊原因拒绝完成当前进行中的订单
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapterView, View view, int i, long l) {
//Bmob获取listview中某一行数据
// System.out.println("弹窗显示订单选择详情");
//传入当前准备评分的任务的tid
orderDialog.SetTaskid(mapList.get(i).get("tid"));
orderDialog.show();
return true;
}
});
//在取消dialog弹窗时添加一个事件监听
orderDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
//刷新当前界面
@Override
public void onDismiss(DialogInterface dialogInterface) {
Intent intent = new Intent(ViewOrderingActivity.this,ViewOrderingActivity.class);
startActivity(intent);
finish();
}
});
- 具体实现效果图,如下所示:
4.消息删除
管理员审核当前进行中的订单是否能够取消,如果同意取消当前进行中的订单,那么就会通知发单者和接单者;如果不同意取消,那么只会通知接单者,要求其继续执行当前订单。用户能够对通知的消息进行删除操作,部分代码如下:
/**记录选中item的下标*/
private List<Integer> checkedIndexList;
/**保存每个item中的checkbox*/
private List<CheckBox> checkBoxList;
private MyNotifyAdapter myNotifyAdapter;
//获取数据显示在列表中
ListView listView=findViewById(R.id.listView);
myNotifyAdapter=new MyNotifyAdapter();
listView.setAdapter(myNotifyAdapter);
checkedIndexList = new ArrayList<Integer>();
checkBoxList = new ArrayList<CheckBox>();
class MyNotifyAdapter extends BaseAdapter {
@Override
public int getCount() {
return mapList.size();
}
@Override
public Object getItem(int position) {
return mapList.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(ViewOrderAbnormalActivity.this).inflate(R.layout.view_order_abnormalitem_info, null);
holder.jiefinish_tname = (TextView) convertView.findViewById(R.id.jiefinish_tname);
holder.item_abnormaltext =(TextView) convertView.findViewById(R.id.item_abnormaltext);
holder.checkbox1=(CheckBox) convertView.findViewById(R.id.checkbox1);
checkBoxList.add(holder.checkbox1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.jiefinish_tname.setText(String.valueOf(mapList.get(position).get("tname")));
holder.item_abnormaltext.setText(String.valueOf(mapList.get(position).get("torderabnormaledetails")));
holder.checkbox1.setOnCheckedChangeListener(new CheckBox1Listener(position));
//将所有消息的checkbox设置为可见
for(int i=0;i<checkBoxList.size();i++){
checkBoxList.get(i).setVisibility(View.VISIBLE);
}
return convertView;
}
class ViewHolder {
TextView jiefinish_tname, item_abnormaltext;
CheckBox checkbox1;
}
}
class CheckBox1Listener implements CompoundButton.OnCheckedChangeListener {
int position;
public CheckBox1Listener(int position){
this.position=position;
}
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b){
checkedIndexList.add(position);
}else {
checkedIndexList.remove((Integer) position);
}
}
}
/**对checkedIndexList中的数据进行从大到小排序*/
public List<Integer> sortCheckedIndexList(List<Integer> list){
int[] ass = new int[list.size()];//辅助数组
for(int i=0;i<list.size();i++){
ass[i] = list.get(i);
}
Arrays.sort(ass);
list.clear();
for(int i=ass.length-1;i>=0;i--){
list.add(ass[i]);
}
return list;
}
//删除按钮,删除消息
public void readbutton(View v){
//先将checkedIndexList中的元素从大到小排列,否则可能会出现错位删除或下标溢出的错误
checkedIndexList = sortCheckedIndexList(checkedIndexList);
for(int i=0;i<checkedIndexList.size();i++) {
// mapList.remove((int) checkedIndexList.get(i));
// checkBoxList.remove(checkedIndexList.get(i));
//当前用户是当前订单的接单者,则修改MyOrderRead表
if (LoginActivity.uid==Integer.parseInt(mapList.get(i).get("id"))){
BmobQuery<MyOrderRead> bmobQuery=new BmobQuery<>();
String bql="select * from MyOrderRead where tid = ?";
bmobQuery.setSQL(bql);
bmobQuery.setPreparedParams(new Object[]{Integer.parseInt(mapList.get(i).get("tid"))});
bmobQuery.doSQLQuery(new SQLQueryListener<MyOrderRead>(){
@Override
public void done(BmobQueryResult<MyOrderRead> bmobQueryResult, BmobException e) {
List<MyOrderRead> list = (List<MyOrderRead>) bmobQueryResult.getResults();//查询结果
if (e==null){
Objectid=list.get(0).getObjectId();//获取bmob中默认的ObjectId值
myOrderRead.setTid(list.get(0).getTid());
myOrderRead.setId(list.get(0).getId());
myOrderRead.setTname(list.get(0).getTname());
myOrderRead.setTorderreaddetails(list.get(0).getTorderreaddetails());
myOrderRead.setTorderread(0);//表示消息已读
//更新MyOrderRead表
myOrderRead.update(Objectid, new UpdateListener() {
@Override
public void done(BmobException e) {
if (e==null){
Toast.makeText(ViewOrderAbnormalActivity.this,"已删除一条消息",Toast.LENGTH_SHORT).show();
// System.out.println("已删除一条消息");
//刷新界面
Intent intent = new Intent(ViewOrderAbnormalActivity.this,ViewOrderAbnormalActivity.class);
startActivity(intent);
finish();
}
}
});
}
}
});
}
else {//那么此时用户是该订单的发单者并且没有接单者权限,修改MyTask表
BmobQuery<MyTask> bmobQuery=new BmobQuery<MyTask>();
String bql = "select * from MyTask where tid = ?";
bmobQuery.setSQL(bql);
bmobQuery.setPreparedParams(new Object[]{Integer.parseInt(mapList.get(i).get("tid"))});
bmobQuery.doSQLQuery(new SQLQueryListener<MyTask>(){
@Override
public void done(BmobQueryResult<MyTask> bmobQueryResult, BmobException e) {
List<MyTask> list = (List<MyTask>) bmobQueryResult.getResults();//查询结果
if (e==null){
Objectid=list.get(0).getObjectId();//获取bmob中默认的ObjectId值
myTask.setUid(list.get(0).getUid());
myTask.setTid(list.get(0).getTid());
myTask.setId(list.get(0).getId());
myTask.setTname(list.get(0).getTname());
myTask.setTkind(list.get(0).getTkind());
myTask.setTphone(list.get(0).getTphone());
myTask.setTprice(list.get(0).getTprice());
myTask.setTdetail(list.get(0).getTdetail());
myTask.setMyaddress(list.get(0).getMyaddress());
myTask.setTargetaddress(list.get(0).getTargetaddress());
myTask.setTcheck(1);//任务审核
myTask.setTorder(list.get(0).getTorder());
myTask.setTordercheck(0);//置0
myTask.update(Objectid,new UpdateListener(){
@Override
public void done(BmobException e) {
if (e == null) {
Toast.makeText(ViewOrderAbnormalActivity.this,"已删除一条消息",Toast.LENGTH_SHORT).show();
// System.out.println("已删除一条消息");
//刷新界面
Intent intent = new Intent(ViewOrderAbnormalActivity.this,ViewOrderAbnormalActivity.class);
startActivity(intent);
finish();
}
}
});
}
}
});
}
}
for(int j=0;j<checkBoxList.size();j++){
//将已选的设置成未选状态
checkBoxList.get(j).setChecked(false);
//将checkbox设置为不可见
checkBoxList.get(j).setVisibility(View.INVISIBLE);
}
- 具体效果实现图,如下所示: