The effect of wechat applet
1: Wechat code
(2)wxxml
<view class="container-body container-gray" style="display:{{showfootertab==0?'block':'none'}}"> <form bindsubmit="evaSubmit"> <view class="group"> <view class="group-header">Problem description</view> <view class="group-body"> <textarea name="evaContent" maxlength="500" value="{{evaContent}}" class="weui-textarea" placeholder="Fill in content(12-500 word)" bindblur="charChange" /> </view> <view class="group-header">Upload pictures</view> <view class="group-body"> <view class="img-upload"> <view class="img-add" bindtap="chooseImage"></view> <view class="img-item" name="img" bindlongtap="editImage" wx:for="{{uploadimgs}}" wx:key="{{index}}"> <icon type="clear" size="20" color="red" style="display:{{editable?'block':'none'}}" bindtap="deleteImg" data-index="{{index}}"/> <image src="{{item}}" mode="aspectFill"></image> </view> </view> </view> </view> <button formType="submit" disabled="{{subdisabled}}" class="btn-block btn-orange" type="primary" size="mini">Submission</button> </form> <view class="question-text"> <text>If the problem cannot be described clearly</text> <text>Can make direct calls</text> <text>We will answer your questions as soon as possible</text> <view bindtap="callContact" data-phonenumber="400-1234-567">***********</view> </view> </view>
(2) wxjs (here is the key point, you need to take a serious look)
var app = getApp() Page({ data: { showtabtype: '', //Selected type showfootertab: 0, //Bottom tab index tabnav: {}, //Top tab data questionsall: [], //All questions questions: [], //List of questions showquestionindex: null, //View the problem index, uploadimgs: [], //Upload picture list editable: false //Editable or not }, onLoad: function () { }, chooseImage: function () { let _this = this; wx.showActionSheet({ itemList: ['Choose from album', 'Photograph'], itemColor: "#f7982a", success: function (res) { if (!res.cancel) { if (res.tapIndex == 0) { _this.chooseWxImage('album') } else if (res.tapIndex == 1) { _this.chooseWxImage('camera') } } } }) }, chooseWxImage: function (type) { let _this = this; wx.chooseImage({ sizeType: ['original', 'compressed'], sourceType: [type], success: function (res) { const tempFilePaths = res.tempFilePaths app.globalData.filepath = res.tempFilePaths _this.setData({ uploadimgs: _this.data.uploadimgs.concat(res.tempFilePaths) }) //Picture upload wx.uploadFile({ url: 'http://localhost:8080/lg/test/upload ', / / upload the photo to the backend and return the name and format of the photo. This step does not really put the data into the database filePath: tempFilePaths[0], name: 'file', success: function (res) { var s = res.data console.log(s) console.log(s.length) var s1 = s.length - 21 var rs = s.slice(8, s1) console.log(rs) wx.setStorageSync("picturepath", rs) }, fail: function (err) { console.log(err.data) } }) } }) }, //Event / / obtain the content of the complaint textBlur: function (e) { if (e.detail && e.detail.value.length > 0) { if (e.detail.value.length < 12 || e.detail.value.length > 500) { //app.func.showToast('content is 12-500 characters', 'loading',1200); } else { this.setData({ evaContent: e.detail.value }); } } else { this.setData({ evaContent: '' }); evaData.evaContent = ''; app.func.showToast('Please enter the complaint', 'loading', 1200); } }, //Submission of events evaSubmit: function (eee) { var utel = wx.getStorageSync("utel") //Determine whether to log in if (!utel) { wx.showModal({ title: 'Tips', content: 'Operation after login', }) } else { var tel = wx.getStorageSync("utel") var content = eee.detail.value.evaContent//Content of complaint const picture = wx.getStorageSync("picturepath")//Name and format of photo //Real data into the database wx.request({ url: 'http://localhost:8080/lg/Complain/edit_handle', data: { ttel:tel, tcontent: content, tpiac: picture }, success: function (res) { var mess = res.data.msg console.log(mess) if (mess === "Successful operation") { wx.showModal({ title: 'Feedback success', content: 'success', }) } else { wx.showModal({ title: 'Feedback failure' }) } } }) } //Submit (custom get method) } })
(3) wxcss (for direct replication)
.question-text{ padding: 20rpx; text-align: center; } .question-text text{ display: block; color: #888; font-size: 28rpx; } .question-text view{ font-size: 48rpx; color: #f7982a; } .footer-tab{ display: flex; width: 100%; border-top: 1rpx solid #ddd; } .footer-tab .footer-tab-item{ flex: 1; text-align: center; } .footer-tab-widthicon image{ width: 44rpx; height: 44rpx; display: block; margin: 10rpx auto 0; } .footer-tab-item text{ font-size: 24rpx; color: #888; } .footer-tab-item.active text{ color: #f7982a; } .tab{ display: flex; flex-direction: column; height: 100%; } .tab-nav{ height: 80rpx; background: #fff; border-bottom: 1rpx solid #ddd; display: flex; line-height: 79rpx; position: relative; } .tab-nav text{ display: block; flex: 1; text-align: center; width: 25%; } .tab-nav text.active{ color: #f7982a; } .tab-line{ position: absolute; left: 0; bottom: -1rpx; height: 4rpx; background: #f7982a; transition: all 0.3s; } .tab-content{ flex: 1; overflow-y: auto; overflow-x: hidden; } .question-list{ padding: 20rpx; } .question-item{ background: #fff; margin-bottom: 20rpx; border-bottom: 1rpx solid #ddd; } .question-item-q{ padding: 20rpx; background: #cecece; padding-left: 80rpx; padding-right: 70rpx; position: relative; line-height: 1.2; color: #fff; } .question-item-q:before, .question-item-a:before{ content: 'Q'; display: block; width: 50rpx; height: 50rpx; border-radius: 50%; background: #f97c29; font-size: 34rpx; text-align: center; line-height: 50rpx; position: absolute; left: 20rpx; top: 14rpx; } .question-item-a{ padding: 0 20rpx; padding-left: 80rpx; position: relative; line-height: 1.4; color: #666; } .question-item-a.active{ background: #f7982a; } .question-item-a:before{ content: 'A'; background: #f7982a; color: #fff; top: 0; } .question-item .question-item-a{ display: -webkit-box; -webkit-line-clamp: 2; overflow: hidden; text-overflow: ellipsis; -webkit-box-orient: vertical; margin: 20rpx 0; } .question-item.active .question-item-q{ background: #f97c29; } .question-item.active .question-item-a{ -webkit-line-clamp: inherit; } /**app.wxss**/ /**app.wxss**/ page{ height: 100%; color: #333; display: flex; flex-direction: column; font: normal 30rpx/1.68 -apple-system-font, 'Helvetica Neue', Helvetica, 'Microsoft YaHei', sans-serif; } .container { flex: 1; display: flex; flex-direction: column; box-sizing: border-box; } .container-body{ flex: 1; overflow-y: auto; overflow-x: hidden; } .container-footer{ width: 100%; display: flex; height: 88rpx; border-top: 1rpx solid #ddd; background: #fff; } .container-footer text{ flex: 1; display: block; text-align: center; height: 88rpx; line-height: 88rpx; font-size: 34rpx; border-left: 1rpx solid #ddd; } .container-footer text:first-child{ border-left: none; } .container-footer .btn-block{ border-radius: 0; } .container-footer .btn-block:after{ border: none; } .container-gray{ background: #f9f9f9; } input{ height: 60rpx; line-height: 60rpx; font-family: inherit; } .input-list{ padding: 0 20rpx; margin: 20rpx 0; background: #fff; border-top: 1rpx solid #ddd; border-bottom: 1rpx solid #ddd; } .input-list .input-item{ padding: 20rpx; line-height: 2; display: flex; font-size: 30rpx; border-top: 1rpx solid #e8e8e8; } .input-list .input-item:first-child{ border-top: 0; } .input-item-label{ display: block; width: 5em; color: #666; } .input-item-content{ color: #333; flex:1; } .input-item.input-item-full{ display: block; } .input-item.input-item-full .input-item-label{ width: 100%; } .input-item.input-item-full .input-item-content{ width: 100%; } .input-item.input-item-full textarea{ padding: 0; height: 150rpx; border: 1rpx solid #e8e8e8; padding: 10rpx; } .input-item.input-item-full .img-upload{ padding: 0; } .input-item.input-item-adaption .input-item-label{ width: auto; margin-right: 20rpx; } button{ font-size: 32rpx; line-height: 72rpx; } textarea{ width: 100%; padding: 20rpx; box-sizing: border-box; } radio-group radio{ position:absolute; left: -999em; } radio-group label{ margin-right: 16rpx; } radio-group label:before{ content: ''; display: inline-block; width: 40rpx; height: 40rpx; vertical-align: -8rpx; margin-right: 4rpx; } .btn-submit{ padding: 20rpx; } .btn-block{ width: 100%; line-height: 88rpx; } .btn-orange{ background: #f7982a; color: #fff; } .btn-gray{ background: #e8e8e8; color: #333; } .search-flex{ display: flex; padding: 20rpx; border-bottom: 1rpx solid #ddd; position: relative; z-index: 13; background: #f9f9f9; /* transform: translateY(-100%); */ margin-top: 0; transition: all 0.3s; } .search-flex.tophide{ margin-top: -117rpx; } .search-flex button{ background: #f7982a; color: #fff; line-height: 72rpx; height: 72rpx; font-size: 30rpx; border-radius: 6rpx; } .search-bar{ flex: 1; display: flex; border: 1rpx solid #e8e8e8; border-radius: 6rpx; } .search-bar input{ flex: 1; height: 72rpx; line-height: 72rpx; padding: 0 10rpx; background: #fff; } .search-extra-btn{ margin-left: 20rpx; white-space: nowrap; } .filter-tab{ display: flex; width: 100%; line-height: 80rpx; border-bottom: 1rpx solid #ddd; position: relative; z-index: 2; background: #fff; } .filter-tab text{ flex: 1; text-align: center; } .filter-tab text:after{ content: ''; display: inline-block; vertical-align: 4rpx; width: 0; height: 0; border-left: 12rpx solid transparent; border-right: 12rpx solid transparent; border-top: 12rpx solid #bbb; margin-left: 8rpx; } .filter-tab text.active{ color: #f7982a; } .filter-tab:not(.sort-tab) text.active:after{ border-top: 0; border-bottom: 12rpx solid #f7982a; } .filter-tab.sort-tab text.active:after{ border-top: 12rpx solid #f7982a; } .filter-panel{ display: flex; background: #f5f5f5; position: absolute; width: 100%; z-index: 13; overflow: hidden; } .filter-panel-left,.filter-panel-right{ flex: 1; line-height: 80rpx; text-align: center; max-height: 480rpx; overflow-y: auto; } .filter-panel-left .active{ background: #fff; } .filter-panel-right .active{ color: #f7982a; } .filter-panel-right{ background: #fff; } .filter-panel-right:empty{ display: none; } .filter-shadow{ position: absolute; width: 100%; top: 0; bottom: 0; z-index: 1; background: rgba(0,0,0,.5); } .gototop{ width: 70rpx; height: 70rpx; position: fixed; bottom: 20rpx; right: 20rpx; transition: all 0.3s; opacity: 0; transform: translateY(200rpx); } .gototop.active{ opacity: 1; transform: translateY(0); } .group{ display: block; width: 100%; } .group-header{ line-height: 70rpx; display: flex; padding: 0 20rpx; background: #f9f9f9; } .group-body{ background: #fff; border-top: 1rpx solid #ddd; border-bottom: 1rpx solid #ddd; } .group-body .input-list{ margin: 0; border: none; } .img-upload{ padding: 20rpx; font-size: 0; overflow: hidden; } .img-upload .img-add{ width: 100rpx; height: 100rpx; float: left; margin: 10rpx; border: 1rpx solid transparent; } .img-upload .img-add{ border: 1rpx dashed #ddd; } .img-upload .img-item image{ width: 100rpx; height: 100rpx; } .img-upload .img-item{ position: relative; } .img-upload .img-item icon{ position: absolute; right: -12rpx; top: -12rpx; } .container { height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: space-between; padding: 200rpx 0; box-sizing: border-box; } /* pages/problem/problem.wxss */
2: ssm background processing
(1) Photo upload processing (photo upload, that is, when you select a photo, you need to process it and put it into the project folder)
@Controller public class uploadeController { @RequestMapping("test/upload") @ResponseBody public JSONObject upload(@RequestParam MultipartFile[] file,String id, HttpServletRequest request){ String[] path = uploadfile.uploadfile(file, request); HashMap<String, Object> map = new HashMap<String, Object>(); if(path.equals("error")){ map.put("status", "error"); }else{ map.put("url",path[1]); map.put("status","success"); } JSONObject json=JSONObject.fromObject(map); return json; } }
A method String[] path = uploadfile.uploadfile(file, request) is called here;
The code is as follows
public static String[] uploadfile(MultipartFile[] files,HttpServletRequest request){ String dir = request.getSession().getServletContext().getRealPath("/picturefile"); //String dir = "C:\\nodejs\\app\\mini2048\\static"; //String dir = "D:\\static"; String[] b = null; for (MultipartFile file : files){ // System.out.println("file type:" + file.getContentType()); String filename = file.getOriginalFilename(); String suffix = filename.substring(filename.lastIndexOf(".")); //String suffix = filename.substring(filename.length() - 3); // System.out.println("filename:" + filename); // System.out.println("file suffix:" + suffix); // System.out.println("file size:" + file.getSize()/1024+"KB"); String path = filename; //Create a path to save the file String time = new Date().getTime()+"."+suffix; String[] a = {path,time}; File dirFile = new File(dir,time); if (!dirFile.exists()){ dirFile.mkdirs(); } try { //Write file to created path file.transferTo(dirFile); return a; } catch (IOException e) { e.printStackTrace(); } } return b; } }
(2) Receive data put data into database
(the name and format of the photo and the content of the complaint are displayed)
@RequestMapping(value="Complain/edit_handle") @ResponseBody public JSONObject Complainedit(Complain complain) { int ret = 0; if(complain.getTid() == null || complain.getTid() == 0) { complain.setTstatus(1); ret=complainService.insertSelective(complain); }else { ret=complainService.updateByPrimaryKeySelective(complain); } Map<String, String> map = new HashMap<String, String>(); if(ret>0){ map.put("status","succ"); map.put("msg","Successful operation"); }else{ map.put("status","error"); map.put("msg","operation failed"); } JSONObject json = JSONObject.fromObject(map); return json; }
3: ssm backend echo
<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <jsp:include page="../header.jsp"/> <jsp:include page="../menu.jsp"/> <div class="tpl-content-wrapper"> <div class="tpl-portlet-components"> <div class="portlet-title"> <div class="caption font-green bold"> <span class="am-icon-code"></span> Complaint management </div> <div class="tpl-portlet-input tpl-fz-ml"> <div class="portlet-input input-small input-inline"> <div class="input-icon right"> <input type="hidden" class="form-control form-control-solid" placeholder="search..."> </div> </div> </div> </div> <div class="tpl-block"> <div class="am-g"> <div class="am-u-sm-12 am-u-md-6"> </div> <div class="am-u-sm-12 am-u-md-3"> </div> <div class="am-u-sm-12 am-u-md-3"> <div class="am-input-group am-input-group-sm"> </div> </div> <div class="am-g"> <div class="am-u-sm-12"> <table class="am-table am-table-striped am-table-hover table-main"> <thead> <tr> <th class="table-title">picture</th> <th class="table-title">content</th> <th class="table-title">Telephone number of complainer</th> <th class="table-title">current state</th> <th class="table-type">operation</th> </tr> </thead> <tbody> <c:forEach items="${complainlist}" var="item"> <tr> <td><img src="picturefile/${item.tpiac}" width="50px;" height="50px;"></td> <td>${item.tcontent}</td> <td>${item.ttel}</td> <td> <c:if test="${item.tstatus==1}"> //Untreated </c:if> <c:if test="${item.tstatus==2}"> //Processing completed </c:if> </td> <td> <c:if test="${item.tstatus==1}"> <button type="button" class="am-btn am-btn-default am-btn-xs am-text-secondary" onclick="updatebyid(${item.tid},2);"> <span class="am-icon-pencil-square-o"></span> Handle </button> </c:if> <button type="button" class="am-btn am-btn-default am-btn-xs am-text-secondary" onclick="deletebyid(${item.tid});"> <span class="am-icon-pencil-square-o"></span> delete </button> </td> </tr> </c:forEach> </tbody> </table> </div> </div> </div> <div class="tpl-alert"></div> </div> </div> </div> <script type="text/javascript"> function deletebyid(id){ layer.confirm("Delete",{ icon:1, skin:'layui-layer-lan', btn:['Determine','cancel'] },function(){ var url = "Complain/deleteComplain"; var data = {}; data["tid"] = id; fajax(url,data,deletecallback); },function(){ }) } function deletecallback(data){ if(data.status == "succ"){ layer.confirm("Successfully deleted",{ icon:1, skin:'layui-layer-lan', btn:['Determine'] },function(){ window.location.href = "culturalHeritage/list"; }) }else{ alert("Undeleted"); } } function updatebyid(id,stat){ layer.confirm("Processed or not",{ icon:1, skin:'layui-layer-lan', btn:['Determine','cancel'] },function(){ var url = "Complain/edit_handle"; var data = {}; data["tid"] = id; data["tstatus"]=stat; fajax(url,data,deletecallback); },function(){ }) } function deletecallback(data){ if(data.status == "succ"){ layer.confirm("Processed successfully",{ icon:1, skin:'layui-layer-lan', btn:['Determine'] },function(){ window.location.href = "Complain/findAll"; }) }else{ alert("Undeleted"); } } /* function select_handle(){ var index=layer.load(1, {shade: [0.5,'#000']}); window.location.href='city/list?chName='+$('#anTitle').val(); } */ </script> <jsp:include page="../footer.jsp"/>