init

parents
/node_modules/
/unpackage/dist
.idea
\ No newline at end of file
{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
"version": "0.0",
"configurations": [{
"default" :
{
"launchtype" : "local"
},
"mp-weixin" :
{
"launchtype" : "local"
},
"type" : "uniCloud"
}
]
}
<script>
import { MINI, LOGIN_ACTION, ENV_MODEL, TokenPrefix } from './publicConfig/config.js'
const loginBehavior = require('./mixins/loginBehavior.js')
// #ifdef H5
import VConsole from 'vconsole'; //引入H5调试工具
// #endif
export default {
mixins: [loginBehavior],
onLaunch: function() {
this.judgePlatform(); //判断运行平台,仅初始化时执行
},
globalData: {
cacheUserInfo: {},//用户信息
projectMini: '', //项目名
loginAction: '', //登录Action
userLocation: {},
cacheUserLocation: {}, //用户地址位置信息缓存,含经、纬度地址描述等
transferAddress: {}, //中转地址 中转操作时更新
shipmentInfo: { //运单信息 查看运单详情时进行修改
shipmentId: "", //运单id
shipmentBizName: "", //运单对象名 路由跳转详情时赋值
shipmentNo: '', //运单号
truckName: '' //车牌号
},
stopsInfo: { //站点信息 查看站点详情时修改
locationId: '',
loadStop: '', //是否装货站点
unloadStop: '', //是否卸货站点
locationName: '', //站点名称
locationAddress: '', //站点地址
locationOrders: '', //订单数
locationQty: '', //件数数
locationWeight: '', //重量
locationVolume: '', //体积
},
backPagePath: '', //回退页面路径,含完整参数
serviceProvider: 'AMap' ,//地图服务商,默认为高德地图
MapIns: null , //地图实例, 默认在Index首页初始化, mxins下getUserLocation中赋值
},
methods: {
//判断平台
judgePlatform() {
//项目是否为H5 条件编译,代码块仅判断成功才运行
//#ifdef H5
if (process.env.NODE_ENV === 'development') { //HBuilderX中,点击运行是--开发环境,点击发行是--生产环境
this.globalData.projectMini = MINI.h5Dev
const vConsole = new VConsole(); //H5实例化调试工具,工具git地址:https://github.com/Tencent/vConsole
} else { //生产环境区分,默认生产PROD
switch(ENV_MODEL.model){
case 'UAT':
this.globalData.projectMini = MINI.h5Uat
break;
default:
this.globalData.projectMini = MINI.h5Prod
}
}
this.globalData.loginAction = LOGIN_ACTION.h5
this.isRunningWxBrowser()
//#endif
//项目是否为小程序 MP代表所有小程序 MP-WEIXIN:微信小程序
//#ifdef MP
this.globalData.projectMini = MINI.wxApp
this.globalData.loginAction = LOGIN_ACTION.wxApp
this.getWxToken()
//#endif
},
//判断是否运行于微信环境
isRunningWxBrowser() {
if (this.isWxBrowser()) {
const { code, time } = this.getH5Code()
if (code) {
this.login(code)
}
} else {
this.globalData.projectMini = MINI.web
this.login('')
}
},
//判断是否为微信浏览器
isWxBrowser(){
let ua = window.navigator.userAgent.toLowerCase() //判断浏览器类型, 包含浏览器类型、版本、操作系统类型、浏览器引擎类型等信息
return ua.match(/MicroMessenger/i) == 'micromessenger'
}
}
}
</script>
<style lang="scss">
@import "uview-ui/index.scss";
@import "static/iconfont/iconfont-weapp-icon.css";
/*每个页面公共css */
// 设置整个项目的背景色
page,
view {
margin: 0;
padding: 0;
font-family: PingFangSC-Regular, PingFang SC !important; //苹方简体
}
page,
view,
::after,
::before {
box-sizing: border-box
}
/*flex布局容器*/
.flex {
display: flex;
}
.flex_col {
display: flex;
flex-direction: column;
}
.flex_center {
display: flex;
align-items: center;
}
.flex_sb {
display: flex;
justify-content: space-between;
}
.flex_wrap {
flex-wrap: wrap;
}
.flex_end {
justify-content: flex-end;
}
.flex_cen {
display: flex;
justify-content: center;
}
/* 写一个CSS用于隐藏页面 */
.display_none {
display: none;
}
/* 字体加粗 */
.font_bolder {
font-weight: bolder;
}
/* 单行字体溢出省略 */
.overflowOmitRow {
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* 多行字体溢出省略 */
.overflowOmitRows {
width: 100%;
display: -webkit-box;
word-break: break-all;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
.content_box {
color: #434343;
background: #FAFAFA;
min-height: 100vh;
font-size: 32rpx;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
/* 统一样式类 */
.box_shadow_card {
padding: 20rpx;
border-radius: 24rpx;
background-color: #FFFFFF;
box-shadow: 1px 3px 12px 0px rgba(0, 0, 0, 0.04);
}
.routine_radius_card {
padding: 24rpx;
margin: 0 24rpx 24rpx;
background-color: #FFFFFF;
border-radius: 0 0 16rpx 16rpx;
}
// 通用按钮
.common_btn {
width: 327rpx;
height: 88rpx;
font-size: 32rpx;
font-weight: bolder;
color: #2E75E6;
border-radius: 44rpx;
border: 2rpx solid;
margin-top: 20rpx;
&::after {
border: none;
}
}
.shipment_code {
font-size: 28rpx;
font-weight: 400;
}
.operation-btn {
width: 100%;
margin-bottom: 40rpx;
flex-grow: 1;
display: flex;
align-items: flex-end;
.submitBtn {
color: #FFFFFF;
background: linear-gradient(136deg, #2E75E6 0%, #2E2EE6 100%);
}
}
.u-form-item__body__left__content__required {
font-size: 28rpx !important;
top: auto !important;
left: -16rpx !important;
}
//常用按钮样式
.footer-btns{
width: 100%;
position:fixed;
bottom: 0;
height: 144rpx;
background: #FFFFFF;
padding: 28rpx 24rpx;
z-index: 999;
border-top:2rpx solid #F0F0F0;
}
.size-small{
width: 327rpx !important;
}
.primary-btn{
width: 100%;
height: 88rpx;
background: linear-gradient(90deg, #2E75E6 0%, #5E58EE 100%);
border-radius: 48rpx;
color: #FFFFFF;
border-radius: 44rpx;
line-height: 86rpx;
font-size: 32rpx;
font-weight: 500;
}
.info-btn{
width: 100%;
height: 88rpx;
border-radius: 44rpx;
border: 3rpx solid #2E75E6;
color: #2E75E6;
background: #FFFFFF;
line-height: 86rpx;
font-size: 32rpx;
font-weight: 500;
}
</style>
# biz-driver-uniapp
司机端
## 项目初始化
1. git clone #####项目地址
2. yarn/yarn start
3. 替换publicConfig目录下config.js 中的项目名、APPid等信息为实际项目信息。H5项目需要同步将manifest.json下H5代理地址替换为BASEURL的请求地址
4. 步骤3中项目名等信息,需要提前在bo-designer中系统配置 → 移动端配置下配置。
## 打包发布
1. HBuilderX工具中点击发布。(点击运行为开发环境,点击发布为生产环境)
2. 选择H5或网站PC将发布为H5项目,打包后文件部署至服务器即可。
3. 选择微信开发者工具则为小程序项目,将代码点击上传即可
## 添加彩色图标
1. 在iconfont官网将所需图标添加至购物车→我的项目中→下载至本地解压缩
2. 安装icon工具包
npm install -g iconfont-tools
yarn add -g iconfont-tools
3. 执行命令iconfont-tools
一路回车,将 iconfont-weapp 文件夹下iconfont-weapp-icon.css 替换static下文件即可。 更新图标只需执行步骤3即可
This diff is collapsed.
import { BASEURL, TokenPrefix, APIPrefix} from '../publicConfig/config'
let downloadFile = (api, filePath, header = {}, showLoading = true) => {
filePath = filePath.split('=')[1] ? filePath.split('=')[1] : filePath
header = {
'Cookie': 'XSRF-TOKEN=' + uni.getStorageSync(`${TokenPrefix}_XSRFToken`) || '',
"X-XSRF-TOKEN": uni.getStorageSync(`${TokenPrefix}_XSRFToken`) || '',
"Authorization": uni.getStorageSync(`${TokenPrefix}_token`) || '',
}
if(showLoading){
uni.showLoading({
title: '下载中',
})
}
return new Promise((reslove, reject) => {
api = APIPrefix + api
uni.downloadFile({
//#ifdef MP
url: BASEURL.url + `${api}/` + filePath, //下载资源的 url
//#endif
//#ifdef H5
url: `${api}/` + filePath, //H5使用代理
//#endif
header,
success: (res) => {
if(showLoading){
uni.hideLoading()
}
if (res.statusCode == 401 || res.statusCode == -1) {
let app = getApp()
uni.showToast({
title: '登录已过期',
icon: 'error',
duration: 3000
})
uni.removeStorageSync(`${TokenPrefix}_token`)
uni.removeStorageSync(`${TokenPrefix}_XSRFToken`)
uni.removeStorageSync('cookies')
app.judgePlatform();
}
reslove(res.tempFilePath)
},
fail: (err) => {
if(showLoading){
uni.hideLoading()
}
uni.showToast({
title: '下载失败!',
icon: 'error'
})
reject(err)
}
})
})
}
export default downloadFile
import { BASEURL, TokenPrefix, APIPrefix } from '../publicConfig/config'
let serverCode = {
3: '重定向',
4: '请求包含错误或未找到资源',
5: '服务器错误'
}
let Request = (api, data, method = 'POST', header = {}, showLoading = true) => {
//获取token
const XSRFToken=uni.getStorageSync(`${TokenPrefix}_XSRFToken`);
const token=uni.getStorageSync(`${TokenPrefix}_token`);
header = {
'Content-Type': 'application/json;charset=UTF-8',
'Cookie': 'XSRF-TOKEN=' + uni.getStorageSync(`${TokenPrefix}_XSRFToken`) || '',
"X-XSRF-TOKEN": uni.getStorageSync(`${TokenPrefix}_XSRFToken`) || '',
"Authorization": uni.getStorageSync(`${TokenPrefix}_token`) || '',
...header
}
if(showLoading){
uni.showLoading({
title: '加载中...',
})
}
console.log('请求参数:', data);
return new Promise((reslove, reject) => {
const { projectMini } = getApp().globalData
const newApi = APIPrefix + api.replace(/{mini}/g, projectMini)
uni.request({
//#ifdef MP
url: BASEURL.url + newApi,
//#endif
//#ifdef H5
url: newApi,
//#endif
data,
method,
header,
success: (res) => {
if(showLoading){
uni.hideLoading()
}
if (res.statusCode == '404') {
uni.showToast({
title: '无法找到资源',
icon: 'error',
duration: 3000
})
} else if (res.statusCode === 401 && !newApi.includes('/auth/app-login')) {
//#ifdef MP
if(!XSRFToken&&!token){
//如果没有token,说明不是token过期,而是访客身份
reject("");
}else{
let app = getApp()
uni.showToast({
title: '登录已过期',
icon: 'error',
duration: 3000
})
uni.removeStorageSync(`${TokenPrefix}_token`)
uni.removeStorageSync(`${TokenPrefix}_XSRFToken`)
uni.removeStorageSync('cookies')
app.judgePlatform();
}
//#endif
//#ifdef H5
let app = getApp()
uni.showToast({
title: '登录已过期',
icon: 'error',
duration: 3000
})
uni.removeStorageSync(`${TokenPrefix}_token`)
uni.removeStorageSync(`${TokenPrefix}_XSRFToken`)
uni.removeStorageSync('cookies')
app.judgePlatform();
//#endif
} else if (res.statusCode !== 200) {
console.log('响应日志:', res.data);
if (res.data.messageType) {
if(!newApi.includes('/auth/app-login')){ //登录接口自定义处理
uni.showToast({
title: res.data.message,
icon: 'none',
duration: 3000
})
}
reject(res.data)
} else {
uni.showToast({
title: serverCode[res.statusCode.toString()[0]],
icon: 'error',
duration: 3000
})
}
} else {
reslove(res)
}
},
fail: (err) => {
if(showLoading){
uni.hideLoading()
}
uni.showToast({
title: err.info || '请求失败!',
icon: 'error',
duration: 2000
})
reject(err)
}
})
})
}
export default Request
import {BASEURL, TokenPrefix, APIPrefix} from '../publicConfig/config'
import compress from '../utils/compress'
let uploadFile = async (api, filePath, fileType, header = {}) => {
header = {
'Cookie': 'XSRF-TOKEN=' + uni.getStorageSync(`${TokenPrefix}_XSRFToken`) || '',
"X-XSRF-TOKEN": uni.getStorageSync(`${TokenPrefix}_XSRFToken`) || '',
"Authorization": uni.getStorageSync(`${TokenPrefix}_token`) || '',
}
uni.showLoading({
title: '上传中',
})
if(fileType === 'image'){
filePath = await compress(filePath) //图片压缩
}
return new Promise((reslove, reject) => {
api = APIPrefix + api
uni.uploadFile({
//#ifdef MP
url: BASEURL.url + `${api}`, //开发者服务器地址
//#endif
//#ifdef H5
url: api, //H5使用代理
//#endif
filePath,
name: 'file',
header,
success: (res) => {
uni.hideLoading()
if (res.data.reCode == 401 || res.data.reCode == -1) {
let app = getApp()
uni.showToast({
title: '登录已过期',
icon: 'error',
duration: 3000
})
uni.removeStorageSync(`${TokenPrefix}_token`)
uni.removeStorageSync(`${TokenPrefix}_XSRFToken`)
uni.removeStorageSync('cookies')
app.judgePlatform();
}
reslove(res.data)
},
fail: (err) => {
uni.hideLoading()
uni.showToast({
title: '上传失败!',
icon: 'error'
})
console.log(err);
reject(err)
}
})
})
}
export default uploadFile
<template>
<view class="bs-autoInput">
<input type="text" :disabled="disabled" :placeholder="placeholder" v-model="inputValue" @focus='onFocus'
@input='onChange' />
<scroll-view :class="['auto-options', {'flex_center': !searchData.length}]" scroll-y v-show="visible">
<view class="option-item flex_sb" v-for="(item,index) in searchData" :key="index" @click="onSelect(item)">
<text class="options-label">{{item.label}}</text>
<text class="options-value">{{item.value}}</text>
</view>
<u-empty mode="data" textSize='32' iconSize="160" text="暂无数据" v-if="!searchData.length" />
</scroll-view>
</view>
</template>
<script>
import Request from '@/api/request.js'
import { getOptionEnum } from '@/api/apiList.js'
export default {
name: "bs-autoInput",
options: { styleIsolation: 'shared' },
props: {
placeholder: {
type: String,
default: '' //默认提示
},
disabled: {
type: Boolean,
default: false //是否禁用
},
name: {
type: String,
default: 'label' //是否禁用
},
autoApi: {
type: String,
default: '' //数据API
},
},
data() {
return {
inputValue: '', //输入值
showSelect: '', //当前选中的值
visible: false, //是否显示下拉框
sourceData: [], //源数据
searchData: [], // 搜索数据
};
},
methods: {
onVisible() {
this.visible = !this.visible
},
async onFocus() {
const api = this.autoApi
if (api) {
const res = await Request(api) //详细参数参考Request请求
const datas = res.data.data.datas
this.sourceData = datas
this.searchData = datas
this.onVisible()
}
},
onChange(e) {
const value = e.detail.value
let newData = []
if (value) {
newData = this.searchData.filter(item => item.label.includes(value))
} else {
newData = this.sourceData
}
this.searchData = [...newData]
},
onSelect(data) {
const value = data[this.name]
this.inputValue = value
this.$emit('onSearch', value)
this.onVisible()
}
}
}
</script>
<style lang="scss">
.bs-autoInput {
position: relative;
/deep/.uni-input-input {
width: 99%;
border-right: 2rpx solid #797979;
}
/deep/.uni-input-placeholder {
font-size: 28rpx;
color: rgb(192, 196, 204);
}
.auto-options {
width: 100%;
max-height: 400rpx;
min-height: 400rpx;
padding: 10rpx;
position: absolute;
top: 80rpx;
z-index: 999;
background-color: #FFFFFF;
border-radius: 6px;
border: 2prx solid #ebeef5;
box-shadow: 0 4rpx 24rpx 0 rgba(0, 0, 0, .1);
&::after {
content: '';
position: absolute;
top: -20rpx;
left: 10%;
width: 0;
height: 0;
border: 16rpx solid #FFFFFF;
border-top-width: 0;
border-bottom-color: #DFE2E5;
}
.option-item {
padding: 20rpx;
border-bottom: 1rpx solid #DFE2E5;
&:last-child {
border-bottom: none;
}
}
}
}
</style>
<template>
<view class="custom-cell-row">
<u-row>
<u-col :span="labelCol">
<view class="custom-cell-label">
<slot name="label"></slot>
<text class="custom-cell-col" v-if="label">{{label}}</text>
</view>
</u-col>
<u-col :span="wrapCol">
<view class="custom-cell-value">
<slot name="value"></slot>
<text class="custom-cell-col" v-if="value">{{value}}</text>
</view>
</u-col>
<slot name="right-icon"></slot>
</u-row>
</view>
</template>
<script>
export default {
name: 'bs-customCell',
props: {
label: {
type: String,
default: "" //默认值为空
},
value: {
type: String,
default: "" //默认值为空
},
labelCol: {
type: String,
default: '6'
},
wrapCol: {
type: String,
default: '6'
},
},
methods:{
}
}
</script>
<style lang="scss">
.custom-cell-row {
font-size: 28rpx;
margin-top: 24rpx;
color: #434343;
&>view{
align-items: stretch !important;
}
.custom-cell-col {
width: 100%;
}
}
</style>
<template>
<view class="customRowCell">
<u-cell-group>
<u-cell center :url="linkUrl" :link-type="linkType" arrow="false">
<view slot="icon" :class="['t-icon cell-leftIcon', 't-icon-' + leftIcon]" />
<view slot="title" class="customRow-title">
<slot name="title"></slot>
<text :class="{ overflowOmitRows: isOmits}" v-if="title">{{title}}</text>
</view>
<view class="customRow-value" slot="value">
<slot name="value"></slot>
<text v-if="value"> {{value}}</text>
</view>
<view slot="right-icon" class="flex_sb icon-min-width">
<text class="right-separator" v-if="separator" />
<slot name="rightIcon"></slot>
<view slot="icon" :class="['t-icon cell-rightIcon', 't-icon-' + rightIcon]" v-if="rightIcon" />
</view>
</u-cell>
</u-cell-group>
</view>
</template>
<script>
export default {
name: 'bs-customRowCell',
options: { styleIsolation: 'shared' },
props: {
title: { //标题
type: String,
default: ''
},
value: { //右侧内容
type: String,
default: ''
},
leftIcon: { //标题左侧图标
type: String,
default: ""
},
rightIcon: { //右侧图标
type: String,
default: ""
},
linkUrl: { //跳转页面地址
type: String,
default: ""
},
linkType: { //跳转类型
type: String,
default: 'navigateTo'
},
isOmits: { //是否多行省略
type: Boolean,
default: false
},
separator: { //是否显示分隔符
type: Boolean,
default: false
}
}
}
</script>
<style lang="scss">
.customRowCell {
&/deep/.u-cell-group {
.u-line {
border: none !important;
}
.u-cell__body {
padding: 20rpx 0;
border: none !important;
}
}
.cell-leftIcon,
.cell-rightIcon {
width: 44rpx;
height: 44rpx;
}
.right-separator {
border-left: 2rpx solid #E5E5E5;
min-height: 30rpx;
}
.customRow-title {
margin-left: 20rpx;
}
.customRow-value {
color: #333333;
white-space: nowrap;
}
.icon-min-width {
min-width: 75rpx;
}
}
</style>
<template>
<view class="datetimePicker" @touchmove.stop.prevent = "moveHandle">
<u-datetime-picker ref="datetimePicker" itemHeight="120" :visibleItemCount="visibleItem" :show="visible"
v-model="timestamp" :mode="dateType" @confirm="onSelsectDate" @cancel="onVisible" />
</view>
</template>
<script>
export default {
name: "bs-datetimePicker",
options: { styleIsolation: 'shared' },
props: {
visible: {
type: Boolean,
default: false
},
dateType: {
type: String,
default: 'date'
}
},
onReady() {
// 微信小程序需要用此写法
this.$refs.datetimePicker.setFormatter(this.formatter)
},
data() {
return {
//时间选择配置
showPopup: false,
timestamp: new Date().getTime(),
dateValue: "", //时间戳转换后 年-月-日
visibleItem: 4,
};
},
methods: {
moveHandle(){
},
//自定义时间格式
formatter(type, value) {
if (type === 'year') {
return `${value}年`;
}
if (type === 'month') {
return `${value}月`;
}
if (type === 'day') {
return `${value}日`;
}
if (type === 'hour') {
return `${value}时`;
}
return `${value}分`;
},
onVisible() {
this.$emit('onVisible')
},
// 时间选择
onSelsectDate(dateInfo) {
const date = this.formatDate(dateInfo.value)
this.dateValue = date
this.timestamp = dateInfo.value
this.$emit('onSelsectDate', { dateValue: date, timestamp: dateInfo.value, })
},
//时间戳转换
formatDate(timestamp) {
const nowDate = new Date(timestamp)
var year = nowDate.getFullYear();
var month = nowDate.getMonth() + 1;
var date = nowDate.getDate();
const hour = nowDate.getHours()
const minute = nowDate.getMinutes()
if (this.dateType === 'date') {
return `${year}-${ month}-${date}`
} else {
return `${year}-${ month}-${date} ${hour}-${ minute}`
}
},
}
}
</script>
<style lang="scss">
/* #ifdef MP */
/deep/.u-popup__content {
height: 40vh !important;
.u-picker__view__column {
.u-picker__view__column__item {
line-height: 88rpx !important;
}
}
}
/* #endif */
</style>
<template>
<view class="page-header">
<view class="page-header-orderNo flex_center">
运单号: {{shipmentNo}}
</view>
</view>
</template>
<script>
export default {
name: "bs-pageHeader-orderNo2",
props: {
shipmentNo: {
type: String,
default: "" //运单号
},
}
}
</script>
<style lang="scss">
.page-header {
padding: 40rpx 24rpx 0;
// background: linear-gradient(90deg, #2E75E6 0%, #5E58EE 100%);
border-radius: 0 0 32rpx 32rpx;
background-color: #2E75E6;
.page-header-orderNo {
color: #2E75E6;
padding: 30rpx 24rpx;
background: linear-gradient(90deg, rgba(46, 117, 230, .1), rgba(46, 117, 230, .1));
background-color: #EDEFFD;
border-radius: 16rpx 16rpx 0 0;
font-size: 28rpx;
}
}
</style>
<template>
<view class="bs-popup">
<image :src="'../../..'+src" @click="showPopup"></image>
<view class="triangle" v-if="popUp">
</view>
<view class="description" v-if="popUp">
{{placeholder}}
</view>
</view>
</template>
<script>
import Request from '@/api/request.js'
import {
getOptionEnum
} from '@/api/apiList.js'
export default {
name: "bs-popup",
options: {
styleIsolation: 'shared'
},
props: {
src: {
type: String,
default: '' //默认提示
},
placeholder: {
type: String,
default: '', //默认提示
},
popUp:{
type: Boolean,
default: false, //默认提示
}
},
data() {
return {
};
},
methods: {
showPopup() {
this.$emit('openPopup')
}
}
}
</script>
<style lang="scss">
.bs-popup {
position: relative;
margin-left: 12rpx;
image,
img {
width: 30rpx;
height: 30rpx;
}
.triangle {
width: 0;
height: 0;
border: 10rpx solid;
border-color: #FFFFFF00 #FFFFFF00 #000000 #FFFFFF00;
position: absolute;
top: 25rpx;
opacity: .7;
transform: translate(-50%, 0);
left: 50%;
}
.description {
position: absolute;
top: 40rpx;
left: -30%;
width: 400rpx;
z-index: 1;
background-color: #000000FF;
opacity: .7;
border-radius: 8rpx;
color: #FFFFFF;
transform: translate(-20%);
padding: 4rpx;
}
}
</style>
<template>
<view class="selectPicker" @touchmove.stop.prevent="moveHandle">
<u-picker ref="uPicker" keyName="label" immediateChange confirmText="确定" :show="visible" :title="PanelTitle"
:columns="[pickerEnums]" :singleIndex="singleIndex" :visibleItemCount="visibleNum" @cancel="onCancel" @confirm="onConfirm" />
</view>
</template>
<script>
export default {
name: "bs-selectPicker",
options: { styleIsolation: 'shared' },
data() {
return {
singleIndex: 0 //默认选中项
};
},
props: {
visible: {
type: Boolean,
default: false
},
pickerEnums: { //选择项枚举
type: Array,
default: []
},
PanelTitle: { //面板标题
type: String,
default: ""
},
visibleNum: {
type: Number,
default: 3
}
},
methods: {
moveHandle(){
},
//确定
onConfirm(e) {
const value = e.value[0].value
this.$emit('onConfirm', value)
},
//设置默认值
setDefaultValue(index) {
this.singleIndex = index
},
//取消
onCancel() {
this.$emit('onVisible')
}
}
}
</script>
<style lang="scss">
.selectPicker{
/deep/.u-toolbar{
height: 80rpx !important;
}
/deep/.u-slide-up-enter-active {
height: 240rpx;
}
/deep/.u-picker__view__column__item{
line-height: 68rpx !important;
}
}
</style>
<template>
<!-- 选择弹窗 -->
<view class="selectPopup" @touchmove.stop.prevent="onTouchMove">
<u-popup :show="visible" round="32" mode="bottom" closeable @close="onCancel" duration="1">
<view class="select-container">
<view class="popTitle"> <text>{{popTitle}}</text> </view>
<scroll-view scroll-y class="select-list">
<u-radio-group v-model="currentChecked" placement="column" iconPlacement="right">
<u-radio :customStyle="{margin: '22rpx 40rpx'}" :size="40" :iconSize="32" :labelSize="32"
labelColor="#262626" v-for="(item, index) in selectEnum" :key="index" :label="item.label"
:name="item.value" @change="onChange">
</u-radio>
</u-radio-group>
</scroll-view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
name: "bs-selectPopup",
options: { styleIsolation: 'shared' },
props: {
visible: { //弹窗显隐
type: Boolean,
default: false
},
selectEnum: { //选择项枚举
type: Array,
default: []
},
popTitle: { //弹窗标题
type: String,
default: ""
}
},
data() {
return {
currentChecked: '', //当前选中类型
};
},
methods: {
setSelect(value) {
this.currentChecked = value
},
onChange(value) {
this.setSelect(value)
setTimeout(() => {
this.onConfirm()
}, 350)
},
onCancel() {
this.$emit('onVisible')
},
//确认选择
onConfirm() {
this.$emit('onConfirm', this.currentChecked)
},
//防止滚动穿透
onTouchMove() {}
}
}
</script>
<style lang="scss">
.selectPopup {
.select-container {
min-width: 70vw;
height: 50vh;
padding: 30rpx;
font-weight: 400;
.popTitle {
color: #8C8C8C;
font-size: 32rpx;
text-align: center;
margin-bottom: 44rpx;
}
.select-list{
height: 460rpx;
}
}
/deep/.uicon-close {
font-size: 40rpx !important;
width: 24rpx;
height: 24rpx;
margin-right: 20rpx;
}
}
</style>
<template>
<u-tabbar
:value="value"
:fixed="true"
:placeholder="true"
:safeAreaInsetBottom="true"
activeColor="#2E75E6"
inactiveColor="#8C8C8C"
>
<u-tabbar-item v-for="item in tabbars" :text="item.text" :key="item.name" @click="onTabbarClick(item)" :name="item.name">
<image
:style="{width: item.size || '56rpx',height: item.size || '56rpx'}"
class="u-page__item__slot-icon"
slot="active-icon"
:src="item.selectedIconPath"
></image>
<image
:style="{width: item.size || '56rpx',height: item.size || '56rpx'}"
class="u-page__item__slot-icon"
slot="inactive-icon"
:src="item.iconPath"
></image>
</u-tabbar-item>
</u-tabbar>
</template>
<script>
export default{
options: { styleIsolation: 'shared' },
data() {
return {
tabbars:[
{
name:'visitOrder',
"pagePath": "/subpkg/visitOrderList/visitOrderList",
"text": "拜访单",
"iconPath": "/static/img/tabbar/order.png",
"selectedIconPath": "/static/img/icon/visitOrder.png"
},
{
name:'addVisit',
"pagePath": "/subpkg/addNewVisitOrder/addNewVisitOrder",
"text": "",
"iconPath": "/static/img/icon/addVisit.png",
"selectedIconPath": "/static/img/icon/addVisit.png",
size:"120rpx"
},
{
name:'user',
"pagePath": "/pages/user/user",
"text": "我的",
"iconPath": "/static/img/tabbar/user.png",
"selectedIconPath": "/static/img/tabbar/user-active.png"
}
]
}
},
props:{
value:{
type:String,
default:''
}
},
methods: {
onTabbarClick(tab){
if(tab.pagePath.includes('subpkg')){
if(tab.text){
uni.reLaunch({ url: tab.pagePath })
}else{
uni.navigateTo({ url: tab.pagePath })
}
}else{
uni.switchTab({ url: tab.pagePath})
}
}
},
}
</script>
<style lang="scss">
/deep/.u-tabbar-item__text{
font-size: 20rpx !important;
}
.u-page__item__slot-icon{
width: 56rpx;
height: 56rpx
}
</style>
\ No newline at end of file
<template>
<view class="todo-remark">
<view class="remark-title">{{title}}</view>
<u-textarea v-model="value" :placeholder="isReadonly ? '' : placeholder" :count="!isReadonly" autoHeight
:disabled="isReadonly" maxlength="200" border="none" @blur="onBlur" holdKeyboard/>
</view>
</template>
<script>
export default {
name: "bs-todoRemark",
options: { styleIsolation: 'shared' },
props: {
placeholder: {
type: String,
default: "请输入备注......"
},
title: {
type: String,
default: "备注"
},
isReadonly: {
type: Boolean,
default: false
}
},
data() {
return {
value: ""
};
},
methods: {
onBlur(e) {
const { value } = e.detail
this.setValue(value)
},
//设置默认值
setValue(value) {
this.value = value
}
}
}
</script>
<style lang="scss">
.todo-remark {
font-size: 28rpx;
margin-top: 32rpx;
.remark-title {
color: #8C8C8C;
margin-bottom: 24rpx;
}
.u-textarea {
min-height: 150rpx;
background-color: #FAFAFA;
.u-textarea__field{
min-height: 120rpx;
}
}
}
</style>
<template>
<view class="uploade-file">
<view class="fileList flex flex_wrap">
<view class="previewImages" v-for="(item,index) in fileList" :key="index">
<image mode="aspectFill" :src="item" :data-index="index" @click="previewImage" class="previewImg" />
<u-icon name="close-circle-fill" class="clearIcon" size="30" @click="deleteFile" :index='index' />
</view>
<template v-if="isIos">
<view class="uploadeBtn flex_col" @click="onUpLoad">
<view class="t-icon t-icon-picture" />
<view class="">
上传图片
</view>
<view class="required" v-if="required">
*
</view>
</view>
</template>
<template v-else>
<u-upload :fileList="fileList" :maxCount="maxCount" :sizeType="['compressed']" multiple @afterRead="uploadAfterRead" :previewImage="false">
<!-- 自定义上传按钮 -->
<view class="uploadeBtn flex_col" v-if="isShowBtn">
<view class="t-icon t-icon-picture" />
<view class="">
上传图片
</view>
<view class="required" v-if="required">
*
</view>
</view>
<view v-else style=" height: 140rpx"></view>
</u-upload>
</template>
</view>
</view>
</template>
<script>
const uploadBehavior = require('../../../mixins/uploadBehavior')
export default {
name: "bs-uploader",
mixins: [uploadBehavior],
options: { styleIsolation: 'shared' },
props: {
uploadTitle: {
type: String,
default: ""
},
btnTitle: { //按钮名字
type: String,
default: "上传图片"
},
isShowBtn: {
type: Boolean,
default: true //是否显示上传按钮
},
required: {
type: Boolean,
default: false //图片是否必传
},
maxCount: {
type: Number,
default: 6
}
},
data() {
return {
}
},
methods:{
}
}
</script>
<style lang="scss">
.uploade-file {
.uploade-title {
font-size: 28rpx;
color: #8C8C8C;
margin-bottom: 24rpx;
}
.fileList {
width: 100%;
.previewImages {
position: relative;
overflow: hidden;
.previewImg {
width: 218rpx;
height: 218rpx;
margin: 0 0 20rpx 20rpx;
}
/deep/.uicon-close-circle-fill {
width: 30rpx;
height: 30rpx;
border-radius: 50%;
background-color: #fff;
color: #D81E06 !important;
position: absolute;
top: 4rpx;
right: 4rpx;
}
}
.uploadeBtn {
position: relative;
color: #929292;
width: 218rpx;
height: 218rpx;
border: 2rpx dashed #D9D9D9;
border-radius: 4rpx;
background-color: #FFFFFF;
justify-content: center;
align-items: center;
font-size: 24rpx;
.t-icon-picture{
width: 50rpx;
height: 50rpx;
}
.orderTotal {
color: #333333;
position: absolute;
right: -100rpx;
bottom: 0;
z-index: 999;
}
.required{
color: #D81E06;
position: absolute;
left: -15rpx;
top: 0rpx;
}
}
}
}
</style>
<template>
<view class="uploade-file">
<view class="uploade-title" v-if="uploadTitle">
<text style="color: #f56c6c;position: absolute;left: 18rpx;" v-if="required">*</text>
<text>{{uploadTitle}}{{fileList.length}}/6)</text>
</view>
<view class="fileList flex flex_wrap">
<view class="previewImages" v-for="(item,index) in fileDetailList" :key="index">
<template v-if="item.type === 'image'">
<image mode="aspectFill" :src="item.url" :data-index="index" @click="previewImage" class="previewImg" />
</template>
<template v-if="item.type === 'video'">
<video class="previewImg" :src="item.url" :page-gesture="true" :show-mute-btn="true" :enable-play-gesture="true"/>
</template>
<u-icon v-if="isShowDelete" name="close-circle-fill" class="clearIcon" size="30" @click="deleteFile" :index='index' />
</view>
<template v-if="isIos">
<view class="uploadeBtn flex_col" @click="onUpLoad">
<view class="t-icon t-icon-picture" />
<text style="margin-top:10rpx">{{btnTitle}}</text>
<text class="font_bolder orderTotal" v-if="!uploadTitle">{{fileList.length}}/6)</text>
</view>
</template>
<template v-else>
<u-upload :fileList="fileList" :maxCount="maxCount" :accept="uploadAccept" :maxDuration="maxDuration"
:sizeType="['compressed']" multiple @afterRead="uploadAfterRead" :previewImage="false">
<!-- 自定义上传按钮 -->
<view class="uploadeBtn flex_col" v-if="isShowBtn">
<view class="t-icon t-icon-picture" />
<text style="margin-top:10rpx">{{btnTitle}}</text>
<text class="font_bolder orderTotal" v-if="!uploadTitle">{{fileList.length}}/6)</text>
</view>
<view v-else style=" height: 140rpx"></view>
</u-upload>
</template>
</view>
<!-- #ifdef MP-WEIXIN -->
<canvas type="2d" id="upload-canvas" class="uploadCanvas"
:style="{'width':width+'px','height':height+'px','position':'absolute','z-index':'-999','top':'0px','left':'-1000000px'}"></canvas>
<!-- #endif -->
<!-- #ifdef H5 -->
<canvas canvas-id="upload-canvas" class="uploadCanvas"
:style="{'width':width+'px','height':height+'px','position':'absolute','z-index':'-9999999','top':'0px','left':'-1000000px'}"></canvas>
<!-- #endif -->
</view>
</template>
<script>
const uploadBehavior = require('../../../mixins/uploadBehavior')
export default {
name: "bs-uploader",
mixins: [uploadBehavior],
options: { styleIsolation: 'shared' },
props: {
uploadTitle: {
type: String,
default: ""
},
uploadAccept: {
type: String, //接受的文件类型: image | video | file | all | media; file只支持H5(all、media仅小程序支持)
default: "image"
},
maxDuration: {
type: Number, //当accept为video时生效,拍摄视频最长拍摄时间,单位秒
default: 60
},
maxCount: {
type: Number, //最大上传数量
default: 6
},
btnTitle: { //按钮名字
type: String,
default: "上传图片"
},
isShowBtn: {
type: Boolean,
default: true //是否显示上传按钮
},
required: {
type: Boolean,
default: false //图片是否必传
},
isShowDelete: {
type: Boolean,
default: true
}
},
data() {
return {
}
},
created() {
// #ifdef H5
const platform = uni.getSystemInfoSync().platform
if (platform === 'ios') {
// this.isIos = true
}
// #endif
},
}
</script>
<style lang="scss">
.uploade-file {
.uploade-title {
font-size: 28rpx;
color: #8C8C8C;
margin-bottom: 24rpx;
}
.fileList {
width: 100%;
.previewImages {
position: relative;
overflow: hidden;
.previewImg {
width: 180rpx;
height: 140rpx;
margin: 0 0 20rpx 20rpx;
}
/deep/.uicon-close-circle-fill {
width: 30rpx;
height: 30rpx;
border-radius: 50%;
background-color: #fff;
color: #D81E06 !important;
position: absolute;
top: 4rpx;
right: 4rpx;
}
}
.uploadeBtn {
position: relative;
color: #929292;
width: 180rpx;
height: 140rpx;
border: 2rpx dashed #D9D9D9;
margin-left: 20rpx;
background-color: #FAFAFA;
justify-content: center;
align-items: center;
font-size: 24rpx;
.t-icon-picture{
width: 50rpx;
height: 50rpx;
}
.orderTotal {
color: #333333;
position: absolute;
right: -100rpx;
bottom: 0;
z-index: 999;
}
}
}
}
</style>
<template>
<view class="user-agreement flex_center flex_cen">
<u-checkbox-group>
<u-checkbox name="userAuth" shape="circle" size="44" iconSize='44' @change="onChange" />
</u-checkbox-group>
<text>请您详细阅读并授权</text>
<text class="special-text" @click="onVisible(true)">运匠用户协议</text>
<text></text>
<text class="special-text" @click="onVisible(true)">隐私政策</text>
<!-- 协议详情 -->
<view @touchmove.stop.prevent="onTouchMove">
<u-popup :show="visible" mode="right" duration="300" :overlay="false">
<view class="agreement-contentBox" style="width: 100%;">
<view class="agreement-title flex_center">
<u-icon name="arrow-left" size="48" style="margin-right: 25rpx;" @click="onVisible(false)" />
<view class="flex_cen" style="flex-grow: 1;font-size: 38rpx; color: #2c3e50;">用户隐私协议</view>
</view>
<scroll-view scroll-y class="agreement-container">
<view class="detail-title">一、位置及第三方授权</view>
<view class="detail-content">
您明确知悉并同意,您授权我平台通过中交兴路及关联方、第三方机构对您在平台认证的车辆进行当前位置、轨迹跟踪等定位信息查询并授权我平台及其关联方予以使用。授权时间为长期有效。
</view>
<view class="detail-title">二、其它</view>
<view class="detail-content">本应用仅公司内部用户和POC演示使用</view>
</scroll-view>
</view>
</u-popup>
</view>
</view>
</template>
<script>
export default {
name: 'bs-userPrivacy',
data() {
return {
userAuth: false, //用户是否授权
visible: false,
}
},
methods: {
onTouchMove() {
//防止滚动穿透
},
onVisible(value) {
this.visible = value
},
onChange(value) {
this.userAuth = value
this.$emit('onAuthChange', value)
}
}
}
</script>
<style lang="scss">
.user-agreement {
font-size: 26rpx;
font-weight: 400;
color: #8C8C8C;
line-height: 37rpx;
letter-spacing: 2rpx;
margin: 40rpx 0 95rpx;
.special-text {
font-size: 28rpx;
font-weight: bolder;
color: #2E75E6;
margin: 0 4rpx
}
.agreement-title {
padding: 50rpx 25rpx;
}
.agreement-container {
padding: 0 12rpx;
height: calc(100vh - 148rpx);
.detail-title {
color: #2c3e50;
font-weight: 400;
padding: 10rpx 14rpx;
}
.detail-content {
text-indent: 50rpx; //首行缩进
letter-spacing: 4rpx; //字符间距
}
}
}
</style>
\ No newline at end of file
<template>
<view class="deliveryCard">
<view class="shipment-header flex_sb">
<view class="shipment_code flex_center">
<text selectable> 交货单号:{{deliveryInfo["deliverySchedule.billNo"]}}</text>
</view>
<view
:class="deliveryInfo['deliverySchedule.status'] !== 'Executing' ? 'shipment-state' : 'shipment-state shipmenting'">
{{deliveryInfo['deliverySchedule.statusLabel']}}
</view>
</view>
<u-line customStyle="position: absolute; left: 0" margin="22rpx 0"></u-line>
<!-- 主要运单信息 -->
<view style="padding-top: 18rpx; margin-bottom: 32rpx;">
<bs-customCell label="交货地址" :value="deliveryInfo['deliverySchedule.address.name']" labelCol="3"
wrapCol="9" />
<bs-customCell label="交货日期" :value="commitTime" labelCol="3" wrapCol="9" />
<bs-customCell label="业务类型" :value="deliveryInfo['deliverySchedule.billTypeLabel']" labelCol="3"
wrapCol="9" />
<bs-customCell label="车牌号" :value="deliveryInfo['truck.name']" labelCol="3" wrapCol="9" />
</bs-customCell>
</view>
<view class="deliveryCardButton">
<button @click="signIn">确认</button>
</view>
<view class="success_info" @click="isError=false">
<u-popup v-model="isError" :show="isError" mode="center">
<img src="../../static/img/icon/fail.png" />
<view style="font-size: 36rpx; font-weight: bolder; margin-bottom: 24rpx;">确认失败</view>
<view style="font-size: 28rpx;margin-bottom: 56rpx;">{{messageInfo}}</view>
</u-popup>
</view>
</view>
</template>
<script>
import {
userMobileOperation,
GetReserveExamResult,
CreatSubscribeArrowDelivery
} from '../../api/apiList.js'
const getUserLocation = require('../../mixins/getUserLocation')
export default {
name: "deliveryCard",
props: ['deliveryInfo'],
mixins: [getUserLocation],
options: {
// 组件可选值:isolated | apply-shared | shared
// 页面组件可选值:page-isolated | page-apply-shared | page-shared
styleIsolation: 'shared',
},
data() {
return {
userInfo: {},
isError: false,
messageInfo: '',
};
},
mounted() {
this.getUserInfo()
},
methods: {
deliveryCardBg(path){
// #ifdef MP
let base64Png = uni.getFileSystemManager().readFileSync( path, 'base64');
path = 'data:image/jpg;base64,' + base64Png
// #endif
return `url(${path})`
},
getUserInfo() {
userMobileOperation('getUserInfo').then(res => {
const data = res.data.data
this.userInfo = {
...data
}
// this.getReserveExamResult()
})
},
getReserveExamResult() {
GetReserveExamResult({
"aux": {
"accessId": this.deliveryInfo.id,
// "driverTel": this.userInfo.userExt.mobile,
// "driverName": this.userInfo.name,
// "address": this.deliveryInfo['deliverySchedule.address.name']
}
}).then(res => console.log(res))
},
signIn() {
this.getUserSetting()
// const data = {
// formNumber: this.deliveryInfo["deliverySchedule.billNo"],
// deliveryId: this.deliveryInfo["id"],
// type: "delivery"
// }
CreatSubscribeArrowDelivery({
"args": {
"selectedIds": [ this.deliveryInfo["id"]],
"additionalIds": null
}
}).then(res => {
if (res.data.messageType === "success") {
const data = {
subscribeInfo: res.data.data
}
uni.hideToast()
// this.isSuccess = true
uni.navigateTo({
url: `/subpkg/orderTime/orderTime?data=${JSON.stringify(data)}`,
})
} else {
uni.hideToast()
this.isError = true
this.messageInfo = res.data.message
setTimeout(() => {
this.isError = false
}, 3000)
}
}).catch(err => {
uni.hideToast()
this.isError = true
this.messageInfo = err.message
setTimeout(() => {
this.isError = false
}, 3000)
})
// uni.navigateTo({
// url: `/subpkg/signIn/signIn?data=${JSON.stringify(data)}`,
// })
}
},
computed: {
commitTime() {
return this.deliveryInfo['deliverySchedule.deliveryDate'].split('T').join(' ').split('Z').join('')
}
}
}
</script>
<style lang="scss">
.deliveryCard {
position: relative;
padding: 28rpx 24rpx 32rpx 24rpx;
border-radius: 24rpx;
margin-top: 24rpx;
font-size: 28rpx;
box-shadow: 1rpx 3rpx 12rpx rgba(0, 0, 0, 0.0400);
background: rgba(46, 117, 230, 0.15);
.bg{
position:absolute;
top:0;
height:100%;
width:100%
}
.shipment_code {
color: #8C8C8C;
line-height: 40rpx;
text-shadow: 1rpx 3rpx 12rpx rgba(0, 0, 0, 0.04);
}
.shipment-state {
font-size: 28rpx;
color: #F7A64A;
line-height: 33rpx;
padding: 6rpx 24rpx;
border-radius: 8rpx;
background: rgba(247, 166, 74, .1);
text-shadow: 1rpx 3rpx 12rpx rgba(0, 0, 0, 0.04);
}
.shipmenting {
color: #66CCCC;
background: rgba(61, 204, 185, .1);
}
.t-icon-location {
width: 50rpx;
height: 50rpx;
}
.deliveryCardButton {
button {
background-image: linear-gradient(90deg, #2E75E6, #5E58EE), linear-gradient(90deg, #2E75E6, #5E58EE);
height: 88rpx;
line-height: 88rpx;
color: #FFFFFF;
font-size: 32rpx;
font-weight: bolder;
border-radius: 44rpx;
}
}
.success_info {
opacity: 1;
/deep/.u-popup__content {
border-radius: 24rpx;
display: flex;
justify-content: center;
align-items: center;
width: 620rpx;
img {
height: 120rpx;
width: 120rpx;
margin-bottom: 34rpx;
margin-top: 60rpx;
}
}
}
}
</style>
<template>
<view class="expense_card">
<view class="expense_card_header">
{{month}}
</view>
<view class="expense_card_content">
<view class="" v-for="( personExpense, index) in personExpenseList" :key="index" @click="viewDetailInfo(personExpense.id)">
<view class="expense_card_date">
{{formatDate(personExpense.costDate)}}
</view>
<view class="flex_center flex_sb">
<view class="">
{{personExpense.costTypeLabel || ''}}
</view>
<view class="flex_center">
<view style="font-size: 36rpx; font-weight: bolder;">
{{personExpense.amount || 0}}
</view>
<view style="margin-left: 8rpx;">
</view>
</view>
</view>
<u-line margin="40rpx 0" v-if="index !== personExpenseList.length-1" color="#F0F0F0"></u-line>
</view>
</view>
</view>
</template>
<script>
import {
formatGMT
} from '../../utils/util.js'
export default {
name: "expenseCard",
data() {
return {
};
},
props: {
personExpenseList: {
default: []
},
month: {
default: ''
}
},
methods: {
formatDate(date) {
const weekDay = ['日', '一', '二', '三', '四', '五', '六']
return formatGMT(date, 'D') + ' ' + '周' + weekDay[new Date(date).getDay()] + ' ' + formatGMT(date, 'H')
},
viewDetailInfo(id){
uni.navigateTo({
url: `/subpkg/personExpenseDetail/personExpenseDetail?id=${id}`
})
}
}
}
</script>
<style lang="scss">
.expense_card {
.expense_card_header {
color: #262626;
font-weight: bolder;
font-size: 32rpx;
padding-left: 24rpx;
padding-top: 32rpx;
padding-bottom: 16rpx;
background-color: #FAFAFA;
}
.expense_card_date{
color: #8C8C8C;
font-size: 28rpx;
margin-bottom: 14rpx;
}
.expense_card_content {
padding: 42rpx 24rpx;
color: #434343;
font-size: 28rpx;
background-color: #FFFFFF;
}
}
</style>
<template>
<view class="expenseReceiptCard" @click="viewDetailInfo">
<view class=" flex_center flex_sb">
<view class="expenseReceiptCard_date">
{{insertDate}}
</view>
<view class="expenseReceiptCard_label"
:style="expenseReceiptInfo.statusLabel === '已通过'?'color: rgba(39, 196, 136, 1); background-color: rgba(39, 196, 136, .1)':(expenseReceiptInfo.statusLabel === '未通过'?'color: rgba(235, 47, 72, 1); background-color: rgba(235, 47, 72, .1)':(expenseReceiptInfo.statusLabel === '审核中'?'color: rgba(247, 166, 74, 1); background-color: rgba(247, 166, 74, .1)':''))">
{{expenseReceiptInfo.statusLabel}}
</view>
</view>
<u-line margin="18rpx 0 7rpx 0" color="#E5E5E5"></u-line>
<view class="flex_center">
<image src="../../static/img/icon/money.png" style="width: 80rpx; height: 80rpx; margin-left: -16rpx;">
</image>
<view style="margin-right: 8rpx; font-size: 36rpx; color: #434343; font-weight: bolder;">
{{expenseReceiptInfo.amount || 0}}
</view>
</view>
<view class="expenseReceiptCard_billNo">
报销单号:{{expenseReceiptInfo.billNo}}
</view>
</view>
</template>
<script>
import {
formatGMT
} from '../../utils/util.js'
export default {
name: "expenseReceiptCard",
data() {
return {
};
},
props: {
expenseReceiptInfo: {
default: {}
}
},
computed: {
insertDate() {
const weekDay = ['日', '一', '二', '三', '四', '五', '六']
return formatGMT(this.expenseReceiptInfo.insertDate, 'D') + ' ' + '周' + weekDay[new Date(this
.expenseReceiptInfo.insertDate).getDay()] + ' ' + formatGMT(this.expenseReceiptInfo.insertDate,
'H')
}
},
methods:{
viewDetailInfo(){
uni.navigateTo({
url: `/subpkg/personExpenseReceiptDetail/personExpenseReceiptDetail?id=${this.expenseReceiptInfo.id}`
})
}
}
}
</script>
<style lang="scss">
.expenseReceiptCard {
height: 268rpx;
border-radius: 24rpx;
box-shadow: 3rpx 1rpx 12rpx 0 rgba(0, 0, 0, 0.04);
padding: 28rpx 24rpx;
margin: 12rpx 24rpx;
background-color: #FFFFFF;
.expenseReceiptCard_date {
color: #8C8C8C;
font-size: 28rpx;
}
.expenseReceiptCard_label {
padding: 5rpx 24rpx;
border-radius: 8rpx;
color: #2E75E6;
background-color: rgba(46, 117, 230, .1);
}
.expenseReceiptCard_billNo {
margin-top: 14rpx;
color: #434343;
font-size: 28rpx;
}
}
</style>
<template>
<view class="popupRadio">
<u-popup :show="radioShow" :mode="mode">
<view v-if="title" class="popupRadioTitle">
<text>{{title}}</text>
</view>
<view v-if="!radioList.length" style="height: 10vh; line-height: 10vh; text-align: center;">
暂无数据选择
</view>
<u-radio-group :value="currentSelect" placement="column" iconPlacement="right" @change="onChange" v-else>
<u-radio :customStyle="{marginBottom: '8px', 'font-weight': 'bolder'}"
v-for="(item, index) in radioList" :key="index" :label="item.name" :name="item.name">
</u-radio>
</u-radio-group>
<view class="popupRadioFoot">
<button @click="cancel">取消</button>
<button @click="confirm">确定</button>
</view>
</u-popup>
</view>
</template>
<script>
export default {
options: {
styleIsolation: 'shared'
},
props: {
radioShow: {
type: Boolean,
default: false
},
radioList: {
type: Array,
default: [
]
},
mode: {
type: String,
default: "bottom"
},
title: {
type: String,
default: ""
},
currentSelect: {
type: String,
default: ""
}
},
name: "popupRadio",
data() {
return {
currentSelectName: ""
};
},
methods: {
confirm() {
this.$emit('confirm', this.currentSelectName)
},
cancel(){
this.$emit('cancel')
},
onChange(value){
this.currentSelectName = value
}
},
mounted() {
}
}
</script>
<style lang="scss" scoped>
.popupRadio {
opacity: 1;
/deep/.u-popup__content {
border-radius: 32rpx 32rpx 0 0;
padding-bottom: 50rpx;
}
.popupRadioTitle {
margin-top: 48rpx;
text-align: center;
color: #8C8C8C;
font-size: 32rpx;
}
/deep/.u-radio-group {
margin: 24rpx;
max-height: 50vh;
overflow-y: scroll;
.u-radio {
height: 45rpx;
line-height: 45rpx;
}
.u-radio__text {
font-size: 32rpx !important;
}
.u-radio__icon-wrap {
height: 32rpx !important;
width: 32rpx !important;
line-height: 32rpx;
}
}
/deep/.popupRadioFoot{
display: flex;
justify-content: space-between;
bottom: 100rpx;
width: 100%;
button{
width: 339rpx;
height: 88rpx;
line-height: 88rpx;
border-radius: 44rpx;
color: #2E75E6;
padding: 0 24rpx;
border: 3rpx solid transparent;
position: relative;
background-clip: padding-box, border-box;
background-origin: padding-box, border-box;
background-image: linear-gradient(90deg, #FAFAFA, #FAFAFA), linear-gradient(90deg, #2E75E6, #5E58EE);
&:after{
content: "";
}
&:last-child{
background-image: linear-gradient(90deg, #2E75E6, #5E58EE), linear-gradient(90deg, #2E75E6, #5E58EE);
color: #FFFFFF;
}
}
}
}
</style>
This diff is collapsed.
This diff is collapsed.
<template>
<view class="shipmentBriefInfo">
<bs-pageHeader-orderNo :shipmentNo="shipmentNo" />
<view class="primary-info routine_radius_card flex_center">
<view class="left-icon">
<view :class="['t-icon', stopsInfo.loadStop ? 't-icon-a-zhuang2x1' : 't-icon-a-xie2x1']" />
</view>
<view class="primary-desc flex_col">
<view style="margin-bottom: 8rpx;" class="font_bolder">{{stopsInfo.locationName}}</view>
<view>{{stopsInfo.locationAddress}}</view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "shipmentBriefInfo",
options: { styleIsolation: 'shared' },
created: function() { //定义组件的生命周期
this.initData()
},
data() {
return {
stopsInfo: {}, //站点信息,
shipmentNo: '' //运单号
};
},
methods: {
initData() {
const appInstance = getApp()
const { stopsInfo, shipmentInfo } = appInstance.globalData
this.stopsInfo = stopsInfo
this.shipmentNo = shipmentInfo.shipmentNo
}
}
}
</script>
<style lang="scss">
.primary-info {
.left-icon {
position: relative;
margin-right: 20rpx;
.t-icon {
width: 70rpx;
height: 70rpx;
}
}
}
</style>
<template>
<view class="routine_radius_card shipmentCard">
<view class="shipment-header flex_sb">
<view class="shipment_code flex_center">
<text selectable> 运单号:{{data.uc_master_no}}</text>
</view>
<view :class="data.shipmentStatus ==='Approved' ? 'shipment-state' : 'shipment-state shipmenting'">
{{data.shipment_status_label}}
</view>
</view>
<!-- 主要运单信息 -->
<bs-customCell label="当前位置 :" :value="locationInfo.address" labelCol="3" wrapCol="8">
<view slot="right-icon" class="flex_center">
<view v-if="isLocation" class="t-icon t-icon-location" @click="onGetLocation" />
<view class="t-icon" v-else>
<u-loading-icon color="#2E75E6" size="40" mode="semicircle"></u-loading-icon>
</view>
</view>
</bs-customCell>
<!-- <bs-customCell label="发运日期 :" :value="data.shipmentDate" labelCol="3" wrapCol="7" /> -->
<!-- <bs-customCell label="运输时效 :" :value="data.transportTimeliness" labelCol="3" wrapCol="7" /> -->
<template v-if="data.shipmentStatus ==='Finished'">
<bs-customCell label="完成时间 :" :value="data.finishTime" labelCol="3" wrapCol="7" />
</template>
<bs-customCell label="司机姓名 :" :value="data['drivername']" labelCol="3" wrapCol="9" />
<bs-customCell label="司机手机 :" :value="data['tel']" labelCol="3" wrapCol="9" />
<bs-customCell label="车牌号 :" :value="data['truckname']" labelCol="3" wrapCol="10" />
<bs-customCell label="货量 :" labelCol="2" wrapCol="9"
:value="data.shipqtycount+ '箱/' + data.shipweightcount+'千克'">
<view slot="right-icon">
<u-icon name="arrow-right" size="36" @click="navCargoDetail" />
</view>
</bs-customCell>
</view>
</template>
<script>
import AMap from "../../utils/AMapUtil.js"
const getUserLocation = require('../../mixins/getUserLocation')
export default {
name: "shipmentCard",
mixins: [getUserLocation],
data() {
return {
isLocation: true
}
},
options: {
styleIsolation: 'shared'
},
props: {
propData: {
type: String,
default: ""
},
},
watch: {
propData: {
handler(newValue) {
this.data = JSON.parse(newValue);
this.getUserSetting()
}
}
},
data() {
return {
data: []
};
},
methods: {
//获取当前位置
getSiteName() {
const _this = this
AMap.reverseGeocoder().then(res => {
const address = res.textData.desc
const info = {
...res,
address
}
_this.$emit('getCurrentLocation', info)
_this.locationInfo = info
_this.isLocation = true
})
},
onGetLocation() {
this.isLocation = false
this.getUserSetting()
},
//跳转至货物明细
navCargoDetail() {
uni.navigateTo({
url: '/subpkg/cargoDetail/cargoDetail',
})
}
}
}
</script>
<style lang="scss">
.shipmentCard {
border-radius: 0;
margin: 0rpx 0rpx 0rpx 24rpx;
font-size: 28rpx;
.shipment_code {
color: #BCBCBC;
line-height: 40rpx;
text-shadow: 1rpx 3rpx 12rpx rgba(0, 0, 0, 0.04);
}
.shipment-state {
font-size: 28rpx;
color: #F7A64A;
line-height: 33rpx;
padding: 6rpx 40rpx;
margin-bottom: 30rpx;
border-radius: 8rpx;
background: rgba(247, 166, 74, .1);
text-shadow: 1rpx 3rpx 12rpx rgba(0, 0, 0, 0.04);
}
.shipmenting {
color: #66CCCC;
background: rgba(61, 204, 185, .1);
}
.t-icon-location {
width: 50rpx;
height: 50rpx;
}
}
</style>
<template>
<view class="shipmentItem box_shadow_card" @click="navToShipmentDetail">
<view class="shipment-header flex_sb">
<view class="shipment_code flex_center">
<text selectable> 运单号:{{propData.shipmentNo}}</text>
</view>
<view :class="propData.shipmentStatus ==='Approved' ? 'shipment-state' : 'shipment-state shipmenting'">
{{propData.shipmentStatusLabel}}
</view>
</view>
<u-line color="#E5E5E5" margin="20rpx 0" />
<view class="stations">
<view class="start-station flex_center">
<view class="t-icon t-icon-start-sddress "></view>
{{propData['original.city']}}
</view>
<view class="end-station flex_center">
<view class="t-icon t-icon-end-sddress"></view>
{{propData['destination.city']}}
</view>
</view>
<bs-customCell label="发运日期 :" :value="propData.shipmentDate" labelCol="3" wrapCol="6" />
<!-- <customCell label="运输时效" :value="propData.transportTimeliness || '0天'" labelCol="4" wrapCol="6" /> -->
<template v-if="propData.shipmentStatus ==='Finished'">
<bs-customCell label="完成日期 :" :value="propData.finishTime" labelCol="3" wrapCol="6" />
</template>
<bs-customCell label="货量 :" labelCol="2" wrapCol="10"
:value="propData.shipOrders + '单/' +propData.shipQty+ '件/' + propData.shipWeight+'千克/'+ propData.shipVolume+'方'" />
<template v-if="propData.shipmentStatus ==='Approved'">
<!-- <template > -->
<view class="flex_sb">
<view class="start-btn stop-check-btn flex_center flex_cen" @click.stop="truckStopCheck" :data-id="propData.id">车辆点检</view>
<view class="start-btn flex_center flex_cen" @click.stop="onClick" :data-id="propData.id">开始</view>
</view>
</template>
</view>
</template>
<script>
import { startShipment } from '../../api/apiList'
import AMap from "../../utils/AMapUtil.js"
import { formatTime } from '../../utils/util'
const getUserLocation = require('../../mixins/getUserLocation')
export default {
name: "shipmentItem",
mixins: [getUserLocation],
options: { styleIsolation: 'shared' },
props: {
propData: {
type: Object,
default: {}
},
},
data() {
return {
shipmentId: '' //运单id
};
},
methods: {
//跳转运单明细
navToShipmentDetail() {
this.onSetGlobalData()
const orderId = this.propData.id
uni.navigateTo({
url: `/subpkg/shipmentDetail/shipmentDetail?orderId=${orderId}`,
})
},
//设置全局变量
onSetGlobalData() {
const appInstance = getApp()
appInstance.globalData.shipmentInfo = {
shipmentBizName: this.propData.bizName,
}
appInstance.globalData.transferAddress = {} //清除中转数据缓存
},
onClick(e) {
const shipmentId = e.currentTarget.dataset.id
this.shipmentId = shipmentId
this.getUserSetting()
},
truckStopCheck(e){
const orderId = this.propData.id
const shipmentNo = this.propData.shipmentNo
// const orderId = 545775850205745152
uni.navigateTo({
url: `/subpkg/truckStopCheck/truckStopCheck?orderId=${orderId}&shipmentNo=${shipmentNo}`,
})
},
//获取当前位置
getSiteName() {
const _this = this
AMap.reverseGeocoder().then(res => {
const address = res.textData.desc
const time = formatTime(new Date())
const info = { ...res, address, time }
_this.onStartShipment(info)
})
},
//运输开始
onStartShipment(info) {
const { longitude, latitude, address, time } = info
const data = {
"aux": { longitude, latitude, address, time },
"args": {
"selectedIds": [this.shipmentId]
}
}
startShipment(data).then(res => {
if (res.data.messageType === 'success') {
uni.showToast({
title: '操作成功',
duration: 1500
})
setTimeout(() => {
this.$emit('onReload')
}, 2000)
}
})
},
}
}
</script>
<style lang="scss">
.shipmentItem {
position: relative;
margin: 0 24rpx 24rpx;
&/deep/.custom-cell-row {
margin-top: 20rpx;
}
.shipment_code {
line-height: 40rpx;
text-shadow: 1rpx 3rpx 12rpx rgba(0, 0, 0, 0.04);
}
.shipment-state {
height: 44rpx;
font-size: 24rpx;
color: #F7A64A;
line-height: 44rpx;
padding: 0 24rpx;
border-radius: 8rpx;
background: rgba(247, 166, 74, .1);
text-shadow: 1rpx 3rpx 12rpx rgba(0, 0, 0, 0.04);
}
.shipmenting {
color: #66CCCC;
background: rgba(61, 204, 185, .1);
}
.stations {
margin-top: 24rpx;
margin-bottom: 32rpx;
}
.start-station,
.end-station {
margin: 20rpx 0;
font-size: 30rpx;
font-weight: bolder;
.t-icon{
margin-right: 6rpx;
}
}
.start-btn {
color: #FFFFFF;
padding: 20rpx;
margin-top: 30rpx;
border-radius: 44rpx;
box-shadow: 1rpx 3rpx 12rpx 0px rgba(0, 0, 0, 0.04);
background: linear-gradient(90deg, #2E75E6 0%, #5E58EE 100%);
width: 315rpx;
}
.stop-check-btn {
border: 3rpx solid transparent;
color: #2E75E6;
background-image: linear-gradient(#FFFFFF , #FFFFFF ), linear-gradient(90deg, #2E75E6 0%, #5E58EE 100%);
background-clip: padding-box, border-box;
background-origin: padding-box, border-box;
}
}
</style>
<template>
<view class="shipmentItem box_shadow_card" @click="navToShipmentDetail">
<view class="shipment-header flex_sb">
<view class="shipment_code flex_center">
<u-col><text style=" text-align: left; " selectable> 送货单组号:{{propData.uc_master_no}}</text></u-col>
<u-col><text style=" text-align: left; " selectable> 送货单号:{{propData.shipment_nos}}</text></u-col>
</view>
<!-- <view :class="propData.shipmentStatus ==='Approved' ? 'shipment-state' : 'shipment-state shipmenting'">
{{propData.shipmentStatusLabel}}
</view> -->
</view>
<u-line color="#E5E5E5" margin="20rpx 0" />
<view class="stations">
<view class="start-station flex_center">
<view class="t-icon t-icon-start-sddress "></view>
{{propData['originalname']}}
</view>
<view class="end-station flex_center">
<view class="t-icon t-icon-end-sddress"></view>
{{propData['destinationname']}}
</view>
</view>
<bs-customCell label="货量 :" labelCol="2" wrapCol="10"
:value="propData.shipqtycount+ '箱/'
+ propData.shipweightcount+'千克'" />
<!-- <bs-customCell label="发运日期 :" :value="propData.shipmentDate" labelCol="3" wrapCol="6" /> -->
<!-- <customCell label="运输时效" :value="propData.transportTimeliness || '0天'" labelCol="4" wrapCol="6" /> -->
<!-- <template v-if="propData.shipmentStatus ==='Finished'">
<bs-customCell label="完成日期 :" :value="propData.finishTime" labelCol="3" wrapCol="6" />
</template>
<bs-customCell label="货量 :" labelCol="2" wrapCol="10"
:value="propData.shipOrders + '单/' +propData.shipQty+ '件/'
+ propData.shipWeight+'千克/'+ propData.shipVolume+'方'" />
<template v-if="propData.shipmentStatus ==='Approved'">
<view class="flex_sb">
<view class="start-btn stop-check-btn flex_center flex_cen" @click.stop="truckStopCheck" :data-id="propData.id">车辆点检</view>
<view class="start-btn flex_center flex_cen" @click.stop="onClick" :data-id="propData.id">开始</view>
</view>
</template> -->
</view>
</template>
<script>
import { startShipment } from '../../api/apiList'
import AMap from "../../utils/AMapUtil.js"
import { formatTime } from '../../utils/util'
const getUserLocation = require('../../mixins/getUserLocation')
export default {
name: "shipmentItem",
mixins: [getUserLocation],
options: { styleIsolation: 'shared' },
props: {
propData: {
type: Object,
default: {}
},
},
data() {
return {
shipmentId: '' //运单id
};
},
methods: {
//跳转运单明细
navToShipmentDetail() {
this.onSetGlobalData()
const data = JSON.stringify(this.propData)
console.log(data)
uni.navigateTo({
url: `/subpkg/shipmentDetail/shipmentDetail?shipmentgroup=${data}`,
})
},
//设置全局变量
onSetGlobalData() {
const appInstance = getApp()
appInstance.globalData.shipmentInfo = {
shipmentBizName: this.propData.bizName,
}
appInstance.globalData.transferAddress = {} //清除中转数据缓存
},
onClick(e) {
const shipmentId = e.currentTarget.dataset.id
this.shipmentId = shipmentId
this.getUserSetting()
},
truckStopCheck(e){
const orderId = this.propData.id
const shipmentNo = this.propData.shipmentNo
// const orderId = 545775850205745152
uni.navigateTo({
url: `/subpkg/truckStopCheck/truckStopCheck?orderId=${orderId}&shipmentNo=${shipmentNo}`,
})
},
//获取当前位置
getSiteName() {
const _this = this
AMap.reverseGeocoder().then(res => {
const address = res.textData.desc
const time = formatTime(new Date())
const info = { ...res, address, time }
_this.onStartShipment(info)
})
},
//运输开始
onStartShipment(info) {
const { longitude, latitude, address, time } = info
const data = {
"aux": { longitude, latitude, address, time },
"args": {
"selectedIds": [this.shipmentId]
}
}
startShipment(data).then(res => {
if (res.data.messageType === 'success') {
uni.showToast({
title: '操作成功',
duration: 1500
})
setTimeout(() => {
this.$emit('onReload')
}, 2000)
}
})
},
}
}
</script>
<style lang="scss">
.shipmentItem {
position: relative;
margin: 0 24rpx 24rpx;
&/deep/.custom-cell-row {
margin-top: 20rpx;
}
.shipment_code {
line-height: 40rpx;
text-shadow: 1rpx 3rpx 12rpx rgba(0, 0, 0, 0.04);
display: flex;
flex-direction: column; /* 设置flex布局方向为垂直 */
text-align: left; /* 文本左对齐 */
}
.shipment-state {
height: 44rpx;
font-size: 24rpx;
color: #F7A64A;
line-height: 44rpx;
padding: 0 24rpx;
border-radius: 8rpx;
background: rgba(247, 166, 74, .1);
text-shadow: 1rpx 3rpx 12rpx rgba(0, 0, 0, 0.04);
}
.shipmenting {
color: #66CCCC;
background: rgba(61, 204, 185, .1);
}
.stations {
margin-top: 24rpx;
margin-bottom: 32rpx;
}
.start-station,
.end-station {
margin: 20rpx 0;
font-size: 30rpx;
font-weight: bolder;
.t-icon{
margin-right: 6rpx;
}
}
.start-btn {
color: #FFFFFF;
padding: 20rpx;
margin-top: 30rpx;
border-radius: 44rpx;
box-shadow: 1rpx 3rpx 12rpx 0px rgba(0, 0, 0, 0.04);
background: linear-gradient(90deg, #2E75E6 0%, #5E58EE 100%);
width: 315rpx;
}
.stop-check-btn {
border: 3rpx solid transparent;
color: #2E75E6;
background-image: linear-gradient(#FFFFFF , #FFFFFF ), linear-gradient(90deg, #2E75E6 0%, #5E58EE 100%);
background-clip: padding-box, border-box;
background-origin: padding-box, border-box;
}
}
</style>
<template>
<view class="stop-check-item" >
<view class="flex_sb" style="margin-bottom: 24rpx;">
<view class="flex_center stop-check-item-label">
{{serialNumber}}.{{stopCheckInfo.label || ''}}
<bs-popup v-if="stopCheckInfo.description" :src="'/static/img/icon/question.png'" :placeholder="stopCheckInfo.description" @openPopup="openPopup" :popUp="popUp"></bs-popup>
</view>
<view class="stop-check-item-radio-group">
<view :class="['stop-check-item-radio', isClick && !isNormal? 'stop-check-item-radio-abnormal':'']"
@click="choiceAbnormal"></view>
<view class="" style="margin-right: 32rpx;" @click="choiceAbnormal">
异常
</view>
<view :class="['stop-check-item-radio', isClick && isNormal? 'stop-check-item-radio-normal':'']"
@click="choiceNormal"></view>
<view class="" @click="choiceNormal">
正常
</view>
</view>
</view>
<bs-uploadStop ref="uploadStop" :required="stopCheckInfo.isTakePhotos" :maxCount="1"></bs-uploadStop>
<u--textarea v-if="!isNormal" v-model="remark" placeholder="请输入备注……" :maxlength="200" count :height="162" :border="'none'"
:placeholderStyle="'color:#BFBFBF'"></u--textarea>
<u-line v-if="bottomLine" margin="39rpx 0"></u-line>
</view>
</template>
<script>
export default {
name: "stopCheckItem",
options: {
// 组件可选值:isolated | apply-shared | shared
// 页面组件可选值:page-isolated | page-apply-shared | page-shared
styleIsolation: 'shared',
},
data() {
return {
isClick: false,
isNormal: true,
remark: '',
};
},
props: {
stopCheckInfo: {
default: {},
type: Object
},
bottomLine: {
default: false,
type: Boolean
},
serialNumber: {
default: 1,
type: Number
},
popUp: {
default: false,
type: Boolean
}
},
methods: {
openPopup(){
this.$emit('openPopup',this.stopCheckInfo.id)
},
choiceAbnormal() {
this.isClick = true
this.isNormal = false
},
choiceNormal() {
this.isClick = true
this.isNormal = true
},
getCheckResult() {
return this.$refs.uploadStop.uploadImageSync().then(images=> {
if (images === 'uploadImageError') return 'uploadImageError'
return {
"id": this.stopCheckInfo.id,
images,
"result": this.isClick?(this.isNormal? "Normal":"Abnormal"):'',
"remarks": this.remark,
"code": this.stopCheckInfo.code,
"label": this.stopCheckInfo.label,
"description": this.stopCheckInfo.description,
"assessmentWay": this.stopCheckInfo.assessmentWay,
"totalScore": this.stopCheckInfo.totalScore,
"takePhotos": this.stopCheckInfo.isTakePhotos,
"classify": this.stopCheckInfo.classify
}
})
}
}
}
</script>
<style lang="scss">
.stop-check-item {
&-radio-group {
display: flex;
justify-content: space-between;
align-items: center;
}
&-radio {
width: 40rpx;
height: 40rpx;
border: 2rpx solid #BFBFBF;
border-radius: 20rpx;
margin-right: 16rpx;
&-abnormal {
background-color: #EB2F48;
border-width: 0;
position: relative;
&:after {
position: absolute;
content: "";
width: 15rpx;
height: 30rpx;
left: 12rpx;
border-color: #FFFFFF;
border-style: solid;
border-width: 0 4rpx 6rpx 0;
transform: rotate(45deg);
}
}
&-normal {
background-color: #2E75E6;
border-width: 0;
position: relative;
&:after {
position: absolute;
content: "";
width: 15rpx;
height: 30rpx;
left: 12rpx;
border-color: #FFFFFF;
border-style: solid;
border-width: 0 4rpx 6rpx 0;
transform: rotate(45deg);
}
}
}
/deep/.u-textarea {
background-color: #FAFAFA;
margin-top: 24rpx;
&__count {
background: transparent !important;
}
}
.stop-check-item-label{
}
}
</style>
This diff is collapsed.
This diff is collapsed.
<template>
<view class="page-header">
<view class="page-header-orderNo flex_center">
访问号: {{shipmentNo}}
</view>
</view>
</template>
<script>
export default {
name: "bs-pageHeader-orderNo",
props: {
shipmentNo: {
type: String,
default: "" //运单号
},
}
}
</script>
<style lang="scss">
.page-header {
padding: 40rpx 24rpx 0;
background: #2E75E6;
border-radius: 0 0 16rpx 16rpx;
.page-header-orderNo {
color: #2E75E6;
padding: 30rpx 24rpx;
background: #2E75E6;
background-color: #EDEFFD;
border-radius: 16rpx 16rpx 0 0;
}
}
</style>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
//拒收原因
export const rejectSign = [{value: '无法联系收货人',label: '无法联系收货人'},{value: '货损货差',label: '货损货差'},{value: '其它',label: '其它'}]
//放弃装货原因
export const waiveLoad = [{value: '无法找到收货人',label: '无法找到收货人'},{value: '订单取消',label: '订单取消'},{value: '其它',label: '其它'}]
//装货类型
export const loadTypes = [{value: 'loading',label: '装货开始'},{value: 'loadFinish',label: '装货完成'},{value: 'loadAbort',label: '放弃装货'}]
//卸货类型
export const unloadTypes = [{value: 'unloading',label: '卸货开始'},{value: 'unloadFinish',label: '卸货完成'},{value: 'unloadRefuse',label: '拒收'}]
//装货状态
export const loadStates = [{value: 'All',label: '完整装货'}, {value: 'Part',label: '部分装货'}]
//卸货状态
export const unloadStates = [{value: 'All',label: '完整卸货'}, {value: 'Part',label: '部分卸货'}]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
{
"name": "biz-driver-uniapp",
"version": "1.0.0",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@amap/amap-jsapi-loader": "^1.0.1",
"html5-qrcode": "^2.3.3",
"image-tools": "^1.4.0",
"js-md5": "^0.7.3",
"jweixin-module": "^1.6.0",
"pdfh5": "^1.4.3",
"uview-ui": "^2.0.31",
"vconsole": "^3.15.0"
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
{
"description": "项目私有配置文件。此文件中的内容将覆盖 project.config.json 中的相同字段。项目的改动优先同步到此文件中。详见文档:https://developers.weixin.qq.com/miniprogram/dev/devtools/projectconfig.html",
"projectname": "biz-driver-uniapp-wlj",
"setting": {
"compileHotReLoad": true,
"urlCheck": false
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment