余菲 9 місяці тому
джерело
коміт
ca6283dc66
5 змінених файлів з 600 додано та 0 видалено
  1. +12
    -0
      api/report.js
  2. +301
    -0
      package_A/pages/report-page/index.js
  3. +5
    -0
      package_A/pages/report-page/index.json
  4. +50
    -0
      package_A/pages/report-page/index.wxml
  5. +232
    -0
      package_A/pages/report-page/index.wxss

+ 12
- 0
api/report.js Переглянути файл

@@ -0,0 +1,12 @@
const {request} = require("../request/index")
/**
* 上报
* @param {*} data
*/
export const applyReport = function (data) {
return request({
url: '/westreamSubmit/report',
method: 'POST',
data
})
}

+ 301
- 0
package_A/pages/report-page/index.js Переглянути файл

@@ -0,0 +1,301 @@
// package_A/pages/report-page/index.js
import {getOssAuth} from '../../../api/uploadOss.js'
import {applyReport} from '../../../api/report.js'
import {Base64} from 'js-base64'
import {isNoCharacters} from '../../../utils/check.js'
const crypto = require('crypto-js')
Page({

/**
* 页面的初始数据
*/
data: {
checkAgree: false, // 是否勾选用户协议
form: {},
ossForm: {},
imagePreviewList: [], // 上传图片预览列表
imageList: [], // 图片列表
// 表单验证
formRules: {
location: {
validator: function (value) {
return value;
},
warning: false
},
problemDesc: {
validator: function (value) {
return value && isNoCharacters(value);
},
warning: false
},
imageList: {
validator: function (value) {
return value.length!=0;
},
warning: false
}
}
},

/**
* 生命周期函数--监听页面加载
*/
onLoad: function () {
},


/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
this.getOssAuthForm()
const openid = wx.getStorageSync('openid')
let form = this.data.form
form.openid = openid
this.setData({form})
},
bindValue(e) {
let name = e.currentTarget.dataset.name;
let form = this.data.form;
form[name] = e.detail.value;
this.setData({
form,
})
this.validate(name, e.detail.value)
},
validate(name) {
let formRules = this.data.formRules;
let validator = formRules[name].validator
let result
if(name === 'imageList') {
result = validator ? !validator(this.data.imageList) : false
} else {
result = validator ? !validator(this.data.form[name]) : false;
}
formRules[name].warning = result
this.setData({formRules})
return result
},
validateForm() {
return new Promise((resolve, reject) => {
try {
let formRules = this.data.formRules;
let result = false;
for (let key in formRules) {
let temp = this.validate(key)
if (temp) {
result = temp
}
}
resolve(!result)
} catch (e) {
reject(e)
}
})
},
/* 获取图片上传鉴权 */
getOssAuthForm() {
let that = this
getOssAuth().then((res)=> {
let client = {
region: 'oss-cn-shanghai',
secure: true,
accessKeyId: res.accessKeyId,
accessKeySecret: res.accessKeySecret,
securityToken: res.securityToken,
bucket: 'ta-tech-image'
}
// 计算签名
function computeSignature(accessKeySecret, canonicalString) {
return crypto.enc.Base64.stringify(crypto.HmacSHA1(canonicalString, accessKeySecret));
}
const date = new Date();
date.setHours(date.getHours() + 1);
const policyText = {
expiration: date.toISOString(), // 设置policy过期时间。
conditions: [
// 限制上传大小。
["content-length-range", 0, 1024 * 1024 * 1024],
],
};
// 获取签名
const policy = Base64.encode(JSON.stringify(policyText)) // policy必须为base64的string。
const signature = computeSignature(client.accessKeySecret, policy)
let ossForm = that.data.ossForm
ossForm = {
OSSAccessKeyId: client.accessKeyId,
signature,
policy,
SecurityToken: client.securityToken
}
that.setData({ossForm})
})
},
/* 上传图片 */
uploadImage(){
wx.chooseMedia({
count: 5 - this.data.imageList.length, // 最多可以选择的图片张数,默认9
mediaType: ['image'], // 图片
sizeType: ['original'], // original 原图,compressed 压缩图,默认二者都有
sourceType: ['album', 'camera'], // album 从相册选图,camera 使用相机,默认二者都有
success:(res) =>{
const list = res.tempFiles.map((item)=> {
return item.tempFilePath
})
// success
let imagePreviewList = this.data.imagePreviewList.concat(list)
let imageList = this.data.imageList.concat(list);
this.setData({ imageList, imagePreviewList })
this.validate('imageList')
},
fail: (e) => {
console.log(e);
}
})
},
// 删除图片
deleteImage(e) {
let index = this.getCurrentData(e);
let imageList = this.data.imageList
imageList.splice(index, 1)
let imagePreviewList = this.data.imagePreviewList
imagePreviewList.splice(index, 1)
this.setData({ imageList, imagePreviewList })
this.validate('imageList')
},
getCurrentData(e) {
return e.currentTarget.dataset.current;
},

/**
* 选择位置
*/
selectLocation() {
let location = wx.getStorageSync('location')
wx.chooseLocation({
latitude: location.latitude,
longitude: location.longitude,
success: (res)=>{
let form = this.data.form
form.location = res.address
form.latitude = res.latitude
form.longitude = res.longitude
this.setData({form})
this.validate('location')
},
fail(e) {
console.log(e);
}
})
},
/**
* 同意用户协议
*/
checkBoxChange() {
let checkAgree = this.data.checkAgree
this.setData({
checkAgree: !checkAgree
})
},
// 用户服务协议
showAgree() {
wx.navigateTo({
url: '/package_A/pages/agree/index',
})
},
// 隐私政策
showConceal() {
wx.navigateTo({
url: '/package_A/pages/conceal/index',
})
},
/**
* 图片上传到oss
*/
/* 表单上传 */
submit(){
if(this.data.checkAgree) {
this.validateForm().then(res => {
if(res) {
let ossForm = this.data.ossForm
let temp = []
if (this.data.imageList.length > 0) {
wx.showLoading({title:"上传中",mask:true})
temp = this.data.imageList.map(item => {
// 设置文件上传路径
const randomString = Math.random().toString(36).slice(2)
const timestamp = new Date().getTime()
const key = `imagedir/${randomString}_${timestamp}.png`
// 上传图片
return new Promise((resolve, reject)=> {
wx.uploadFile({
url: 'https://ta-tech-image.oss-cn-shanghai.aliyuncs.com',
filePath: item,
name: 'file',
formData: {
key,
OSSAccessKeyId: ossForm.OSSAccessKeyId,
signature: ossForm.signature,
policy: ossForm.policy,
'x-oss-security-token': ossForm.SecurityToken
},
success: (res)=> {
if(res.statusCode === 204) {
// 上传成功,将图片路径resolve出去
resolve(key)
} else {
wx.showToast({
title: '图片上传失败',
})
reject('图片上传失败')
}
},
fail: (e)=> {
console.log(e);
reject('图片上传失败')
}
})
})
})
Promise.all(temp).then((res)=> {
let form = this.data.form
form.photoUrl = res.join(',')
applyReport(form).then(res => {
if (res.code === 0) {
wx.showModal({
title: '上报成功',
confirmColor: '#3175E8',
showCancel: false,
content: '等待审核,审核通过后就可以获得积分。',
success(res) {
if(res.confirm) {
wx.navigateBack()
}
}
})
}
}).finally(()=>{
wx.hideLoading();
})
}).catch(()=> {
wx.hideLoading()
})
}
}
})
} else {
wx.showToast({
icon: 'none',
title: '请先勾选用户服务协议以及隐私政策!',
})
}
}
})

+ 5
- 0
package_A/pages/report-page/index.json Переглянути файл

@@ -0,0 +1,5 @@
{
"usingComponents": {},
"navigationBarTitleText": "我要上报",
"navigationBarBackgroundColor": "#008CFF"
}

+ 50
- 0
package_A/pages/report-page/index.wxml Переглянути файл

@@ -0,0 +1,50 @@
<!--package_A/pages/report-page/index.wxml-->
<view class="upload_container">
<image class="head_img" mode="widthFix" src="../../img/want_report.png"></image>
<view class="form_container">
<!-- 河道信息 -->
<view class="info_box">
<view class="box_title">河道信息</view>
<view class="form_item {{formRules.location.warning ? 'warning' : ''}}">
<text><text style="color: red;">* </text>问题位置</text>
<view class="value_box" bindtap="selectLocation">
<text class="picker_text" wx:if="{{form.location}}">{{form.location}}</text>
<text style="color: #a6a6a6;font-size: 28rpx;" wx:else>请选择问题位置</text>
<image src="../../../assets/img/location.png" style="width:54rpx;height:54rpx;position: absolute;right: 0rpx;top: 7rpx;z-index: 99;"></image>
</view>
<text class="tips">请选择问题位置</text>
</view>
<view class="use_purpose {{formRules.problemDesc.warning ? 'warning' : ''}}">
<text><text style="color: red;">* </text>问题描述</text>
<textarea maxlength="500" style="width:620rpx; height: 120rpx;padding: 20rpx;" type="text" adjust-position="{{true}}" placeholder="请输入问题描述" placeholder-style="font-size: 28rpx; color: #A6A6A6;" value="{{form.problemDesc}}" data-name="problemDesc" name="problemDesc" bindblur="bindValue" />
<text class="tips">请输入问题描述</text>
</view>
<view class="upload_images {{formRules.imageList.warning? 'warning': ''}}">
<text><text style="color: red;">* </text>上传图片</text>
<view class="image_list">
<view class="image_preview" wx:for="{{imagePreviewList}}" wx:key="index">
<image class="image_item" src="{{item}}" mode="aspectFill" data-item="{{item}}">
</image>
<div class="close" data-current="{{index}}" catchtap="deleteImage"></div>
</view>
<view class="upload_image" bindtap="uploadImage" wx:if="{{imageList.length<5}}">
<image style="height: 53rpx;width: 53rpx;margin-bottom: 27rpx;" mode="widthFix" src="../../../assets/img/open_upload.png"></image>
<text style="font-size: 28rpx;">上传图片</text>
</view>
</view>
<text class="tips">请上传图片</text>
</view>
</view>

<view class="safe_box">
<label class="checkbox" bindtap="checkBoxChange">
<checkbox value="{{checkAgree}}" /><text>同意</text>
</label>
<text style="color: #2a82e4;" bindtap="showAgree">《用户服务协议》</text>和<text style="color: #2a82e4;" bindtap="showConceal">《隐私政策》</text>
</view>
<!-- 按钮 -->
<view class="{{ checkAgree ? 'btn_item submit_btn' : 'btn_item'}}" bindtap="submit">上报</view>
</view>


</view>

+ 232
- 0
package_A/pages/report-page/index.wxss Переглянути файл

@@ -0,0 +1,232 @@
/* package_A/pages/report-page/index.wxss */
.upload_container {
width: 100%;
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
position: relative;
background-color: #f8f8f8;
}
.head_img {
width: 100vw;
}
.form_container {
width: 100%;
margin-top: -300rpx;
padding: 30rpx;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
}
.info_box {
width: 100%;
padding: 30rpx 27rpx;
margin-bottom: 40rpx;
background-color: #FFFFFF;
border-radius: 20rpx;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
font-size: 28rpx;
color: #6F6F6F;
}
.box_title {
width: 100%;
margin-bottom: 30rpx;
font-size: 30rpx;
color: #000000;
font-weight: bold;
}
.form_item {
width: 100%;
padding: 15rpx 0;
/* margin-bottom: 30rpx; */
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
font-size: 28rpx;
color: #666666;
border-top: 1rpx solid #EDEDED;
}
.use_purpose {
width: 100%;
padding: 25rpx 0;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
position: relative;
font-size: 28rpx;
color: #666666;
border-top: 1rpx solid #EDEDED;
}
.value_box {
width: 460rpx;
min-height: 68rpx;
padding: 0 50rpx 0 10rpx;
display: flex;
justify-content: flex-end;
align-items: center;
border-radius: 4rpx;
position: relative;
color: #333333;
font-size: 28rpx;
text-align: end;
}
.picker_text {
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.disable_class {
border: none;
color: #006DF7;
}
.tips{
position: absolute;
bottom: -32rpx;
left: -13rpx;
color: red;
font-size: 24rpx;
transform: translate(27rpx, -5rpx);
display: none;
}
.form_item.warning .tips, .use_purpose.warning .tips, .upload_images.warning .tips{
display: block;
}

/* 上传图片 */
.upload_images {
width: 100%;
padding: 25rpx 0;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
font-size: 28rpx;
color: #666666;
position: relative;
border-top: 1rpx solid #EDEDED;
}
.image_list {
width: 500rpx;
margin-top: 30rpx;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
align-content: flex-start;
}
.image_preview {
height: 200rpx;
width: 200rpx;
margin-right: 20rpx;
margin-bottom: 20rpx;
position: relative;
}
.image_item {
height:100%;
width: 100%;
margin-bottom: 20rpx;
margin-right: 30rpx;
border-radius: 10rpx;
}
.close{
position: absolute;
top:0;
right:0;
transform: translate(40%,-40%);
height:50rpx;
width:50rpx;
background:rgba(179, 179, 179, 0.5);
border-radius: 50%;
z-index: 10;
}
.close::before{
content: "";
display: block;
position: absolute;
width: 60%;
height: 6rpx;
top:50%;
left:50%;
background:rgb(124, 124, 124);
transform-origin: center;
transform: translate(-50%,-50%) rotate(45deg);
}
.close::after{
content: "";
display: block;
position: absolute;
width: 60%;
height: 6rpx;
top:50%;
left:50%;
background:rgb(124, 124, 124);
transform-origin: center;
transform: translate(-50%,-50%) rotate(-45deg);
}
.upload_image {
width: 200rpx;
height: 200rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 10rpx;
background-color: #FBFBFB;
border: 1px dashed #CECECE;
}

.upload_image text {
color: rgba(0, 0, 0, 0.5);
font-size: 30rpx;
}
.note_mark {
margin-top: 20rpx;
font-size: 24rpx;
color: rgba(153, 153, 153, 1);
}

/* 按钮区 */
.btn_item {
width: 100%;
height: 80rpx;
margin-bottom: 30rpx;
border-radius: 40rpx;
text-align: center;
line-height: 80rpx;
font-size: 32rpx;
color: #6F6F6F;
background-color: #EEEEEE;
}

.submit_btn {
color: #ffffff;
background-color: #2a82e4;
}
/* 用户协议确认框 */
.safe_box {
width: 100%;
margin-top: 110rpx;
margin-bottom: 30rpx;
display: flex;
justify-content: flex-start;
align-items: center;
font-size: 26rpx;
color: #959595;
}
.checkbox {
display: flex;
justify-content: flex-start;
align-items: center;
}
checkbox {
transform: scale(0.8);
}

Завантаження…
Відмінити
Зберегти