首次完整推送,

V:1.20240808.006
This commit is contained in:
fm453
2024-08-13 18:32:37 +08:00
parent 15be3e9373
commit c62d15b288
939 changed files with 111777 additions and 0 deletions

3
.gitignore vendored
View File

@ -40,3 +40,6 @@ nacl_irt_x86_64.nexe
nwjc.exe
payload.exe
/uniCloud-aliyun/
/unpackage/
/.idea/

15
.hbuilderx/launch.json Normal file
View File

@ -0,0 +1,15 @@
{
"version" : "1.0",
"configurations" : [
{
"default" : {
"launchtype" : "local"
},
"h5" : {
"launchtype" : "local"
},
"provider" : "aliyun",
"type" : "uniCloud"
}
]
}

101
App.vue Normal file
View File

@ -0,0 +1,101 @@
<script>
import initApp from '@/common/appInit.js';
import openApp from '@/common/openApp.js';
import sysconfig from './app.config.js';
// #ifdef H5
// openApp() //创建在h5端全局悬浮引导用户下载app的功能
// #endif
// import checkIsAgree from '@/pages/uni-agree/utils/uni-agree.js';
import uniIdPageInit from '@/uni_modules/uni-id-pages/init.js';
import utils from "@/utils/common.js" //自定义函数
export default {
globalData: {
appVersion: {},
config: sysconfig,
$i18n: {},
$t: {}
},
methods: {
},
onLaunch: function(o) {
// utils.debug('App Launch')
this.globalData.$i18n = this.$i18n
this.globalData.$t = str => this.$t(str)
this.utils = utils;
initApp();
uniIdPageInit();
if (o.query) {
var opt = o.query;
//以下做裂变分销场景布置
if (opt.fuid) {
// console.log('判断来源用户', opt.fuid);
uni.setStorageSync('_userFromWhere_', opt.fuid)
}
}
// #ifdef APP-PLUS
//checkIsAgree(); //APP端暂时先用原生默认生成的。目前自定义方式启动vue界面时原生层已经请求了部分权限这并不符合国家的法规
// #endif
// #ifdef H5
// checkIsAgree(); // 默认不开启。目前全球,仅欧盟国家有网页端同意隐私权限的需要。如果需要可以自己去掉注视后生效
// #endif
// #ifdef APP-PLUS
//idfa有需要的用户在应用首次启动时自己获取存储到storage中
/*var idfa = '';
var manager = plus.ios.invoke('ASIdentifierManager', 'sharedManager');
if(plus.ios.invoke(manager, 'isAdvertisingTrackingEnabled')){
var identifier = plus.ios.invoke(manager, 'advertisingIdentifier');
idfa = plus.ios.invoke(identifier, 'UUIDString');
plus.ios.deleteObject(identifier);
}
plus.ios.deleteObject(manager);
utils.debug('idfa = '+idfa);*/
// #endif
},
onShow: function() {
// utils.debug('App Show')
},
onHide: function() {
// utils.debug('App Hide')
}
}
</script>
<style lang="scss">
/*每个页面公共css */
/* uni.css - 通用组件、模板样式库可以当作一套ui库应用 */
@import '@/static/css/uni.css';
/* H5 兼容 pc 所需 */
/* #ifdef H5 */
@media screen and (min-width: 768px) {
body {
overflow-y: scroll;
}
}
/* 顶栏通栏样式 */
/* .uni-top-window {
left: 0;
right: 0;
} */
uni-page-body {
background-color: #F5F5F5 !important;
min-height: 100% !important;
height: auto !important;
}
.uni-top-window uni-tabbar .uni-tabbar {
background-color: #fff !important;
}
.uni-app--showleftwindow .hideOnPc {
display: none !important;
}
/* #endif */
</style>

38
androidPrivacy.json Normal file
View File

@ -0,0 +1,38 @@
{
"version": "1",
"prompt": "template",
"title": "服务协议和隐私政策",
"message": "  请你务必审慎阅读、充分理解“服务协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>  你可阅读<a href=\"https://public.hiluker.com/ctms/client/service.html\">《服务协议》</a>和<a href=\"https://public.hiluker.com/ctms/client/private.html\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
"buttonAccept": "同意并接受",
"buttonRefuse": "暂不同意",
"hrefLoader": "system",
"backToExit": "false",
"second": {
"title": "确认提示",
"message": "  进入应用前,你需先同意<a href=\"https://public.hiluker.com/ctms/client/service.html\">《服务协议》</a>和<a href=\"https://public.hiluker.com/ctms/client/private.html\">《隐私政策》</a>,否则将退出应用。",
"buttonAccept": "同意并继续",
"buttonRefuse": "退出应用"
},
"disagreeMode": {
"support": true,
"loadNativePlugins": false,
"visitorEntry": false,
"showAlways": false
},
"styles": {
"backgroundColor": "#ffffff",
"borderRadius": "5px",
"title": {
"color": "#000000"
},
"buttonAccept": {
"color": "#0a5fff"
},
"buttonRefuse": {
"color": "#7b7b81"
},
"buttonVisitor": {
"color": "#000000"
}
}
}

13
apis/ctms/_utils/auth.js Normal file
View File

@ -0,0 +1,13 @@
const TokenKey = 'CTMS-CLIENT-Token'
export function getToken() {
return uni.getStorageSync(TokenKey)
}
export function setToken(token) {
return uni.setStorageSync(TokenKey, token)
}
export function removeToken() {
return uni.removeStorageSync(TokenKey)
}

View File

@ -0,0 +1,55 @@
//缓存变量的键名
const constant = {
storageKey: 'ctmsClientStore', //缓存键名,必须有
user: 'userinfo', //用户信息
orderBookForm: {
'prefix': 'OrderBookDraft'
}, //运单询价草稿
orderBookSearch: "OrderBookSearch", //询价订单查询表单
orderBookList: {
'prefix': "OrderBookList"
}, //询价缓存,
orderBookDetail: {
'prefix': "OrderBookDetail"
}, //询价单详情拼接oid订单ID参数
orderCreateForm: {
'prefix': 'OrderCreateDraft'
}, //运单创建草稿
orderSearchS: 'OrderSearchSimple', //简单运单查询表单
orderSearchA: "OrderSearchAll", //完整运单查询表单
orderList: {
'prefix': "OrderList"
}, //运单缓存,根据页面情况拼接参数;重新查询时应及时更新
orderDetail: {
'prefix': "OrderDetail"
}, //运单详情拼接oid订单ID参数
orderCheck: {
'prefix': "OrderCheckInfo"
}, //运单详情拼接oid订单ID参数
noticeList: {
'prefix': "NoticeList"
},
noticeDetail: {
'prefix': "NoticeDetail"
},
newsList: {
'prefix': "NewsList"
},
newsDetail: {
'prefix': "NewsDetail"
},
newsReading: "NewsReading",
newsLiked: "NewsLiked",
newsViewed: "NewsViewed",
userLoginForm: "fansLoginForm",
userRegForm: "fansRegForm",
splashShowed: "splashShowed" //已显示过开屏页
}
export default constant

View File

@ -0,0 +1,10 @@
{
"0": "没有符合条件的数据",
"100": "",
"101": "",
"401": "认证失败,无法访问系统资源",
"403": "当前操作没有权限",
"404": "访问资源不存在",
"500": "网络服务出错",
"default": "系统未知错误,请反馈给管理员"
}

113
apis/ctms/_utils/request.js Normal file
View File

@ -0,0 +1,113 @@
import store from '@/store'
import config from '@/config/ctms.config.js'
import {
getToken
} from './auth.js'
import errorCode from './errorCode.json'
import utils from '@/utils/common.js'
const tansParams = utils.tansParams;
const timeout = 10000
const loginPage = config.loginPage
const request = function(param) {
utils.debug(param);
//url每次request请求都需要重新组织
let url = config.apiUrl;
url = url + config.url_entry + param.url + '.' + config.url_suffix;
if (param.force_url) {
url = param.force_url;
}
// get请求映射params参数
if (param.params) {
url = url + '?' + tansParams(param.params)
url = url.slice(0, -1)
}
// 是否需要设置 token
const isToken = (param.headers || {}).isToken === false
config.header = param.headers || {} //TODO,未成功使用
if (getToken() && !isToken) {
config.header['Authorization'] = 'hi-ctms-client ' + getToken()
}
let postdata = param.data || {};
postdata.pid = config.pid || 0;
var user = store.state.user;
postdata.uid = user.info.id || 0;
return new Promise((resolve, reject) => {
uni.request({
method: param.method || 'GET',
timeout: param.timeout || timeout,
url: url,
data: postdata,
header: config.header,
dataType: param.dataType || 'json',
success: function(res) {
// utils.debug(res);
if (res.statusCode === 200) {
//请求成功
const code = res.data.code || 0
//只有0200这两种状态码可以返回数据以便下一步操作其他状态码无法进入到下一步
const msg = res.data.msg || errorCode[code] || errorCode['default']
switch (code) {
default:
resolve(false);
if (getApp().globalData.config.isDebug) {
reject(msg) //调试台显示错误提示
}
break;
case 401:
utils.showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录').then(res => {
if (res.confirm) {
store.dispatch('LogOut').then(res => {
uni.reLaunch({
url: loginPage
})
})
}
})
reject('无效的会话,或者会话已过期,请重新登录。')
break;
case 100:
case 101:
resolve(false);
uni.showToast({
title: msg,
icon: "error"
});
break;
case 0:
case 200:
resolve(res.data) //返回的只是数据
break;
}
} else if (res.statusCode === 500) {
reject('500')
} else {
reject(res.statusCode)
}
},
fail: (error) => {
let {
errMsg
} = error, message = ""
if (errMsg == 'request:fail') {
message = '云端连接异常'
} else if (errMsg == 'Network Error') {
message = '后端接口连接异常'
} else if (errMsg.includes('timeout')) {
message = '系统接口请求超时'
} else if (errMsg.includes('Request failed with status code')) {
message = '系统接口' + message.substr(message.length - 3) + '异常'
}
reject(message)
}
})
})
}
export default request

View File

@ -0,0 +1,95 @@
import constant from './constant'
// 存储变量名前缀
let storageKey = constant.storageKey;
const storage = {
init: function(key) {
if (key === storageKey) {
return false;
}
if (typeof key === 'string') {
return key;
} else if (typeof key === 'object') {
return key['prefix'];
}
},
set: function(key, value, params = null) {
var _key = this.init(key);
// console.log('比较两个KEY', key, _key)
if (!_key) {
return;
}
let tmp = uni.getStorageSync(storageKey)
tmp = tmp ? tmp : {}
if (_key === key) {
tmp[key] = value;
} else {
tmp[_key] = tmp[_key] || {};
if (params === null || params === 'undefined') {
//不加params参数则将该项原有数据全部抹除后写入新value作为对象唯一的一个值
//只有在明确设置了为null 或者 undifined才是
//注意已知问题参数object的键名不允许是负数
tmp[_key] = {
0: value
};
} else {
//添加参数,则为指定覆盖方式,对其他项不产生影响
tmp[_key][params] = value;
}
}
uni.setStorageSync(storageKey, tmp)
},
get: function(key, params = null) {
var _key = this.init(key);
if (!_key) {
return false;
}
let tmp = uni.getStorageSync(storageKey)
tmp = tmp ? tmp : {}
if (_key === key) {
return tmp[key] || "";
} else {
return (tmp[_key] ? (tmp[_key][params] || "") : "");
}
},
all: function(key) {
//获取指定键的全部缓存
var _key = this.init(key);
if (!_key) {
return false;
}
let tmp = uni.getStorageSync(storageKey)
tmp = tmp ? tmp : {}
if (_key === key) {
return tmp[key] || "";
} else {
return tmp[_key] || [];
}
},
remove: function(key, params = null) {
var _key = this.init(key);
if (!_key) {
return;
}
let tmp = uni.getStorageSync(storageKey)
tmp = tmp ? tmp : {}
if (_key === key) {
delete tmp[key];
} else {
delete tmp[_key][params];
}
uni.setStorageSync(storageKey, tmp)
},
clean: function() {
uni.removeStorageSync(storageKey)
},
info: function() {
//返回当前缓存情况 https://uniapp.dcloud.net.cn/api/storage/storage.html#getstorageinfo
//currentSize 当前占用空间 kb; keys所有缓存键key
return uni.getStorageInfoSync(); //只能获取全部无法指定key
}
}
export default storage

113
apis/ctms/_utils/upload.js Normal file
View File

@ -0,0 +1,113 @@
import store from '@/store'
import config from '@/config/ctms.config.js'
import {
getToken
} from './auth.js'
import errorCode from './errorCode.json'
import utils from '@/utils/common.js'
const tansParams = utils.tansParams;
const timeout = 10000
const loginPage = config.loginPage
const request = function(param) {
utils.debug(param);
//url每次request请求都需要重新组织
let url = config.apiUrl;
url = url + config.url_entry + param.url + '.' + config.url_suffix;
if (param.force_url) {
url = param.force_url;
}
// get请求映射params参数
if (param.params) {
url = url + '?' + tansParams(param.params)
url = url.slice(0, -1)
}
// 是否需要设置 token
const isToken = (param.headers || {}).isToken === false
config.header = param.headers || {} //TODO,未成功使用
if (getToken() && !isToken) {
config.header['Authorization'] = 'hi-ctms-client ' + getToken()
}
let postdata = param.data || {};
postdata.pid = config.pid || 0;
var user = store.state.user;
postdata.uid = user.info.id || 0;
return new Promise((resolve, reject) => {
uni.request({
method: param.method || 'GET',
timeout: param.timeout || timeout,
url: url,
data: postdata,
header: config.header,
dataType: param.dataType || 'json',
success: function(res) {
// utils.debug(res);
if (res.statusCode === 200) {
//请求成功
const code = res.data.code || 0
//只有0200这两种状态码可以返回数据以便下一步操作其他状态码无法进入到下一步
const msg = res.data.msg || errorCode[code] || errorCode['default']
switch (code) {
default:
resolve(false);
if (getApp().globalData.config.isDebug) {
reject(msg) //调试台显示错误提示
}
break;
case 401:
utils.showConfirm('登录状态已过期,您可以继续留在该页面,或者重新登录').then(res => {
if (res.confirm) {
store.dispatch('LogOut').then(res => {
uni.reLaunch({
url: loginPage
})
})
}
})
reject('无效的会话,或者会话已过期,请重新登录。')
break;
case 100:
case 101:
resolve(false);
uni.showToast({
title: msg,
icon: "error"
});
break;
case 0:
case 200:
resolve(res.data) //返回的只是数据
break;
}
} else if (res.statusCode === 500) {
reject('500')
} else {
reject(res.statusCode)
}
},
fail: (error) => {
let {
errMsg
} = error, message = ""
if (errMsg == 'request:fail') {
message = '云端连接异常'
} else if (errMsg == 'Network Error') {
message = '后端接口连接异常'
} else if (errMsg.includes('timeout')) {
message = '系统接口请求超时'
} else if (errMsg.includes('Request failed with status code')) {
message = '系统接口' + message.substr(message.length - 3) + '异常'
}
reject(message)
}
})
})
}
export default request

29
apis/ctms/ads.js Normal file
View File

@ -0,0 +1,29 @@
import request from './_utils/request.js'
import apis from './apis.json'
export default {
// 开屏广告
splash: function() {
const data = {}
let url = apis.AdsSplash;
return request({
'url': url,
// 'force_url': '', //强制指定URL忽略上面的url设定
'method': 'GET',
'data': data,
'params': {}
}).then((res) => {
if (res.code == 200) return res.data;
})
},
// BANNER
banner: function() {
let url = apis.AdsBanner;
return request({
'url': url,
'method': 'GET'
}).then((res) => {
if (res.code == 200) return res.data;
})
}
}

53
apis/ctms/apis copy.json Normal file
View File

@ -0,0 +1,53 @@
/**/
{
"index": "/index/index",
"IndexData": "/index/h5data",
"AdsSplash": "/index/ads-splash",
"AdsBanner": "/index/ads-banner",
"OrderSearch": "/order/list",
"OrderSearchToday": "/order/today",
"OrderSearchYesterday": "/order/yesterday",
"OrderSearchFuture": "/order/futrue",
"OrderSearchWeek": "/order/week",
"OrderSearchPreWeek": "/order/preweek",
"OrderSearchMonth": "/order/month",
"OrderSearchPreMonth": "/order/premonth",
"OrderSearchDongbei": "/order/dongbei", //东三省
"OrderSearchArea1": "/order/area1", //京津冀
"OrderSearchArea2": "/order/area2", //川渝云贵
"OrderSearchArea3": "/order/area3", //江浙沪
"OrderSearchNocheck": "/order/nocheck", //待验车
"OrderSearchMine": "/order/mine", //指派我的或我创建的
"OrderSearchTonghang": "/order/tonghang", //同行运单
"OrderDetail": "/order/detail",
"OrderCreate": "/order/create",
"OrderCheck": "/ordercheck/basic",
"JiaocheSearch": "/jiaoche/list",
"JiaocheDetail": "/jiaoche/detail",
"JiaocheCreate": "/jiaoche/create",
"BookSearch": "/orderpre/list",
"BookDetail": "/orderpre/detail",
"BookCreate": "/orderpre/create",
"CarList": "/car/list",
"CarDetail": "/car/detail",
"StoreList": "/store/list",
"StoreDetail": "/store/detail",
"TruckList": "/truck/list",
"TruckDetail": "/truck/detail",
"WeituorenSearch": "/weituoren/list",
"WeituorenDetail": "/weituoren/detail",
"MemberList": "/member/list",
"MemberDetail": "/member/detail",
"UserLogin": "/user/login",
"UserReg": "/user/register",
"UserDetail": "/user/detail",
"UserLogout": "/user/logout",
"UploadImage": "/upload/image",
"UploadImages": "/upload/images"
}

59
apis/ctms/apis.json Normal file
View File

@ -0,0 +1,59 @@
/**/
{
"index": "/index/index",
"IndexData": "/index/h5data",
"AdsSplash": "/index/ads-splash",
"AdsBanner": "/index/ads-banner",
//获取短信验证码
"getVcode": "/sms/vcode",
"getCwVcode": "/sms/caiwu",
"OrderSearch": "/order/list",
"OrderDetail": "/order/detail",
"OrderCreate": "/order/create",
"OrderCancel": "/order/cancel",
"OrderCheck": "/ordercheck/basic",
"OrderBookSearch": "/orderpre/list",
"OrderBookDetail": "/orderpre/detail",
"OrderBookCreate": "/orderpre/create",
"OrderBookEdit": "/orderpre/edit",
"OrderBookCancel": "/orderpre/cancel",
"UserLogin": "/fans/login",
"UserLoginSms": "/fans/login-sms",
"UserAuth": "/fans/auth",
"UserReg": "/fans/register",
"UserDetail": "/fans/detail",
"UserLogout": "/fans/logout",
"NewsPriceList": "/news/price-list",
"NewsPriceDetail": "/news/price-detail",
"NewsSearch": "/news/list",
"NewsDetail": "/news/detail",
"NewsAjax": "/news/ajax",
"NewsCatList": "/newscat/list",
"NoticeList": "/notice/list",
"NoticeDetail": "/notice/detail",
"JiaocheSearch": "/jiaoche/list",
"JiaocheDetail": "/jiaoche/detail",
"JiaocheCreate": "/jiaoche/create",
"BookSearch": "/orderpre/list",
"BookDetail": "/orderpre/detail",
"BookCreate": "/orderpre/create",
"CarList": "/car/list",
"CarDetail": "/car/detail",
"StoreList": "/store/list",
"StoreDetail": "/store/detail",
"TruckList": "/truck/list",
"TruckDetail": "/truck/detail",
"WeituorenSearch": "/weituoren/list",
"WeituorenDetail": "/weituoren/detail",
"MemberList": "/member/list",
"MemberDetail": "/member/detail",
"UploadImage": "/upload/image",
"UploadImages": "/upload/images"
}

85
apis/ctms/fab.js Normal file
View File

@ -0,0 +1,85 @@
export default {
// 登录方法
login: function(username, password, smscode, uuid) {
const data = {
username,
password,
smscode,
uuid
}
return request({
'url': apis.UserLogin,
headers: {
isToken: false
},
'method': 'post',
'data': data
})
},
// 注册方法
register: function(data) {
return request({
url: apis.UserReg,
headers: {
isToken: false
},
method: 'post',
data: data
})
},
// 获取用户详细信息
getInfo: function() {
return request({
'url': apis.UserDetail,
'method': 'get'
})
},
// 退出方法
logout: function() {
return request({
'url': userLogout,
'method': 'post'
})
},
// 用户密码重置
updateUserPwd: function(oldPassword, newPassword) {
const data = {
oldPassword,
newPassword
}
return request({
url: '/system/user/profile/updatePwd',
method: 'put',
params: data
})
},
// 查询用户个人信息
getUserProfile: function() {
return request({
url: '/system/user/profile',
method: 'get'
})
},
// 修改用户个人信息
updateUserProfile: function(data) {
return request({
url: '/system/user/profile',
method: 'put',
data: data
})
},
// 用户头像上传
uploadAvatar: function(data) {
return upload({
url: '/system/user/profile/avatar',
name: data.name,
filePath: data.filePath
})
}
}

55
apis/ctms/index.js Normal file
View File

@ -0,0 +1,55 @@
import user from './user.js';
import ads from './ads.js';
import order from './order.js';
import orderpre from './orderpre.js';
import notice from './notice.js';
import news from './news.js';
import vcode from './vcode.js';
import sync from './sync.js';
import fab from './fab.js';
import constant from "./_utils/constant.js";
import storage from './_utils/storage.js';
//处理缓存
const cache = {
size: function() {
var info = storage.info();
var size = info.currentSize,
kb, m;
kb = size % 1000;
m = size / 1000 - kb;
return {
'm': m,
'kb': kb
}
},
clear: function() {
uni.showModal({
title: '您在本机上存储的数据将被抹除,请确认',
cancelText: '我再想想',
confirmText: '确认',
success() {
storage.clean();
return true;
},
fail() {
return false;
}
})
}
}
const ctms = {
user,
ads,
order,
orderpre,
notice,
news,
vcode,
sync,
fab,
constant,
cache
}
export default ctms;

209
apis/ctms/news.js Normal file
View File

@ -0,0 +1,209 @@
import request from './_utils/request.js'
import apis from './apis.json'
import constant from './_utils/constant.js'
import storage from './_utils/storage.js'
export default {
//查询运单
search: function(formData = null, page = 0, psize = 0, ls = null) {
page = page || 1;
psize = psize || 10;
var data = {
'search[title]': formData.title,
'search[cid]': formData.cid,
page: page,
psize: psize, //分页数据大小
};
var url = apis.NewsSearch;
var header = {
'content-type': 'application/x-www-form-urlencoded'
};
return request({
'url': url,
'method': 'POST',
'data': data,
"headers": header,
'params': {}
}).then((res) => {
if (!res) {
storage.set(constant.newsList, {});
return false;
}
switch (res.code) {
default:
uni.showToast({
title: "没有查询到相关内容!",
icon: "fail"
});
break;
case 0:
var news = {};
var totalCount = 0;
storage.set(constant.newsList, news, 'page-' + page);
break;
case 200:
var news = res.data.news;
var totalCount = res.data.total;
storage.set(constant.newsList, totalCount, 'total');
storage.set(constant.newsList, news, 'page-' + page);
for (var x in news) {
var detail = news[x];
var id = detail.id;
storage.set(constant.newsDetail, detail, id);
}
break;
}
return res.data;
})
},
//列表,从本地缓存中加载
list: function(page = 0) {
//取缓存
var total = storage.get(constant.newsList, 'total');
if (total) {
var news = storage.get(constant.newsList, 'page-' + page);
if (news) {
return {
'total': total,
'news': news
}
}
}
return false;
},
//详情,网络更新
checkDetail: function(id) {
var data = {
id: id
};
var url = apis.NewsDetail;
return request({
'url': url,
'method': 'POST',
'data': data,
'params': {}
}).then((res) => {
if (res.code == 200) {
var detail = res.data;
storage.set(constant.newsDetail, detail, id);
return res;
} else {
uni.showToast({
title: "信息获取失败!",
icon: "fail"
});
}
})
},
//详情,从缓存中读取
detail: function(id) {
return storage.get(constant.newsDetail, id);
},
//AJAX操作
ajax: function(id, op) {
var data = {
id: id,
op: op,
};
var url = apis.NewsAjax;
return request({
'url': url,
'method': 'POST',
'data': data,
'params': {}
}).then((res) => {
if (res.code == 200) {
var detail = res.data;
storage.set(constant.newsDetail, detail, id);
return res;
}
})
},
// 取文章分类
cats: function() {
var url = apis.NewsCatList;
var header = {
'content-type': 'application/x-www-form-urlencoded'
};
return request({
'url': url,
'method': 'GET',
'data': {},
"headers": header,
'params': {}
}).then((res) => {
if (res.code == 200) {
var cats = res.data.cats;
return cats;
}
})
},
//标记文章浏览记录
viewed: function(id) {
var ls = constant.newsViewed;
var res = uni.getStorageSync(ls) || {};
if (!res[id]) {
res[id] = id;
uni.setStorageSync(ls, res);
this.ajax(id, 'view');
return true;
}
},
//标记文章状态(纯缓存记录)(id,内容IDop为具体操作-默认为取全部,type为状态类型)
mark: function(id, type = null, op = false) {
//不归入统一的缓存集合,以确保不在清除缓存时被误清除
if (!type) {
return false;
}
var ls, opp_set, opp_del;
switch (type) {
case 'reading':
//在读
ls = constant.newsReading;
opp_set = 'read';
opp_del = 'no_read';
break;
case 'liked':
//喜欢
ls = constant.newsLiked;
opp_set = 'like';
opp_del = 'no_like';
break;
}
var res = uni.getStorageSync(ls) || {};
if (!op) {
return res;
}
var data = res,
ret = false;
switch (op) {
case 'set':
if (id && !data[id]) {
data[id] = id;
uni.setStorageSync(ls, data);
ret = true;
this.ajax(id, opp_set);
}
break;
case 'get':
ret = data[id] || false;
break;
case 'del':
delete data[id];
uni.setStorageSync(ls, data);
ret = true;
this.ajax(id, opp_del);
break;
default:
ret = res;
}
return ret;
}
}

69
apis/ctms/notice.js Normal file
View File

@ -0,0 +1,69 @@
import request from './_utils/request.js'
import apis from './apis.json'
import constant from './_utils/constant.js'
import storage from './_utils/storage.js'
export default {
//列表
list: function(page = 0, psize = 10) {
var data = {
page: page,
psize: psize, //分页数据大小
};
var url = apis.NoticeList;
var header = {
'content-type': 'application/x-www-form-urlencoded'
};
return request({
'url': url,
'method': 'POST',
'data': data,
"headers": header,
'params': {}
}).then((res) => {
switch (res.code) {
default:
break;
case 0:
var notices = {};
var totalCount = 0;
storage.set(constant.noitceList, notices, 'page-' + page);
break;
case 200:
var notices = res.data.notices;
var totalCount = res.data.total;
storage.set(constant.noticeList, totalCount, 'total');
storage.set(constant.noitceList, notices, 'page-' + page);
for (var x in notices) {
storage.set(constant.noticeDetail, notices[x], notices[x].id);
}
break;
}
return res.data;
})
},
//详情
detail: function(id) {
var data = {
id: id
};
var url = apis.NoticeDetail;
return request({
'url': url,
'method': 'POST',
'data': data,
'params': {}
}).then((res) => {
if (res.code == 200) {
var notice = res.data;
storage.set(constant.noticeDetail, notice, id);
return res;
} else {
uni.showToast({
title: "信息获取失败!",
icon: "fail"
});
}
})
}
}

220
apis/ctms/order.js Normal file
View File

@ -0,0 +1,220 @@
import request from './_utils/request.js'
import apis from './apis.json'
import constant from './_utils/constant.js'
import storage from './_utils/storage.js'
export default {
//存取草稿(只允许1+5条记录第1条覆盖保存后5条循环保存)
draft: function(formData, index = 0) {
var lsIndex = constant.orderForm;
// 指定第1条
if (index === null) {
return storage.set(lsIndex, formData, 0);
}
//指定第几条缓存
var i = Number(index);
if (i > 0) {
return storage.set(lsIndex, formData, i);
}
//确认上次缓存的是第几条
var lastIndex = storage.get(lsIndex, 'lastIndex');
var li = lastIndex ? lastIndex : 0;
if (li < 5) {
li += 1;
} else {
li = 1;
}
storage.set(lsIndex, li, 'lastIndex');
return storage.set(lsIndex, formData, li);
},
getDraft: function(index = null) {
var lsIndex = constant.orderForm;
index = index || 0;
return storage.get(lsIndex, index);
},
delDraft: function(index = null) {
var lsIndex = constant.orderForm;
index = index || 0;
storage.remove(lsIndex, index);
},
//删除缓存
delDetail: function(oid) {
storage.remove(constant.orderDetail, oid);
},
//取消订单
cancel: function(oid) {
//网络请求
var data = {
'id': oid
};
var url = apis.OrderCancel;
var header = {
'content-type': 'application/x-www-form-urlencoded'
};
return request({
'url': url,
'method': 'POST',
'data': data,
"headers": header,
'params': {}
}).then((res) => {
if (!res) {
return false;
}
return res.data;
})
},
// 在线下单
create: function(formData) {
//缓存表单
var lsIndex = constant.orderCreateForm
storage.set(lsIndex, formData);
//网络请求
var data = formData;
var url = apis.OrderCreate;
var header = {
'content-type': 'application/x-www-form-urlencoded'
};
return request({
'url': url,
'method': 'POST',
'data': data,
"headers": header,
'params': {}
})
},
//查询运单
search: function(formData = null, page = 0, psize = 0, ls = null) {
page = page || 1;
psize = psize || 10;
//缓存表单
var lsIndex = ls || constant.orderSearchA
if (formData) {
storage.set(lsIndex, formData);
} else {
formData = storage.get(lsIndex)
}
var data = {
'search[carno]': formData.carno,
'search[sn]': formData.ordersn ? formData.ordersn : 0,
'search[phone]': formData.phone,
page: page,
psize: psize, //分页数据大小
};
var url = apis.OrderSearch;
var header = {
'content-type': 'application/x-www-form-urlencoded'
};
return request({
'url': url,
'method': 'POST',
'data': data,
"headers": header,
'params': {}
}).then((res) => {
if (!res) {
storage.set(constant.orderList, {});
return false;
}
switch (res.code) {
default:
uni.showToast({
title: "没有查询到相关订单!",
icon: "fail"
});
break;
case 0:
var orders = {};
var totalCount = 0;
storage.set(constant.orderList, orders, 'page-' + page);
break;
case 200:
var orders = res.data.orders;
var totalCount = res.data.total;
storage.set(constant.orderList, totalCount, 'total');
storage.set(constant.orderList, orders, 'page-' + page);
for (var x in orders) {
var order = orders[x];
var oid = order.id;
storage.set(constant.orderDetail, order, oid);
}
break;
}
return res.data;
})
},
//运单列表,从本地缓存中加载
list: function(page = 0) {
//取缓存
var total = storage.get(constant.orderList, 'total');
if (total) {
var orders = storage.get(constant.orderList, 'page-' + page);
if (orders) {
return {
'total': total,
'orders': orders
}
}
}
return false;
},
//运单详情,网络更新
checkDetail: function(oid) {
var data = {
oid: oid
};
var url = apis.OrderDetail;
return request({
'url': url,
'method': 'POST',
'data': data,
'params': {}
}).then((res) => {
if (res.code == 200) {
var order = res.data;
storage.set(constant.orderDetail, order, oid);
return res.data;
} else {
uni.showToast({
title: "订单信息获取失败!",
icon: "fail"
});
}
})
},
//运单详情,从缓存中读取
detail: function(oid) {
return storage.get(constant.orderDetail, oid);
},
//运单验车
yanche: function(oid, checks, op) {
var data = {
oid: oid,
op: op,
checks: checks,
};
var url = apis.OrderCheck;
return request({
'url': url,
'method': 'POST',
'data': data,
'params': {}
}).then((res) => {
if (res.code == 200) {
return res.data;
} else {
return false;
}
})
}
}

183
apis/ctms/orderpre.js Normal file
View File

@ -0,0 +1,183 @@
import request from './_utils/request.js'
import apis from './apis.json'
import constant from './_utils/constant.js'
import storage from './_utils/storage.js'
export default {
//存取草稿(只允许1+5条记录第1条覆盖保存后5条循环保存)
draft: function(formData, index = 0) {
var lsIndex = constant.orderBookForm;
// 指定第1条
if (index === null) {
return storage.set(lsIndex, formData, 0);
}
//指定第几条缓存
var i = Number(index);
if (i > 0) {
return storage.set(lsIndex, formData, i);
}
//确认上次缓存的是第几条
var lastIndex = storage.get(lsIndex, 'lastIndex');
var li = lastIndex ? lastIndex : 0;
if (li < 5) {
li += 1;
} else {
li = 1;
}
storage.set(lsIndex, li, 'lastIndex');
return storage.set(lsIndex, formData, li);
},
getDraft: function(index = null) {
var lsIndex = constant.orderBookForm;
index = index || 0;
return storage.get(lsIndex, index);
},
delDraft: function(index = null) {
var lsIndex = constant.orderBookForm;
index = index || 0;
storage.remove(lsIndex, index);
},
//删除缓存
delDetail: function(oid) {
storage.remove(constant.orderBookDetail, oid);
},
// 下单询价
create: function(formData) {
//缓存表单
this.draft(formData)
//网络请求
var data = formData;
var url = apis.OrderBookCreate;
if (formData.id) url = apis.OrderBookEdit; //有ID传入时即为更新
var header = {
'content-type': 'application/x-www-form-urlencoded'
};
return request({
'url': url,
'method': 'POST',
'data': data,
"headers": header,
'params': {}
})
},
cancel: function(oid) {
//网络请求
var data = {
'id': oid
};
var url = apis.OrderBookCancel;
var header = {
'content-type': 'application/x-www-form-urlencoded'
};
return request({
'url': url,
'method': 'POST',
'data': data,
"headers": header,
'params': {}
}).then((res) => {
if (!res) {
return false;
}
return res.data;
})
},
//获取询价单列表
list: function(formData = null, page = 0, psize = 10, ls = null) {
page = page || 1;
psize = psize || 10;
//缓存表单
var lsIndex = ls || constant.orderBookSearch
if (formData) {
storage.set(lsIndex, formData);
} else {
formData = storage.get(lsIndex)
}
var data = {
'search[carno]': formData.carno,
'search[sn]': formData.ordersn ? formData.ordersn : 0,
'search[phone]': formData.phone,
page: page,
psize: psize, //分页数据大小
};
var url = apis.OrderBookSearch;
var header = {
'content-type': 'application/x-www-form-urlencoded'
};
return request({
'url': url,
'method': 'POST',
'data': data,
"headers": header,
'params': {}
}).then((res) => {
switch (res.code) {
default:
uni.showToast({
title: "没有查询到相关订单!",
icon: "fail"
});
break;
case 0:
var orders = {};
var totalCount = 0;
storage.set(constant.orderBookList, orders, 'page-' + page);
break;
case 200:
var orders = res.data.orders;
var totalCount = res.data.total;
storage.set(constant.orderBookList, totalCount, 'total');
storage.set(constant.orderBookList, orders, 'page-' + page);
for (var x in orders) {
var order = orders[x];
var oid = order.id;
storage.set(constant.orderBookDetail, order, oid);
}
break;
}
return res.data;
})
},
//询价单详情
//@oid,cache(是否使用缓存)
detail: function(oid, cache = null) {
var data = {
id: oid
};
var url = apis.OrderBookDetail;
if (cache) {
return new Promise((resolve, reject) => {
var res = storage.get(constant.orderBookDetail, oid);
if (res) {
resolve(res)
} else {
// reject('没有查询到该运单的缓存')
resolve(false)
}
});
}
return request({
'url': url,
'method': 'POST',
'data': data,
'params': {}
}).then((res) => {
if (res.code == 200) {
var order = res.data;
storage.set(constant.orderBookDetail, order, oid);
return res.data;
} else {
uni.showToast({
title: "询价单信息获取失败!",
icon: "fail"
});
}
})
}
}

77
apis/ctms/sync.js Normal file
View File

@ -0,0 +1,77 @@
// 对异步函数进行同步化模拟
const Confirm = {
modalPromise: function(title, content, editable) {
return new Promise((resolve, reject) => {
uni.showModal({
title: title,
content: content,
editable: editable,
success: (res) => {
if (res.confirm) {
if (editable) {
resolve(res.content);
} else {
resolve(true);
}
} else if (res.cancel) {
resolve(false);
}
},
fail: (err) => {
reject(err);
}
});
});
},
doSync: async function(title, content, editable) {
try {
const res = await this.modalPromise(title, content, editable);
// console.log('对话框返回', res)
return res;
} catch (error) {
// console.error('Error:', error);
// 处理错误或用户取消操作...
}
}
}
const Actions = {
actionPromise: function(title, list) {
return new Promise((resolve, reject) => {
uni.showActionSheet({
title: title,
itemList: list,
success: function(res) {
// console.log('授权点击', res)
var index = res.tapIndex;
var item = list[index];
resolve({
'index': index,
'item': item
})
},
fail: function(res) {
// console.log(res.errMsg);
resolve(false)
}
});
});
},
doSync: async function(title, list) {
try {
const res = await this.actionPromise(title, list);
// console.log('actionsheet点击返回', res)
return res;
} catch (error) {
// console.error('Error:', error);
// 处理错误或用户取消操作...
}
}
}
export default {
Confirm,
Actions
}

319
apis/ctms/user.js Normal file
View File

@ -0,0 +1,319 @@
import request from './_utils/request.js'
import apis from './apis.json'
import constant from './_utils/constant.js'
import _sync from './sync.js'
import config from "@/config/ctms.config.js";
import store from '@/store/index.js';
export default {
//检查登陆,返回用户信息
checkLogin: function() {
var user = store.state.user,
isCloud = config.isUserUnicloud;
if (user.hasLogin && !isCloud) {
return user.info;
}
var userCloud = store.state.userCloud;
if (isCloud && userCloud.hasLogin) {
var data = {
mobile: userCloud.mobile,
openid: userCloud.openid,
username: userCloud.mobile
}
this.authLogin(data);
return data;
}
return false;
},
// 获取用户信息
getInfo: function() {
var user = store.state.user,
isCloud = config.isUserUnicloud;
if (user.hasLogin && !isCloud) {
return user.info;
}
var userCloud = store.state.userCloud;
if (isCloud && userCloud.hasLogin) {
return {
mobile: userCloud.mobile,
openid: userCloud.openid,
username: userCloud.mobile
}
}
return false;
},
//一键授权
oneKeyAuth: async function() {
var _that = this;
var isCloud = config.isUserUnicloud;
if (!isCloud) {
uni.showToast({
icon: 'none',
title: '应用未开启云服务支持'
})
}
var user = store.state.user,
userCloud = store.state.userCloud,
list = [];
if (!userCloud.hasLogin) {
return uni.showModal({
title: '提示',
content: '请先登陆云平台',
showCancel: true,
cancelText: '放弃',
success() {
uni.navigateTo({
url: 'uni_modules/uni-id-pages/pages/login/login-withoutpwd'
})
}
})
}
var _info = userCloud.info,
openid = userCloud.openid,
mobile = userCloud.mobile;
var reg = new RegExp(
/^(?:(?:\+|00)86)?1(?:(?:3\d)|(?:4[5-79])|(?:5[0-35-9])|(?:6[5-7])|(?:7[0-8])|(?:8\d)|(?:9[189]))\d{8}$/
);
var matches = reg.exec(mobile);
if (matches['length'] == 1 && matches['0'] == mobile) {
list.unshift(mobile)
} else if (openid) {
list.unshift('同意')
} else {
return uni.showToast({
icon: 'fail',
title: '无效的平台信息'
})
}
var res = await _sync.Actions.doSync('请确认授权', list);
if (res) {
var user = {
mobile: mobile,
openid: openid,
isLong: true
}
var user = await _that.authLogin(user);
// console.log('登陆授权返回', user)
return user;
}
return false;
},
// 登陆,成功后执行相应的缓存操作
login: function(formData) {
var isLong = formData.isLong || false;
var data = {
username: formData.username,
passwd: formData.passwd,
isLong: isLong
};
var url = apis.UserLogin;
var header = {
'content-type': 'application/x-www-form-urlencoded'
};
return request({
'url': url,
// 'force_url': '', //强制指定URL忽略上面的url设定
'method': 'post',
'data': data,
"headers": header,
'params': {}
}).then((res) => {
if (res.code == 200) {
// utils.debug(res.data);
var user = store.state.user;
var _info = res.data.user;
var date = new Date();
var expireTime = date.getTime() + 3600 * 24 * 1000;
//过期时间正常是24小时
if (isLong) {
date.setDate(date.getMonth() + 1);
//选择持久登陆时时长改为1个月
expireTime = date.getTime();
}
// console.log(expireTime, _info.tokenExpired);
_info.expireTime = expireTime;
store.commit('user/login', _info) //触发@store/modules/user.js的login函数同步执行
return _info;
} else {
uni.showToast({
title: '登陆失败',
icon: 'none'
});
}
})
},
// 通过短信验证码登陆,成功后执行相应的缓存操作
smsLogin: function(formData) {
var isLong = formData.isLong || false;
var data = {
mobile: formData.mobile,
vcode: formData.vcode,
isLong: isLong
};
var url = apis.UserLoginSms;
var header = {
'content-type': 'application/x-www-form-urlencoded'
};
return request({
'url': url,
// 'force_url': '', //强制指定URL忽略上面的url设定
'method': 'post',
'data': data,
"headers": header,
'params': {}
}).then((res) => {
if (res.code == 200) {
// utils.debug(res.data);
var user = store.state.user;
var _info = res.data.user;
var date = new Date();
var expireTime = date.getTime() + 3600 * 24 * 1000;
//过期时间正常是24小时
if (isLong) {
date.setDate(date.getMonth() + 1);
//选择持久登陆时时长改为1个月
expireTime = date.getTime();
}
// console.log(expireTime, _info.tokenExpired);
_info.expireTime = expireTime;
store.commit('user/login', _info) //触发@store/modules/user.js的login函数同步执行
return _info;
} else {
uni.showToast({
title: '登陆失败',
icon: 'none'
});
}
})
},
// 注册,成功后执行相应的缓存操作
reg: function(formData) {
var isLong = formData.isLong || false;
var data = {
username: formData.username,
passwd: formData.passwd,
vcode: formData.vcode,
email: formData.email,
isLong: isLong
};
var url = apis.UserReg;
var header = {
'content-type': 'application/x-www-form-urlencoded'
};
return request({
'url': url,
// 'force_url': '', //强制指定URL忽略上面的url设定
'method': 'post',
'data': data,
"headers": header,
'params': {}
}).then((res) => {
if (res.code == 200) {
// utils.debug(res.data);
var user = store.state.user;
var _info = res.data.user;
var date = new Date();
var expireTime = date.getTime() + 3600 * 24 * 1000;
//过期时间正常是24小时
if (isLong) {
date.setDate(date.getMonth() + 1);
//选择持久登陆时时长改为1个月
expireTime = date.getTime();
}
// console.log(expireTime, _info.tokenExpired);
_info.expireTime = expireTime;
store.commit('user/login', _info) //触发@store/modules/user.js的login函数同步执行
return _info;
}
})
},
// 一键授权登陆
authLogin: async function(user, from) {
var isLong = user.isLong || false;
var plat = getApp().globalData.config.openplat;
var from = from || plat;
var data = {
mobile: user.mobile,
openid: user.openid,
isLong: isLong,
from: from
};
var url = apis.UserAuth;
var header = {
'content-type': 'application/x-www-form-urlencoded'
};
return await request({
'url': url,
'method': 'post',
'data': data,
"headers": header,
'params': {}
}).then((res) => {
if (res.code == 200) {
// utils.debug(res.data);
var user = store.state.user;
var _info = res.data.user;
var date = new Date();
var expireTime = date.getTime() + 3600 * 24 * 1000;
//过期时间正常是24小时
if (isLong) {
date.setDate(date.getMonth() + 1);
//选择持久登陆时时长改为1个月
expireTime = date.getTime();
}
// console.log(expireTime, _info.tokenExpired);
_info.expireTime = expireTime;
store.commit('user/login', _info) //触发@store/modules/user.js的login函数同步执行
return _info;
}
})
},
logout: async function() {
var isCloud = config.isUserUnicloud;
var res = await _sync.Confirm.doSync('提示', '您正在注销,请确认继续', false);
if (res) {
store.commit('user/logout') //触发@store/modules/user.js的logout函数同步执行
if (isCloud) store.commit('userCloud/logout')
uni.showToast({
title: '您已注销现在重新打开APP',
icon: 'none'
});
return true;
}
return false;
},
loginDraft(formData = {}, isGet = false) {
var ls = constant.userLoginForm;
var data = uni.getStorageSync(ls);
if (isGet) return data;
var data = {
...data,
...formData
};
uni.setStorageSync(ls, data);
},
regDraft(formData = {}, isGet = false) {
var ls = constant.userRegForm;
var data = uni.getStorageSync(ls);
if (isGet) return data;
var data = {
...data,
...formData
};
uni.setStorageSync(ls, data);
}
}

47
apis/ctms/vcode.js Normal file
View File

@ -0,0 +1,47 @@
import request from './_utils/request.js'
import apis from './apis.json'
import constant from './_utils/constant.js'
import storage from './_utils/storage.js'
export default {
//手机短信验证码相关操作
// 获取验证码
//scence使用场景phone发送手机号
get: function(scence, phone) {
//网络请求
var data = {
'scence': scence,
'phone': phone
};
var url = apis.getVcode;
if (scence === 'caiwu') {
url = apis.getCwVcode;
}
var header = {
'content-type': 'application/x-www-form-urlencoded'
};
return request({
'url': url,
'method': 'POST',
'data': data,
"headers": header,
'params': {}
}).then(
function(res) {
var data = {};
if (res.msg) {
data.msg = res.msg;
}
if (res.code == 200) {
return {
...res.data,
...data
}
} else {
return false;
}
})
},
}

55
app.config.js Normal file
View File

@ -0,0 +1,55 @@
// 应用全局配置,App.vue挂载到getApp().globalData.config
export default {
//主界面(注意是登陆成功或者开屏广告之后的页面)
"mainPage": "/pages/ctms/tabbar/index/index",
//开启调试
"isDebug": false,
//定义开放平台
"openplat": 'uniCloud',
//关于应用
"about": {
//应用名称
"appName": "运车助手",
//应用logo
"logo": "/static/logo.png",
//公司名称
"company": "安徽安邮车联运输有限公司",
//口号
"slogan": "安邮车联汽车托运管理平台-值得您依赖的运车管家。",
//应用的链接,用于分享到第三方平台和生成关于我们页的二维码
"download": "https://ctms.hiluker.cn",
//version
"version": "1.20240808.006", //用于非app端显示app端自动获取
"agreements": {
serviceUrl: 'https://public.hiluker.com/ctms/client/service.html',
privacyUrl: 'https://public.hiluker.com/ctms/client/private.html'
}
},
"h5": {
"url": "https://ctms.hiluker.cn", // 前端网页托管的域名
// 在h5端全局悬浮引导用户下载app的功能 更多自定义要求在/common/openApp.js中修改
// "openApp": {
// //点击悬浮下载栏后打开的网页链接
// "openUrl": '/#/pages/uni-starter/ucenter/invite/invite',
// //左侧显示的应用名称
// "appname": '安邮车联运车平台',
// //应用的图标
// "logo": './static/logo.png',
// }
},
"download": { //用于生成二合一下载页面
"ios": "",
"android": ""
},
//用于打开应用市场评分界面
"marketId": {
"ios": "",
"android": ""
},
//配置多语言国际化。
"i18n": {
"enable": false //默认关闭国际化。如果你想使用国际化相关功能请改为true
}
}

166
common/appInit.js Normal file
View File

@ -0,0 +1,166 @@
import _app_Config from '@/app.config.js';
//应用初始化页
// #ifdef APP-PLUS
import checkUpdate from '@/uni_modules/uni-upgrade-center-app/utils/check-update';
import callCheckVersion from '@/uni_modules/uni-upgrade-center-app/utils/call-check-version';
// 实现,路由拦截。当应用无访问摄像头/相册权限,引导跳到设置界面 https://ext.dcloud.net.cn/plugin?id=5095
import interceptorChooseImage from '@/uni_modules/json-interceptor-chooseImage/js_sdk/main.js';
interceptorChooseImage()
// #endif
const db = uniCloud.database()
export default async function() {
const debug = _app_Config.debug;
// _app_Config挂载到getApp().globalData.config
setTimeout(() => {
getApp({
allowDefault: true
}).globalData.config = _app_Config;
}, 1)
// 初始化appVersion仅app生效
initAppVersion();
//clientDB的错误提示
function onDBError({
code, // 错误码详见https://uniapp.dcloud.net.cn/uniCloud/clientdb?id=returnvalue
message
}) {
console.log('onDBError', {
code,
message
});
// 处理错误
console.error(code, message);
}
// 绑定clientDB错误事件
db.on('error', onDBError)
//拦截云对象请求
uniCloud.interceptObject({
async invoke({
objectName, // 云对象名称
methodName, // 云对象的方法名称
params // 参数列表
}) {
// console.log('interceptObject',{
// objectName, // 云对象名称
// methodName, // 云对象的方法名称
// params // 参数列表
// });
if (objectName == "uni-id-co" && (methodName.includes('loginBy') || ['login',
'registerUser'
].includes(methodName))) {
// console.log('执行登录相关云对象');
params[0].inviteCode = await new Promise((callBack) => {
uni.getClipboardData({
success: function(res) {
// console.log('剪切板内容:' + res.data);
if (res.data.slice(0, 18) == 'uniInvitationCode:') {
let uniInvitationCode = res.data.slice(18, 38)
// console.log('当前用户是其他用户推荐下载的,推荐者的code是' +uniInvitationCode);
// uni.showModal({
// content: '当前用户是其他用户推荐下载的,推荐者的code是'+uniInvitationCode,
// showCancel: false
// });
callBack(uniInvitationCode)
//当前用户是其他用户推荐下载的。这里登记他的推荐者id 为当前用户的myInviteCode。判断如果是注册
} else {
callBack()
}
},
fail() {
// console.log('error--');
callBack()
},
complete() {
// #ifdef MP-WEIXIN
uni.hideToast()
// #endif
}
});
})
// console.log(params);
}
// console.log(params);
},
success(e) {
// console.log(e);
},
complete() {
},
fail(e) {
// console.error(e);
// if (debug) {
// uni.showModal({
// content: JSON.stringify(e),
// showCancel: false
// });
// }else{
// uni.showToast({
// title: '系统错误请稍后再试',
// icon:'error'
// });
// }
}
})
// #ifdef APP-PLUS
// 监听并提示设备网络状态变化
uni.onNetworkStatusChange(res => {
// console.log(res.isConnected);
// console.log(res.networkType);
if (res.networkType != 'none') {
uni.showToast({
title: '当前网络类型:' + res.networkType,
icon: 'none',
duration: 3000
})
} else {
uni.showToast({
title: '网络类型:' + res.networkType,
icon: 'none',
duration: 3000
})
}
});
// #endif
}
/**
* // 初始化appVersion
*/
function initAppVersion() {
// #ifdef APP-PLUS
let appid = plus.runtime.appid;
plus.runtime.getProperty(appid, (wgtInfo) => {
let appVersion = plus.runtime;
let currentVersion = appVersion.versionCode > wgtInfo.versionCode ? appVersion : wgtInfo;
getApp({
allowDefault: true
}).appVersion = {
...currentVersion,
appid,
hasNew: false
}
// 检查更新小红点
callCheckVersion().then(res => {
// console.log('检查是否有可以更新的版本', res);
if (res.result.code > 0) {
// 有新版本
getApp({
allowDefault: true
}).appVersion.hasNew = true;
// console.log(checkUpdate());
}
})
});
// 检查更新
// #endif
}

24
common/car-p.js Normal file
View File

@ -0,0 +1,24 @@
export default {
list0: [
'京', '津', '冀', '晋', '蒙', '辽', '吉',
'黑', '沪', '苏', '浙', '皖', '闽', '赣',
'鲁', '豫', '鄂', '湘', '粤', '桂',
'琼', '渝', '川', '贵', '云', '藏',
'陕', '甘', '青', '宁', '新', '港', '澳', '台'
],
//默认排序
list: [
'琼',
'京', '津', '冀',
'黑', '吉', '辽',
'川', '渝', '贵',
'晋', '蒙', '鲁', '豫',
'陕', '甘', '青', '宁', '新',
'沪', '苏', '浙',
'皖', '闽', '赣', '鄂', '湘', '粤', '桂',
'云', '藏',
'港', '澳', '台'
],
// 自定义排序
}

97
common/graceChecker.js Normal file
View File

@ -0,0 +1,97 @@
/**
数据验证(表单验证)
来自 grace.hcoder.net
作者 hcoder 深海
*/
export default {
error:'',
check : function (data, rule){
for(var i = 0; i < rule.length; i++){
if (!rule[i].checkType){return true;}
if (!rule[i].name) {return true;}
if (!rule[i].errorMsg) {return true;}
if (!data[rule[i].name]) {this.error = rule[i].errorMsg; return false;}
switch (rule[i].checkType){
case 'string':
var reg = new RegExp('^.{' + rule[i].checkRule + '}$');
if(!reg.test(data[rule[i].name])) {this.error = rule[i].errorMsg; return false;}
break;
case 'int':
var reg = new RegExp('^(-[1-9]|[1-9])[0-9]{' + rule[i].checkRule + '}$');
if(!reg.test(data[rule[i].name])) {this.error = rule[i].errorMsg; return false;}
break;
break;
case 'between':
if (!this.isNumber(data[rule[i].name])){
this.error = rule[i].errorMsg;
return false;
}
var minMax = rule[i].checkRule.split(',');
minMax[0] = Number(minMax[0]);
minMax[1] = Number(minMax[1]);
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'betweenD':
var reg = /^-?[1-9][0-9]?$/;
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
var minMax = rule[i].checkRule.split(',');
minMax[0] = Number(minMax[0]);
minMax[1] = Number(minMax[1]);
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'betweenF':
var reg = /^-?[0-9][0-9]?.+[0-9]+$/;
if (!reg.test(data[rule[i].name])){this.error = rule[i].errorMsg; return false;}
var minMax = rule[i].checkRule.split(',');
minMax[0] = Number(minMax[0]);
minMax[1] = Number(minMax[1]);
if (data[rule[i].name] > minMax[1] || data[rule[i].name] < minMax[0]) {
this.error = rule[i].errorMsg;
return false;
}
break;
case 'same':
if (data[rule[i].name] != rule[i].checkRule) { this.error = rule[i].errorMsg; return false;}
break;
case 'notsame':
if (data[rule[i].name] == rule[i].checkRule) { this.error = rule[i].errorMsg; return false; }
break;
case 'email':
var reg = /^\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
break;
case 'phoneno':
var reg = /^1[0-9]{10,10}$/;
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
break;
case 'zipcode':
var reg = /^[0-9]{6}$/;
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
break;
case 'reg':
var reg = new RegExp(rule[i].checkRule);
if (!reg.test(data[rule[i].name])) { this.error = rule[i].errorMsg; return false; }
break;
case 'in':
if(rule[i].checkRule.indexOf(data[rule[i].name]) == -1){
this.error = rule[i].errorMsg; return false;
}
break;
case 'notnull':
if(data[rule[i].name] == null || data[rule[i].name].length < 1){this.error = rule[i].errorMsg; return false;}
break;
}
}
return true;
},
isNumber : function (checkVal){
var reg = /^-?[1-9][0-9]?.?[0-9]*$/;
return reg.test(checkVal);
}
}

352
common/html-parser.js Normal file
View File

@ -0,0 +1,352 @@
/*
* HTML5 Parser By Sam Blowes
*
* Designed for HTML5 documents
*
* Original code by John Resig (ejohn.org)
* http://ejohn.org/blog/pure-javascript-html-parser/
* Original code by Erik Arvidsson, Mozilla Public License
* http://erik.eae.net/simplehtmlparser/simplehtmlparser.js
*
* ----------------------------------------------------------------------------
* License
* ----------------------------------------------------------------------------
*
* This code is triple licensed using Apache Software License 2.0,
* Mozilla Public License or GNU Public License
*
* ////////////////////////////////////////////////////////////////////////////
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* ////////////////////////////////////////////////////////////////////////////
*
* The contents of this file are subject to the Mozilla Public License
* Version 1.1 (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is Simple HTML Parser.
*
* The Initial Developer of the Original Code is Erik Arvidsson.
* Portions created by Erik Arvidssson are Copyright (C) 2004. All Rights
* Reserved.
*
* ////////////////////////////////////////////////////////////////////////////
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ----------------------------------------------------------------------------
* Usage
* ----------------------------------------------------------------------------
*
* // Use like so:
* HTMLParser(htmlString, {
* start: function(tag, attrs, unary) {},
* end: function(tag) {},
* chars: function(text) {},
* comment: function(text) {}
* });
*
* // or to get an XML string:
* HTMLtoXML(htmlString);
*
* // or to get an XML DOM Document
* HTMLtoDOM(htmlString);
*
* // or to inject into an existing document/DOM node
* HTMLtoDOM(htmlString, document);
* HTMLtoDOM(htmlString, document.body);
*
*/
// Regular Expressions for parsing tags and attributes
var startTag = /^<([-A-Za-z0-9_]+)((?:\s+[a-zA-Z_:][-a-zA-Z0-9_:.]*(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/;
var endTag = /^<\/([-A-Za-z0-9_]+)[^>]*>/;
var attr = /([a-zA-Z_:][-a-zA-Z0-9_:.]*)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; // Empty Elements - HTML 5
var empty = makeMap('area,base,basefont,br,col,frame,hr,img,input,link,meta,param,embed,command,keygen,source,track,wbr'); // Block Elements - HTML 5
// fixed by xxx 将 ins 标签从块级名单中移除
var block = makeMap('a,address,article,applet,aside,audio,blockquote,button,canvas,center,dd,del,dir,div,dl,dt,fieldset,figcaption,figure,footer,form,frameset,h1,h2,h3,h4,h5,h6,header,hgroup,hr,iframe,isindex,li,map,menu,noframes,noscript,object,ol,output,p,pre,section,script,table,tbody,td,tfoot,th,thead,tr,ul,video'); // Inline Elements - HTML 5
var inline = makeMap('abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var'); // Elements that you can, intentionally, leave open
// (and which close themselves)
var closeSelf = makeMap('colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr'); // Attributes that have their values filled in disabled="disabled"
var fillAttrs = makeMap('checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected'); // Special Elements (can contain anything)
var special = makeMap('script,style');
function HTMLParser(html, handler) {
var index;
var chars;
var match;
var stack = [];
var last = html;
stack.last = function () {
return this[this.length - 1];
};
while (html) {
chars = true; // Make sure we're not in a script or style element
if (!stack.last() || !special[stack.last()]) {
// Comment
if (html.indexOf('<!--') == 0) {
index = html.indexOf('-->');
if (index >= 0) {
if (handler.comment) {
handler.comment(html.substring(4, index));
}
html = html.substring(index + 3);
chars = false;
} // end tag
} else if (html.indexOf('</') == 0) {
match = html.match(endTag);
if (match) {
html = html.substring(match[0].length);
match[0].replace(endTag, parseEndTag);
chars = false;
} // start tag
} else if (html.indexOf('<') == 0) {
match = html.match(startTag);
if (match) {
html = html.substring(match[0].length);
match[0].replace(startTag, parseStartTag);
chars = false;
}
}
if (chars) {
index = html.indexOf('<');
var text = index < 0 ? html : html.substring(0, index);
html = index < 0 ? '' : html.substring(index);
if (handler.chars) {
handler.chars(text);
}
}
} else {
html = html.replace(new RegExp('([\\s\\S]*?)<\/' + stack.last() + '[^>]*>'), function (all, text) {
text = text.replace(/<!--([\s\S]*?)-->|<!\[CDATA\[([\s\S]*?)]]>/g, '$1$2');
if (handler.chars) {
handler.chars(text);
}
return '';
});
parseEndTag('', stack.last());
}
if (html == last) {
throw 'Parse Error: ' + html;
}
last = html;
} // Clean up any remaining tags
parseEndTag();
function parseStartTag(tag, tagName, rest, unary) {
tagName = tagName.toLowerCase();
if (block[tagName]) {
while (stack.last() && inline[stack.last()]) {
parseEndTag('', stack.last());
}
}
if (closeSelf[tagName] && stack.last() == tagName) {
parseEndTag('', tagName);
}
unary = empty[tagName] || !!unary;
if (!unary) {
stack.push(tagName);
}
if (handler.start) {
var attrs = [];
rest.replace(attr, function (match, name) {
var value = arguments[2] ? arguments[2] : arguments[3] ? arguments[3] : arguments[4] ? arguments[4] : fillAttrs[name] ? name : '';
attrs.push({
name: name,
value: value,
escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') // "
});
});
if (handler.start) {
handler.start(tagName, attrs, unary);
}
}
}
function parseEndTag(tag, tagName) {
// If no tag name is provided, clean shop
if (!tagName) {
var pos = 0;
} // Find the closest opened tag of the same type
else {
for (var pos = stack.length - 1; pos >= 0; pos--) {
if (stack[pos] == tagName) {
break;
}
}
}
if (pos >= 0) {
// Close all the open elements, up the stack
for (var i = stack.length - 1; i >= pos; i--) {
if (handler.end) {
handler.end(stack[i]);
}
} // Remove the open elements from the stack
stack.length = pos;
}
}
}
function makeMap(str) {
var obj = {};
var items = str.split(',');
for (var i = 0; i < items.length; i++) {
obj[items[i]] = true;
}
return obj;
}
function removeDOCTYPE(html) {
return html.replace(/<\?xml.*\?>\n/, '').replace(/<!doctype.*>\n/, '').replace(/<!DOCTYPE.*>\n/, '');
}
function parseAttrs(attrs) {
return attrs.reduce(function (pre, attr) {
var value = attr.value;
var name = attr.name;
if (pre[name]) {
pre[name] = pre[name] + " " + value;
} else {
pre[name] = value;
}
return pre;
}, {});
}
function parseHtml(html) {
html = removeDOCTYPE(html);
var stacks = [];
var results = {
node: 'root',
children: []
};
HTMLParser(html, {
start: function start(tag, attrs, unary) {
var node = {
name: tag
};
if (attrs.length !== 0) {
node.attrs = parseAttrs(attrs);
}
if (unary) {
var parent = stacks[0] || results;
if (!parent.children) {
parent.children = [];
}
parent.children.push(node);
} else {
stacks.unshift(node);
}
},
end: function end(tag) {
var node = stacks.shift();
if (node.name !== tag) console.error('invalid state: mismatch end tag');
if (stacks.length === 0) {
results.children.push(node);
} else {
var parent = stacks[0];
if (!parent.children) {
parent.children = [];
}
parent.children.push(node);
}
},
chars: function chars(text) {
var node = {
type: 'text',
text: text
};
if (stacks.length === 0) {
results.children.push(node);
} else {
var parent = stacks[0];
if (!parent.children) {
parent.children = [];
}
parent.children.push(node);
}
},
comment: function comment(text) {
var node = {
node: 'comment',
text: text
};
var parent = stacks[0];
if (!parent.children) {
parent.children = [];
}
parent.children.push(node);
}
});
return results.children;
}
export default parseHtml;

84
common/letter.js Normal file
View File

@ -0,0 +1,84 @@
export default {
list: [
'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N',
'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z'
],
listDatacom: [{
value: 'A',
text: "A"
}, {
value: 'B',
text: "B"
}, {
value: 'C',
text: "C"
}, {
value: 'D',
text: "D"
}, {
value: 'E',
text: "F"
}, {
value: 'G',
text: "G"
}, {
value: 'H',
text: "H"
}, {
value: 'I',
text: "I"
}, {
value: 'J',
text: "J"
}, {
value: 'K',
text: "K"
}, {
value: 'L',
text: "L"
}, {
value: 'M',
text: "M"
}, {
value: 'N',
text: "N"
}, {
value: 'O',
text: "O"
}, {
value: 'P',
text: "P"
}, {
value: 'Q',
text: "Q"
}, {
value: 'R',
text: "R"
}, {
value: 'S',
text: "S"
}, {
value: 'T',
text: "T"
}, {
value: 'U',
text: "U"
}, {
value: 'V',
text: "V"
}, {
value: 'W',
text: "W"
}, {
value: 'X',
text: "X"
}, {
value: 'Y',
text: "Y"
}, {
value: 'Z',
text: "Z"
}]
}

36
common/openApp.js Normal file
View File

@ -0,0 +1,36 @@
/*
创建在h5端全局悬浮引导用户下载app的功能
如不需要本功能直接移除配置文件app.config.js下的h5/openApp即可
*/
import CONFIG from '../app.config.js';
const CONFIG_OPEN = CONFIG.h5.openApp || {};
// 仅H5端添加"打开APP"
export default function() {
// #ifdef H5
if (!CONFIG_OPEN.openUrl) return;
let openLogo = CONFIG_OPEN.logo ?
`<img src="${CONFIG_OPEN.logo}" style="width: 2rem;height: 2rem;border-radius: 3px;">` : '';
let openApp = document.createElement("div");
openApp.id = 'openApp';
openApp.style =
'position: fixed;background:#FFFFFF;box-shadow: #eeeeee 1px 1px 9px; ;top: 0;left: 0;right: 0;z-index: 999;width: 100%;height: 45px;display: flex;flex-direction: row;justify-content: space-between;align-items: center;box-sizing: border-box;padding: 0 0.5rem;'
openApp.innerHTML = `
<div style="display: flex;flex-direction: row;justify-content: flex-start;align-items: center;">
${openLogo}
<div style="padding-left: 0.3rem;font-size: 12px;">${CONFIG_OPEN.appname || ''}</div>
</div>
<div class="openBtn" style="padding: 5px;font-size:12px;border-radius: 2px;border: 1px solid #007AFF;color: #007AFF;">下载app</div>
`;
document.body.insertBefore(openApp, document.body.firstChild);
document.body.style = 'height:calc(100% - 45px); margin-top:45px;';
openApp.addEventListener('click', e => {
var target = e.target || e.srcElement;
if (target.className.indexOf('openBtn') >= 0) {
window.location.href = CONFIG_OPEN.openUrl;
}
})
//#endif
}

245
common/permission.js Normal file
View File

@ -0,0 +1,245 @@
/// null = 未请求1 = 已允许0 = 拒绝|受限, 2 = 系统未开启
var isIOS
function album() {
var result = 0;
var PHPhotoLibrary = plus.ios.import("PHPhotoLibrary");
var authStatus = PHPhotoLibrary.authorizationStatus();
if (authStatus === 0) {
result = null;
} else if (authStatus == 3) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(PHPhotoLibrary);
return result;
}
function camera() {
var result = 0;
var AVCaptureDevice = plus.ios.import("AVCaptureDevice");
var authStatus = AVCaptureDevice.authorizationStatusForMediaType('vide');
if (authStatus === 0) {
result = null;
} else if (authStatus == 3) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(AVCaptureDevice);
return result;
}
function location() {
var result = 0;
var cllocationManger = plus.ios.import("CLLocationManager");
var enable = cllocationManger.locationServicesEnabled();
var status = cllocationManger.authorizationStatus();
if (!enable) {
result = 2;
} else if (status === 0) {
result = null;
} else if (status === 3 || status === 4) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(cllocationManger);
return result;
}
function push() {
var result = 0;
var UIApplication = plus.ios.import("UIApplication");
var app = UIApplication.sharedApplication();
var enabledTypes = 0;
if (app.currentUserNotificationSettings) {
var settings = app.currentUserNotificationSettings();
enabledTypes = settings.plusGetAttribute("types");
if (enabledTypes == 0) {
result = 0;
console.log("推送权限没有开启");
} else {
result = 1;
console.log("已经开启推送功能!")
}
plus.ios.deleteObject(settings);
} else {
enabledTypes = app.enabledRemoteNotificationTypes();
if (enabledTypes == 0) {
result = 3;
console.log("推送权限没有开启!");
} else {
result = 4;
console.log("已经开启推送功能!")
}
}
plus.ios.deleteObject(app);
plus.ios.deleteObject(UIApplication);
return result;
}
function contact() {
var result = 0;
var CNContactStore = plus.ios.import("CNContactStore");
var cnAuthStatus = CNContactStore.authorizationStatusForEntityType(0);
if (cnAuthStatus === 0) {
result = null;
} else if (cnAuthStatus == 3) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(CNContactStore);
return result;
}
function record() {
var result = null;
var avaudiosession = plus.ios.import("AVAudioSession");
var avaudio = avaudiosession.sharedInstance();
var status = avaudio.recordPermission();
// console.log("permissionStatus:" + status);
if (status === 1970168948) {
result = null;
} else if (status === 1735552628) {
result = 1;
} else {
result = 0;
}
plus.ios.deleteObject(avaudiosession);
return result;
}
function calendar() {
var result = null;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(0);
if (ekAuthStatus == 3) {
result = 1;
console.log("日历权限已经开启");
} else {
console.log("日历权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
function memo() {
var result = null;
var EKEventStore = plus.ios.import("EKEventStore");
var ekAuthStatus = EKEventStore.authorizationStatusForEntityType(1);
if (ekAuthStatus == 3) {
result = 1;
console.log("备忘录权限已经开启");
} else {
console.log("备忘录权限没有开启");
}
plus.ios.deleteObject(EKEventStore);
return result;
}
function requestIOS(permissionID) {
return new Promise((resolve, reject) => {
switch (permissionID) {
case "push":
resolve(push());
break;
case "location":
resolve(location());
break;
case "record":
resolve(record());
break;
case "camera":
resolve(camera());
break;
case "album":
resolve(album());
break;
case "contact":
resolve(contact());
break;
case "calendar":
resolve(calendar());
break;
case "memo":
resolve(memo());
break;
default:
resolve(0);
break;
}
});
}
function requestAndroid(permissionID) {
return new Promise((resolve, reject) => {
plus.android.requestPermissions(
[permissionID],
function(resultObj) {
var result = 0;
for (var i = 0; i < resultObj.granted.length; i++) {
var grantedPermission = resultObj.granted[i];
console.log('已获取的权限:' + grantedPermission);
result = 1
}
for (var i = 0; i < resultObj.deniedPresent.length; i++) {
var deniedPresentPermission = resultObj.deniedPresent[i];
console.log('拒绝本次申请的权限:' + deniedPresentPermission);
result = 0
}
for (var i = 0; i < resultObj.deniedAlways.length; i++) {
var deniedAlwaysPermission = resultObj.deniedAlways[i];
console.log('永久拒绝申请的权限:' + deniedAlwaysPermission);
result = -1
}
resolve(result);
},
function(error) {
console.log('result error: ' + error.message)
resolve({
code: error.code,
message: error.message
});
}
);
});
}
function gotoAppPermissionSetting() {
if (permission.isIOS) {
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
var setting2 = NSURL2.URLWithString("app-settings:");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
} else {
var Intent = plus.android.importClass("android.content.Intent");
var Settings = plus.android.importClass("android.provider.Settings");
var Uri = plus.android.importClass("android.net.Uri");
var mainActivity = plus.android.runtimeMainActivity();
var intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
var uri = Uri.fromParts("package", mainActivity.getPackageName(), null);
intent.setData(uri);
mainActivity.startActivity(intent);
}
}
const permission = {
get isIOS() {
return typeof isIOS === 'boolean' ? isIOS : (isIOS = uni.getSystemInfoSync().platform === 'ios')
},
requestIOS: requestIOS,
requestAndroid: requestAndroid,
gotoAppSetting: gotoAppPermissionSetting
}
export default permission

503
common/province.js Normal file
View File

@ -0,0 +1,503 @@
export default {
listByCode: {
'110000': "北京",
'120000': "天津",
'130000': "河北省",
'140000': "山西省",
'150000': "内蒙古自治区",
'210000': "辽宁省",
'220000': "吉林省",
'230000': "黑龙江省",
'310000': "上海",
'320000': "江苏省",
'330000': "浙江省",
'340000': "安徽省",
'350000': "福建省",
'360000': "江西省",
'370000': "山东省",
'410000': "河南省",
'420000': "湖北省",
'430000': "湖南省",
'440000': "广东省",
'450000': "广西壮族自治区",
'460000': "海南省",
'500000': "重庆",
'510000': "四川省",
'520000': "贵州省",
'530000': "云南省",
'540000': "西藏自治区",
'610000': "陕西省",
'620000': "甘肃省",
'630000': "青海省",
'640000': "宁夏回族自治区",
'650000': "新疆维吾尔自治区",
'710000': "台湾省",
'810000': "香港特别行政区",
'820000': "澳门特别行政区",
'990000': "海外",
},
listByTitle: {
"北京": '110000',
"天津": '120000',
"河北省": '130000',
"山西省": '140000',
"内蒙古自治区": '150000',
"辽宁省": '210000',
"吉林省": '220000',
"黑龙江省": '230000',
"上海": '310000',
"江苏省": '320000',
"浙江省": '330000',
"安徽省": '340000',
"福建省": '350000',
"江西省": '360000',
"山东省": '370000',
"河南省": '410000',
"湖北省": '420000',
"湖南省": '430000',
"广东省": '440000',
"广西壮族自治区": '450000',
"海南省": '460000',
"重庆": '500000',
"四川省": '510000',
"贵州省": '520000',
"云南省": '530000',
"西藏自治区": '540000',
"陕西省": '610000',
"甘肃省": '620000',
"青海省": '630000',
"宁夏回族自治区": '640000',
"新疆维吾尔自治区": '650000',
"台湾省": '710000',
"香港特别行政区": '810000',
"澳门特别行政区": '820000',
"海外": '990000',
},
listByChar: {
beijing: {
k: '110000',
v: "北京"
},
tianjin: {
k: '120000',
v: "天津"
},
hebei: {
k: '130000',
v: "河北省"
},
shanxi1: {
k: '140000',
v: "山西省"
},
neimenggu: {
k: '150000',
v: "内蒙古自治区"
},
liaoning: {
k: '210000',
v: "辽宁省"
},
jilin: {
k: '220000',
v: "吉林省"
},
heilongjiang: {
k: '230000',
v: "黑龙江省"
},
shanghai: {
k: '310000',
v: "上海"
},
jiangsu: {
k: '320000',
v: "江苏省"
},
zhejiang: {
k: '330000',
v: "浙江省"
},
anhui: {
k: '340000',
v: "安徽省"
},
fujian: {
k: '350000',
v: "福建省"
},
jiangxi: {
k: '360000',
v: "江西省"
},
shandong: {
k: '370000',
v: "山东省"
},
henan: {
k: '410000',
v: "河南省"
},
hubei: {
k: '420000',
v: "湖北省"
},
hunan: {
k: '430000',
v: "湖南省"
},
guangdong: {
k: '440000',
v: "广东省"
},
guangxi: {
k: '450000',
v: "广西壮族自治区"
},
hainan: {
k: '460000',
v: "海南省"
},
chongqing: {
k: '500000',
v: "重庆"
},
sichuan: {
k: '510000',
v: "四川省"
},
guizhou: {
k: '520000',
v: "贵州省"
},
yunnan: {
k: '530000',
v: "云南省"
},
xizang: {
k: '540000',
v: "西藏自治区"
},
shanxi2: {
k: '610000',
v: "陕西省"
},
gansu: {
k: '620000',
v: "甘肃省"
},
qinghai: {
k: '630000',
v: "青海省"
},
ningxia: {
k: '640000',
v: "宁夏回族自治区"
},
xinjiang: {
k: '650000',
v: "新疆维吾尔自治区"
},
taiwan: {
k: '710000',
v: "台湾省"
},
xianggang: {
k: '810000',
v: "香港特别行政区"
},
aomen: {
k: '820000',
v: "澳门特别行政区"
},
haiwai: {
k: '990000',
v: "海外"
},
},
listDatacom: [{
value: '110000',
text: "北京"
},
{
value: '120000',
text: "天津"
},
{
value: '130000',
text: "河北省"
},
{
value: '140000',
text: "山西省"
},
{
value: '150000',
text: "内蒙古自治区"
},
{
value: '210000',
text: "辽宁省"
},
{
value: '220000',
text: "吉林省"
},
{
value: '230000',
text: "黑龙江省"
},
{
value: '310000',
text: "上海"
},
{
value: '320000',
text: "江苏省"
},
{
value: '330000',
text: "浙江省"
},
{
value: '340000',
text: "安徽省"
},
{
value: '350000',
text: "福建省"
},
{
value: '360000',
text: "江西省"
},
{
value: '370000',
text: "山东省"
},
{
value: '410000',
text: "河南省"
},
{
value: '420000',
text: "湖北省"
},
{
value: '430000',
text: "湖南省"
},
{
value: '440000',
text: "广东省"
},
{
value: '450000',
text: "广西壮族自治区"
},
{
value: '460000',
text: "海南省"
},
{
value: '500000',
text: "重庆"
},
{
value: '510000',
text: "四川省"
},
{
value: '520000',
text: "贵州省"
},
{
value: '530000',
text: "云南省"
},
{
value: '540000',
text: "西藏自治区"
},
{
value: '610000',
text: "陕西省"
},
{
value: '620000',
text: "甘肃省"
},
{
value: '630000',
text: "青海省"
},
{
value: '640000',
text: "宁夏回族自治区"
},
{
value: '650000',
text: "新疆维吾尔自治区"
},
{
value: '710000',
text: "台湾省"
},
{
value: '810000',
text: "香港特别行政区"
},
{
value: '820000',
text: "澳门特别行政区"
},
{
value: '990000',
text: "海外"
},
],
listCarP: [{
value: '京',
text: "京"
},
{
value: '津',
text: "津"
},
{
value: '冀',
text: "冀"
},
{
value: '晋',
text: "晋"
},
{
value: '蒙',
text: "蒙"
},
{
value: '辽',
text: "辽"
},
{
value: '220000',
text: "吉林省"
},
{
value: '230000',
text: "黑龙江省"
},
{
value: '310000',
text: "上海"
},
{
value: '320000',
text: "江苏省"
},
{
value: '330000',
text: "浙江省"
},
{
value: '340000',
text: "安徽省"
},
{
value: '350000',
text: "福建省"
},
{
value: '360000',
text: "江西省"
},
{
value: '370000',
text: "山东省"
},
{
value: '410000',
text: "河南省"
},
{
value: '420000',
text: "湖北省"
},
{
value: '430000',
text: "湖南省"
},
{
value: '440000',
text: "广东省"
},
{
value: '450000',
text: "广西壮族自治区"
},
{
value: '460000',
text: "海南省"
},
{
value: '500000',
text: "重庆"
},
{
value: '510000',
text: "四川省"
},
{
value: '520000',
text: "贵州省"
},
{
value: '530000',
text: "云南省"
},
{
value: '540000',
text: "西藏自治区"
},
{
value: '610000',
text: "陕西省"
},
{
value: '620000',
text: "甘肃省"
},
{
value: '630000',
text: "青海省"
},
{
value: '640000',
text: "宁夏回族自治区"
},
{
value: '650000',
text: "新疆维吾尔自治区"
},
{
value: '710000',
text: "台湾省"
},
{
value: '810000',
text: "香港特别行政区"
},
{
value: '820000',
text: "澳门特别行政区"
},
{
value: '990000',
text: "海外"
},
],
}

160
common/util.js Normal file
View File

@ -0,0 +1,160 @@
import permission from "./permission"
function formatTime(time) {
if (typeof time !== 'number' || time < 0) {
return time
}
var hour = parseInt(time / 3600)
time = time % 3600
var minute = parseInt(time / 60)
time = time % 60
var second = time
return ([hour, minute, second]).map(function(n) {
n = n.toString()
return n[1] ? n : '0' + n
}).join(':')
}
function formatLocation(longitude, latitude) {
if (typeof longitude === 'string' && typeof latitude === 'string') {
longitude = parseFloat(longitude)
latitude = parseFloat(latitude)
}
longitude = longitude.toFixed(2)
latitude = latitude.toFixed(2)
return {
longitude: longitude.toString().split('.'),
latitude: latitude.toString().split('.')
}
}
var dateUtils = {
UNITS: {
'年': 31557600000,
'月': 2629800000,
'天': 86400000,
'小时': 3600000,
'分钟': 60000,
'秒': 1000
},
humanize: function(milliseconds) {
var humanize = '';
for (var key in this.UNITS) {
if (milliseconds >= this.UNITS[key]) {
humanize = Math.floor(milliseconds / this.UNITS[key]) + key + '前';
break;
}
}
return humanize || '刚刚';
},
format: function(dateStr) {
var date = this.parse(dateStr)
var diff = Date.now() - date.getTime();
if (diff < this.UNITS['天']) {
return this.humanize(diff);
}
var _format = function(number) {
return (number < 10 ? ('0' + number) : number);
};
return date.getFullYear() + '/' + _format(date.getMonth() + 1) + '/' + _format(date.getDate()) + '-' +
_format(date.getHours()) + ':' + _format(date.getMinutes());
},
parse: function(str) { //将"yyyy-mm-dd HH:MM:ss"格式的字符串转化为一个Date对象
var a = str.split(/[^0-9]/);
return new Date(a[0], a[1] - 1, a[2], a[3], a[4], a[5]);
}
};
// 验证并返回手机号或null
function isPhone(phone) {
var pattern = /^(?:(?:\+|00)86)?1(?:3\d|4[5-79]|5[0-35-9]|6[5-7]|7[0-8]|8\d|9[189])\d{8}$/;
var regex = new RegExp(pattern);
var res = regex.exec(phone);
if (res) {
return res[0];
}
return false;
}
function tel(phone) {
permission.requestAndroid('contact').then(
(res) => {
if (res !== 1) {
uni.showModal({
title: '权限申请',
content: '拨打电话需要您的授权',
success: function(res) {
if (res.confirm) {
permission.gotoAppSetting();
} else if (res.cancel) {
// console.log('用户点击取消');
}
}
})
} else {
uni.makePhoneCall({
phoneNumber: phone
})
}
}
);
}
const captcha = {
ls: 'LocalCaptcha',
get: function(scence = 'vcode', useLetter = 'false') {
let digits = '0123456789';
let upperCaseLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let code = '',
charType = digits;
for (let i = 0; i < 4; i++) {
// 随机选择生成数字还是大写字母
if (useLetter === true) charType = Math.random() < 0.5 ? digits : upperCaseLetters;
code += charType[Math.floor(Math.random() * charType.length)];
}
var codes = uni.getStorageSync(this.ls) || {};
codes[scence] = code;
uni.getStorageSync(this.ls, codes);
return code;
},
check: function(scence = 'vcode', code) {
var codes = uni.getStorageSync(this.ls) || {};
if (codes[scence] === code) {
return true;
}
return false;
},
pop: function(scence = 'vcode', useLetter = 'false') {
var code = this.get(scence, useLetter);
uni.showModal({
title: '请输入数字 ' + code + ' 验证',
editable: true,
success: function(res) {
if (res.confirm) {
// console.log('数字码', res.content)
if (res.content === code) return true;
return false;
} else if (res.cancel) {
// console.log('用户点击取消');
return false;
}
}
})
}
};
export default {
formatTime,
formatLocation,
dateUtils,
tel,
captcha,
isPhone
}

View File

@ -0,0 +1,95 @@
<template>
<refresh @refresh="refresh" @pullingdown="onpullingdown" :display="showRefresh ? 'show' : 'hide'">
<view class="refreshBox">
<!-- 可以自己添加图片路径或base64实现图片 <image class="refreshImg" :src="config[state].img" mode="widthFix" resize="cover"></image> -->
<text class="refreshText">{{config[state].text}}</text>
</view>
</refresh>
</template>
<script>
export default {
data() {
return {
showRefresh:false,
state:0
}
},
methods:{
onpullingdown({pullingDistance,viewHeight}) {
if(pullingDistance < viewHeight){
this.state = 0
}else{
this.state = 1
}
},
refresh(){
// console.log('refresh');
this.showRefresh = true
this.state = 2
this.$emit('refresh')
}
},
watch: {
loading(loading, oldValue) {
if(!loading){
this.showRefresh = false
this.state = 3
}
}
},
props: {
loading: {
type:Boolean,
default(){
return false
}
},
config: {
type: Array,
default(){
return [
{
text:"继续下拉执行刷新",
img:""//可以自己添加图片路径或base64实现图片
},
{
text:"释放立即刷新",
img:""//可以自己添加图片路径或base64实现图片
},
{
text:"正在疯狂的加载中",
img:""//可以自己添加图片路径或base64实现图片
},
{
text:"加载成功",
img:""//可以自己添加图片路径或base64实现图片
}
]
}
},
},
}
</script>
<style lang="scss" scoped>
.refreshBox{
width: 750rpx;
height: 50px;
justify-content: center;
align-items: center;
flex-direction: row;
/* #ifndef APP-PLUS */
margin-top: -50px;
/* #endif */
}
.refreshImg{
width: 55rpx;
height: 55rpx;
z-index: 111;
}
.refreshText{
font-size: 26rpx;
color: #999999;
padding-left: 6rpx;
}
</style>

38
config/ctms.config.js Normal file
View File

@ -0,0 +1,38 @@
// 应用子项目配置
export default {
/*接口设置*/
apiUrl: 'https://api.ctms.hiluker.cn/',
// apiUrl: 'http://11.22.33.48:10032/',
//网址后缀
url_suffix: '453',
//入口脚本文件
url_entry: 'index.php/client/v1',
// url_entry: 'index_test.php/client/v1',
//运单H5预览地址
h5_view: 'https://h5.ctms.hiluker.cn/pages/order/detail.html',
//应用ID对应到vapp-sass轻应用系统
appid: 1,
//归属商户ID(即平台ID)
pid: 1,
//请求头配置
headers: {
isToken: true,
Authorization: 'hiCtmsClientXXXXXXXXXXXXXX', //请求授权的token示范
params: [], //TODO,暂未想好如何配置
},
// loginPage: 'uni_modules/uni-id-pages/pages/login/login-withoutpwd',
loginPage: 'pages/ctms/login/loginSms',
pageDir: "/pages/ctms/", //子项目页面目录
kfPhone: "13211111058", //客服手机号
"version": "1.20240808.008", //内置版本号
isUserUnicloud: false,
//是否使用 用户uni云服务
demoCarno: '皖ABBBBB',
//示例车牌号
'poweredBy': '安徽安邮车联运输有限公司',
//版权归属
'supportedBy': 'Hiluker & Fm453',
//技术支持
'thanksFor': ['北京数字天堂科技 DCloud', '阿里云 aliyun.com'],
//鸣谢
}

5
config/im.config.js Normal file
View File

@ -0,0 +1,5 @@
// 应用子项目配置,App.vue挂载到getApp().globalData.config
export default {
apiUrl: 'https://im.hiluker.cn/',
}

36
hybrid/html/404.html Normal file
View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>页面走丢了</title>
<style type="text/css">
.btn {
display: block;
margin: 20px auto;
padding: 5px;
background-color: #007aff;
border: 0;
color: #ffffff;
height: 40px;
width: 200px;
}
.btn-red {
background-color: #dd524d;
}
.btn-yellow {
background-color: #f0ad4e;
}
.desc {
padding: 10px;
color: #999999;
}
</style>
</head>
<body>
<p class="desc">啊,抱歉,您要访问的页面找不到了。</p>
</body>
</html>

88
hybrid/html/local.html Normal file
View File

@ -0,0 +1,88 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>本地网页</title>
<style type="text/css">
.btn {
display: block;
margin: 20px auto;
padding: 5px;
background-color: #007aff;
border: 0;
color: #ffffff;
height: 40px;
width: 200px;
}
.btn-red {
background-color: #dd524d;
}
.btn-yellow {
background-color: #f0ad4e;
}
.desc {
padding: 10px;
color: #999999;
}
</style>
</head>
<body>
<p class="desc">web-view 组件加载本地 html 示例,仅在 App 环境下生效。点击下列按钮,跳转至其它页面。</p>
<div class="btn-list">
<button class="btn" type="button" data-action="navigateTo">navigateTo</button>
<button class="btn" type="button" data-action="redirectTo">redirectTo</button>
<button class="btn" type="button" data-action="navigateBack">navigateBack</button>
<button class="btn" type="button" data-action="reLaunch">reLaunch</button>
<button class="btn" type="button" data-action="switchTab">switchTab</button>
</div>
<p class="desc">网页向应用发送消息。注意:小程序端应用会在此页面后退时接收到消息。</p>
<div class="btn-list">
<button class="btn btn-red" type="button" id="postMessage">postMessage</button>
</div>
<!-- uni 的 SDK -->
<script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.1/index.js"></script>
<script type="text/javascript">
document.addEventListener('UniAppJSBridgeReady', function() {
document.querySelector('.btn-list').addEventListener('click', function(evt) {
var target = evt.target;
if (target.tagName === 'BUTTON') {
var action = target.getAttribute('data-action');
switch (action) {
case 'switchTab':
uni.switchTab({
url: '/pages/tabBar/API/API'
});
break;
case 'reLaunch':
uni.reLaunch({
url: '/pages/tabBar/API/API'
});
break;
case 'navigateBack':
uni.navigateBack({
delta: 1
});
break;
default:
uni[action]({
url: '/pages/component/button/button'
});
break;
}
}
});
document.querySelector("#postMessage").addEventListener('click', function() {
uni.postMessage({
data: {
action: 'message'
}
});
})
});
</script>
</body>
</html>

22
index.html Normal file
View File

@ -0,0 +1,22 @@
<!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' : '') + '" />');
document.write(
'<meta http-equiv="pragma" content="no-cache"/>')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

191
lang/en.js Normal file
View File

@ -0,0 +1,191 @@
export default {
tabbar: 'Home,Work,Mine',
agreementsTitle: 'User service agreement,Privacy policy',
common: {
wechatFriends: "friends",
wechatBbs: "bbs",
weibo: "weibo",
more: "more",
agree: "agree",
copy: "copy",
wechatApplet: "applet",
cancelShare: "cancel sharing",
updateSucceeded: "update succeeded",
phonePlaceholder: "Please enter your mobile phone number",
verifyCodePlaceholder: "Please enter the verification code",
newPasswordPlaceholder: "Please enter a new password",
confirmNewPasswordPlaceholder: "Please confirm the new password",
confirmPassword: "Please confirm the password",
verifyCodeSend: "Verification code has been sent to via SMS",
passwordDigits: "The password is 6 - 20 digits",
getVerifyCode: "Get Code",
noAgree: "You have not agreed to the privacy policy agreement",
gotIt: "got it",
login: "sign in",
error: "error",
complete: "complete",
submit: "Submit",
formatErr: "Incorrect mobile phone number format",
sixDigitCode: "Please enter a 6-digit verification code",
resetNavTitle: "Reset password"
},
list: {
inputPlaceholder: "Please enter the search content",
},
search: {
cancelText: "cancel",
searchHistory: "search history",
searchDiscovery: "search discovery",
deleteAll: "delete all",
delete: "delete",
deleteTip: "Are you sure to clear the search history ?",
complete: "complete",
searchHiddenTip: "Current search found hidden",
},
grid: {
grid: "Grid Assembly",
visibleToAll: "Visible to all",
invisibleToTourists: "Invisible to tourists",
adminVisible: "Admin visible",
clickTip: "Click the",
clickTipGrid: "grid",
},
mine: {
showText: "Text",
signIn: "Check In Reward",
signInByAd: "Check In Reward By AD",
toEvaluate: "To Evaluate",
readArticles: "Read Articles",
myScore: "My Score",
invite: "Invite Friends",
feedback: "Problems And Feedback",
settings: "Settings",
about: "About",
checkUpdate: "Check for Updates",
clicked: "You Clicked",
checkScore: "Please check your points after logging in",
currentScore: "The current score is ",
noScore: "There are currently no points",
notLogged: "not logged in",
},
userinfo: {
navigationBarTitle: "My Profile",
ProfilePhoto: "Profile Photo",
nickname: "Nickname",
notSet: "not set",
phoneNumber: "Phone Number",
notSpecified: "Not Specified",
setNickname: "Set Nickname ",
setNicknamePlaceholder: "Please enter a nickname to set",
bindPhoneNumber: "One click binding of local number",
bindOtherLogin: "Other number binding",
noChange: "No change",
uploading: "uploading",
requestFail: "Request for service failed",
setting: "setting",
deleteSucceeded: "Delete succeeded",
setSucceeded: "Set successfully",
},
smsCode: {
resendVerifyCode: "resend",
phoneErrTip: "Mobile phone number format error",
sendSuccessTip: "SMS verification code sent successfully",
},
loadMore: {
noData: "No Data",
noNetwork: "Network error",
toSet: "Go to settings",
error: "error",
},
uniFeedback: {
navigationBarTitle: "Problems and feedback",
msgTitle: "Message content",
imgTitle: "Picture list",
contacts: "contacts",
phone: "contact number",
submit: "submit",
},
settings: {
navigationBarTitle: "Settings",
userInfo: "Personal Data",
changePassword: "change password",
clearTmp: "clean cache",
pushServer: "push function",
fingerPrint: "fingerprint unlock",
facial: "face unlock",
deactivate: "Deactivate",
logOut: "Logout",
login: "Login",
changeLanguage: "Language",
please: "please",
successText: "success",
failTip: "Authentication failed. Please try again",
authFailed: "authentication failed",
deviceNoOpen: "The device is not turned on",
fail: "fail",
tips: "tips",
exitLogin: "Do you want to log out",
cancelText: "cancel",
confirmText: "confirm",
clearing: "clearing",
clearedSuccessed: "Cleared successfully",
},
deactivate: {
cancelText: "cancel",
nextStep: "next step",
navigationBarTitle: "Logout prompt"
},
about: {
sacnQR: "Scan the QR Code and your friends can also download it",
client: "applCantion",
and: "And",
about: "About",
},
invite: {
download: "Download",
},
login: {
phoneLogin: "After logging in, you can show yourself",
phoneLoginTip: "Unregistered mobile phone numbers will be automatically registered after verification",
getVerifyCode: "Get Code",
},
uniQuickLogin: {
accountLogin: "Account",
SMSLogin: "SMS",
wechatLogin: "wechat",
appleLogin: "Apple",
oneClickLogin: "One click login",
QQLogin: "QQ",
xiaomiLogin: "Xiaomi",
getProviderFail: "Failed to get service provider",
loginErr: "Login service initialization error",
chooseOtherLogin: "Click the third-party login",
},
pwdLogin: {
pwdLogin: "User name password login",
placeholder: "Please enter mobile number / user name",
passwordPlaceholder: "Please input a password",
verifyCodePlaceholder: "Please enter the verification code",
login: "sign in",
forgetPassword: "Forget password",
register: "Registered account",
},
register: {
navigationBarTitle: "register",
usernamePlaceholder: "Please enter user name",
nicknamePlaceholder: "Please enter user nickname",
passwordDigitsPlaceholder: "Please enter a 6-20 digit password",
passwordAgain: "Enter the password again",
registerAndLogin: "Register and log in",
},
listDetail: {
follow: "Click follow",
newsErr: "Error, news ID is empty",
},
newsLog: {
navigationBarTitle: "Reading Log"
},
bindMobile: {
navigationBarTitle: "Bind Mobile"
}
}

100
lang/i18n.js Normal file
View File

@ -0,0 +1,100 @@
import langEn from './en'
import zhHans from './zh-Hans'
import _app_Config from '../app.config.js'
const {
i18n: {
enable: i18nEnable
}
} = _app_Config
const messages = {
'en': langEn,
'zh-Hans': zhHans
}
let currentLang
if (i18nEnable) {
currentLang = uni.getStorageSync('CURRENT_LANG')
} else {
currentLang = "zh-Hans"
}
// console.log(uni.getStorageSync('CURRENT_LANG'),currentLang);
if (!currentLang) {
if (uni.getLocale) {
console.log('获取应用语言:', uni.getLocale());
let language = 'en'
if (uni.getLocale() != 'en') {
language = 'zh-Hans'
}
uni.setStorageSync('CURRENT_LANG', language)
currentLang = language
} else {
uni.getSystemInfo({
success: function(res) {
console.log('获取设备信息:', res);
let language = 'zh-Hans'
if (res.language == 'en') {
language = 'en'
}
uni.setStorageSync('CURRENT_LANG', language)
currentLang = language
},
fail: (err) => {
console.error(err)
}
})
}
}
let i18nConfig = {
locale: currentLang, // set locale
messages // set locale messages
}
// #ifdef VUE2
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
const i18n = new VueI18n(i18nConfig)
// #endif
// #ifdef VUE3
import {
createI18n
} from 'vue-i18n'
const i18n = createI18n(i18nConfig)
// #endif
export default i18n
if (i18nEnable) {
console.log(`
你已开启多语言国际化将自动根据语言获取【lang/en.js】或【lang/en.js】文件中配置的tabbar的值
覆盖你在pages.json中的tabbar的值
如果你不需要多语言国际化请打开配置文件app.config.js找到 -> i18n -> enable把值设置为false
`);
let initLanguageAfter = () => {
function $i18n(e) {
// #ifdef VUE3
return i18n.global.messages[i18n.global.locale][e]
// #endif
return i18n.messages[i18n.locale][e]
}
setTimeout(function() {
//底部tabbar更新
$i18n('tabbar').split(',').forEach((text, index) => {
// console.log(text);
uni.setTabBarItem({
index,
text,
complete: e => {
// console.log("e: " + JSON.stringify(e));
}
})
})
}, 1)
}
initLanguageAfter()
uni.$on('changeLanguage', e => {
console.log('changeLanguage', e);
initLanguageAfter(e)
})
}

198
lang/zh-Hans.js Normal file
View File

@ -0,0 +1,198 @@
export default {
tabbar: '首页,功能,我的',
agreementsTitle: '用户服务协议,隐私政策',
common: {
wechatFriends: "微信好友",
wechatBbs: "微信朋友圈",
weibo: "微博",
more: "更多",
agree: "同意",
copy: "复制",
wechatApplet: "微信小程序",
cancelShare: "取消分享",
updateSucceeded: "更新成功",
phonePlaceholder: "请输入手机号",
verifyCodePlaceholder: "请输入验证码",
newPasswordPlaceholder: "请输入新密码",
confirmNewPasswordPlaceholder: "请确认新密码",
confirmPassword: "请确认密码",
verifyCodeSend: "验证码已通过短信发送至",
passwordDigits: "密码为6 - 20位",
getVerifyCode: "获取验证码",
noAgree: "你未同意隐私政策协议",
gotIt: "知道了",
login: "登录",
error: "错误",
complete: "完成",
submit: "提交",
formatErr: "手机号码格式不正确",
sixDigitCode: "请输入6位验证码",
resetNavTitle: "重置密码"
},
list: {
inputPlaceholder: "请输入搜索内容",
},
search: {
cancelText: '取消',
searchHistory: "搜索历史",
searchDiscovery: "搜索发现",
deleteAll: "全部删除",
delete: "删除",
deleteTip: "确认清空搜索历史吗?",
complete: "完成",
searchHiddenTip: "当前搜索发现已隐藏",
},
grid: {
grid: "宫格组件",
visibleToAll: "所有人可见",
invisibleToTourists: "游客不可见",
adminVisible: "管理员可见",
clickTip: "点击第",
clickTipGrid: "个宫格",
},
mine: {
showText: "文字",
scanText: "扫码",
appsText: "应用",
scoreText: "积分",
noticeText: "消息",
signIn: "普通签到",
signInByAd: "看广告签到",
toEvaluate: "去评分",
readArticles: "阅读过的文章",
myScore: "我的积分",
invite: "分销推荐",
feedback: "问题与反馈",
settings: "设置",
checkUpdate: "检查更新",
about: "关于",
clicked: "你点击了",
checkScore: "请登录后查看积分",
currentScore: "当前积分为",
noScore: "当前无积分",
notLogged: "未登录",
newsList: "新闻",
articleList: "文章",
},
userinfo: {
navigationBarTitle: "个人资料",
ProfilePhoto: "头像",
nickname: "昵称",
notSet: "未设置",
phoneNumber: "手机号",
notSpecified: "未绑定",
setNickname: "设置昵称",
setNicknamePlaceholder: "请输入要设置的昵称",
bindPhoneNumber: "本机号码一键绑定",
bindOtherLogin: "其他号码绑定",
noChange: "没有变化",
uploading: "正在上传",
requestFail: "请求服务失败",
setting: "设置中",
deleteSucceeded: "删除成功",
setSucceeded: "设置成功",
},
smsCode: {
resendVerifyCode: "重新发送",
phoneErrTip: "手机号格式错误",
sendSuccessTip: "短信验证码发送成功",
},
loadMore: {
noData: "暂无数据",
noNetwork: "网络异常",
toSet: "前往设置",
error: "错误",
},
uniFeedback: {
navigationBarTitle: "问题与反馈",
msgTitle: "留言内容",
imgTitle: "图片列表",
contacts: "联系人",
phone: "联系电话",
submit: "提交",
},
settings: {
navigationBarTitle: "设置",
userInfo: "账号资料",
changePassword: "修改密码",
clearTmp: "清理缓存",
pushServer: "推送功能",
fingerPrint: "指纹解锁",
facial: "人脸解锁",
deactivate: "注销账号",
logOut: "退出登录",
login: "登录",
failTip: "认证失败请重试",
authFailed: "认证失败",
changeLanguage: "切换语言",
please: "请用",
successText: "成功",
deviceNoOpen: "设备未开启",
fail: "失败",
tips: "提示",
exitLogin: "是否退出登录?",
clearing: "清除中",
clearedSuccessed: "清除成功",
confirmText: "确定",
cancelText: '取消',
},
deactivate: {
cancelText: '取消',
nextStep: "下一步",
navigationBarTitle: "注销提示"
},
about: {
sacnQR: "扫描二维码,您的朋友也可以下载",
client: "客户端",
and: "和",
about: "关于",
},
invite: {
download: "下载",
},
login: {
phoneLogin: "登录后即可展示自己",
phoneLoginTip: "未注册的手机号验证通过后将自动注册",
getVerifyCode: "获取验证码",
},
uniQuickLogin: {
accountLogin: "账号登录",
SMSLogin: "短信验证码",
wechatLogin: "微信登录",
appleLogin: "苹果登录",
oneClickLogin: "一键登录",
QQLogin: "QQ登录",
xiaomiLogin: "小米登录",
getProviderFail: "获取服务供应商失败",
loginErr: "登录服务初始化错误",
chooseOtherLogin: "点击了第三方登录",
},
pwdLogin: {
pwdLogin: "用户名密码登录",
placeholder: "请输入手机号/用户名",
passwordPlaceholder: "请输入密码",
verifyCodePlaceholder: "请输入验证码",
login: "登录",
forgetPassword: "忘记密码",
register: "注册账号",
},
register: {
navigationBarTitle: "注册",
usernamePlaceholder: "请输入用户名",
nicknamePlaceholder: "请输入用户昵称",
registerAndLogin: "注册并登录",
passwordDigitsPlaceholder: "请输入6-20位密码",
passwordAgain: "再次输入密码",
},
listDetail: {
follow: "点击关注",
newsErr: "出错了新闻ID为空",
},
newsLog: {
navigationBarTitle: "阅读记录"
},
bindMobile: {
navigationBarTitle: "绑定手机号码"
}
}

30
main.js Normal file
View File

@ -0,0 +1,30 @@
import App from './App'
import i18n from './lang/i18n'
import utils from "@/utils/common.js" //自定义函数
// #ifdef VUE2
import Vue from 'vue'
Vue.config.productionTip = false
Vue.mixin(utils); //vue2方式混入 //未测试可用性
App.mpType = 'app'
const app = new Vue({
i18n,
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import {
createSSRApp
} from 'vue'
export function createApp() {
const app = createSSRApp(App)
app.use(i18n);
return {
app
}
}
// #endif

254
manifest.json Normal file
View File

@ -0,0 +1,254 @@
{
"name" : "运车助手",
"appid" : "__UNI__B63B6BD",
"description" : "ctms运车平台用户前端为用户提供下单、查询及相关售后跟进等服务",
"versionName" : "1.20240808.006",
"versionCode" : 106,
"transformPx" : false,
"app-plus" : {
"usingComponents" : true,
"nvueCompiler" : "uni-app",
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"modules" : {
"Barcode" : {},
"Camera" : {},
"Geolocation" : {},
"Maps" : {},
"Share" : {},
"OAuth" : {},
"Push" : {}
},
"distribute" : {
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\" />",
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>"
],
"schemes" : "ctms,ctms-client",
"minSdkVersion" : 26,
"targetSdkVersion" : 33,
"abiFilters" : [ "armeabi-v7a", "arm64-v8a" ]
},
"ios" : {
"urltypes" : "ctms,ctms-client",
"capabilities" : {
"entitlements" : {
"com.apple.developer.associated-domains" : []
}
},
"UIBackgroundModes" : "location",
"dSYMs" : false,
"idfa" : false
},
"sdkConfigs" : {
"geolocation" : {
"system" : {
"__platform__" : [ "ios", "android" ]
},
"amap" : {
"name" : "map_18608981880QdibHebq",
"__platform__" : [ "ios", "android" ],
"appkey_ios" : "f83067a97f0523331c3b06cf4ea28775",
"appkey_android" : "0467567b45ec78d05357615209c7e69d"
}
},
"maps" : {
"amap" : {
"name" : "map_18608981880QdibHebq",
"appkey_ios" : "f83067a97f0523331c3b06cf4ea28775",
"appkey_android" : "0467567b45ec78d05357615209c7e69d"
}
},
"push" : {
"unipush" : {
"version" : "2",
"offline" : false,
"icons" : {
"small" : {
"hdpi" : "unpackage/res/push/icon-36.png"
}
}
}
},
"share" : {},
"speech" : {},
"statics" : {},
"ad" : {},
"oauth" : {}
},
"icons" : {
"android" : {
"hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi" : "unpackage/res/icons/192x192.png"
},
"ios" : {
"appstore" : "unpackage/res/icons/1024x1024.png",
"ipad" : {
"app" : "unpackage/res/icons/76x76.png",
"app@2x" : "unpackage/res/icons/152x152.png",
"notification" : "unpackage/res/icons/20x20.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x" : "unpackage/res/icons/167x167.png",
"settings" : "unpackage/res/icons/29x29.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png"
},
"iphone" : {
"app@2x" : "unpackage/res/icons/120x120.png",
"app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
}
},
"splashscreen" : {
"androidStyle" : "default",
"android" : {
"hdpi" : "unpackage/res/splash/splash-480X762.png",
"xhdpi" : "unpackage/res/splash/splash-720X1242.png",
"xxhdpi" : "unpackage/res/splash/splash-1080X1882.png"
},
"useOriginalMsgbox" : true
}
},
"error" : {
"url" : "hybrid/html/404.html"
},
"uniStatistics" : {
"enable" : true
}
},
"quickapp" : {},
"mp-weixin" : {
"appid" : "wxccd7e2a0911b3397",
"setting" : {
"urlCheck" : false,
"es6" : false,
"minified" : true,
"postcss" : true
},
"optimization" : {
"subPackages" : true
},
"usingComponents" : true,
"uniStatistics" : {
"enable" : false
},
"unipush" : {
"enable" : true
}
},
"vueVersion" : "3",
"h5" : {
"template" : "static/index.html",
"devServer" : {
"port" : 9090,
"https" : false
},
"title" : "汽车托运助手",
"router" : {
"mode" : "hash",
"base" : "./"
},
"unipush" : {
"enable" : true
},
"sdkConfigs" : {
"maps" : {
"amap" : {
"key" : "e3df95513a8c0ca18fdecbac3c4c7bc4",
"securityJsCode" : "d21c9d60fe573e0ceb8e23396fe29233",
"serviceHost" : ""
}
}
},
"uniStatistics" : {
"enable" : true
},
"optimization" : {
"treeShaking" : {
"enable" : true
}
}
},
"locale" : "zh-Hans",
"fallbackLocale" : "zh-Hans",
"uniStatistics" : {
"version" : "2",
"enable" : false
},
"mp-alipay" : {
"uniStatistics" : {
"enable" : false
}
},
"mp-baidu" : {
"uniStatistics" : {
"enable" : false
}
},
"mp-jd" : {
"uniStatistics" : {
"enable" : false
}
},
"mp-kuaishou" : {
"uniStatistics" : {
"enable" : false
}
},
"mp-lark" : {
"uniStatistics" : {
"enable" : false
}
},
"mp-qq" : {
"uniStatistics" : {
"enable" : false
}
},
"mp-toutiao" : {
"uniStatistics" : {
"enable" : false
}
},
"quickapp-webview-huawei" : {
"uniStatistics" : {
"enable" : false
}
},
"quickapp-webview-union" : {
"uniStatistics" : {
"enable" : false
}
}
}

13
node_modules/.package-lock.json generated vendored Normal file
View File

@ -0,0 +1,13 @@
{
"name": "uniStarter",
"version": "2.2.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"node_modules/qrcodejs2": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/qrcodejs2/-/qrcodejs2-0.0.2.tgz",
"integrity": "sha512-+Y4HA+cb6qUzdgvI3KML8GYpMFwB24dFwzMkS/yXq6hwtUGNUnZQdUnksrV1XGMc2mid5ROw5SAuY9XhI3ValA=="
}
}
}

4
node_modules/qrcodejs2/.npmignore generated vendored Normal file
View File

@ -0,0 +1,4 @@
.DS_Store
.idea
.project

14
node_modules/qrcodejs2/LICENSE generated vendored Normal file
View File

@ -0,0 +1,14 @@
The MIT License (MIT)
---------------------
Copyright (c) 2012 davidshimjs
Permission is hereby granted, free of charge,
to any person obtaining a copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

43
node_modules/qrcodejs2/README.md generated vendored Normal file
View File

@ -0,0 +1,43 @@
# QRCode.js
QRCode.js is javascript library for making QRCode. QRCode.js supports Cross-browser with HTML5 Canvas and table tag in DOM.
QRCode.js has no dependencies.
## Basic Usages
```
<div id="qrcode"></div>
<script type="text/javascript">
new QRCode(document.getElementById("qrcode"), "http://jindo.dev.naver.com/collie");
</script>
```
or with some options
```
var qrcode = new QRCode("test", {
text: "http://jindo.dev.naver.com/collie",
width: 128,
height: 128,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRCode.CorrectLevel.H
});
```
and you can use some methods
```
qrcode.clear(); // clear the code.
qrcode.makeCode("http://naver.com"); // make another code.
```
## Browser Compatibility
IE6~10, Chrome, Firefox, Safari, Opera, Mobile Safari, Android, Windows Mobile, ETC.
## License
MIT License
## Contact
twitter @davidshimjs
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/davidshimjs/qrcodejs/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

18
node_modules/qrcodejs2/bower.json generated vendored Normal file
View File

@ -0,0 +1,18 @@
{
"name": "qrcode.js",
"version": "0.0.1",
"homepage": "https://github.com/davidshimjs/qrcodejs",
"authors": [
"Sangmin Shim", "Sangmin Shim <ssm0123@gmail.com> (http://jaguarjs.com)"
],
"description": "Cross-browser QRCode generator for javascript",
"main": "qrcode.js",
"ignore": [
"bower_components",
"node_modules",
"index.html",
"index.svg",
"jquery.min.js",
"qrcode.min.js"
]
}

47
node_modules/qrcodejs2/index-svg.html generated vendored Normal file
View File

@ -0,0 +1,47 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko">
<head>
<title>Cross-Browser QRCode generator for Javascript</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="qrcode.js"></script>
</head>
<body>
<input id="text" type="text" value="http://jindo.dev.naver.com/collie" style="width:80%" />
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g id="qrcode"/>
</svg>
<script type="text/javascript">
var qrcode = new QRCode(document.getElementById("qrcode"), {
width : 100,
height : 100,
useSVG: true
});
function makeCode () {
var elText = document.getElementById("text");
if (!elText.value) {
alert("Input a text");
elText.focus();
return;
}
qrcode.makeCode(elText.value);
}
makeCode();
$("#text").
on("blur", function () {
makeCode();
}).
on("keydown", function (e) {
if (e.keyCode == 13) {
makeCode();
}
});
</script>
</body>
</html>

44
node_modules/qrcodejs2/index.html generated vendored Normal file
View File

@ -0,0 +1,44 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko">
<head>
<title>Cross-Browser QRCode generator for Javascript</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="qrcode.js"></script>
</head>
<body>
<input id="text" type="text" value="http://jindo.dev.naver.com/collie" style="width:80%" /><br />
<div id="qrcode" style="width:100px; height:100px; margin-top:15px;"></div>
<script type="text/javascript">
var qrcode = new QRCode(document.getElementById("qrcode"), {
width : 100,
height : 100
});
function makeCode () {
var elText = document.getElementById("text");
if (!elText.value) {
alert("Input a text");
elText.focus();
return;
}
qrcode.makeCode(elText.value);
}
makeCode();
$("#text").
on("blur", function () {
makeCode();
}).
on("keydown", function (e) {
if (e.keyCode == 13) {
makeCode();
}
});
</script>
</body>

37
node_modules/qrcodejs2/index.svg generated vendored Normal file
View File

@ -0,0 +1,37 @@
<?xml version="1.0" standalone="yes"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-50 0 200 100">
<g id="qrcode"/>
<foreignObject x="-50" y="0" width="100" height="100">
<body xmlns="http://www.w3.org/1999/xhtml" style="padding:0; margin:0">
<div style="padding:inherit; margin:inherit; height:100%">
<textarea id="text" style="height:100%; width:100%; position:absolute; margin:inherit; padding:inherit">james</textarea>
</div>
<script type="application/ecmascript" src="qrcode.js"></script>
<script type="application/ecmascript">
var elem = document.getElementById("qrcode");
var qrcode = new QRCode(elem, {
width : 100,
height : 100
});
function makeCode () {
var elText = document.getElementById("text");
if (elText.value === "") {
//alert("Input a text");
//elText.focus();
return;
}
qrcode.makeCode(elText.value);
}
makeCode();
document.getElementById("text").onkeyup = function (e) {
makeCode();
};
</script>
</body>
</foreignObject>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

2
node_modules/qrcodejs2/jquery.min.js generated vendored Normal file

File diff suppressed because one or more lines are too long

21
node_modules/qrcodejs2/package.json generated vendored Normal file
View File

@ -0,0 +1,21 @@
{
"name": "qrcodejs2",
"version": "0.0.2",
"description": "Javsacript QRCode for all browsers",
"main": "qrcode.js",
"repository": {
"type": "git",
"url": "git://github.com/davidshimjs/qrcodejs.git"
},
"keywords": [
"qrcode",
"javascript"
],
"author": "davidshimjs <ssm0123@gmail.com>",
"license": "MIT",
"gitHead": "06c7a5e134f116402699f03cda5819e10a0e5787",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/davidshimjs/qrcodejs/issues"
}
}

627
node_modules/qrcodejs2/qrcode.js generated vendored Normal file
View File

@ -0,0 +1,627 @@
/**
* @fileoverview
* - Using the 'QRCode for Javascript library'
* - Fixed dataset of 'QRCode for Javascript library' for support full-spec.
* - this library has no dependencies.
*
* @author davidshimjs
* @see <a href="http://www.d-project.com/" target="_blank">http://www.d-project.com/</a>
* @see <a href="http://jeromeetienne.github.com/jquery-qrcode/" target="_blank">http://jeromeetienne.github.com/jquery-qrcode/</a>
*/
var QRCode;
(function (root, factory) {
/* CommonJS */
if (typeof exports == 'object') module.exports = factory()
/* AMD module */
else if (typeof define == 'function' && define.amd) define(factory)
/* Global */
else root.QRCode = factory()
}(this, function () { //---------------------------------------------------------------------
// QRCode for JavaScript
//
// Copyright (c) 2009 Kazuhiko Arase
//
// URL: http://www.d-project.com/
//
// Licensed under the MIT license:
// http://www.opensource.org/licenses/mit-license.php
//
// The word "QR Code" is registered trademark of
// DENSO WAVE INCORPORATED
// http://www.denso-wave.com/qrcode/faqpatent-e.html
//
//---------------------------------------------------------------------
function QR8bitByte(data) {
this.mode = QRMode.MODE_8BIT_BYTE;
this.data = data;
this.parsedData = [];
// Added to support UTF-8 Characters
for (var i = 0, l = this.data.length; i < l; i++) {
var byteArray = [];
var code = this.data.charCodeAt(i);
if (code > 0x10000) {
byteArray[0] = 0xF0 | ((code & 0x1C0000) >>> 18);
byteArray[1] = 0x80 | ((code & 0x3F000) >>> 12);
byteArray[2] = 0x80 | ((code & 0xFC0) >>> 6);
byteArray[3] = 0x80 | (code & 0x3F);
} else if (code > 0x800) {
byteArray[0] = 0xE0 | ((code & 0xF000) >>> 12);
byteArray[1] = 0x80 | ((code & 0xFC0) >>> 6);
byteArray[2] = 0x80 | (code & 0x3F);
} else if (code > 0x80) {
byteArray[0] = 0xC0 | ((code & 0x7C0) >>> 6);
byteArray[1] = 0x80 | (code & 0x3F);
} else {
byteArray[0] = code;
}
this.parsedData.push(byteArray);
}
this.parsedData = Array.prototype.concat.apply([], this.parsedData);
if (this.parsedData.length != this.data.length) {
this.parsedData.unshift(191);
this.parsedData.unshift(187);
this.parsedData.unshift(239);
}
}
QR8bitByte.prototype = {
getLength: function (buffer) {
return this.parsedData.length;
},
write: function (buffer) {
for (var i = 0, l = this.parsedData.length; i < l; i++) {
buffer.put(this.parsedData[i], 8);
}
}
};
function QRCodeModel(typeNumber, errorCorrectLevel) {
this.typeNumber = typeNumber;
this.errorCorrectLevel = errorCorrectLevel;
this.modules = null;
this.moduleCount = 0;
this.dataCache = null;
this.dataList = [];
}
QRCodeModel.prototype={addData:function(data){var newData=new QR8bitByte(data);this.dataList.push(newData);this.dataCache=null;},isDark:function(row,col){if(row<0||this.moduleCount<=row||col<0||this.moduleCount<=col){throw new Error(row+","+col);}
return this.modules[row][col];},getModuleCount:function(){return this.moduleCount;},make:function(){this.makeImpl(false,this.getBestMaskPattern());},makeImpl:function(test,maskPattern){this.moduleCount=this.typeNumber*4+17;this.modules=new Array(this.moduleCount);for(var row=0;row<this.moduleCount;row++){this.modules[row]=new Array(this.moduleCount);for(var col=0;col<this.moduleCount;col++){this.modules[row][col]=null;}}
this.setupPositionProbePattern(0,0);this.setupPositionProbePattern(this.moduleCount-7,0);this.setupPositionProbePattern(0,this.moduleCount-7);this.setupPositionAdjustPattern();this.setupTimingPattern();this.setupTypeInfo(test,maskPattern);if(this.typeNumber>=7){this.setupTypeNumber(test);}
if(this.dataCache==null){this.dataCache=QRCodeModel.createData(this.typeNumber,this.errorCorrectLevel,this.dataList);}
this.mapData(this.dataCache,maskPattern);},setupPositionProbePattern:function(row,col){for(var r=-1;r<=7;r++){if(row+r<=-1||this.moduleCount<=row+r)continue;for(var c=-1;c<=7;c++){if(col+c<=-1||this.moduleCount<=col+c)continue;if((0<=r&&r<=6&&(c==0||c==6))||(0<=c&&c<=6&&(r==0||r==6))||(2<=r&&r<=4&&2<=c&&c<=4)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}},getBestMaskPattern:function(){var minLostPoint=0;var pattern=0;for(var i=0;i<8;i++){this.makeImpl(true,i);var lostPoint=QRUtil.getLostPoint(this);if(i==0||minLostPoint>lostPoint){minLostPoint=lostPoint;pattern=i;}}
return pattern;},createMovieClip:function(target_mc,instance_name,depth){var qr_mc=target_mc.createEmptyMovieClip(instance_name,depth);var cs=1;this.make();for(var row=0;row<this.modules.length;row++){var y=row*cs;for(var col=0;col<this.modules[row].length;col++){var x=col*cs;var dark=this.modules[row][col];if(dark){qr_mc.beginFill(0,100);qr_mc.moveTo(x,y);qr_mc.lineTo(x+cs,y);qr_mc.lineTo(x+cs,y+cs);qr_mc.lineTo(x,y+cs);qr_mc.endFill();}}}
return qr_mc;},setupTimingPattern:function(){for(var r=8;r<this.moduleCount-8;r++){if(this.modules[r][6]!=null){continue;}
this.modules[r][6]=(r%2==0);}
for(var c=8;c<this.moduleCount-8;c++){if(this.modules[6][c]!=null){continue;}
this.modules[6][c]=(c%2==0);}},setupPositionAdjustPattern:function(){var pos=QRUtil.getPatternPosition(this.typeNumber);for(var i=0;i<pos.length;i++){for(var j=0;j<pos.length;j++){var row=pos[i];var col=pos[j];if(this.modules[row][col]!=null){continue;}
for(var r=-2;r<=2;r++){for(var c=-2;c<=2;c++){if(r==-2||r==2||c==-2||c==2||(r==0&&c==0)){this.modules[row+r][col+c]=true;}else{this.modules[row+r][col+c]=false;}}}}}},setupTypeNumber:function(test){var bits=QRUtil.getBCHTypeNumber(this.typeNumber);for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[Math.floor(i/3)][i%3+this.moduleCount-8-3]=mod;}
for(var i=0;i<18;i++){var mod=(!test&&((bits>>i)&1)==1);this.modules[i%3+this.moduleCount-8-3][Math.floor(i/3)]=mod;}},setupTypeInfo:function(test,maskPattern){var data=(this.errorCorrectLevel<<3)|maskPattern;var bits=QRUtil.getBCHTypeInfo(data);for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<6){this.modules[i][8]=mod;}else if(i<8){this.modules[i+1][8]=mod;}else{this.modules[this.moduleCount-15+i][8]=mod;}}
for(var i=0;i<15;i++){var mod=(!test&&((bits>>i)&1)==1);if(i<8){this.modules[8][this.moduleCount-i-1]=mod;}else if(i<9){this.modules[8][15-i-1+1]=mod;}else{this.modules[8][15-i-1]=mod;}}
this.modules[this.moduleCount-8][8]=(!test);},mapData:function(data,maskPattern){var inc=-1;var row=this.moduleCount-1;var bitIndex=7;var byteIndex=0;for(var col=this.moduleCount-1;col>0;col-=2){if(col==6)col--;while(true){for(var c=0;c<2;c++){if(this.modules[row][col-c]==null){var dark=false;if(byteIndex<data.length){dark=(((data[byteIndex]>>>bitIndex)&1)==1);}
var mask=QRUtil.getMask(maskPattern,row,col-c);if(mask){dark=!dark;}
this.modules[row][col-c]=dark;bitIndex--;if(bitIndex==-1){byteIndex++;bitIndex=7;}}}
row+=inc;if(row<0||this.moduleCount<=row){row-=inc;inc=-inc;break;}}}}};QRCodeModel.PAD0=0xEC;QRCodeModel.PAD1=0x11;QRCodeModel.createData=function(typeNumber,errorCorrectLevel,dataList){var rsBlocks=QRRSBlock.getRSBlocks(typeNumber,errorCorrectLevel);var buffer=new QRBitBuffer();for(var i=0;i<dataList.length;i++){var data=dataList[i];buffer.put(data.mode,4);buffer.put(data.getLength(),QRUtil.getLengthInBits(data.mode,typeNumber));data.write(buffer);}
var totalDataCount=0;for(var i=0;i<rsBlocks.length;i++){totalDataCount+=rsBlocks[i].dataCount;}
if(buffer.getLengthInBits()>totalDataCount*8){throw new Error("code length overflow. ("
+buffer.getLengthInBits()
+">"
+totalDataCount*8
+")");}
if(buffer.getLengthInBits()+4<=totalDataCount*8){buffer.put(0,4);}
while(buffer.getLengthInBits()%8!=0){buffer.putBit(false);}
while(true){if(buffer.getLengthInBits()>=totalDataCount*8){break;}
buffer.put(QRCodeModel.PAD0,8);if(buffer.getLengthInBits()>=totalDataCount*8){break;}
buffer.put(QRCodeModel.PAD1,8);}
return QRCodeModel.createBytes(buffer,rsBlocks);};QRCodeModel.createBytes=function(buffer,rsBlocks){var offset=0;var maxDcCount=0;var maxEcCount=0;var dcdata=new Array(rsBlocks.length);var ecdata=new Array(rsBlocks.length);for(var r=0;r<rsBlocks.length;r++){var dcCount=rsBlocks[r].dataCount;var ecCount=rsBlocks[r].totalCount-dcCount;maxDcCount=Math.max(maxDcCount,dcCount);maxEcCount=Math.max(maxEcCount,ecCount);dcdata[r]=new Array(dcCount);for(var i=0;i<dcdata[r].length;i++){dcdata[r][i]=0xff&buffer.buffer[i+offset];}
offset+=dcCount;var rsPoly=QRUtil.getErrorCorrectPolynomial(ecCount);var rawPoly=new QRPolynomial(dcdata[r],rsPoly.getLength()-1);var modPoly=rawPoly.mod(rsPoly);ecdata[r]=new Array(rsPoly.getLength()-1);for(var i=0;i<ecdata[r].length;i++){var modIndex=i+modPoly.getLength()-ecdata[r].length;ecdata[r][i]=(modIndex>=0)?modPoly.get(modIndex):0;}}
var totalCodeCount=0;for(var i=0;i<rsBlocks.length;i++){totalCodeCount+=rsBlocks[i].totalCount;}
var data=new Array(totalCodeCount);var index=0;for(var i=0;i<maxDcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<dcdata[r].length){data[index++]=dcdata[r][i];}}}
for(var i=0;i<maxEcCount;i++){for(var r=0;r<rsBlocks.length;r++){if(i<ecdata[r].length){data[index++]=ecdata[r][i];}}}
return data;};var QRMode={MODE_NUMBER:1<<0,MODE_ALPHA_NUM:1<<1,MODE_8BIT_BYTE:1<<2,MODE_KANJI:1<<3};var QRErrorCorrectLevel={L:1,M:0,Q:3,H:2};var QRMaskPattern={PATTERN000:0,PATTERN001:1,PATTERN010:2,PATTERN011:3,PATTERN100:4,PATTERN101:5,PATTERN110:6,PATTERN111:7};var QRUtil={PATTERN_POSITION_TABLE:[[],[6,18],[6,22],[6,26],[6,30],[6,34],[6,22,38],[6,24,42],[6,26,46],[6,28,50],[6,30,54],[6,32,58],[6,34,62],[6,26,46,66],[6,26,48,70],[6,26,50,74],[6,30,54,78],[6,30,56,82],[6,30,58,86],[6,34,62,90],[6,28,50,72,94],[6,26,50,74,98],[6,30,54,78,102],[6,28,54,80,106],[6,32,58,84,110],[6,30,58,86,114],[6,34,62,90,118],[6,26,50,74,98,122],[6,30,54,78,102,126],[6,26,52,78,104,130],[6,30,56,82,108,134],[6,34,60,86,112,138],[6,30,58,86,114,142],[6,34,62,90,118,146],[6,30,54,78,102,126,150],[6,24,50,76,102,128,154],[6,28,54,80,106,132,158],[6,32,58,84,110,136,162],[6,26,54,82,110,138,166],[6,30,58,86,114,142,170]],G15:(1<<10)|(1<<8)|(1<<5)|(1<<4)|(1<<2)|(1<<1)|(1<<0),G18:(1<<12)|(1<<11)|(1<<10)|(1<<9)|(1<<8)|(1<<5)|(1<<2)|(1<<0),G15_MASK:(1<<14)|(1<<12)|(1<<10)|(1<<4)|(1<<1),getBCHTypeInfo:function(data){var d=data<<10;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)>=0){d^=(QRUtil.G15<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G15)));}
return((data<<10)|d)^QRUtil.G15_MASK;},getBCHTypeNumber:function(data){var d=data<<12;while(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)>=0){d^=(QRUtil.G18<<(QRUtil.getBCHDigit(d)-QRUtil.getBCHDigit(QRUtil.G18)));}
return(data<<12)|d;},getBCHDigit:function(data){var digit=0;while(data!=0){digit++;data>>>=1;}
return digit;},getPatternPosition:function(typeNumber){return QRUtil.PATTERN_POSITION_TABLE[typeNumber-1];},getMask:function(maskPattern,i,j){switch(maskPattern){case QRMaskPattern.PATTERN000:return(i+j)%2==0;case QRMaskPattern.PATTERN001:return i%2==0;case QRMaskPattern.PATTERN010:return j%3==0;case QRMaskPattern.PATTERN011:return(i+j)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(i/2)+Math.floor(j/3))%2==0;case QRMaskPattern.PATTERN101:return(i*j)%2+(i*j)%3==0;case QRMaskPattern.PATTERN110:return((i*j)%2+(i*j)%3)%2==0;case QRMaskPattern.PATTERN111:return((i*j)%3+(i+j)%2)%2==0;default:throw new Error("bad maskPattern:"+maskPattern);}},getErrorCorrectPolynomial:function(errorCorrectLength){var a=new QRPolynomial([1],0);for(var i=0;i<errorCorrectLength;i++){a=a.multiply(new QRPolynomial([1,QRMath.gexp(i)],0));}
return a;},getLengthInBits:function(mode,type){if(1<=type&&type<10){switch(mode){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error("mode:"+mode);}}else if(type<27){switch(mode){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error("mode:"+mode);}}else if(type<41){switch(mode){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error("mode:"+mode);}}else{throw new Error("type:"+type);}},getLostPoint:function(qrCode){var moduleCount=qrCode.getModuleCount();var lostPoint=0;for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount;col++){var sameCount=0;var dark=qrCode.isDark(row,col);for(var r=-1;r<=1;r++){if(row+r<0||moduleCount<=row+r){continue;}
for(var c=-1;c<=1;c++){if(col+c<0||moduleCount<=col+c){continue;}
if(r==0&&c==0){continue;}
if(dark==qrCode.isDark(row+r,col+c)){sameCount++;}}}
if(sameCount>5){lostPoint+=(3+sameCount-5);}}}
for(var row=0;row<moduleCount-1;row++){for(var col=0;col<moduleCount-1;col++){var count=0;if(qrCode.isDark(row,col))count++;if(qrCode.isDark(row+1,col))count++;if(qrCode.isDark(row,col+1))count++;if(qrCode.isDark(row+1,col+1))count++;if(count==0||count==4){lostPoint+=3;}}}
for(var row=0;row<moduleCount;row++){for(var col=0;col<moduleCount-6;col++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row,col+1)&&qrCode.isDark(row,col+2)&&qrCode.isDark(row,col+3)&&qrCode.isDark(row,col+4)&&!qrCode.isDark(row,col+5)&&qrCode.isDark(row,col+6)){lostPoint+=40;}}}
for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount-6;row++){if(qrCode.isDark(row,col)&&!qrCode.isDark(row+1,col)&&qrCode.isDark(row+2,col)&&qrCode.isDark(row+3,col)&&qrCode.isDark(row+4,col)&&!qrCode.isDark(row+5,col)&&qrCode.isDark(row+6,col)){lostPoint+=40;}}}
var darkCount=0;for(var col=0;col<moduleCount;col++){for(var row=0;row<moduleCount;row++){if(qrCode.isDark(row,col)){darkCount++;}}}
var ratio=Math.abs(100*darkCount/moduleCount/moduleCount-50)/5;lostPoint+=ratio*10;return lostPoint;}};var QRMath={glog:function(n){if(n<1){throw new Error("glog("+n+")");}
return QRMath.LOG_TABLE[n];},gexp:function(n){while(n<0){n+=255;}
while(n>=256){n-=255;}
return QRMath.EXP_TABLE[n];},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)};for(var i=0;i<8;i++){QRMath.EXP_TABLE[i]=1<<i;}
for(var i=8;i<256;i++){QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];}
for(var i=0;i<255;i++){QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;}
function QRPolynomial(num,shift){if(num.length==undefined){throw new Error(num.length+"/"+shift);}
var offset=0;while(offset<num.length&&num[offset]==0){offset++;}
this.num=new Array(num.length-offset+shift);for(var i=0;i<num.length-offset;i++){this.num[i]=num[i+offset];}}
QRPolynomial.prototype={get:function(index){return this.num[index];},getLength:function(){return this.num.length;},multiply:function(e){var num=new Array(this.getLength()+e.getLength()-1);for(var i=0;i<this.getLength();i++){for(var j=0;j<e.getLength();j++){num[i+j]^=QRMath.gexp(QRMath.glog(this.get(i))+QRMath.glog(e.get(j)));}}
return new QRPolynomial(num,0);},mod:function(e){if(this.getLength()-e.getLength()<0){return this;}
var ratio=QRMath.glog(this.get(0))-QRMath.glog(e.get(0));var num=new Array(this.getLength());for(var i=0;i<this.getLength();i++){num[i]=this.get(i);}
for(var i=0;i<e.getLength();i++){num[i]^=QRMath.gexp(QRMath.glog(e.get(i))+ratio);}
return new QRPolynomial(num,0).mod(e);}};function QRRSBlock(totalCount,dataCount){this.totalCount=totalCount;this.dataCount=dataCount;}
QRRSBlock.RS_BLOCK_TABLE=[[1,26,19],[1,26,16],[1,26,13],[1,26,9],[1,44,34],[1,44,28],[1,44,22],[1,44,16],[1,70,55],[1,70,44],[2,35,17],[2,35,13],[1,100,80],[2,50,32],[2,50,24],[4,25,9],[1,134,108],[2,67,43],[2,33,15,2,34,16],[2,33,11,2,34,12],[2,86,68],[4,43,27],[4,43,19],[4,43,15],[2,98,78],[4,49,31],[2,32,14,4,33,15],[4,39,13,1,40,14],[2,121,97],[2,60,38,2,61,39],[4,40,18,2,41,19],[4,40,14,2,41,15],[2,146,116],[3,58,36,2,59,37],[4,36,16,4,37,17],[4,36,12,4,37,13],[2,86,68,2,87,69],[4,69,43,1,70,44],[6,43,19,2,44,20],[6,43,15,2,44,16],[4,101,81],[1,80,50,4,81,51],[4,50,22,4,51,23],[3,36,12,8,37,13],[2,116,92,2,117,93],[6,58,36,2,59,37],[4,46,20,6,47,21],[7,42,14,4,43,15],[4,133,107],[8,59,37,1,60,38],[8,44,20,4,45,21],[12,33,11,4,34,12],[3,145,115,1,146,116],[4,64,40,5,65,41],[11,36,16,5,37,17],[11,36,12,5,37,13],[5,109,87,1,110,88],[5,65,41,5,66,42],[5,54,24,7,55,25],[11,36,12],[5,122,98,1,123,99],[7,73,45,3,74,46],[15,43,19,2,44,20],[3,45,15,13,46,16],[1,135,107,5,136,108],[10,74,46,1,75,47],[1,50,22,15,51,23],[2,42,14,17,43,15],[5,150,120,1,151,121],[9,69,43,4,70,44],[17,50,22,1,51,23],[2,42,14,19,43,15],[3,141,113,4,142,114],[3,70,44,11,71,45],[17,47,21,4,48,22],[9,39,13,16,40,14],[3,135,107,5,136,108],[3,67,41,13,68,42],[15,54,24,5,55,25],[15,43,15,10,44,16],[4,144,116,4,145,117],[17,68,42],[17,50,22,6,51,23],[19,46,16,6,47,17],[2,139,111,7,140,112],[17,74,46],[7,54,24,16,55,25],[34,37,13],[4,151,121,5,152,122],[4,75,47,14,76,48],[11,54,24,14,55,25],[16,45,15,14,46,16],[6,147,117,4,148,118],[6,73,45,14,74,46],[11,54,24,16,55,25],[30,46,16,2,47,17],[8,132,106,4,133,107],[8,75,47,13,76,48],[7,54,24,22,55,25],[22,45,15,13,46,16],[10,142,114,2,143,115],[19,74,46,4,75,47],[28,50,22,6,51,23],[33,46,16,4,47,17],[8,152,122,4,153,123],[22,73,45,3,74,46],[8,53,23,26,54,24],[12,45,15,28,46,16],[3,147,117,10,148,118],[3,73,45,23,74,46],[4,54,24,31,55,25],[11,45,15,31,46,16],[7,146,116,7,147,117],[21,73,45,7,74,46],[1,53,23,37,54,24],[19,45,15,26,46,16],[5,145,115,10,146,116],[19,75,47,10,76,48],[15,54,24,25,55,25],[23,45,15,25,46,16],[13,145,115,3,146,116],[2,74,46,29,75,47],[42,54,24,1,55,25],[23,45,15,28,46,16],[17,145,115],[10,74,46,23,75,47],[10,54,24,35,55,25],[19,45,15,35,46,16],[17,145,115,1,146,116],[14,74,46,21,75,47],[29,54,24,19,55,25],[11,45,15,46,46,16],[13,145,115,6,146,116],[14,74,46,23,75,47],[44,54,24,7,55,25],[59,46,16,1,47,17],[12,151,121,7,152,122],[12,75,47,26,76,48],[39,54,24,14,55,25],[22,45,15,41,46,16],[6,151,121,14,152,122],[6,75,47,34,76,48],[46,54,24,10,55,25],[2,45,15,64,46,16],[17,152,122,4,153,123],[29,74,46,14,75,47],[49,54,24,10,55,25],[24,45,15,46,46,16],[4,152,122,18,153,123],[13,74,46,32,75,47],[48,54,24,14,55,25],[42,45,15,32,46,16],[20,147,117,4,148,118],[40,75,47,7,76,48],[43,54,24,22,55,25],[10,45,15,67,46,16],[19,148,118,6,149,119],[18,75,47,31,76,48],[34,54,24,34,55,25],[20,45,15,61,46,16]];QRRSBlock.getRSBlocks=function(typeNumber,errorCorrectLevel){var rsBlock=QRRSBlock.getRsBlockTable(typeNumber,errorCorrectLevel);if(rsBlock==undefined){throw new Error("bad rs block @ typeNumber:"+typeNumber+"/errorCorrectLevel:"+errorCorrectLevel);}
var length=rsBlock.length/3;var list=[];for(var i=0;i<length;i++){var count=rsBlock[i*3+0];var totalCount=rsBlock[i*3+1];var dataCount=rsBlock[i*3+2];for(var j=0;j<count;j++){list.push(new QRRSBlock(totalCount,dataCount));}}
return list;};QRRSBlock.getRsBlockTable=function(typeNumber,errorCorrectLevel){switch(errorCorrectLevel){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[(typeNumber-1)*4+3];default:return undefined;}};function QRBitBuffer(){this.buffer=[];this.length=0;}
QRBitBuffer.prototype={get:function(index){var bufIndex=Math.floor(index/8);return((this.buffer[bufIndex]>>>(7-index%8))&1)==1;},put:function(num,length){for(var i=0;i<length;i++){this.putBit(((num>>>(length-i-1))&1)==1);}},getLengthInBits:function(){return this.length;},putBit:function(bit){var bufIndex=Math.floor(this.length/8);if(this.buffer.length<=bufIndex){this.buffer.push(0);}
if(bit){this.buffer[bufIndex]|=(0x80>>>(this.length%8));}
this.length++;}};var QRCodeLimitLength=[[17,14,11,7],[32,26,20,14],[53,42,32,24],[78,62,46,34],[106,84,60,44],[134,106,74,58],[154,122,86,64],[192,152,108,84],[230,180,130,98],[271,213,151,119],[321,251,177,137],[367,287,203,155],[425,331,241,177],[458,362,258,194],[520,412,292,220],[586,450,322,250],[644,504,364,280],[718,560,394,310],[792,624,442,338],[858,666,482,382],[929,711,509,403],[1003,779,565,439],[1091,857,611,461],[1171,911,661,511],[1273,997,715,535],[1367,1059,751,593],[1465,1125,805,625],[1528,1190,868,658],[1628,1264,908,698],[1732,1370,982,742],[1840,1452,1030,790],[1952,1538,1112,842],[2068,1628,1168,898],[2188,1722,1228,958],[2303,1809,1283,983],[2431,1911,1351,1051],[2563,1989,1423,1093],[2699,2099,1499,1139],[2809,2213,1579,1219],[2953,2331,1663,1273]];
function _isSupportCanvas() {
return typeof CanvasRenderingContext2D != "undefined";
}
// android 2.x doesn't support Data-URI spec
function _getAndroid() {
var android = false;
var sAgent = navigator.userAgent;
if (/android/i.test(sAgent)) { // android
android = true;
var aMat = sAgent.toString().match(/android ([0-9]\.[0-9])/i);
if (aMat && aMat[1]) {
android = parseFloat(aMat[1]);
}
}
return android;
}
var svgDrawer = (function() {
var Drawing = function (el, htOption) {
this._el = el;
this._htOption = htOption;
};
Drawing.prototype.draw = function (oQRCode) {
var _htOption = this._htOption;
var _el = this._el;
var nCount = oQRCode.getModuleCount();
var nWidth = Math.floor(_htOption.width / nCount);
var nHeight = Math.floor(_htOption.height / nCount);
this.clear();
function makeSVG(tag, attrs) {
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
if (attrs.hasOwnProperty(k)) el.setAttribute(k, attrs[k]);
return el;
}
var svg = makeSVG("svg" , {'viewBox': '0 0 ' + String(nCount) + " " + String(nCount), 'width': '100%', 'height': '100%', 'fill': _htOption.colorLight});
svg.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:xlink", "http://www.w3.org/1999/xlink");
_el.appendChild(svg);
svg.appendChild(makeSVG("rect", {"fill": _htOption.colorLight, "width": "100%", "height": "100%"}));
svg.appendChild(makeSVG("rect", {"fill": _htOption.colorDark, "width": "1", "height": "1", "id": "template"}));
for (var row = 0; row < nCount; row++) {
for (var col = 0; col < nCount; col++) {
if (oQRCode.isDark(row, col)) {
var child = makeSVG("use", {"x": String(col), "y": String(row)});
child.setAttributeNS("http://www.w3.org/1999/xlink", "href", "#template")
svg.appendChild(child);
}
}
}
};
Drawing.prototype.clear = function () {
while (this._el.hasChildNodes())
this._el.removeChild(this._el.lastChild);
};
return Drawing;
})();
var useSVG = document.documentElement.tagName.toLowerCase() === "svg";
// Drawing in DOM by using Table tag
var Drawing = useSVG ? svgDrawer : !_isSupportCanvas() ? (function () {
var Drawing = function (el, htOption) {
this._el = el;
this._htOption = htOption;
};
/**
* Draw the QRCode
*
* @param {QRCode} oQRCode
*/
Drawing.prototype.draw = function (oQRCode) {
var _htOption = this._htOption;
var _el = this._el;
var nCount = oQRCode.getModuleCount();
var nWidth = Math.floor(_htOption.width / nCount);
var nHeight = Math.floor(_htOption.height / nCount);
var aHTML = ['<table style="border:0;border-collapse:collapse;">'];
for (var row = 0; row < nCount; row++) {
aHTML.push('<tr>');
for (var col = 0; col < nCount; col++) {
aHTML.push('<td style="border:0;border-collapse:collapse;padding:0;margin:0;width:' + nWidth + 'px;height:' + nHeight + 'px;background-color:' + (oQRCode.isDark(row, col) ? _htOption.colorDark : _htOption.colorLight) + ';"></td>');
}
aHTML.push('</tr>');
}
aHTML.push('</table>');
_el.innerHTML = aHTML.join('');
// Fix the margin values as real size.
var elTable = _el.childNodes[0];
var nLeftMarginTable = (_htOption.width - elTable.offsetWidth) / 2;
var nTopMarginTable = (_htOption.height - elTable.offsetHeight) / 2;
if (nLeftMarginTable > 0 && nTopMarginTable > 0) {
elTable.style.margin = nTopMarginTable + "px " + nLeftMarginTable + "px";
}
};
/**
* Clear the QRCode
*/
Drawing.prototype.clear = function () {
this._el.innerHTML = '';
};
return Drawing;
})() : (function () { // Drawing in Canvas
function _onMakeImage() {
this._elImage.src = this._elCanvas.toDataURL("image/png");
this._elImage.style.display = "block";
this._elCanvas.style.display = "none";
}
// Android 2.1 bug workaround
// http://code.google.com/p/android/issues/detail?id=5141
if (this._android && this._android <= 2.1) {
var factor = 1 / window.devicePixelRatio;
var drawImage = CanvasRenderingContext2D.prototype.drawImage;
CanvasRenderingContext2D.prototype.drawImage = function (image, sx, sy, sw, sh, dx, dy, dw, dh) {
if (("nodeName" in image) && /img/i.test(image.nodeName)) {
for (var i = arguments.length - 1; i >= 1; i--) {
arguments[i] = arguments[i] * factor;
}
} else if (typeof dw == "undefined") {
arguments[1] *= factor;
arguments[2] *= factor;
arguments[3] *= factor;
arguments[4] *= factor;
}
drawImage.apply(this, arguments);
};
}
/**
* Check whether the user's browser supports Data URI or not
*
* @private
* @param {Function} fSuccess Occurs if it supports Data URI
* @param {Function} fFail Occurs if it doesn't support Data URI
*/
function _safeSetDataURI(fSuccess, fFail) {
var self = this;
self._fFail = fFail;
self._fSuccess = fSuccess;
// Check it just once
if (self._bSupportDataURI === null) {
var el = document.createElement("img");
var fOnError = function() {
self._bSupportDataURI = false;
if (self._fFail) {
self._fFail.call(self);
}
};
var fOnSuccess = function() {
self._bSupportDataURI = true;
if (self._fSuccess) {
self._fSuccess.call(self);
}
};
el.onabort = fOnError;
el.onerror = fOnError;
el.onload = fOnSuccess;
el.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // the Image contains 1px data.
return;
} else if (self._bSupportDataURI === true && self._fSuccess) {
self._fSuccess.call(self);
} else if (self._bSupportDataURI === false && self._fFail) {
self._fFail.call(self);
}
};
/**
* Drawing QRCode by using canvas
*
* @constructor
* @param {HTMLElement} el
* @param {Object} htOption QRCode Options
*/
var Drawing = function (el, htOption) {
this._bIsPainted = false;
this._android = _getAndroid();
this._htOption = htOption;
this._elCanvas = document.createElement("canvas");
this._elCanvas.width = htOption.width;
this._elCanvas.height = htOption.height;
el.appendChild(this._elCanvas);
this._el = el;
this._oContext = this._elCanvas.getContext("2d");
this._bIsPainted = false;
this._elImage = document.createElement("img");
this._elImage.alt = "Scan me!";
this._elImage.style.display = "none";
this._el.appendChild(this._elImage);
this._bSupportDataURI = null;
};
/**
* Draw the QRCode
*
* @param {QRCode} oQRCode
*/
Drawing.prototype.draw = function (oQRCode) {
var _elImage = this._elImage;
var _oContext = this._oContext;
var _htOption = this._htOption;
var nCount = oQRCode.getModuleCount();
var nWidth = _htOption.width / nCount;
var nHeight = _htOption.height / nCount;
var nRoundedWidth = Math.round(nWidth);
var nRoundedHeight = Math.round(nHeight);
_elImage.style.display = "none";
this.clear();
for (var row = 0; row < nCount; row++) {
for (var col = 0; col < nCount; col++) {
var bIsDark = oQRCode.isDark(row, col);
var nLeft = col * nWidth;
var nTop = row * nHeight;
_oContext.strokeStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
_oContext.lineWidth = 1;
_oContext.fillStyle = bIsDark ? _htOption.colorDark : _htOption.colorLight;
_oContext.fillRect(nLeft, nTop, nWidth, nHeight);
// 안티 앨리어싱 방지 처리
_oContext.strokeRect(
Math.floor(nLeft) + 0.5,
Math.floor(nTop) + 0.5,
nRoundedWidth,
nRoundedHeight
);
_oContext.strokeRect(
Math.ceil(nLeft) - 0.5,
Math.ceil(nTop) - 0.5,
nRoundedWidth,
nRoundedHeight
);
}
}
this._bIsPainted = true;
};
/**
* Make the image from Canvas if the browser supports Data URI.
*/
Drawing.prototype.makeImage = function () {
if (this._bIsPainted) {
_safeSetDataURI.call(this, _onMakeImage);
}
};
/**
* Return whether the QRCode is painted or not
*
* @return {Boolean}
*/
Drawing.prototype.isPainted = function () {
return this._bIsPainted;
};
/**
* Clear the QRCode
*/
Drawing.prototype.clear = function () {
this._oContext.clearRect(0, 0, this._elCanvas.width, this._elCanvas.height);
this._bIsPainted = false;
};
/**
* @private
* @param {Number} nNumber
*/
Drawing.prototype.round = function (nNumber) {
if (!nNumber) {
return nNumber;
}
return Math.floor(nNumber * 1000) / 1000;
};
return Drawing;
})();
/**
* Get the type by string length
*
* @private
* @param {String} sText
* @param {Number} nCorrectLevel
* @return {Number} type
*/
function _getTypeNumber(sText, nCorrectLevel) {
var nType = 1;
var length = _getUTF8Length(sText);
for (var i = 0, len = QRCodeLimitLength.length; i <= len; i++) {
var nLimit = 0;
switch (nCorrectLevel) {
case QRErrorCorrectLevel.L :
nLimit = QRCodeLimitLength[i][0];
break;
case QRErrorCorrectLevel.M :
nLimit = QRCodeLimitLength[i][1];
break;
case QRErrorCorrectLevel.Q :
nLimit = QRCodeLimitLength[i][2];
break;
case QRErrorCorrectLevel.H :
nLimit = QRCodeLimitLength[i][3];
break;
}
if (length <= nLimit) {
break;
} else {
nType++;
}
}
if (nType > QRCodeLimitLength.length) {
throw new Error("Too long data");
}
return nType;
}
function _getUTF8Length(sText) {
var replacedText = encodeURI(sText).toString().replace(/\%[0-9a-fA-F]{2}/g, 'a');
return replacedText.length + (replacedText.length != sText ? 3 : 0);
}
/**
* @class QRCode
* @constructor
* @example
* new QRCode(document.getElementById("test"), "http://jindo.dev.naver.com/collie");
*
* @example
* var oQRCode = new QRCode("test", {
* text : "http://naver.com",
* width : 128,
* height : 128
* });
*
* oQRCode.clear(); // Clear the QRCode.
* oQRCode.makeCode("http://map.naver.com"); // Re-create the QRCode.
*
* @param {HTMLElement|String} el target element or 'id' attribute of element.
* @param {Object|String} vOption
* @param {String} vOption.text QRCode link data
* @param {Number} [vOption.width=256]
* @param {Number} [vOption.height=256]
* @param {String} [vOption.colorDark="#000000"]
* @param {String} [vOption.colorLight="#ffffff"]
* @param {QRCode.CorrectLevel} [vOption.correctLevel=QRCode.CorrectLevel.H] [L|M|Q|H]
*/
QRCode = function (el, vOption) {
this._htOption = {
width : 256,
height : 256,
typeNumber : 4,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRErrorCorrectLevel.H
};
if (typeof vOption === 'string') {
vOption = {
text : vOption
};
}
// Overwrites options
if (vOption) {
for (var i in vOption) {
this._htOption[i] = vOption[i];
}
}
if (typeof el == "string") {
el = document.getElementById(el);
}
if (this._htOption.useSVG) {
Drawing = svgDrawer;
}
this._android = _getAndroid();
this._el = el;
this._oQRCode = null;
this._oDrawing = new Drawing(this._el, this._htOption);
if (this._htOption.text) {
this.makeCode(this._htOption.text);
}
};
/**
* Make the QRCode
*
* @param {String} sText link data
*/
QRCode.prototype.makeCode = function (sText) {
this._oQRCode = new QRCodeModel(_getTypeNumber(sText, this._htOption.correctLevel), this._htOption.correctLevel);
this._oQRCode.addData(sText);
this._oQRCode.make();
this._el.title = sText;
this._oDrawing.draw(this._oQRCode);
this.makeImage();
};
/**
* Make the Image from Canvas element
* - It occurs automatically
* - Android below 3 doesn't support Data-URI spec.
*
* @private
*/
QRCode.prototype.makeImage = function () {
if (typeof this._oDrawing.makeImage == "function" && (!this._android || this._android >= 3)) {
this._oDrawing.makeImage();
}
};
/**
* Clear the QRCode
*/
QRCode.prototype.clear = function () {
this._oDrawing.clear();
};
/**
* @name QRCode.CorrectLevel
*/
QRCode.CorrectLevel = QRErrorCorrectLevel;
return QRCode;
}));

1
node_modules/qrcodejs2/qrcode.min.js generated vendored Normal file

File diff suppressed because one or more lines are too long

83
package.json Normal file
View File

@ -0,0 +1,83 @@
{
"id": "ctms-client",
"name": "ctms-client",
"displayName": "ctms-client 运车助手",
"version": "110",
"description": "基于UNI-APP开发制作的CTMS运车助手App。主要面向终端运车客户提供下单查单、询价、资讯获取等功能及服务。",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": "https://gitea.hiluker.com/lukegzs/ctms-client",
"keywords": [
"hello-uniapp",
"uni-app",
"uni-ui",
"示例工程"
],
"author": "",
"license": "MIT",
"bugs": {
"url": "https://gitea.hiluker.com/lukegzs/ctms-client"
},
"homepage": "https://gitea.hiluker.com/lukegzs/ctms-client#readme",
"dependencies": {},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"京东": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
},
"uni-app": {
"scripts": {
"mp-dingtalk": {
"title": "钉钉小程序",
"env": {
"UNI_PLATFORM": "mp-alipay"
},
"define": {
"MP-DINGTALK": true
}
}
}
}
}

559
pages.json Normal file
View File

@ -0,0 +1,559 @@
{
//主包,即放置默认启动页面/TabBar 页面,以及一些所有分包都需用到公共资源/JS 脚本分包则是根据pages.json的配置进行划分;APP上是不起啥用的
"pages": [{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"enablePullDownRefresh": true,
"titleNView": false
}
}, {
"path": "pages/ctms/tabbar/index/index",
"style": {
"enablePullDownRefresh": true
}
}, {
"path": "pages/ctms/tabbar/order/index",
"style": {}
}, {
"path": "pages/ctms/tabbar/mid/index",
"style": {}
}, {
"path": "pages/ctms/tabbar/notice/index",
"style": {
"enablePullDownRefresh": true
}
}, {
"path": "pages/ctms/tabbar/me/index",
"style": {
"h5": {
"bounce": "none",
"titleNView": {
"buttons": [{
"text": "\ue616 ",
"fontSrc": "/static/font/iconfont.ttf",
"fontSize": "20px"
// "color": "red"
}]
}
}
}
}, {
"path": "uni_modules/uni-upgrade-center-app/pages/upgrade-popup",
"style": {
"disableScroll": true,
"app-plus": {
"backgroundColorTop": "transparent",
"background": "transparent",
"titleNView": false,
"scrollIndicator": false,
"popGesture": "none",
"animationType": "fade-in",
"animationDuration": 200
}
}
}, {
"path": "pages/uni-agree/uni-agree",
"style": {
"navigationStyle": "custom",
"app-plus": {
"popGesture": "none"
}
}
}, {
"path": "pages/common/webview/index",
"style": {
"navigationBarTitleText": "",
"app-plus": {
"bounce": "none",
"titleNView": {
"buttons": [{
"text": "\ue739 ", //分享
"fontSrc": "/static/font/iconfont.ttf",
"fontSize": "20px"
}, {
"text": "\ue616 ", //问号
"fontSrc": "/static/font/iconfont.ttf",
"fontSize": "20px"
}, {
"text": "\ue604 ", //刷新
"fontSrc": "/static/font/iconfont.ttf",
"fontSize": "20px"
}]
}
},
"h5": {
"bounce": "none",
"titleNView": {
"buttons": [{
"text": "\ue616 ", //盾牌
"fontSrc": "/static/font/iconfont.ttf",
"fontSize": "20px"
}, {
"text": "\ue604 ", //刷新
"fontSrc": "/static/font/iconfont.ttf",
"fontSize": "20px"
}, {
"text": "\ue699 ",
"fontSrc": "/static/font/iconfont.ttf",
"fontSize": "20px"
}]
}
}
},
"needLogin": false
}, {
"path": "pages/common/textview/index",
"style": {
"navigationBarTitleText": ""
},
"needLogin": false
}],
"subPackages": [{
"root": "pages/uni-starter",
"pages": [{
"path": "list/list",
"style": {
// #ifndef APP-PLUS
"enablePullDownRefresh": true
// #endif
// "navigationStyle": "custom"
}
}, {
"path": "list/search/search",
"style": {
"navigationBarTitleText": "搜索"
}
}, {
"path": "list/detail",
"style": {
"app-plus": {
"titleNView": {
"buttons": [{
"type": "share"
}],
"type": "transparent"
}
},
"h5": {
"titleNView": {
"type": "transparent"
}
},
"navigationBarTitleText": "文章详情"
}
}, {
"path": "news/list/list",
"style": {
// #ifndef APP-PLUS
"enablePullDownRefresh": true
// #endif
// "navigationStyle": "custom"
}
}, {
"path": "news/search/search",
"style": {
"navigationBarTitleText": "搜索"
}
}, {
"path": "news/detail/detail",
"style": {
"app-plus": {
"titleNView": {
"buttons": [{
"type": "share"
}],
"type": "transparent"
}
},
"h5": {
"titleNView": {
"type": "transparent"
}
},
"navigationBarTitleText": "文章详情"
}
}, {
"path": "ucenter/ucenter",
"style": {
"navigationStyle": "custom"
}
}, {
"path": "ucenter/settings/settings",
"style": {
"navigationBarTitleText": "设置"
}
}, {
"path": "ucenter/read-news-log/read-news-log",
"style": {
"navigationBarTitleText": "阅读记录",
"enablePullDownRefresh": true
}
}
// #ifdef APP-PLUS
, {
"path": "ucenter/about/about",
"style": {
"navigationBarTitleText": "关于",
"app-plus": {
"titleNView": {
"buttons": [{
"type": "share"
}]
}
}
}
},
{
"path": "ucenter/invite/invite",
"style": {
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
}
// #endif
]
}, {
"root": "uni_modules/uni-feedback",
"pages": [{
"path": "pages/opendb-feedback/opendb-feedback",
"style": {
"navigationBarTitleText": "意见反馈",
"enablePullDownRefresh": false
}
}]
}, {
"root": "uni_modules/uni-id-pages/pages",
"pages": [{
"path": "userinfo/userinfo",
"style": {
"navigationBarTitleText": "个人资料"
}
}, {
"path": "userinfo/realname-verify/realname-verify",
"style": {
"enablePullDownRefresh": false,
"navigationBarTitleText": "实名认证"
}
}, {
"path": "login/login-withoutpwd"
}, {
"path": "login/login-withpwd"
}, {
"path": "userinfo/deactivate/deactivate",
"style": {
"navigationBarTitleText": "注销账号"
}
}, {
"path": "userinfo/bind-mobile/bind-mobile",
"style": {
"navigationBarTitleText": "绑定手机号码"
}
}, {
"path": "login/login-smscode",
"style": {
"navigationBarTitleText": "手机验证码登录"
}
}, {
"path": "register/register",
"style": {
"navigationBarTitleText": "注册"
}
}, {
"path": "retrieve/retrieve",
"style": {
"navigationBarTitleText": "重置密码"
}
}, {
"path": "common/webview/webview",
"style": {
"enablePullDownRefresh": false,
"navigationBarTitleText": ""
}
}, {
"path": "userinfo/change_pwd/change_pwd",
"style": {
"enablePullDownRefresh": false,
"navigationBarTitleText": "修改密码"
}
}, {
"path": "register/register-by-email",
"style": {
"navigationBarTitleText": "邮箱验证码注册"
}
}, {
"path": "retrieve/retrieve-by-email",
"style": {
"navigationBarTitleText": "通过邮箱重置密码"
}
}, {
"path": "userinfo/set-pwd/set-pwd",
"style": {
"enablePullDownRefresh": false,
"navigationBarTitleText": "设置密码"
}
}
// #ifdef H5
, {
"path": "userinfo/cropImage/cropImage"
}, {
"path": "register/register-admin",
"style": {
"enablePullDownRefresh": false,
"navigationBarTitleText": "注册管理员账号"
}
}
// #endif
]
}, {
"root": "uni_modules/uni-cms-article/pages",
"pages": [{
"path": "list/list",
"style": {
"backgroundColor": "#FFFFFF",
"disableScroll": true
// "navigationStyle": "custom"
}
}, {
"path": "search/search",
"style": {
"navigationBarTitleText": "搜索"
}
}, {
"path": "detail/detail",
"style": {
"backgroundColor": "#FFFFFF",
"navigationBarTitleText": "详情"
}
}, {
"path": "detail/preview",
"style": {
"backgroundColor": "#FFFFFF",
"navigationBarTitleText": "预览"
}
}]
}, {
"root": "pages/ctms",
"pages": [{
"path": "index/index",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom",
"enablePullDownRefresh": true
}
}, {
"path": "login/login",
"style": {
"navigationBarTitleText": "登录"
}
}, {
"path": "login/loginSms",
"style": {
"navigationBarTitleText": "登陆"
}
}, {
"path": "login/reg",
"style": {
"navigationBarTitleText": "注册"
}
}, {
"path": "about/about",
"style": {
"navigationBarTitleText": "关于APP",
"enablePullDownRefresh": false
}
}, {
"path": "me/index",
"style": {
"navigationBarTitleText": "个人中心",
"enablePullDownRefresh": true
}
}, {
"path": "order/list/list",
"style": {
"navigationBarTitleText": "运单列表",
"enablePullDownRefresh": true
}
}, {
"path": "order/detail/detail",
"style": {
"navigationBarTitleText": "运单详情",
"enablePullDownRefresh": true,
"app-plus": {
"bounce": "none",
"titleNView": {
"buttons": [
//#ifdef APP
{
"type": "share"
}
//#endif
]
}
}
}
}, {
"path": "order/detail/check",
"style": {
"navigationBarTitleText": "运单验车详情",
"enablePullDownRefresh": true
}
}, {
"path": "order/index/index",
"style": {
"navigationBarTitleText": "运单查询",
"enablePullDownRefresh": false
}
}, {
"path": "order/create/create",
"style": {
"navigationBarTitleText": "在线下单",
"enablePullDownRefresh": false
}
}, {
"path": "orderpre/list/list",
"style": {
"navigationBarTitleText": "询价记录",
"enablePullDownRefresh": true
}
}, {
"path": "orderpre/detail/detail",
"style": {
"navigationBarTitleText": "询价详情",
"enablePullDownRefresh": true,
"app-plus": {
"bounce": "none",
"titleNView": {
"buttons": [
//#ifdef APP
{
"type": "share"
}
//#endif
]
}
}
}
}, {
"path": "orderpre/create/create",
"style": {
"navigationBarTitleText": "获取报价",
"enablePullDownRefresh": false
},
"needLogin": false
}, {
"path": "news/list/list",
"style": {
"navigationBarTitleText": "资讯中心",
"enablePullDownRefresh": true
}
}, {
"path": "news/detail/detail",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": true,
"app-plus": {
"bounce": "none",
"titleNView": {
"buttons": [
//#ifdef APP
{
"type": "share"
}
//#endif
]
}
}
}
},
{
"path": "order/yanche/yanche",
"style": {
"navigationBarTitleText": "验车上传"
}
},
{
"path": "scan/scan",
"style": {
"navigationBarTitleText": ""
}
}
]
}],
"globalStyle": {
// #ifdef H5
"h5": {
"titleNView": true //为false的在H5界面不显示导航栏
},
// #endif
"navigationBarTextStyle": "black",
"navigationBarTitleText": "运车助手",
"navigationBarBackgroundColor": "#FFFFFF",
"backgroundColor": "#F8F8F8",
"enablePullDownRefresh": false,
// "maxWidth":375,
"rpxCalcMaxDeviceWidth": 375,
"rpxCalcBaseDeviceWidth": 375
// "rpxCalcIncludeWidth":0
},
"tabBar": {
"borderStyle": "black",
"backgroundColor": "#333",
"color": "#8F8F94",
"selectedColor": "#f33e54",
"list": [{
"pagePath": "pages/ctms/tabbar/index/index",
"iconPath": "static/img/tabbar/default/home.png",
"selectedIconPath": "static/img/tabbar/default/homeactive.png",
"text": "首页"
},
{
"pagePath": "pages/ctms/tabbar/order/index",
"iconPath": "static/img/tabbar/default/guanzhu.png",
"selectedIconPath": "static/img/tabbar/default/guanzhuactive.png",
"text": "查单"
},
{
"pagePath": "pages/ctms/tabbar/mid/index",
"iconPath": "static/img/tabbar/default/add.png",
"selectedIconPath": "static/img/tabbar/default/addactive.png"
},
{
"pagePath": "pages/ctms/tabbar/notice/index",
"iconPath": "static/img/tabbar/default/news.png",
"selectedIconPath": "static/img/tabbar/default/newsactive.png",
"text": "消息"
},
{
"pagePath": "pages/ctms/tabbar/me/index",
"iconPath": "static/img/tabbar/default/me.png",
"selectedIconPath": "static/img/tabbar/default/meactive.png",
"text": "我"
}
]
},
"uniIdRouter": {
//自动路由
// "loginPage": "uni_modules/uni-id-pages/pages/login/login-withoutpwd",
"loginPage": "pages/ctms/login/loginSms",
// 需要登录的页面路径
"needLogin": [
// 需要登录才可访问的页面列表,可以使用正则语法
"uni_modules/uni-id-pages/pages/userinfo/userinfo",
"pages/uni-starter/.*",
"pages/ctms/order/.*",
//order目录下全部需要登陆
"pages/ctms/orderpre/.*",
"pages/ctms/tabbar/order/.*",
"pages/ctms/me/.*"
],
// 客户端未登录或登录状态过期的判断: uni_id_token失效
"resToLogin": true
// 自动解析云对象及clientDB的错误码如果是客户端token不正确或token过期则自动跳转配置的登录页面
}
}

View File

@ -0,0 +1,43 @@
<template>
<view>
<uni-card class="view-title" :title="title">
<text class="uni-body view-content">{{ content }}</text>
</uni-card>
</view>
</template>
<script>
export default {
data() {
return {
title: '',
content: ''
}
},
onLoad(options) {
this.title = options.title
this.content = options.content
uni.setNavigationBarTitle({
title: options.title
})
}
}
</script>
<style scoped>
page {
background-color: #ffffff;
}
.view-title {
font-weight: bold;
}
.view-content {
font-size: 26rpx;
padding: 12px 5px 0;
color: #333;
line-height: 24px;
font-weight: normal;
}
</style>

View File

@ -0,0 +1,104 @@
<template>
<view class="container">
<!-- #ifndef APP-PLUS -->
<uni-nav-bar class="status_bar" dark :fixed="true" shadow status-bar left-icon="left" left-text="" title=""
right-icon="refresh" @clickLeft="goBack" @clickRight="goRefresh" />
<!-- #endif -->
<view v-if="params.url">
<web-view :webview-styles="webviewStyles" :src="`${params.url}`"></web-view>
</view>
</view>
</template>
<script>
import store from '@/store/index.js';
import utils from "@/utils/common.js";
export default {
data() {
return {
params: {},
oldUrl: '', //储存传参的url
webviewStyles: {
progress: {
color: "#FF3333"
}
}
}
},
props: {
//接收父组件的数据
src: {
type: [String],
default: null
}
},
methods: {
goRefresh() {
//TBD
}
},
onLoad(event) {
// store.commit('user/login'); //调用登陆user的函数
this.params = event
if (!event.url) {
uni.showToast({
title: "未提供网址链接",
complete: () => {
uni.navigateBack()
}
})
} else {
let url = event.url;
this.oldUrl = url;
var user = store.state.userCloud;
if (url.substring(0, 4) === 'http') {
//打开网址
if (event.title) {
uni.setNavigationBarTitle({
title: event.title
})
}
if (user.hasLogin) {
var openid = user.openid;
utils.debug(openid)
this.params.url = url + '?&open_id=' + openid;
}
} else if (url.substring(0, 7) === '/pages/') {
//打开指定页面
uni.navigateTo({
url: url
})
} else {
uni.showModal({
title: "错误",
content: '不是一个有效的网站链接,' + '"' + url + '"',
showCancel: false,
confirmText: "知道了",
complete: () => {
uni.navigateBack()
}
});
uni.setNavigationBarTitle({
title: "页面路径错误"
});
}
}
},
onNavigationBarButtonTap(e) {
// #ifdef APP-PLUS
let currentWebview = this.$mp.page.$getAppWebview().children()[0]; //获取当前页面的webview对象
utils.debug(currentWebview);
// #endif
return;
}
}
</script>
<style>
@import url('../../ctms/statusBar.css');
/*针对 webview进行的设置*/
uni-app {
margin-top: 88rpx;
}
</style>

270
pages/ctms/about/about.vue Normal file
View File

@ -0,0 +1,270 @@
<template>
<view class="about">
<view class="content">
<view class="qrcode">
<image src="@/static/logo.png" @longtap="save"></image>
<text class="tip">{{userinfo.username}}</text>
</view>
<view class="desc">
欢迎登陆使用本系统APP如果您在使用过程中遇到问题欢迎您及时向我们反馈我们将第一时间响应并及时根据情况进行优化或升级
</view>
<view class="source">
<view class="title">软件系统</view>
<view class="source-list">
<view class="source-cell">
<text space="nbsp">1. </text>
<text>
<text class="code">应用版本</text> {{config.version}}
</text>
</view>
<view class="source-cell">
<text space="nbsp">2. </text>
<text>
<text class="code">运营主体</text> {{config.poweredBy}}
</text>
</view>
<view class="source-cell">
<text space="nbsp">3. </text>
<text>
<text class="code">技术支持</text> {{config.supportedBy}}
</text>
</view>
<view class="source-cell">
<text space="nbsp">4. </text>
<text>
感谢 {{thanks}} 等公司/平台提供的云服务器开发文档等支持
</text>
</view>
</view>
</view>
<view class="source">
<view class="title">隐私安全</view>
<view class="source-list">
<view class="source-cell">
<text space="nbsp">1. </text>
<text>
<text class="code">用户服务协议</text>
<text @click="xieyi('fuwu')">
>>>点击查看
</text>
</text>
</view>
<view class="source-cell">
<text space="nbsp">2. </text>
<text>
<text class="code">隐私条款协议</text>
<text @click="xieyi('yinsi')">
>>>点击查看
</text>
</text>
</view>
</view>
</view>
<view class="source">
<view class="title">数据空间</view>
<view class="source-list">
<view class="source-cell">
<text space="nbsp">1. </text>
<text>
<text class="code">缓存大小</text> {{cacheSize}}
<button type="default" @click="clearCache">清除缓存</button>
</text>
</view>
</view>
</view>
<!-- #ifdef APP-PLUS -->
<button type="primary" @click="share">分享</button>
<!-- #endif -->
</view>
<!-- #ifdef APP-PLUS -->
<view class="version">
当前版本{{version}}
</view>
<!-- #endif -->
</view>
</template>
<script>
import config from "@/config/ctms.config.js";
import utils from "@/utils/common.js";
import ctms from '@/apis/ctms/index.js';
export default {
data() {
return {
userinfo: {},
version: config.version,
thanks: '',
cacheSize: '计算中',
}
},
onLoad() {
this.userinfo = ctms.user.getInfo();
var configApp = getApp().globalData.config;
//使用扩展运算符合并对象
var _cfg = {
...configApp,
...config
};
this.config = _cfg;
this.thanks = _cfg.thanksFor.join(' , ');
},
onShow() {
var size = ctms.cache.size();
var m = size.m,
kb = size.kb;
this.cacheSize = '';
if (m > 0) this.cacheSize += m + ' M ';
this.cacheSize += kb + ' KB ';
},
methods: {
clearCache() {
var res = ctms.cache.clear();
if (res) {
uni.showToast({
title: '已清除,请刷新页面',
icon: "success"
})
}
},
// #ifdef APP-PLUS
save() {
uni.showActionSheet({
itemList: ['保存图片到相册'],
success: () => {
plus.gallery.save(
'https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/app_download.png',
function() {
uni.showToast({
title: '保存成功',
icon: 'none'
});
},
function() {
uni.showToast({
title: '保存失败,请重试!',
icon: 'none'
});
});
}
});
},
share(e) {
plus.share.sendWithSystem();
uni.shareWithSystem({
summary: "安邮车联运车平台,一个专门服务于汽车托运的系统,致力于推动轿运市场标准化、现代化发展。",
href: "http://ctms.hiluker.cn",
success() {
// 分享完成,请注意此时不一定是成功分享
},
fail() {
// 分享失败
}
})
},
// #endif
goTo(page) {
page = config.pageDir + page;
uni.navigateTo({
url: page
});
},
xieyi(op) {
var url;
switch (op) {
case 'fuwu':
url = this.config.about.agreements.serviceUrl;
break;
case 'yinsi':
url = this.config.about.agreements.privacyUrl;
break;
}
uni.navigateTo({
url: '/pages/common/webview/index?url=' + url
})
}
}
}
</script>
<style>
page,
view {
display: flex;
}
page {
min-height: 100%;
background-color: #FFFFFF;
}
image {
width: 360rpx;
height: 360rpx;
}
.about {
flex-direction: column;
flex: 1;
}
.content {
flex: 1;
padding: 30rpx;
flex-direction: column;
justify-content: center;
}
.qrcode {
display: flex;
align-items: center;
flex-direction: column;
}
.qrcode .tip {
margin-top: 20rpx;
}
.desc {
margin-top: 30rpx;
display: block;
}
.code {
color: #e96900;
background-color: #f8f8f8;
}
button {
width: 100%;
margin-top: 40rpx;
}
.version {
height: 80rpx;
line-height: 80rpx;
justify-content: center;
color: #ccc;
}
.source {
margin-top: 30rpx;
flex-direction: column;
}
.source-list {
flex-direction: column;
}
.link {
color: #007AFF;
}
</style>

148
pages/ctms/index/index.vue Normal file
View File

@ -0,0 +1,148 @@
<template>
<view class="content">
<!-- 轮播图 -->
<view class="uni-margin-wrap">
<swiper class="swiper" circular indicator-dots="true" autoplay="true" interval="2000" duration="500">
<swiper-item v-for="(item, index) in banner" :key="index">
<view class="swiper-item" @click="clickBannerItem(item)" :data-link="item.link">
<image class="swiper-image" :src="item.image" mode="aspectFill" :draggable="true" />
</view>
</swiper-item>
</swiper>
</view>
<image class="logo" src="@/static/logo.png"></image>
<view class="text-area">
<text class="title">安邮车联</text>
</view>
<view class="text-area">
<text class="title">运车助手</text>
</view>
</view>
</template>
<script>
import ctms from '@/apis/ctms/index.js';
import utils from "@/utils/common.js";
export default {
data() {
return {
current: 0,
swiperDotIndex: 0,
banner: [{
image: '/static/img/banner/banner.jpg',
link: ""
}]
}
},
methods: {
clickBannerItem(item) {
if (item.link) {
var link = item.link;
uni.navigateTo({
url: "/pages/common/webview/index?url=" + link
})
}
},
changeSwiper(e) {
this.current = e.detail.current
},
getBanner() {
ctms.ads.banner().then((res) => {
var _data = res;
if (_data) {
this.banner = _data;
}
});
},
checkSplash() {
var ls = "splashShowed";
var a = uni.getStorageSync(ls);
if (!a) {
uni.navigateTo({
url: "/pages/index/index"
})
}
}
},
onLoad: function() {
this.checkSplash();
},
onShow: function() {
this.getBanner();
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
<style lang="scss">
.uni-margin-wrap {
width: 100%;
}
.uni-padding-wrap {
width: 550rpx;
padding: 0 100rpx;
}
/*轮播幻灯*/
.swiper {
height: 300rpx;
position: relative;
}
.swiper-list {
margin-top: 40rpx;
margin-bottom: 0;
}
.swiper-item {
width: 100%;
display: block;
height: 300rpx;
line-height: 300rpx;
text-align: center;
}
.swiper-image {
width: 100%;
height: 300rpx;
}
/*滑动区*/
.swiper-box {
height: 370rpx;
background: #fff;
margin-top: 20rpx;
}
.swiper-box .wx-swiper-dots.wx-swiper-dots-horizontal {
padding-bottom: 10rpx;
}
</style>

View File

@ -0,0 +1,95 @@
body {
/* background-color: #e6e6e60e; */
}
radio,
checkbox,
switch {
transform: scale(1.5);
margin-left: 1rem;
margin-right: 1rem;
margin-top: 36rpx;
}
input {
margin-left: 1rem;
margin-right: 1rem;
margin-top: 66rpx;
border-bottom: 1upx #333 dashed;
}
.content {
padding-bottom: 50rpx;
}
.header {
text-align: center;
}
.header>image {
width: 300rpx;
height: 300rpx;
}
.uni-form {
width: 94%;
margin: 0rpx 3% 0 3%;
}
.uni-form-item {
width: 100%;
display: inline-flex;
height: 96rpx;
line-height: 96rpx;
}
.uni-form-item .title,
.uni-form-item .data {}
/**不生效**/
.uni-form-item .title {
width: 180rpx;
padding: 40rpx 20rpx;
text-align: justify;
text-align-last: justify;
}
.uni-form .uni-btn-v {
margin-top: 50rpx;
}
.radio {
width: auto;
}
.btn {
margin: 40rpx 30rpx;
}
.btn-success {
background-color: #09BB07;
color: #fff;
}
.btn-error {
background-color: #fc0107;
color: #fff;
}
.footer {
display: block;
/* width: 100%; */
font-size: 1rem;
height: 1rem;
line-height: 1.5rem;
margin: 1.5rem;
}
.help-block {
display: block;
width: 100%;
color: #666666;
font-size: 0.8rem;
line-height: 1rem;
margin: 1.5rem;
}

281
pages/ctms/login/login.vue Normal file
View File

@ -0,0 +1,281 @@
<template>
<view class="content">
<view class="header">
<image src="@/static/logo.png" mode="aspectFit"></image>
<text v-if="userinfo.mobile" class="tip">您当前已登陆账号{{userinfo.username}}</text>
</view>
<uni-notice-bar text="在这里,您可以通过邮箱或手机号进行登陆。" />
<view class="uni-common-mt uni-form">
<form @submit="formSubmit" @reset="formReset">
<view class="uni-form-item ">
<view class="title">账号</view>
<input class="uni-input" name="username" v-model="FormData.username" placeholder="您的手机号或用户名" />
</view>
<view class="uni-form-item ">
<view class="title">密码</view>
<input class="uni-input" name="passwd" v-model="FormData.passwd" type="password" placeholder="" />
</view>
<view class="uni-form-item ">
<view class="title">持久登陆</view>
<view>
<switch name="isLong" :checked="isLong==1?true:false" />
</view>
</view>
<view class="uni-form-item">
<view class="help-block">
启用后只有您主动点击退出按钮后你的登陆状态才会被取消
</view>
</view>
<view class="uni-button-group">
<uni-row class="demo-uni-row" width="100%">
<uni-col :span="12">
<button class="btn btn-success" form-type="submit">登陆</button>
</uni-col>
<uni-col :span="12">
<button class="btn btn-default" type="default" form-type="reset">重置</button>
</uni-col>
</uni-row>
</view>
<view class="uni-button-group">
<button class="btn btn-info" type="default" @click="goToSms">使用验证码登陆</button>
<button class="btn btn-info" type="warn" @click="logout">注销</button>
<button :hidden="true" class="btn btn-success" type="primary" @click="authApp">一键授权</button>
<button class="btn btn-primary" type="primary" @click="goToReg">注册</button>
<button class="btn btn-info" type="default" @click="callMe">技术支持</button>
</view>
</form>
</view>
<uni-fab ref="fab" :pattern="fabs.pattern" :content="fabs.content" :horizontal="fabs.horizontal"
:vertical="fabs.vertical" :direction="fabs.direction" @trigger="fabTrigger" @fabClick="fabClick" />
<view class="footer" v-if="FormData.username">
您好您刚填写的用户名是{{FormData.username}}如果您在登陆过程中遇到任何问题请联系技术部门或您的直属管理人员解决
</view>
</view>
</template>
<script>
import graceChecker from "@/common/graceChecker.js";
import config from "@/config/ctms.config.js";
import utils from "@/utils/common.js";
import ctms from '@/apis/ctms/index.js';
import hi from '@/common/util.js';
export default {
data() {
return {
userinfo: {},
FormData: {
username: '',
passwd: ''
},
isLong: 1,
uniIdRedirectUrl: '',
//悬浮按钮
fabs: {
horizontal: 'left',
vertical: 'bottom',
direction: 'horizontal', //horizontal水平展开vertical垂直展开
pattern: {
color: '#7A7E83',
backgroundColor: '#fff',
selectedColor: '#007AFF',
buttonColor: '#fff',
iconColor: '#aaa'
},
content: [{
iconPath: '/static/fab/home.png',
selectedIconPath: '/static/fab/homeactive.png',
text: '首页',
active: false,
diyfn: 'home'
},
{
iconPath: '/static/fab/guanzhu.png',
selectedIconPath: '/static/fab/guanzhuactive.png',
text: '关注',
active: false,
diyfn: 'news'
},
{
iconPath: '/static/fab/me.png',
selectedIconPath: '/static/fab/meactive.png',
text: '用户',
active: false,
diyfn: 'user'
},
{
iconPath: '/static/fab/news.png',
selectedIconPath: '/static/fab/newsactive.png',
text: '公告',
active: false,
diyfn: 'notice'
}
]
}
}
},
methods: {
async authApp() {
//TODO 主包内单独设计一个授权页面,子项目则调用并确认,后端接收用户数据并自动注册绑定到子项目。
var res = await ctms.user.oneKeyAuth();
if (res) {
this.userinfo = res;
utils.toast('授权完成!');
uni.navigateBack()
}
},
formSubmit: function(e) {
var _that = this;
//定义表单规则
var rule = [{
name: "username",
checkType: "notnull",
checkRule: "",
errorMsg: "用户名不能为空"
},
{
name: "passwd",
checkType: "string",
checkRule: "8,32",
errorMsg: "密码不对"
}
];
//进行表单检查
var formData = e.detail.value;
var checkRes = graceChecker.check(formData, rule);
if (!checkRes) {
uni.showToast({
title: graceChecker.error,
icon: "error"
});
return false;
}
//请求封装
ctms.user.login(formData).then((res) => {
if (res) {
uni.showToast({
title: "登陆成功!",
icon: "success"
});
if (this.uniIdRedirectUrl) {
uni.redirectTo({
url: this.uniIdRedirectUrl
})
} else {
uni.navigateBack()
}
}
});
},
formReset: function(e) {
// utils.debug('清空登陆表单数据')
},
async logout() {
var res = await ctms.user.logout();
if (res) {
uni.reLaunch({
url: '../tabbar/index/index'
})
}
this.userinfo = {};
},
goToReg() {
uni.navigateTo({
url: './reg'
})
},
goToSms() {
uni.navigateTo({
url: './loginSms?uniIdRedirectUrl=' + encodeURIComponent(this.uniIdRedirectUrl)
})
},
callMe: function(e) {
var phone = config.kfPhone;
// hi.tel(phone);
uni.makePhoneCall({
phoneNumber: phone
})
},
//浮窗按钮相关操作
fabClick(e) {
// utils.debug('点击了悬浮按钮')
},
fabTrigger(e) {
var eindex = e.index;
this.fabs.content[e.index].active = !e.item.active;
if (!e.item.diyfn) {
//未设置这个difyfn字段的无操作
return false;
}
var diyfn = e.item.diyfn,
dir = config.pageDir,
page;
switch (diyfn) {
case 'home':
page = 'tabbar/index/index';
return uni.reLaunch({
url: dir + page
})
break;
case 'news':
page = 'news/list/list';
break;
case 'user':
page = 'me/index';
break;
case 'notice':
page = 'tabbar/notice/index';
return uni.reLaunch({
url: dir + page
})
break;
}
return uni.navigateTo({
url: dir + page
})
}
},
onShow: function() {
},
onLoad: function(o) {
var user = ctms.user.checkLogin();
this.userinfo = user;
// 自动跳转到登录页面时会携带uniIdRedirectUrl参数
if (o.uniIdRedirectUrl) {
this.uniIdRedirectUrl = decodeURIComponent(o.uniIdRedirectUrl)
}
}
}
</script>
<style>
@import url("login.css");
.header {
display: flex;
align-items: center;
flex-direction: column;
}
.tip {
margin-top: 20rpx;
}
.desc {
margin-top: 30rpx;
display: block;
}
</style>

View File

@ -0,0 +1,391 @@
<template>
<view class="content">
<uni-notice-bar text="手机号及验证码是必填的;为了防止机器恶意注册,获取手机短信前前您需要先进行人机验证。" />
<view class="uni-common-mt uni-form">
<form @submit="formSubmit" @reset="formReset">
<view class="uni-form-item ">
<view class="title"><code>*</code>手机号</view>
<input class="uni-input" name="mobile" v-model="FormData.mobile" placeholder="您的手机号" type="text"
@blur="checkMobile" @input="checkMobile" />
</view>
<view class="uni-form-item ">
<uni-row class="demo-uni-row" width="100%">
<uni-col :span="6">
<view class="demo-uni-col dark">
<view @tap="captchaGet" class="captcha">{{captcha}}
</view>
</view>
</uni-col>
<uni-col :span="18">
<view class="demo-uni-col">
<input class="uni-col-input" @input="captchaInput" placeholder="人机验证,输入左侧数字" type="text"
autocomplete="off" />
</view>
</uni-col>
</uni-row>
</view>
<uni-section title="短信验证码" type="circle" :subTitle="mobileErr">
<view class="example-body">
<uni-row v-show="FormData.mobile" class="demo-uni-row" width="100%">
<uni-col :span="14">
<view class="demo-uni-col">
<view class="uni-form-item ">
<input class="uni-col-input" placeholder="请输入验证码" v-model="FormData.vcode"
name="vcode" type="text" />
</view>
</view>
</uni-col>
<uni-col :span="10">
<view :class='"demo-uni-col vcode-button "+ (captchaPassed?"primary":"dark")'>
<view @tap="getVcode" v-show="!vcode_again">获取验证码
</view>
<view v-show="vcode_again">重新获取 {{leftSecond}}</view>
</view>
</uni-col>
</uni-row>
</view>
</uni-section>
<view class="uni-form-item ">
<view class="title">持久登陆</view>
<view>
<switch name="isLong" :checked="isLong==1?true:false" />
</view>
</view>
<view class="uni-form-item">
<view class="help-block">
启用后只有您主动点击退出按钮后你的登陆状态才会被取消
</view>
</view>
<view class="uni-button-group">
<uni-row class="demo-uni-row" width="100%">
<uni-col :span="12">
<button class="btn btn-success" form-type="submit">确认</button>
</uni-col>
<uni-col :span="12">
<button class="btn btn-default" type="default" form-type="reset">取消</button>
</uni-col>
</uni-row>
</view>
</form>
</view>
<uni-fab ref="fab" :pattern="fabs.pattern" :content="fabs.content" :horizontal="fabs.horizontal"
:vertical="fabs.vertical" :direction="fabs.direction" @trigger="fabTrigger" @fabClick="fabClick" />
</view>
</template>
<script>
import graceChecker from "@/common/graceChecker.js";
import config from "@/config/ctms.config.js";
import utils from "@/utils/common.js";
import ctms from '@/apis/ctms/index.js';
import hi from "@/common/util.js";
export default {
data() {
return {
FormData: {
mobile: '',
vcode: ''
},
isLong: 1,
vcode_again: false,
vcode_time: 90,
leftSecond: 90,
captcha: '8888',
captchaPassed: false,
mobileErr: '填写手机号后获取验证码并输入',
timer: null,
//悬浮按钮
fabs: {
horizontal: 'left',
vertical: 'bottom',
direction: 'horizontal', //horizontal水平展开vertical垂直展开
pattern: {
color: '#7A7E83',
backgroundColor: '#fff',
selectedColor: '#007AFF',
buttonColor: '#fff',
iconColor: '#aaa'
},
content: [{
iconPath: '/static/fab/home.png',
selectedIconPath: '/static/fab/homeactive.png',
text: '首页',
active: false,
diyfn: 'home'
},
{
iconPath: '/static/fab/guanzhu.png',
selectedIconPath: '/static/fab/guanzhuactive.png',
text: '关注',
active: false,
diyfn: 'news'
},
{
iconPath: '/static/fab/me.png',
selectedIconPath: '/static/fab/meactive.png',
text: '用户',
active: false,
diyfn: 'user'
},
{
iconPath: '/static/fab/news.png',
selectedIconPath: '/static/fab/newsactive.png',
text: '公告',
active: false,
diyfn: 'notice'
}
]
}
}
},
methods: {
formSubmit: function(e) {
var _that = this;
//定义表单规则
var rule = [{
name: "mobile",
checkType: "phoneno",
checkRule: "",
errorMsg: "手机号必填"
},
{
name: "vcode",
checkType: "notnull",
checkRule: "",
errorMsg: "验证码必填"
}
];
//进行表单检查
var formData = e.detail.value;
var checkRes = graceChecker.check(formData, rule);
if (!checkRes) {
uni.showToast({
title: graceChecker.error,
icon: "error"
});
return false;
}
//请求封装
ctms.user.smsLogin(formData).then((res) => {
if (res) {
uni.showToast({
title: "登陆成功!",
icon: "success"
});
if (_that.uniIdRedirectUrl) {
uni.reLaunch({
url: _that.uniIdRedirectUrl
})
} else {
uni.navigateBack()
}
}
});
},
formReset: function(e) {
// utils.debug('清空登陆表单数据')
},
captchaGet: function() {
var code = hi.captcha.get('login');
this.captcha = code;
},
captchaInput: function(e) {
if (e.detail.value === this.captcha) this.captchaPassed = true;
},
checkMobile: function() {
var res = hi.isPhone(this.FormData.mobile);
if (!res) {
this.mobileErr = '请输入正确的手机号码';
} else {
this.FormData.mobile = res;
this.mobileErr = '您的手机号码是:' + res;
}
},
getVcode: function() {
if (!this.captchaPassed) {
uni.showToast({
title: "请先通过人机验证",
icon: "none"
})
return false;
}
let timer = setInterval(() => {
if (this.leftSecond == 0) {
clearInterval(this.timer)
this.leftSecond = this.vcode_time;
this.vcode_again = false;
} else {
this.leftSecond--;
}
}, 1000);
this.timer = timer;
this.vcode_again = true;
this.requestVcode();
},
requestVcode: function() {
ctms.vcode.get('login', this.FormData.mobile).then(function(res) {
if (res) {
switch (res.errorcode) {
case 0:
utils.toast('短信已发送');
break;
default:
var msg = res.msg || '短信发送失败';
utils.toast(msg);
break;
}
}
});
},
callMe: function(e) {
var phone = config.kfPhone;
uni.makePhoneCall({
phoneNumber: phone
})
},
//浮窗按钮相关操作
fabClick(e) {
// utils.debug('点击了悬浮按钮')
},
fabTrigger(e) {
var eindex = e.index;
this.fabs.content[e.index].active = !e.item.active;
if (!e.item.diyfn) {
//未设置这个difyfn字段的无操作
return false;
}
var diyfn = e.item.diyfn,
dir = config.pageDir,
page;
switch (diyfn) {
case 'home':
page = 'tabbar/index/index';
return uni.reLaunch({
url: dir + page
})
break;
case 'news':
page = 'news/list/list';
break;
case 'user':
page = 'me/index';
break;
case 'notice':
page = 'tabbar/notice/index';
return uni.reLaunch({
url: dir + page
})
break;
}
return uni.navigateTo({
url: dir + page
})
}
},
onShow: function() {
var code = hi.captcha.get('login');
this.captcha = code;
},
onLoad: function(o) {
// 自动跳转到登录页面时会携带uniIdRedirectUrl参数
if (o.uniIdRedirectUrl) {
this.uniIdRedirectUrl = decodeURIComponent(o.uniIdRedirectUrl)
}
}
}
</script>
<style>
@import url("login.css");
/* 以下是组合输入框 */
.demo-uni-row {
margin-bottom: 10px;
/* 组件在小程序端display为inline */
/* QQ、抖音小程序文档写有 :host但实测不生效 */
/* 百度小程序没有 :host */
/* #ifdef MP-TOUTIAO || MP-QQ || MP-BAIDU */
display: block;
/* #endif */
}
/* 支付宝小程序没有 demo-uni-row 层级 */
/* 微信小程序使用了虚拟化节点,没有 demo-uni-row 层级 */
/* #ifdef MP-ALIPAY || MP-WEIXIN */
::v-deep .uni-row {
margin-bottom: 10px;
}
/* #endif */
.demo-uni-col {
height: 36px;
line-height: 36px;
border-radius: 5px;
}
.uni-col-input {
margin: 1rem 1rem;
width: 100%;
}
.dark_deep {
background-color: #99a9bf;
}
.dark {
background-color: #d3dce6;
}
.primary {
background-color: #0095F6;
color: #fff;
}
.light {
background-color: #e5e9f2;
}
.uni-section {
padding-top: 1rem;
}
.example-body {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
padding: 5rpx 10rpx 0;
overflow: hidden;
}
.vcode-button {
text-align: center;
}
/* 验证码区域 */
.captcha {
color: #fd8208;
font-size: 1.5rem;
font-weight: bolder;
text-align: center;
text-align-last: justify;
}
.captcha:after {
content: '';
display: inline-block;
width: 100%;
}
</style>

347
pages/ctms/login/reg.vue Normal file
View File

@ -0,0 +1,347 @@
<template>
<view class="content">
<uni-notice-bar text="您正在注册新用户,手机号及验证码是必填的;为了防止机器恶意注册,或者手机短信前前您需要先进行人机验证。" />
<view class="uni-common-mt uni-form">
<form @submit="formSubmit" @reset="formReset">
<view class="uni-form-item ">
<view class="title">昵称</view>
<input class="uni-input" name="username" v-model="FormData.username" placeholder="您的姓名或昵称"
type="text" />
</view>
<view class="uni-form-item ">
<view class="title">邮箱</view>
<input class="uni-input" name="email" v-model="FormData.email" placeholder="邮箱号,可用于登陆"
type="text" />
</view>
<view class="uni-form-item ">
<view class="title"><code>*</code>手机号</view>
<input class="uni-input" name="mobile" v-model="FormData.mobile" placeholder="您的手机号" type="text"
@blur="checkMobile" @input="checkMobile" />
</view>
<uni-section title="短信验证码" type="circle" :subTitle="mobileErr" v-show="FormData.mobile">
<view class="example-body">
<uni-row v-show="!captchaPassed" class="demo-uni-row" width="100%">
<uni-col :span="6">
<view class="demo-uni-col dark">
<view @tap="captchaGet" class="captcha">{{captcha}}
</view>
</view>
</uni-col>
<uni-col :span="12">
<view class="demo-uni-col ">
<view class="help-block">人机验证,输入左侧数字</view>
</view>
</uni-col>
<uni-col :span="6">
<view class="demo-uni-col light">
<view class="uni-form-item ">
<input class="uni-col-input" @input="captchaInput" placeholder=" " type="text"
autocomplete="off" />
</view>
</view>
</uni-col>
</uni-row>
<uni-row v-show="captchaPassed" class="demo-uni-row" width="100%">
<uni-col :span="14">
<view class="demo-uni-col light">
<view class="uni-form-item ">
<input class="uni-col-input" placeholder="请输入验证码" v-model="FormData.vcode"
type="text" />
</view>
</view>
</uni-col>
<uni-col :span="10">
<view class="demo-uni-col dark">
<view @tap="getVcode" v-show="!vcode_again">获取验证码
</view>
<view v-show="vcode_again">重新获取 {{leftSecond}}</view>
</view>
</uni-col>
</uni-row>
</view>
</uni-section>
<view class="uni-form-item ">
<view class="title">密码</view>
<input class="uni-input" name="passwd" type="password" v-model="FormData.passwd" placeholder="" />
</view>
<view class="uni-form-item ">
<view class="title">记住我</view>
<radio-group name="isKeep" class="radio">
<label>
<radio value="1" :checked="isKeep==1?true:false" /><text></text>
</label>
<label>
<radio value="-1" :checked="isKeep==-1?true:false" /><text></text>
</label>
</radio-group>
</view>
<view class="uni-form-item ">
<view class="title">持久登陆</view>
<view>
<switch name="isLong" :checked="isLong==1?true:false" />
</view>
</view>
<view class="uni-form-item">
<view class="help-block">
启用后只有您主动点击退出按钮后你的登陆状态才会被取消
</view>
</view>
<view class="uni-button-group">
<uni-row class="demo-uni-row" width="100%">
<uni-col :span="12">
<button class="btn btn-success" form-type="submit">确认</button>
</uni-col>
<uni-col :span="12">
<button class="btn btn-default" type="default" form-type="reset">取消</button>
</uni-col>
</uni-row>
</view>
</form>
</view>
</view>
</template>
<script>
import graceChecker from "@/common/graceChecker.js";
import config from "@/config/ctms.config.js";
import utils from "@/utils/common.js";
import ctms from '@/apis/ctms/index.js';
import hi from "@/common/util.js";
export default {
data() {
return {
logoImage: '@/static/logo.png',
FormData: {
username: '',
passwd: '',
mobile: '',
email: '',
vcode: ''
},
ls: 'fansRegFormData',
isKeep: -1,
isLong: 1,
vcode_again: false,
vcode_time: 90,
leftSecond: 90,
captcha: '8888',
captchaPassed: true,
mobileErr: '填写手机号后获取验证码并输入',
timer: null
}
},
methods: {
formSubmit: function(e) {
var _that = this;
//定义表单规则
var rule = [{
name: "passwd",
checkType: "string",
checkRule: "8,32",
errorMsg: "密码要求8~32位"
},
{
name: "mobile",
checkType: "phoneno",
checkRule: "",
errorMsg: "手机号必填"
},
{
name: "vcode",
checkType: "notnull",
checkRule: "",
errorMsg: "验证码必填"
},
{
name: "isKeep",
checkType: "in",
checkRule: "1,-1",
errorMsg: "是否记住密码"
},
];
//进行表单检查
var formData = e.detail.value;
var checkRes = graceChecker.check(formData, rule);
if (!checkRes) {
uni.showToast({
title: graceChecker.error,
icon: "error"
});
return false;
}
//验证通过,缓存表单、请求登陆
if (formData.isKeep == 1) {
var lsIndex = _that.ls;
var data = {
username: formData.username,
mobile: formData.mobile,
email: formData.email,
passwd: formData.passwd,
};
uni.setStorageSync(lsIndex, data);
} else {
uni.removeStorageSync(lsIndex);
}
//请求封装
ctms.user.reg(formData).then((res) => {
if (res) {
uni.showToast({
title: "注册成功!",
icon: "success"
});
uni.navigateBack()
}
});
},
formReset: function(e) {
// utils.debug('清空登陆表单数据')
},
captchaGet: function() {
var code = hi.captcha.get('reg');
this.captcha = code;
},
captchaInput: function(e) {
if (e.detail.value === this.captcha) this.captchaPassed = true;
},
// captchaCheck: function() {
// var res = hi.captcha.check('reg', this.captcha);
// },
checkMobile: function() {
var res = hi.isPhone(this.FormData.mobile);
if (!res) {
this.mobileErr = '请输入正确的手机号码';
} else {
this.FormData.mobile = res;
this.mobileErr = '您的手机号码是:' + res;
}
},
getVcode: function() {
let timer = setInterval(() => {
if (this.leftSecond == 0) {
clearInterval(this.timer)
this.leftSecond = this.vcode_time;
this.vcode_again = false;
} else {
this.leftSecond--;
}
}, 1000);
this.timer = timer;
this.vcode_again = true;
this.requestVcode();
},
requestVcode: function() {
ctms.vcode.get('reg', this.FormData.mobile).then(function(res) {
if (res) {
switch (res.errorcode) {
case 0:
utils.toast('短信已发送');
break;
default:
var msg = res.msg || '短信发送失败';
utils.toast(msg);
break;
}
}
});
},
callMe: function(e) {
var phone = config.kfPhone;
uni.makePhoneCall({
phoneNumber: phone
})
}
},
onShow: function() {
var code = hi.captcha.get('reg');
this.captcha = code;
},
onLoad: function() {
// ctms.user.checkLogin();
}
}
</script>
<style>
@import url("login.css");
/* 以下是组合输入框 */
.demo-uni-row {
margin-bottom: 10px;
/* 组件在小程序端display为inline */
/* QQ、抖音小程序文档写有 :host但实测不生效 */
/* 百度小程序没有 :host */
/* #ifdef MP-TOUTIAO || MP-QQ || MP-BAIDU */
display: block;
/* #endif */
}
/* 支付宝小程序没有 demo-uni-row 层级 */
/* 微信小程序使用了虚拟化节点,没有 demo-uni-row 层级 */
/* #ifdef MP-ALIPAY || MP-WEIXIN */
::v-deep .uni-row {
margin-bottom: 10px;
}
/* #endif */
.demo-uni-col {
height: 36px;
line-height: 36px;
border-radius: 5px;
}
.uni-col-input {
margin: 0 1rem;
}
.dark_deep {
background-color: #99a9bf;
}
.dark {
background-color: #d3dce6;
}
.light {
background-color: #e5e9f2;
}
.uni-section {
padding-top: 1rem;
}
.example-body {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
padding: 5rpx 10rpx 0;
overflow: hidden;
}
/* 验证码区域 */
.captcha {
color: #fd8208;
font-size: 1.5rem;
font-weight: bolder;
text-align: center;
text-align-last: justify;
}
.captcha:after {
content: '';
display: inline-block;
width: 100%;
}
</style>

261
pages/ctms/me/index.vue Normal file
View File

@ -0,0 +1,261 @@
<template>
<view class="container">
<view class="about">
<view class="content">
<view class="qrcode">
<image src="@/static/logo.png"></image>
<text class="tip">{{userinfo.username}}</text>
</view>
<view class="desc">
{{config.about.slogan}}
</view>
<view class="uni-card">
<view class="uni-list">
<view class="uni-list-cell-divider">
</view>
<!-- #ifndef APP-PLUS -->
<navigator v-for="item in menus" :url="item.url" class="uni-list-cell"
hover-class="uni-list-cell-hover">
<view class="uni-list-cell-navigate uni-navigate-right">
{{item.title}}
</view>
</navigator>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view v-for="item in menus" class="uni-list-cell" hover-class="uni-list-cell-hover"
@click="go(item.url)">
<view class="uni-list-cell-navigate uni-navigate-right">
{{item.title}}
</view>
</view>
<!-- #endif -->
<button type="primary" @click="reload">加载数据资源</button>
</view>
</view>
<!-- #ifdef APP-PLUS -->
<button type="primary" @click="share">分享</button>
<!-- #endif -->
</view>
<!-- #ifdef APP-PLUS -->
<view class="version">
当前版本{{version}}
</view>
<!-- #endif -->
</view>
</view>
</template>
<script>
import utils from "@/utils/common.js";
import config from "@/config/ctms.config.js";
import ctms from '@/apis/ctms/index.js';
export default {
data() {
return {
userinfo: {},
menus: {
orderpre: {
title: '我的询价',
url: '../orderpre/list/list'
},
order: {
title: '运单记录',
url: '../order/list/list'
},
news: {
title: '资讯报道',
url: '../news/list/list'
},
about: {
title: '关于App',
url: '../about/about'
},
login: {
title: '切换登陆',
url: '../login/login'
}
},
version: '',
config: {}
}
},
onLoad() {
var configApp = getApp().globalData.config;
//使用扩展运算符合并对象
var _cfg = {
...configApp,
...config
};
this.config = _cfg;
this.version = _cfg.version;
},
onShow() {
this.userinfo = ctms.user.getInfo();
},
methods: {
// #ifdef APP-PLUS
save() {
uni.showActionSheet({
itemList: ['保存图片到相册'],
success: () => {
plus.gallery.save(
'https://public.hiluker.com/luker_fm2.png',
function() {
uni.showToast({
title: '保存成功',
icon: 'none'
});
},
function() {
uni.showToast({
title: '保存失败,请重试!',
icon: 'none'
});
});
}
});
},
share(e) {
var msg = "运车助手"
plus.share.sendWithSystem();
uni.shareWithSystem({
summary: "安邮车联运车平台,一个专门服务于汽车托运的系统,致力于推动轿运市场标准化、现代化发展。",
href: "http://ctms.hiluker.cn",
success() {
// 分享完成,请注意此时不一定是成功分享
},
fail() {
// 分享失败
}
})
},
// #endif
go(e) {
uni.navigateTo({
url: e
});
},
reload() {
uni.switchTab({
url: '../tabbar/me/index'
})
}
}
}
</script>
<style>
page,
view {
display: flex;
}
page {
min-height: 100%;
background-color: #FFFFFF;
}
image {
width: 360rpx;
height: 360rpx;
}
.about {
flex-direction: column;
flex: 1;
}
.content {
flex: 1;
padding: 30rpx;
flex-direction: column;
justify-content: center;
}
.qrcode {
display: flex;
align-items: center;
flex-direction: column;
}
.qrcode .tip {
margin-top: 20rpx;
}
.desc {
margin-top: 30rpx;
display: block;
}
.code {
color: #e96900;
background-color: #f8f8f8;
}
button {
width: 100%;
margin-top: 40rpx;
}
.version {
height: 80rpx;
line-height: 80rpx;
justify-content: center;
color: #ccc;
}
.source {
margin-top: 30rpx;
flex-direction: column;
}
.source-list {
flex-direction: column;
}
.link {
color: #007AFF;
}
.uni-list-cell-navigate {
position: unset;
}
navigator {
color: #000000;
}
.uni-navigator.uni-list-cell-navigate.uni-navigate-right:after {
font-family: uniicons;
content: '\e583';
position: relative;
right: 0.75rem;
top: 50%;
color: #bbb;
transform: translateY(-50%);
width: 15rpx;
height: 24rpx;
}
.uni-list .uni-list-cell:last-child::after {
height: 1px;
}
.uni-list-cell::after {
position: absolute;
z-index: 3;
right: 0;
bottom: 0;
left: 0.9375rem;
height: 1px;
content: '';
transform: scaleY(.5);
background-color: #c8c7cc;
}
</style>

View File

@ -0,0 +1,50 @@
.container {
overflow: hidden;
}
.custom-cover {
flex: 1;
flex-direction: row;
position: relative;
}
.cover-content {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background-color: rgba($color: #000000, $alpha: 0.4);
display: flex;
flex-direction: row;
align-items: center;
padding-left: 15px;
font-size: 14px;
color: #fff;
}
.card-actions {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
height: 45px;
border-top: 1px #eee solid;
}
.card-actions-item {
display: flex;
flex-direction: row;
align-items: center;
}
.card-actions-item-text {
font-size: 12px;
color: #666;
margin-left: 5px;
}
.cover-image {
flex: 1;
height: 150px;
}
.no-border {
border-width: 0;
}

View File

@ -0,0 +1,360 @@
<template>
<view class="container">
<view class="banner">
<image class="banner-img" :src="detail.thumb"></image>
<view class="banner-title">{{detail.title}}</view>
</view>
<view class="article-meta">
<text class="article-author">
<uni-icons type="contact"></uni-icons>{{detail.author_name}}
</text>
<text class="article-text">更新于</text>
<text class="article-time">{{detail.updateTime}}</text>
</view>
<view v-if="detail.des" class="des">
<text>内容摘要</text>
{{detail.des}}
</view>
<view class="article-content">
<rich-text :nodes="htmlNodes" @itemclick="nodeClick"></rich-text>
</view>
<view class="article-meta">
<text class="article-footer">
<uni-icons type="eye">浏览</uni-icons>
{{detail.viewed}}
</text>
<text :class="'article-footer '+ activeReading" @click="actionReading">
<uni-icons type="hand-up" :style="styleReading"></uni-icons>
{{detail.reading}}
</text>
<text :class="'article-footer '+ activeLike" @click="actionLike">
<uni-icons type="heart" :style="styleLike">喜欢</uni-icons>
{{detail.liked}}
</text>
</view>
<uni-fab ref="fab" :pattern="fabs.pattern" :content="fabs.content" :horizontal="fabs.horizontal"
:vertical="fabs.vertical" :direction="fabs.direction" @trigger="fabTrigger" @fabClick="fabClick" />
</view>
</template>
<script>
import config from "@/config/ctms.config.js";
import ctms from '@/apis/ctms/index.js';
import htmlParser from '@/common/html-parser.js'
const DETAIL_PAGE_PATH = config.pageDir + 'news/detail/detail';
export default {
data() {
return {
userinfo: {},
id: 0,
detail: {
id: 1,
viewed: 0,
liked: 0,
reading: 0
},
htmlNodes: [],
imgs: [], //可用于预览的图片
activeStyle: 'color:#fd8208;',
activeReading: '', //active
styleReading: '',
activeLike: '', //active
styleLike: '',
h5_url: '',
//悬浮按钮
fabs: {
horizontal: 'left',
vertical: 'bottom',
direction: 'horizontal', //horizontal水平展开vertical垂直展开
pattern: {
color: '#7A7E83',
backgroundColor: '#fff',
selectedColor: '#007AFF',
buttonColor: '#fff',
iconColor: '#aaa'
},
content: [{
iconPath: '/static/fab/home.png',
selectedIconPath: '/static/fab/homeactive.png',
text: '首页',
active: false,
diyfn: 'home'
},
{
iconPath: '/static/fab/guanzhu.png',
selectedIconPath: '/static/fab/guanzhuactive.png',
text: '关注',
active: false,
diyfn: 'news'
},
{
iconPath: '/static/fab/me.png',
selectedIconPath: '/static/fab/meactive.png',
text: '用户',
active: false,
diyfn: 'user'
},
{
iconPath: '/static/fab/news.png',
selectedIconPath: '/static/fab/newsactive.png',
text: '公告',
active: false,
diyfn: 'notice'
}
]
}
}
},
methods: {
getNewsDetail: function() {
var _that = this;
ctms.news.checkDetail(this.id).then((res) => {
if (res) {
_that.detail = res.data;
_that.htmlNodes = htmlParser(_that.detail.content);
uni.showToast({
title: "查询完成!",
icon: "success"
});
uni.stopPullDownRefresh();
}
});
},
checkRecords: function() {
// 检查文章在读等本地记录
if (ctms.news.mark(this.id, 'reading', 'get')) {
this.activeReading = "active";
this.styleReading = this.activeStyle;
}
if (ctms.news.mark(this.id, 'liked', 'get')) {
this.activeLike = 'active';
this.styleLike = this.activeStyle;
}
},
actionReading(e) {
var op = this.activeReading ? 'del' : 'set';
this.activeReading = !this.activeReading ? 'active' : false;
this.styleReading = !this.styleReading ? this.activeStyle : false;
ctms.news.mark(this.id, 'reading', op);
},
actionLike(e) {
var op = this.activeLike ? 'del' : 'set';
this.activeLike = !this.activeLike ? 'active' : '';
this.styleLike = !this.styleLike ? this.activeStyle : '';
ctms.news.mark(this.id, 'liked', op);
},
nodeClick(e) {
var _that = this;
// console.log(e.detail);
var url = e.detail.node.attrs.src;
_that.imgs.push(url)
uni.previewImage({
urls: _that.imgs,
indicator: "default",
current: url,
longPressActions: {
itemList: ['保存图片'],
success: function(data) {
// console.log('选中了第' + (data.tapIndex + 1) + '个按钮,第' + (data.index + 1) + '张图片');
uni.showToast({
title: '平台禁止保存图片到本地!',
icon: 'none'
})
},
fail: function(err) {
// console.log(err.errMsg);
}
}
});
},
callTo(tel) {
uni.makePhoneCall({
phoneNumber: tel
})
},
//浮窗按钮相关操作
fabClick(e) {
// utils.debug('点击了悬浮按钮')
},
fabTrigger(e) {
var eindex = e.index;
this.fabs.content[e.index].active = !e.item.active;
if (!e.item.diyfn) {
//未设置这个difyfn字段的无操作
return false;
}
var diyfn = e.item.diyfn,
dir = config.pageDir,
page;
switch (diyfn) {
case 'home':
page = 'tabbar/index/index';
return uni.reLaunch({
url: dir + page
})
break;
case 'news':
page = 'news/list/list';
break;
case 'user':
page = 'me/index';
break;
case 'notice':
page = 'tabbar/notice/index';
return uni.reLaunch({
url: dir + page
})
break;
}
return uni.navigateTo({
url: dir + page
})
}
},
onLoad(o) {
this.id = o.id;
var res = ctms.news.detail(this.id);
if (res) {
this.detail = res;
} else {
this.getNewsDetail();
}
uni.setNavigationBarTitle({
title: this.detail.title
})
ctms.news.viewed(this.id);
},
onReady() {
var nodes = this.htmlNodes = htmlParser(this.detail.content);
// for (var i in nodes) {
// var ps = nodes[i].children;
// for (var j in ps) {
// var p = ps[j];
// if (p.name === 'img') {
// console.log(p.attrs.src)
// p.attrs.mode = 'aspectFit';
// };
// }
// }
// console.log(nodes)
},
onShow: function() {
this.checkRecords();
},
onPullDownRefresh() {
this.getNewsDetail();
uni.stopPullDownRefresh();
},
onShareAppMessage() {
return {
title: this.detail.title,
path: DETAIL_PAGE_PATH + '?id=' + this.id
}
},
//标题栏按钮响应,仅在APP-PLUS下支持
onNavigationBarButtonTap(e) {
//#ifdef APP-PLUS
uni.shareWithSystem({
summary: this.detail.des + "登陆APP查看更多信息",
href: this.h5_url + "?id=" + this.id,
success() {
// 分享完成,请注意此时不一定是成功分享
},
fail() {
// 分享失败
}
})
//#endif
//#ifdef H5
var summary = this.detail.des + "登陆APP查看更多信息";
uni.setClipboardData({
data: summary
})
//#endif
}
}
</script>
<style>
@import url("detail.css");
.des {
text-align: left;
text-indent: 2rem;
padding: 2rem 1rem;
color: #999;
}
.banner {
height: 360rpx;
overflow: hidden;
position: relative;
background-color: #ccc;
}
.banner-img {
width: 100%;
}
.banner-title {
max-height: 84rpx;
overflow: hidden;
position: absolute;
left: 30rpx;
bottom: 30rpx;
width: 90%;
font-size: 32rpx;
font-weight: 400;
line-height: 42rpx;
color: white;
z-index: 11;
}
.article-meta {
padding: 20rpx 40rpx;
display: flex;
flex-direction: row;
justify-content: flex-start;
color: gray;
}
.article-text {
font-size: 26rpx;
line-height: 50rpx;
margin: 0 20rpx;
}
.article-author,
.article-time {
font-size: 30rpx;
}
.article-content {
padding: 0 30rpx;
overflow: hidden;
font-size: 30rpx;
margin-bottom: 30rpx;
}
.article-footer {
font-size: 28rpx;
line-height: 50rpx;
margin: 0 10rpx;
}
.article-footer.active,
.article-footer.active>span {
color: #fd8208;
}
/* 修复详情内图片显示问题 */
img {
max-width: 100%;
}
</style>

View File

@ -0,0 +1,54 @@
.container {
overflow: hidden;
}
.custom-cover {
flex: 1;
flex-direction: row;
position: relative;
}
.cover-content {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background-color: rgba($color: #000000, $alpha: 0.4);
display: flex;
flex-direction: row;
align-items: center;
padding-left: 15px;
font-size: 14px;
color: #fff;
}
.card-actions {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
height: 45px;
border-top: 1px #eee solid;
}
.card-actions-item {
display: flex;
flex-direction: row;
align-items: center;
}
.card-actions-item-text {
font-size: 12px;
color: #666;
margin-left: 5px;
}
.cover-image {
flex: 1;
height: 150px;
}
.no-border {
border-width: 0;
}
.pagination{
margin:20px 20px;
}

View File

@ -0,0 +1,310 @@
<template>
<view class="container">
<uni-search-bar class="uni-mt-10" radius="5" placeholder="点击快速搜索标题" clearButton="auto" cancelButton="none"
@clear="clearSearch" @confirm="search" />
<view class="uni-padding-wrap uni-common-mt">
<uni-segmented-control :current="current" :values="catsArr" style-type="button" @clickItem="changeCat" />
</view>
<view class="content">
<view class="nodata" v-if="!totalCount">
没有相关的内容
</view>
<view v-else :id="'newsCar-'+detail.id" v-for="(detail,index) in news" :data-id="detail.id"
:data-cid="detail.cid" :key="detail.id" :index="index">
<uni-card padding="10px 0">
<template v-if="detail.thumb" v-slot:cover :isFull="true">
<view class="custom-cover">
<image class="cover-image" mode="aspectFill" :src="detail.thumb">
</image>
<view class="cover-content">
<text class="uni-subtitle uni-white">{{detail.title}}</text>
</view>
</view>
</template>
<template v-else v-slot:title>
<uni-list>
<uni-list-item :show-switch="false" :title="detail.title" />
</uni-list>
</template>
<view class="uni-body">
<view>
<text>{{detail.des}}</text>
</view>
</view>
<view slot="actions" class="card-actions">
<view class="card-actions-item" @click="showCheck(detail.id)">
<uni-icons type="heart" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">{{detail.liked}}</text>
</view>
<view class="card-actions-item" @click="actionsRemark(detail.id)">
<uni-icons type="fire" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">{{detail.reading}}</text>
</view>
<view class="card-actions-item" @click="actionsDetail(detail.id)">
<uni-icons type="link" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">详情</text>
</view>
</view>
</uni-card>
</view>
</view>
<view class="pagination">
<uni-pagination :show-icon="false" :total="totalCount" :pageSize='psize' v-model='page' title="分页栏"
@change="newPage" />
</view>
<uni-fab ref="fab" :pattern="fabs.pattern" :content="fabs.content" :horizontal="fabs.horizontal"
:vertical="fabs.vertical" :direction="fabs.direction" @trigger="fabTrigger" @fabClick="fabClick" />
</view>
</template>
<script>
import utils from "@/utils/common.js";
import config from "@/config/ctms.config.js";
import ctms from '@/apis/ctms/index.js';
export default {
data() {
return {
userinfo: {},
cover: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg',
news: {},
cats: {},
catsArr: ['全部'],
catIds: {
'0': {
id: 0
}
}, //与catsArr键对应的,单条完整cat的数据集
catid: 0, //当前分类ID
current: 0, //分段器对应当前分类
stitle: '',
totalCount: 0, //一共多少条数据
psize: 10,
page: 1,
//悬浮按钮
fabs: {
horizontal: 'left',
vertical: 'bottom',
direction: 'horizontal', //horizontal水平展开vertical垂直展开
pattern: {
color: '#7A7E83',
backgroundColor: '#fff',
selectedColor: '#007AFF',
buttonColor: '#fff',
iconColor: '#aaa'
},
content: [{
iconPath: '/static/fab/home.png',
selectedIconPath: '/static/fab/homeactive.png',
text: '首页',
active: false,
diyfn: 'home'
},
{
iconPath: '/static/fab/guanzhu.png',
selectedIconPath: '/static/fab/guanzhuactive.png',
text: '关注',
active: false,
diyfn: 'news'
},
{
iconPath: '/static/fab/me.png',
selectedIconPath: '/static/fab/meactive.png',
text: '用户',
active: false,
diyfn: 'user'
},
{
iconPath: '/static/fab/news.png',
selectedIconPath: '/static/fab/newsactive.png',
text: '公告',
active: false,
diyfn: 'notice'
}
]
}
}
},
methods: {
//搜索框响应
search(res) {
this.stitle = res.value;
this.getNews();
},
clearSearch() {
this.stitle = '';
this.getNews();
},
//切换分类
changeCat(e) {
var i = e.currentIndex;
this.catid = this.catIds[i].id;
this.getNews();
},
actionsDetail(e) {
uni.navigateTo({
url: '../detail/detail?id=' + e
})
},
//分页器动作
newPage(e) {
var page = e.current;
this.page = page;
var res = ctms.news.list(this.page);
if (res) {
this.news = res.news;
} else {
this.getNews();
}
},
getCats: function() {
var _that = this;
ctms.news.cats().then(
(res) => {
_that.cats = res;
for (var i in res) {
var r = res[i];
if (r.is_show) {
_that.catsArr.push(r.title);
_that.catIds[Number(i) + 1] = r;
}
}
}
);
},
//刷新列表
getNews() {
var _that = this;
var searchData = {
title: this.stitle,
cid: this.catid
};
ctms.news.search(searchData, this.page, this.psize).then(
function(res) {
if (res) {
_that.news = res.news;
_that.totalCount = res.total;
} else {
_that.news = {}
_that.totalCount = 0;
}
}
);
},
//浮窗按钮相关操作
fabClick(e) {
// utils.debug('点击了悬浮按钮')
},
fabTrigger(e) {
var eindex = e.index;
this.fabs.content[e.index].active = !e.item.active;
if (!e.item.diyfn) {
//未设置这个difyfn字段的无操作
return false;
}
var diyfn = e.item.diyfn,
dir = config.pageDir,
page;
switch (diyfn) {
case 'home':
page = 'tabbar/index/index';
return uni.reLaunch({
url: dir + page
})
break;
case 'news':
page = 'news/list/list';
break;
case 'user':
page = 'me/index';
break;
case 'notice':
page = 'tabbar/notice/index';
return uni.reLaunch({
url: dir + page
})
break;
}
return uni.navigateTo({
url: dir + page
})
}
},
onLoad() {
// utils.debug('运单列表页启动')
var res = ctms.news.list(this.page);
if (res) {
this.news = res.news;
this.totalCount = res.total;
} else {
this.getNews();
}
this.getCats();
},
onShow() {
},
onPullDownRefresh() {
this.page = 1;
this.getNews();
setTimeout(() => {
uni.stopPullDownRefresh();
}, 3000);
}
}
</script>
<style lang="scss">
@import url("list.css");
.content {
text-align: center;
}
.nodata {
padding: 2rem 1rem;
}
.uni-body,
.uni-list-item {
text-align: left;
}
.custom-cover {
flex: 1;
flex-direction: row;
position: relative;
}
.cover-content {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background-color: rgba($color: #000000, $alpha: 0.4);
display: flex;
flex-direction: row;
align-items: center;
padding-left: 15px;
font-size: 14px;
color: #fff;
}
</style>

View File

@ -0,0 +1,467 @@
<template>
<view class="content">
<uni-notice-bar show-icon scrollable text="平台上新季,全路线大力优惠,欢迎来询!!!。" />
<view class="order-form">
<!-- 自定义表单校验 -->
<uni-forms ref="customForm" :rules="formRules" :modelValue="FormData">
<uni-section title="您要发运的车辆信息" type="line">
<uni-forms-item label="品牌车型" name="car_title">
<uni-easyinput type="text" v-model="FormData.car_title" placeholder="填写品牌车型" />
</uni-forms-item>
<uni-forms-item label="车牌号" name="car_no">
<uni-easyinput type="text" v-model="FormData.car_no" placeholder="无车牌时可填写车架号后六位" />
</uni-forms-item>
<text class="uniui-h6 help-block">无车牌时可填写车架号(至少后六位)</text>
<uni-forms-item label="是否临牌" name="isTempCarno">
<uni-data-checkbox v-model="FormData.isTempCarno" :multiple="false" :localdata="isTempCarno" />
</uni-forms-item>
<uni-forms-item label="车辆保价(万元)" required name="car_value">
<uni-easyinput type="number" v-model="FormData.car_value" placeholder="单位:万元;默认20" />
</uni-forms-item>
</uni-section>
<uni-section title="从哪里出发 - 运到哪儿去" type="line">
<uni-forms-item label="出发省份" required name="start_province">
<uni-data-picker placeholder="请选择省份" popup-title="请选择出发省份" :localdata="provinces"
v-model="FormData.start_province">
</uni-data-picker>
</uni-forms-item>
<uni-forms-item label="始发城市" required name="start_city">
<uni-easyinput v-model="FormData.start_city" placeholder="请填写出发城市名称" />
</uni-forms-item>
<uni-forms-item label="目标省份" required name="aim_province">
<uni-data-picker placeholder="请选择省份" popup-title="请选择运达省份" :localdata="provinces"
v-model="FormData.aim_province">
</uni-data-picker>
</uni-forms-item>
<uni-forms-item label="目标城市" required name="aim_city">
<uni-easyinput v-model="FormData.aim_city" placeholder="请填写目标运达城市名称" />
</uni-forms-item>
<uni-forms-item label="计划日期" name="date">
<uni-datetime-picker type="date" return-type="timestamp" v-model="FormData.date" />
</uni-forms-item>
</uni-section>
<uni-section title="联系信息" type="line">
<uni-forms-item label="您的姓名" name="from_name">
<uni-easyinput v-model="FormData.from_name" placeholder="请输入姓名" />
</uni-forms-item>
<uni-forms-item label="手机号" required name="from_mobile">
<uni-easyinput v-model="FormData.from_mobile" placeholder="请输入联系电话" />
</uni-forms-item>
</uni-section>
<uni-forms-item label="备注" name="remark">
<uni-easyinput type="textarea" v-model="FormData.remark" placeholder="对运单做一些备注,比如 从哪里提车的;根据实际情况" />
</uni-forms-item>
</uni-forms>
<view class="button-group">
<button type="primary" size="mini" @click="formCheck('customForm')">确认提交</button>
<button type="default" size="mini" @click="draft">我再想想</button>
</view>
<uni-fab ref="fab" :pattern="pattern" :content="content" :horizontal="horizontal" :vertical="vertical"
:direction="direction" @trigger="trigger" @fabClick="fabClick" />
</view>
<uni-notice-bar
text="温馨提示: 请不要随车放置 贵重小件物品(如 眼镜\无线充电器\数据线\U盘\手表\Zipporr火机等)、精密仪器设备(如 电脑等)、易燃易爆物品,车内不得放置违规违禁物品(如 燃料油\火机\酒精\散装酒等),否则司机有权拒载、平台有权拒单。" />
<uni-notice-bar text="炎热天气,不要随车装运水果,一定会闷坏的。" />
<text class="uniui-h6 help-block"></text>
</view>
</template>
<script>
import province from '@/common/province.js';
import letter from '@/common/letter.js';
import carP from '@/common/car-p.js';
import config from "@/config/ctms.config.js";
import store from '@/store/index.js';
import utils from "@/utils/common.js";
import ctms from '@/apis/ctms/index.js';
export default {
data() {
return {
userinfo: {},
FormData: {
start_province: '', //默认 460000
start_city: '',
aim_province: '', //默认 230000
aim_city: '',
date: Date(+7).now, //计划发运日期
car_value: 20, //单位万。默认含20万运输险
car_title: '',
carno: '', //车牌/架号
isTempCarno: 0,
username: '',
mobile: '',
remark: ''
},
lsIndex: 'OrderCreateDraft',
//悬浮按钮
horizontal: 'right',
vertical: 'bottom',
direction: 'vertical', //horizontal水平展开vertical垂直展开
pattern: {
color: '#7A7E83',
backgroundColor: '#fff',
selectedColor: '#007AFF',
buttonColor: '#fd8008',
iconColor: '#fff'
},
content: [{
iconPath: '/static/fab/c5.png',
selectedIconPath: '/static/fab/c5.png',
text: '草稿-5',
active: false,
diyfn: '-5' //自定义添加的一个字段
},
{
iconPath: '/static/fab/c4.png',
selectedIconPath: '/static/fab/c4.png',
text: '草稿-4',
active: false,
diyfn: '-4' //自定义添加的一个字段
},
{
iconPath: '/static/fab/c3.png',
selectedIconPath: '/static/fab/c3.png',
text: '草稿-3',
active: false,
diyfn: '-3' //自定义添加的一个字段
},
{
iconPath: '/static/fab/c2.png',
selectedIconPath: '/static/fab/c2.png',
text: '草稿-2',
active: false,
diyfn: '-2' //自定义添加的一个字段
},
{
iconPath: '/static/fab/c1.png',
selectedIconPath: '/static/fab/c1.png',
text: '草稿-1',
active: false,
diyfn: '-1' //自定义添加的一个字段
},
{
iconPath: '/static/fab/draft.png',
selectedIconPath: '/static/fab/draft-active.png',
text: '保存草稿',
active: false,
diyfn: false
},
],
// 单选性别数据源
sexs: [{
text: '男',
value: 0
}, {
text: '女',
value: 1
}, {
text: '保密',
value: 2
}],
//默认省份数据
provinces: [{
value: '460000',
text: "海南省"
},
{
value: '340000',
text: "安徽"
}
],
//车辆省份标识
carPs: carP.list,
letters: letter.list,
//是否临牌
isTempCarno: [{
text: '否',
value: 0
}, {
text: '是',
value: 1
}],
// 自定义表单校验规则
formRules: {
start_province: {
rules: [{
required: true,
errorMessage: '出发省份不能为空'
}]
},
aim_province: {
rules: [{
required: true,
errorMessage: '运达省份不能为空'
}]
},
start_city: {
rules: [{
required: true,
errorMessage: '出发城市不能为空'
}]
},
aim_city: {
rules: [{
required: true,
errorMessage: '运达城市不能为空'
}]
},
},
}
},
onLoad(o) {
// console.log(province.listByTitle['海南省']); //显示海南代码
var user = ctms.user.getInfo();
this.FormData.phone = user.mobile;
},
onReady() {
// 设置自定义表单校验规则,必须在节点渲染完毕后执行
this.$refs.customForm.setRules(this.formRules)
},
onShow: function() {
var lsIndex = this.lsIndex;
var res = uni.getStorageSync(lsIndex);
if (res) {
this.FormData = res;
}
this.provinces = province.listDatacom;
this.userinfo = getApp().globalData;
utils.debug(this.userinfo);
},
onHide() {
this.draft(); //界面隐藏时自动保存草稿
},
methods: {
//表单校验
formCheck(ref) {
this.$refs[ref].validate().then(res => {
utils.debug(res);
this.formSubmit();
}).catch(err => {
utils.debug(err);
uni.showToast({
icon: 'error',
title: err['0'].errorMessage
})
})
},
formSubmit: function(e) {
uni.showLoading({
title: '网络请求中'
})
var FormData,
_that = this;
if (e) {
//直接使用表单内建的提交机制
// uitls.debug('form发生了submit事件携带数据为' + JSON.stringify(e.detail.value))
FormData = e.detail.value;
} else {
FormData = this.FormData;
}
ctms.order.book(FormData).then(
function(res) {
if (res) {
var oid = res.data.id;
uni.showModal({
title: '提交成功',
content: '是否前往查看详情',
success: function(res) {
//清空本次缓存,避免用户重复提交
uni.removeStorageSync(_that.lsIndex);
if (res.confirm) {
uni.navigateTo({
url: '../detail/detail?oid=' + oid
});
} else if (res.cancel) {
//将缓存存入历史草稿模板
uni.setStorageSync(_that.lsIndex + '-0',
FormData);
//重新载入页面
uni.redirectTo({
url: 'create'
});
}
}
})
} else {
uni.showToast({
title: "操作失败",
icon: "error"
});
}
}
);
uni.hideLoading();
},
//存储与取用草稿
/*TD草稿逻辑
当前页面正在录入的内容,视为默认草稿数据,即时更新、主动保存;
索引-1~5追加应用模板草稿或设置当前草稿为对应模板后期考虑加入固定模板
*/
draft(e) {
//e是索引后缀
var lsIndex = this.lsIndex;
if (e) {
lsIndex = lsIndex + e;
}
uni.setStorageSync(lsIndex, this.FormData);
uni.showToast({
title: '草稿已保存'
})
},
useDraft(e) {
var _that = this;
//e为缓存索引
uni.showModal({
title: '覆盖提醒',
content: '即将应用该草稿中的临时数据',
success: function(res) {
if (res.confirm) {
var lsIndex = _that.lsIndex + e;
_that.FormData = uni.getStorageSync(lsIndex);
} else if (res.cancel) {
}
}
})
},
//浮窗按钮相关操作
fabClick(e) {
utils.debug('点击了悬浮按钮')
},
trigger(e) {
//检查是否存在模板,有则提示应用,无则创建保存
var eindex = e.index;
// this.content[e.index].active = !e.item.active;
var hasDraft = false;
var lsIndex = this.lsIndex;
if (!e.item.diyfn) {
//未设置这个difyfn字段的是“保存草稿”按钮
return this.draft();
}
lsIndex = lsIndex + e.item.diyfn;
var res = uni.getStorageSync(lsIndex);
// console.log(e.item.diyfn);
// console.log('error',lsIndex);
// console.log(res);
var _that = this;
if (!res) {
//该按钮对应的缓存不存在,追加模板
return uni.showModal({
title: '提示',
content: `${e.item.text}对应的草稿不存在,创建吗?`,
success: function(res) {
if (res.confirm) {
_that.content[e.index].active = true;
return _that.draft(e.item.diyfn);
} else if (res.cancel) {
uni.showToast({
icon: 'error',
title: '操作已取消'
});
return false;
}
}
});
} else {
}
//缓存存在
return this.useDraft(e.item.diyfn);
}
}
}
</script>
<style>
.container {
/* #ifndef APP-NVUE */
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
/* #endif */
}
.order-form {
padding: 15px;
background-color: #fff;
}
.segmented-control {
margin-bottom: 15px;
}
.button-group {
margin-top: 15px;
display: flex;
justify-content: space-around;
}
.form-item {
display: flex;
align-items: center;
}
.button {
display: flex;
align-items: center;
height: 35px;
margin-left: 10px;
}
/*级联选择器*/
.data-pickerview {
height: 400px;
border: 1px #e5e5e5 solid;
}
.popper__arrow {
top: -6px;
left: 50%;
margin-right: 3px;
border-top-width: 0;
border-bottom-color: #EBEEF5;
}
.popper__arrow {
top: -6px;
left: 50%;
margin-right: 3px;
border-top-width: 0;
border-bottom-color: #EBEEF5;
}
/*自定义样式*/
.help-block {
display: block;
width: 100%;
color: #666666;
font-size: 0.8rem;
line-height: 1rem;
text-align: justify;
text-align-last: justify;
}
.uni-section {
margin-top: 0;
}
</style>

View File

@ -0,0 +1,409 @@
<template>
<view class="container">
<uni-section title="基础信息" type="line">
<uni-card :is-shadow="false">
<view class="uni-body">
<view>车辆{{order.car_title}} -- {{order.car_number}}</view>
<view>运单号{{order.sn}}</view>
<view>日期{{order.signdate}}</view>
<view>起运地{{order.from_province}}-{{order.start_city}} =>
目的地{{order.to_province}}-{{order.aim_city}}
</view>
</view>
</uni-card>
</uni-section>
<uni-section title="链接" subTitle="使用系统浏览器打开" type="line" padding>
<view class="uni-form-item ">
<view class="title">
<uni-link :href="h5_url+'?oid='+oid" :text="h5_url"></uni-link>
</view>
</view>
</uni-section>
</view>
<view class="container">
<view class="uni-common-mt uni-form">
<uni-section title="*)验车备注" type="line">
<view class="uni-form-item ">
<view class="title">验车人</view>
<view class="data">
<input class="uni-input" name="checker" v-model="order_up.checker" placeholder="验车人的名字" />
</view>
</view>
<view class="uni-form-item ">
<view class="title">公里数</view>
<view class="data">
<input class="uni-input" name="start_km" v-model="order_up.start_km" placeholder="当前仪表盘公里数" />
</view>
</view>
<view class="uni-form-item ">
<view class="title">行驶证</view>
<radio-group name="is_driving_lisence" class="radio" @change="radioChangeDriving">
<label>
<radio value="1" :checked="order_up.is_driving_lisence==1?true:false" /><text>未随车</text>
</label>
<label>
<radio value="0" :checked="order_up.is_driving_lisence==-1?true:false" /><text>不确定</text>
</label>
</radio-group>
</view>
<view class="uni-form-item ">
<view class="title">随车物品</view>
<view class="data">
<textarea name="car_extra" auto-height placeholder-style="color:#F76260" placeholder=""
v-model="order_up.car_extra" />
</view>
</view>
</uni-section>
</view>
<uni-section title="点击图片可查看" type="line">
<view class="example-body">
<uni-file-picker v-model="driving_lisence" :auto-upload="false" file-mediatype="image" mode="grid"
file-extname="png,jpg,gif" :limit="1" :delIcon="null" title="行驶证照片" />
</view>
</uni-section>
<uni-section title="点击图片可查看" type="line">
<view class="example-body">
<uni-file-picker v-model="thumb_f" :auto-upload="false" file-mediatype="image" mode="grid"
file-extname="png,jpg,gif" :limit="1" :delIcon="null" title="正面车身照片" />
</view>
</uni-section>
<uni-section title="点击图片可查看" type="line">
<view class="example-body">
<uni-file-picker v-model="thumb_b" :auto-upload="false" file-mediatype="image" mode="grid"
file-extname="png,jpg,gif" :limit="1" :delIcon="null" title="尾部车身照" />
</view>
</uni-section>
<uni-section title="点击图片可查看" type="line">
<view class="example-body">
<uni-file-picker v-model="thumb_l" :auto-upload="false" file-mediatype="image" mode="grid"
file-extname="png,jpg,gif" :limit="1" :delIcon="null" title="左侧车身照" />
</view>
</uni-section>
<uni-section title="点击图片可查看" type="line">
<view class="example-body">
<uni-file-picker v-model="thumb_r" :auto-upload="false" file-mediatype="image" mode="grid"
file-extname="png,jpg,gif" :limit="1" :delIcon="null" title="右侧车照" />
</view>
</uni-section>
<uni-section title="点击图片可查看" type="line">
<view class="example-body">
<uni-file-picker v-model="fileLists" ref="thumbs" :auto-upload="false" file-mediatype="image"
mode="grid" file-extname="png,jpg,gif" :limit="fileLists.length" @select="multiSelect"
title="其他验车照片" :image-styles="imageStyles" :delIcon="null" />
</view>
</uni-section>
</view>
</template>
<script>
import config from "@/config/ctms.config.js";
import ctms from '@/apis/ctms/index.js';
import Hi from '@/common/util.js';
export default {
data() {
return {
userinfo: {},
oid: 0,
order: {
id: 0,
remark: '备注',
},
h5_url: '',
//要上传修改的订单数据部分(留空的则服务端不覆盖)
order_up: {
driving_lisence: '',
thumb_f: '',
thumb_b: '',
thumb_l: '',
thumb_r: '',
thumbs: [],
start_km: 0,
is_driving_lisence: 0,
car_extra: '',
checker: ''
},
driving_lisence: {
url: '',
extname: 'jpg',
name: '行驶证'
},
thumb_f: {
url: '',
extname: 'jpg',
name: '车头照'
},
thumb_b: {
url: '',
extname: 'jpg',
name: '车尾照'
},
thumb_r: {
url: '',
extname: 'jpg',
name: '右车身'
},
thumb_l: {
url: '',
extname: 'jpg',
name: '左车身'
},
//订单详情thumbs转换为可显部分 //该字段未启用
thumbs: [{
url: '',
extname: 'jpg',
name: 'thumbs[]'
}],
thumbs_files: [], //多图待上传
//呈现多图列表 //通过组件内加号选择上传的多图列表也加入到这
fileLists: [],
/*{
url: '//public.hiluker.com/fm.jpg',
extname: 'jpg',
name: 'thumbs[]',
_src: '/pics/X/Y/Z/.test.jpg' //BY FM453自行添加的一个属性将图片原始目录数据保存备用
}*/
//所有已选多图 //该字段未启用
tmpfiles: [{}], //{'blob:http://localhost:3000/4c9d3b56-041b-40fb-8c2b-221ae9d56a56'}
//图片上传组件样式定义
imageStyles: {
width: 128,
height: 128,
border: {
radius: '2%',
color: '#ddd',
},
},
listStyles: {
// 是否显示边框
border: true,
// 是否显示分隔线
dividline: true,
// 线条样式
borderStyle: {
width: 1,
color: 'blue',
style: 'dashed',
radius: 2
},
},
//悬浮按钮
horizontal: 'right',
vertical: 'bottom',
direction: 'vertical', //horizontal水平展开vertical垂直展开
pattern: {
color: '#7A7E83',
backgroundColor: '#eef',
selectedColor: '#007AFF',
buttonColor: '#fd8008',
iconColor: '#fff'
},
content: [{
iconPath: '/static/c1.png',
selectedIconPath: '/static/c1.png',
text: '保存草稿',
active: false,
diyfn: '1' //自定义添加的一个字段
},
{
iconPath: '/static/submit.png',
selectedIconPath: '/static/submit-active.png',
text: '确认上传',
active: false,
diyfn: false
}
],
};
},
methods: {
getOderDetail: function(e) {
var _that = this;
ctms.order.checkDetail(this.oid).then((res) => {
if (res) {
var order = res;
_that.oid = order.id;
order = Hi._that.formatOrder(order, false);
_that.order = order;
uni.stopPullDownRefresh();
}
});
},
//order,订单详情原始数据; restore,是否重新存储
formatOrder: function(order, restore = false) {
if (order.driving_lisence) {
Hi._that.driving_lisence.url = order.driving_lisence_url;
}
if (order.thumb_f) {
Hi._that.thumb_f.url = order.thumb_f_url;
}
if (order.thumb_b) {
Hi._that.thumb_b.url = order.thumb_b_url;
}
if (order.thumb_r) {
Hi._that.thumb_r.url = order.thumb_r_url;
}
if (order.thumb_l) {
Hi._that.thumb_l.url = order.thumb_l_url;
}
if (order.thumbs) {
var f, l;
const t = [];
for (let fi in order.thumbs_url) {
f = order.thumbs_url[fi];
l = {
url: f.url,
extname: 'jpg',
name: 'thumbs',
_src: f.src
};
// console.log(l)
t.push(l);
}
Hi._that.fileLists = t;
}
// console.log(Hi._that.fileLists);
if (order.checker) {
Hi._that.order_up.checker = order.checker;
} else {
Hi._that.order_up.checker = Hi._that.userinfo.username;
}
if (order.car_extra) {
Hi._that.order_up.car_extra = order.car_extra;
}
if (order.start_km) {
Hi._that.order_up.start_km = order.start_km;
}
if (order.no_driving_lisence) {
Hi._that.order_up.is_driving_lisence = order
.no_driving_lisence; //确认行驶证未随车
}
if (restore) {
var lsIndex = Hi._that.orderLsIndex + '-' + Hi._that.oid;
uni.setStorageSync(lsIndex, order);
}
return order;
}
},
onLoad(o) {
Hi._that = this; //在部分函数内部无法再直接调用this所以改用该方法赋值后再调用效果等同于this
this.oid = o.oid;
this.h5_url = config.h5_view;
this.userinfo = ctms.user.getInfo();
},
onShow() {
var res = ctms.order.detail(this.oid);
if (res) {
this.order = res;
this.formatOrder(res, false);
} else {
this.getOderDetail();
}
},
onPullDownRefresh() {
this.getOderDetail();
uni.stopPullDownRefresh();
}
};
</script>
<style>
.example-body {
padding: 10px;
padding-top: 0;
}
.custom-image-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.uni-form-item .title {
width: 150rpx;
text-align: justify;
text-align-last: justify;
}
.text {
font-size: 14px;
color: #333;
}
.btn[size='mini'] {
margin-right: 10rpx;
margin-top: 10rpx;
}
.btn-success {
background-color: #42b983;
color: #fff;
}
.btn-warning {
background-color: #fc8105;
color: #fff;
}
.btn-danger {
background-color: #f00;
color: #fff;
}
.btn-primary {
background-color: #0095f6;
color: #fff;
}
.uni-input {
border: #bbb solid 1rpx;
}
/*调整下上传组件样式*/
.icon-add {
background-color: #bbb;
}
.file-image {
width: 128rpx;
height: 128rpx;
}
.file-image>image {
width: 128rpx;
height: 128rpx;
}
.help-block {
display: block;
width: 100%;
color: #f00;
font-size: 1rem;
line-height: 1rem;
margin: 1.5rem;
}
</style>

View File

@ -0,0 +1,50 @@
.container {
overflow: hidden;
}
.custom-cover {
flex: 1;
flex-direction: row;
position: relative;
}
.cover-content {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background-color: rgba($color: #000000, $alpha: 0.4);
display: flex;
flex-direction: row;
align-items: center;
padding-left: 15px;
font-size: 14px;
color: #fff;
}
.card-actions {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
height: 45px;
border-top: 1px #eee solid;
}
.card-actions-item {
display: flex;
flex-direction: row;
align-items: center;
}
.card-actions-item-text {
font-size: 12px;
color: #666;
margin-left: 5px;
}
.cover-image {
flex: 1;
height: 150px;
}
.no-border {
border-width: 0;
}

View File

@ -0,0 +1,163 @@
<template>
<view class="container">
<uni-section title="基础信息" type="line">
<uni-card :is-shadow="false">
<view class="uni-body">
<view>车辆{{order.car_title}} -- {{order.car_number}}</view>
<view>运单号{{order.sn}}</view>
<view>日期{{order.signdate}}</view>
<view>起运地{{order.from_province}}-{{order.start_city}} =>
目的地{{order.to_province}}-{{order.aim_city}}</view>
</view>
</uni-card>
</uni-section>
<uni-section title="联系信息" type="line">
<uni-card :is-shadow="false">
<view class="uni-body">
<view @click="callTo(order.sender_mobiles)"> <uni-icons type="phone" size="20" color="#0095F6" />
发车人{{order.sender_name}} <em> {{order.sender_mobiles}} </em></view>
<view @click="callTo(order.receiver_mobiles)"> <uni-icons type="phone" size="20"
color="#0095F6" />接车人{{order.receiver_name}}<em>{{order.receiver_mobiles}}</em></view>
<view>送车地址{{order.aim_address}}</view>
</view>
</uni-card>
</uni-section>
<uni-section title="费用信息" type="line">
<uni-card :is-shadow="false">
<view class="uni-body">
<view>总运费{{order.fee_total}} </view>
<view>现付<text class="error">{{order.pay_send}} </text></view>
<view>到付<text class="error">{{order.pay_receive}} </text></view>
</view>
</uni-card>
</uni-section>
<uni-section title="链接" subTitle="使用系统浏览器打开" type="line">
<view class="uni-form-item ">
<view class="title">
<uni-link :href="h5_url+'?oid='+oid" :text="h5_url"></uni-link>
</view>
</view>
</uni-section>
<uni-section title="操作提示" type="line">
<uni-card :is-shadow="false">
<view class="uni-body">
<view>订单详情页首次打开时需要联网搜索运单信息</view>
<view>打开过一次的运单信息将会缓存在APP内一段时间在这期间即使手机没有网络也能查看</view>
<view>如果需要查看该运单的最新信息可通过下拉本页面进行刷新手机需要联网</view>
</view>
</uni-card>
<view class="uni-form-item ">
<view class="title">
<button class="btn btn-warning" @click="actCheck()">查看验车记录</button>
</view>
</view>
</uni-section>
</view>
</template>
<script>
import config from "@/config/ctms.config.js";
import ctms from '@/apis/ctms/index.js';
export default {
data() {
return {
userinfo: {},
oid: 0,
order: {
id: 1,
car_id: 1,
car_number: '车牌号',
car_title: '车型号',
start_city: "起运城市",
from_province: '起运省份',
aim_city: "目的城市",
to_province: '目标省份',
signdate: '下单日期',
car_extra: '随车物品',
checker: '验车人',
receiver_name: '收车人姓名',
receiver_mobiles: '收车人电话',
sender_name: '发车人姓名',
sender_mobiles: '发车人电话',
},
h5_url: '',
}
},
methods: {
getOderDetail: function(e) {
var _that = this;
ctms.order.checkDetail(this.oid).then((res) => {
if (res) {
_that.order = res;
uni.showToast({
title: "查询完成!",
icon: "success"
});
uni.stopPullDownRefresh();
}
});
},
actCheck() {
uni.navigateTo({
url: './check?oid=' + this.oid
})
},
callTo(tel) {
uni.makePhoneCall({
phoneNumber: tel
})
}
},
onLoad(o) {
this.oid = o.oid;
this.h5_url = config.h5_view;
this.userinfo = ctms.user.getInfo();
},
onShow: function() {
var res = ctms.order.detail(this.oid);
if (res) {
this.order = res;
} else {
this.getOderDetail();
}
},
onPullDownRefresh() {
this.getOderDetail();
uni.stopPullDownRefresh();
},
//标题栏按钮响应,仅在APP-PLUS下支持
onNavigationBarButtonTap(e) {
//#ifdef APP-PLUS
uni.shareWithSystem({
summary: '运单【 ' + this.order.sn + ' 】摘要:' + this.order.signdate + ',由' + this.order
.from_province + this.order.start_city + '-->发往-->' + this.order.to_province + this.order
.aim_city + "的车辆:" + this.order.car_title + "--" + this.order.car_number + "。点击链接可查阅更多信息",
href: this.h5_url + "?oid=" + this.oid,
success() {
// 分享完成,请注意此时不一定是成功分享
},
fail() {
// 分享失败
}
})
//#endif
//#ifdef H5
var summary = '运单【 ' + this.order.sn + ' 】摘要:' + this.order.signdate + ',由' + this.order
.from_province + this.order.start_city + '-->发往-->' + this.order.to_province + this.order
.aim_city + "的车辆:" + this.order.car_title + "--" + this.order.car_number + "。点击链接可查阅更多信息:" + this
.h5_url + "?oid=" + this.oid;
uni.setClipboardData({
data: summary
})
//#endif
}
}
</script>
<style>
@import url("detail.css");
</style>

View File

@ -0,0 +1,207 @@
<template>
<view class="content">
<view class="uni-common-mt uni-form">
<form @submit="formSubmit" @reset="formReset">
<view class="uni-form-item ">
<view class="title">车牌号:</view>
<input class="uni-input" name="carno" v-model="search.carno"
:placeholder="'车牌号或车架号,如 '+demoCarno" />
</view>
<view class="uni-form-item ">
<view class="title">手机号:</view>
<input class="uni-input" name="phone" readonly="readonly" disabled="disabled" :value="search.phone"
type="text" placeholder="发车人或收车人的手机号" />
</view>
<view class="uni-form-item" v-if="false">
<view class="title">运单号:</view>
<input class="uni-input" name="ordersn" v-model="search.ordersn" type="text"
placeholder="完整的运单号码" />
</view>
<view class="uni-form-item">
<view class="help-block">
如果搜索不出结果可尝试检查一下搜索条件是否正确无误
</view>
</view>
<uni-notice-bar text="手机号为自动获取您登陆时使用的手机号,如果需要更换查询用的手机号,请退出账号并使用新手机号登陆."></uni-notice-bar>
<view class="uni-btn-v">
<button class="btn btn-success" form-type="submit">查询</button>
<button class="btn btn-error" type="default" form-type="reset">重置</button>
</view>
</form>
</view>
</view>
</template>
<script>
import config from "@/config/ctms.config.js";
import store from '@/store/index.js';
import utils from "@/utils/common.js";
import ctms from '@/apis/ctms/index.js';
export default {
data() {
return {
search: {
carno: '',
phone: '',
ordersn: ''
},
demoCarno: config.demoCarno,
lsIndex: 'OrderSearchTabbar'
}
},
computed: {
},
methods: {
checkLogin() {
return ctms.user.checkLogin()
},
formSubmit: function(e) {
var _that = this;
// utils.debug('form发生了submit事件携带数据为' + JSON.stringify(e.detail.value))
//进行表单检查
var formData = e.detail.value;
ctms.order.search(formData, 0, 5).then(
function(res) {
if (res.code == 200) {
uni.showToast({
title: "查询完成!",
icon: "success"
});
_that.goTo('order/list/list');
} else {
uni.showToast({
title: "没有查询到相关订单!",
icon: "fail"
});
}
}
);
},
formReset: function(e) {
// utils.debug('清空数据')
},
goTo(page) {
page = config.pageDir + page;
uni.navigateTo({
url: page
});
}
},
onLoad() {
var user = ctms.user.checkLogin();
var user = store.state.userCloud;
this.search.phone = user.mobile;
},
onShow: function() {}
}
</script>
<style>
body {
background-color: #e6e6e60e;
}
radio,
checkbox,
switch {
transform: scale(1.5);
margin-left: 1rem;
margin-right: 1rem;
margin-top: 36rpx;
}
input {
margin-left: 1rem;
margin-right: 1rem;
margin-top: 66rpx;
border-bottom: 1upx #333 dashed;
}
.uni-input {
padding: 0;
}
.content {
padding-bottom: 50rpx;
}
.header {
text-align: center;
}
.header>image {
width: 300rpx;
height: 300rpx;
}
.uni-form {
width: 94%;
margin: 0rpx 3% 0 3%;
}
.uni-form-item {
width: 100%;
display: inline-flex;
height: 96rpx;
line-height: 96rpx;
}
.uni-form-item .title,
.uni-form-item .data {}
/**不生效**/
.uni-form-item .title {
width: 150rpx;
padding: 40rpx 20rpx;
text-align: justify;
text-align-last: justify;
}
.uni-form .uni-btn-v {
margin-top: 50rpx;
}
.radio {
width: auto;
}
.btn {
margin: 40rpx 30rpx;
}
.btn-success {
background-color: #09BB07;
color: #fff;
}
.btn-error {
background-color: #fc0107;
color: #fff;
}
.footer {
display: block;
/* width: 100%; */
font-size: 1rem;
height: 1rem;
line-height: 1.5rem;
margin: 1.5rem;
}
.help-block {
display: block;
width: 100%;
color: #666666;
font-size: 0.8rem;
line-height: 1rem;
margin: 1.5rem;
}
</style>

View File

@ -0,0 +1,54 @@
.container {
overflow: hidden;
}
.custom-cover {
flex: 1;
flex-direction: row;
position: relative;
}
.cover-content {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background-color: rgba($color: #000000, $alpha: 0.4);
display: flex;
flex-direction: row;
align-items: center;
padding-left: 15px;
font-size: 14px;
color: #fff;
}
.card-actions {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
height: 45px;
border-top: 1px #eee solid;
}
.card-actions-item {
display: flex;
flex-direction: row;
align-items: center;
}
.card-actions-item-text {
font-size: 12px;
color: #666;
margin-left: 5px;
}
.cover-image {
flex: 1;
height: 150px;
}
.no-border {
border-width: 0;
}
.pagination{
margin:20px 20px;
}

View File

@ -0,0 +1,232 @@
<template>
<view class="container">
<uni-card v-if="!totalCount" title="查询结果" sub-title="" extra="" padding="10px 0">
<view class="uni-body uni-mt-5">
<view>
<text>没有查询到相关运单</text>
</view>
</view>
</uni-card>
<uni-section v-else :title="'运单'+order.id" type="line" v-for="order in orders" :data-oid="order.id"
:data-carid="order.car_id">
<uni-card title="基础卡片" sub-title="副标题" extra="额外信息" padding="10px 0" :thumbnail="avatar">
<template v-slot:title>
<uni-list>
<uni-list-item :show-switch="false" :title="order.car_title + ' ' + order.car_number" />
</uni-list>
</template>
<view class="uni-body uni-mt-5">
<view>
<text>日期{{order.signdate}}</text>
</view>
<view>
<text>起运地{{order.start_city}} => 目的地{{order.aim_city}}</text>
</view>
<view>
<text>验车人{{order.checker}}</text>
</view>
</view>
<view slot="actions" class="card-actions">
<view v-if="order.is_checked" class="card-actions-item" @click="showCheck(order.id)">
<uni-icons type="images" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">验车情况</text>
</view>
<view class="card-actions-item" @click="actionsCheck(order.id)">
<uni-icons type="cloud-upload" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">上传验车</text>
</view>
<view class="card-actions-item" @click="actionsDetail(order.id)">
<uni-icons type="link" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">详情</text>
</view>
</view>
</uni-card>
</uni-section>
<view class="pagination">
<uni-pagination :show-icon="false" :total="totalCount" :pageSize='psize' v-model='page' title="分页栏"
@change="newPage" />
</view>
<uni-fab ref="fab" :pattern="fabs.pattern" :content="fabs.content" :horizontal="fabs.horizontal"
:vertical="fabs.vertical" :direction="fabs.direction" @trigger="fabTrigger" @fabClick="fabClick" />
</view>
</template>
<script>
import utils from "@/utils/common.js";
import config from "@/config/ctms.config.js";
import ctms from '@/apis/ctms/index.js';
export default {
data() {
return {
userinfo: {},
orders: {},
employees: {},
stores: {},
totalCount: 0, //一共多少条数据
psize: 10,
page: 1,
avatar: '@/static/logo.png',
//悬浮按钮
fabs: {
horizontal: 'left',
vertical: 'bottom',
direction: 'horizontal', //horizontal水平展开vertical垂直展开
pattern: {
color: '#7A7E83',
backgroundColor: '#fff',
selectedColor: '#007AFF',
buttonColor: '#fff',
iconColor: '#aaa'
},
content: [{
iconPath: '/static/fab/home.png',
selectedIconPath: '/static/fab/homeactive.png',
text: '首页',
active: false,
diyfn: 'home'
},
{
iconPath: '/static/fab/guanzhu.png',
selectedIconPath: '/static/fab/guanzhuactive.png',
text: '关注',
active: false,
diyfn: 'news'
},
{
iconPath: '/static/fab/me.png',
selectedIconPath: '/static/fab/meactive.png',
text: '用户',
active: false,
diyfn: 'user'
},
{
iconPath: '/static/fab/news.png',
selectedIconPath: '/static/fab/newsactive.png',
text: '公告',
active: false,
diyfn: 'notice'
}
]
}
}
},
methods: {
showCheck(e) {
uni.navigateTo({
url: '../detail/check?oid=' + e
})
},
actionsDetail(e) {
uni.navigateTo({
url: '../detail/detail?oid=' + e
})
},
actionsCheck(e) {
uni.navigateTo({
url: '../yanche/yanche?oid=' + e
})
},
//分页器动作
newPage(e) {
var page = e.current;
this.page = page;
var res = ctms.order.list(this.page);
if (res) {
this.orders = res.orders;
} else {
this.checkOrder();
}
},
//刷新列表
checkOrder() {
var _that = this;
ctms.order.search(null, this.page, this.psize).then(
function(res) {
if (res) {
_that.orders = res.orders;
_that.totalCount = res.total;
uni.showToast({
title: "查询完成!",
icon: "success"
});
} else {
_that.orders = {}
_that.totalCount = 0;
}
}
);
},
//浮窗按钮相关操作
fabClick(e) {
// utils.debug('点击了悬浮按钮')
},
fabTrigger(e) {
var eindex = e.index;
this.fabs.content[e.index].active = !e.item.active;
if (!e.item.diyfn) {
//未设置这个difyfn字段的无操作
return false;
}
var diyfn = e.item.diyfn,
dir = config.pageDir,
page;
switch (diyfn) {
case 'home':
page = 'tabbar/index/index';
return uni.reLaunch({
url: dir + page
})
break;
case 'news':
page = 'news/list/list';
break;
case 'user':
page = 'me/index';
break;
case 'notice':
page = 'tabbar/notice/index';
return uni.reLaunch({
url: dir + page
})
break;
}
return uni.navigateTo({
url: dir + page
})
}
},
onLoad() {
// utils.debug('运单列表页启动')
},
onShow() {
var res = ctms.order.list(this.page);
if (res) {
this.orders = res.orders;
this.totalCount = res.total;
}
},
onPullDownRefresh() {
this.page = 1;
this.checkOrder();
setTimeout(() => {
uni.stopPullDownRefresh();
}, 3000);
}
}
</script>
<style>
@import url("list.css");
@import url("../../statusBar.css");
</style>

View File

@ -0,0 +1,938 @@
<template>
<view class="container">
<uni-section title="基础信息" type="line">
<uni-card :is-shadow="false">
<view class="uni-body">
<view>车辆{{order.car_title}} -- {{order.car_number}}</view>
<view>运单号{{order.sn}}</view>
<view>日期{{order.signdate}}</view>
<view>起运地{{order.from_province}}-{{order.start_city}} =>
目的地{{order.to_province}}-{{order.aim_city}}
</view>
<view>随车物品{{order.car_extra}}</view>
</view>
</uni-card>
</uni-section>
<uni-section title="链接" subTitle="使用系统浏览器打开" type="line" padding>
<uni-link :href="h5_url+'?oid='+oid" :text="h5_url"></uni-link>
</uni-section>
</view>
<view class="container">
<view class="uni-common-mt uni-form">
<uni-section title="*)验车备注" type="line">
<view class="uni-form-item ">
<text class="help-block">请确认提醒客户取下ETC卡并妥善放置</text>
</view>
<view class="uni-form-item ">
<view class="title">验车人</view>
<view class="data">
<input class="uni-input" name="checker" v-model="order_up.checker" placeholder="验车人的名字" />
</view>
</view>
<view class="uni-form-item ">
<view class="title">公里数</view>
<view class="data">
<input class="uni-input" name="start_km" v-model="order_up.start_km" placeholder="当前仪表盘公里数" />
</view>
</view>
<view class="uni-form-item ">
<view class="title">行驶证</view>
<radio-group name="is_driving_lisence" class="radio" @change="radioChangeDriving">
<label>
<radio value="1" :checked="order_up.is_driving_lisence==1?true:false" /><text>未随车</text>
</label>
<label>
<radio value="0" :checked="order_up.is_driving_lisence==-1?true:false" /><text>不确定</text>
</label>
</radio-group>
</view>
<view class="uni-form-item ">
<view class="title">随车物品</view>
<view class="data">
<textarea name="car_extra" auto-height placeholder-style="color:#F76260"
placeholder="点击即可填写;请简要备注一下" v-model="order_up.car_extra" />
</view>
</view>
<view class="uni-form-item ">
<button class="btn btn-success" @click="updata">上传数据</button>
</view>
</uni-section>
</view>
<uni-section title="选择验车图片并点击上传" type="line">
<view class="example-body">
<uni-file-picker v-model="driving_lisence" :auto-upload="false" file-mediatype="image" mode="grid"
:limit="1" :delIcon="null" title="行驶证照片" />
<input hidden="true" class="uni-input" v-model="order_up.driving_lisence"
placeholder="直接在此处填写图片地址也可以" />
<uni-file-picker ref="files" :auto-upload="true" file-mediatype="image" mode="grid" :limit="1" title=""
:image-styles="imageStyles" @select="select1" @progress="progress1" @success="success1"
@fail="fail1" />
<button hidden="true" class="btn btn-primary" size="mini" @click="upload1">上传</button>
<button :hidden="order_up.driving_lisence == '' ? true : false" class="btn btn-danger" size="mini"
@click="reset1">重置</button>
<button class="btn btn-warning" size="mini" @click="recovery1">还原</button>
<button :hidden="order_up.driving_lisence == '' ? true : false" class="btn btn-success" size="mini"
@click="save1">保存</button>
</view>
</uni-section>
<uni-section title="选择验车图片并点击上传" type="line">
<view class="example-body">
<uni-file-picker v-model="thumb_f" :auto-upload="false" file-mediatype="image" mode="grid" :limit="1"
:delIcon="null" title="正面车身照片" />
<input hidden="true" class="uni-input" v-model="order_up.thumb_f" placeholder="直接在此处填写图片地址也可以" />
<uni-file-picker ref="files" :auto-upload="true" file-mediatype="image" mode="grid" :limit="1" title=""
:image-styles="imageStyles" @select="select2" @progress="progress2" @success="success2"
@fail="fail2" />
<button :hidden="order_up.thumb_f == '' ? true : false" class="btn btn-danger" size="mini"
@click="reset2">重置</button>
<button class="btn btn-warning" size="mini" @click="recovery2">还原</button>
<button :hidden="order_up.thumb_f == '' ? true : false" class="btn btn-success" size="mini"
@click="save2">保存</button>
</view>
</uni-section>
<uni-section title="选择验车图片并点击上传" type="line">
<view class="example-body">
<uni-file-picker v-model="thumb_b" :auto-upload="false" file-mediatype="image" mode="grid" :limit="1"
:delIcon="null" title="尾部车身照" />
<input hidden="true" class="uni-input" v-model="order_up.thumb_b" placeholder="直接在此处填写图片地址也可以" />
<uni-file-picker ref="files" :auto-upload="true" file-mediatype="image" mode="grid" :limit="1"
:image-styles="imageStyles" @select="select3" @progress="progress3" @success="success3"
@fail="fail3" />
<button :hidden="order_up.thumb_b == '' ? true : false" class="btn btn-danger" size="mini"
@click="reset3">重置</button>
<button class="btn btn-warning" size="mini" @click="recovery3">还原</button>
<button :hidden="order_up.thumb_b == '' ? true : false" class="btn btn-success" size="mini"
@click="save3">保存</button>
</view>
</uni-section>
<uni-section title="选择验车图片并点击上传" type="line">
<view class="example-body">
<uni-file-picker v-model="thumb_l" :auto-upload="false" file-mediatype="image" mode="grid" :limit="1"
:delIcon="null" title="左侧车身照" />
<input hidden="true" class="uni-input" v-model="order_up.thumb_l" placeholder="直接在此处填写图片地址也可以" />
<uni-file-picker ref="files" :auto-upload="true" file-mediatype="image" mode="grid" :limit="1"
:image-styles="imageStyles" @select="select4" @progress="progress4" @success="success4"
@fail="fail4" />
<button :hidden="order_up.thumb_l == '' ? true : false" class="btn btn-danger" size="mini"
@click="reset4">重置</button>
<button class="btn btn-warning" size="mini" @click="recovery4">还原</button>
<button :hidden="order_up.thumb_l == '' ? true : false" class="btn btn-success" size="mini"
@click="save4">保存</button>
</view>
</uni-section>
<uni-section title="选择验车图片并点击上传" type="line">
<view class="example-body">
<uni-file-picker v-model="thumb_r" :auto-upload="false" file-mediatype="image" mode="grid" :limit="1"
:delIcon="null" title="右侧车照" />
<input hidden="true" class="uni-input" v-model="order_up.thumb_r" placeholder="直接在此处填写图片地址也可以" />
<uni-file-picker ref="files" :auto-upload="true" file-mediatype="image" mode="grid" :limit="1"
:image-styles="imageStyles" @select="select5" @progress="progress5" @success="success5"
@fail="fail5" />
<button :hidden="order_up.thumb_r == '' ? true : false" class="btn btn-danger" size="mini"
@click="reset5">重置</button>
<button class="btn btn-warning" size="mini" @click="recovery5">还原</button>
<button :hidden="order_up.thumb_r == '' ? true : false" class="btn btn-success" size="mini"
@click="save5">保存</button>
</view>
</uni-section>
<uni-section title="选择剩余验车图片并点击上传" type="line">
<view class="example-body">
<uni-file-picker v-model="fileLists" ref="thumbs" :auto-upload="true" file-mediatype="image" mode="grid"
:limit="99" title="其他验车照片" :image-styles="imageStyles" @select="multiSelect"
@progress="multiProgress" @success="multiSuccess" @fail="multiFail" />
<button hidden="true" class="btn btn-danger" size="mini" @click="multiSelectAdd">添加照片至列表</button>
<button hidden="true" class="btn btn-default" size="mini" @click="multiSelectCover">重选照片并覆盖</button>
<button class="btn btn-primary" size="mini" @click="uploadThumbs">上传所选图片</button>
<button class="btn btn-success" size="mini" @click="saveThumbs">保存验车图片</button>
</view>
</uni-section>
<button class="btn btn-warning" @click="saveAll">保存并上传全部验车信息</button>
<uni-fab ref="fab" :pattern="pattern" :content="content" :horizontal="horizontal" :vertical="vertical"
:direction="direction" @trigger="trigger" @fabClick="fabClick" />
</view>
</template>
<script>
import config from "@/config/ctms.config.js";
import ctms from '@/apis/ctms/index.js';
import Hi from '@/common/util.js';
export default {
data() {
return {
userinfo: {},
oid: 0,
order: {
id: 0,
remark: '备注',
},
h5_url: '',
//要上传修改的订单数据部分(留空的则服务端不覆盖)
order_up: {
driving_lisence: '',
thumb_f: '',
thumb_b: '',
thumb_l: '',
thumb_r: '',
thumbs: [],
start_km: 0,
is_driving_lisence: 0,
car_extra: '',
checker: ''
},
driving_lisence: {
url: '',
extname: 'jpg',
name: '行驶证'
},
thumb_f: {
url: '',
extname: 'jpg',
name: '车头照'
},
thumb_b: {
url: '',
extname: 'jpg',
name: '车尾照'
},
thumb_r: {
url: '',
extname: 'jpg',
name: '右车身'
},
thumb_l: {
url: '',
extname: 'jpg',
name: '左车身'
},
//订单详情thumbs转换为可显部分 //该字段未启用
thumbs: [{
url: '',
extname: 'jpg',
name: 'thumbs[]'
}],
thumbs_files: [], //多图待上传
//呈现多图列表 //通过组件内加号选择上传的多图列表也加入到这
fileLists: [],
/*{
url: '//public.hiluker.com/fm.jpg',
extname: 'jpg',
name: 'thumbs[]',
_src: '/pics/X/Y/Z/.test.jpg' //BY FM453自行添加的一个属性将图片原始目录数据保存备用
}*/
//所有已选多图 //该字段未启用
tmpfiles: [{}], //{'blob:http://localhost:3000/4c9d3b56-041b-40fb-8c2b-221ae9d56a56'}
//图片上传组件样式定义
imageStyles: {
width: 128,
height: 128,
border: {
radius: '2%',
color: '#ddd',
},
},
listStyles: {
// 是否显示边框
border: true,
// 是否显示分隔线
dividline: true,
// 线条样式
borderStyle: {
width: 1,
color: 'blue',
style: 'dashed',
radius: 2
},
},
//悬浮按钮
horizontal: 'right',
vertical: 'bottom',
direction: 'vertical', //horizontal水平展开vertical垂直展开
pattern: {
color: '#7A7E83',
backgroundColor: '#eef',
selectedColor: '#007AFF',
buttonColor: '#fd8008',
iconColor: '#fff'
},
content: [{
iconPath: '/static/c1.png',
selectedIconPath: '/static/c1.png',
text: '保存草稿',
active: false,
diyfn: '1' //自定义添加的一个字段
},
{
iconPath: '/static/submit.png',
selectedIconPath: '/static/submit-active.png',
text: '确认上传',
active: false,
diyfn: false
}
],
};
},
methods: {
//行驶证随车按钮切换
radioChangeDriving(e) {
// console.log(e.detail);
Hi._that.order_up.is_driving_lisence = e.detail.value;
},
//仅上传验车数据
updata() {
this.submit('data');
},
// 文件选择与上传
//行驶证
select1(e) {
//缓存文件
Hi._that.driving_lisence_files = e.tempFiles;
},
progress1(e) {
console.log('上传中...', e);
},
fail1(e) {
console.log('上传失败...', e);
},
success1(e) {
console.log('上传成功...', e);
var files = e.tempFiles;
var file = files[0];
var callback = 'driving_lisence';
Hi._that.order_up[callback] = file.url;
uni.setStorageSync(callback, file.url);
},
recovery1() {
//还原,恢复使用刚上传的图片
uni.showToast({
title: "操作成功",
icon: "success"
});
var ls = uni.getStorageSync('driving_lisence');
if (ls) Hi._that.order_up.driving_lisence = ls;
},
reset1() {
//重置,使用最初的图片
uni.showToast({
title: "操作成功",
icon: "success"
});
Hi._that.order_up.driving_lisence = '';
},
save1() {
var callback = 'driving_lisence';
if (!Hi._that.order_up[callback]) {
uni.showToast({
title: "未选择照片",
icon: "error"
});
return false;
}
//仅提交该项数据
this.submit(callback);
},
upload1() {
console.log('准备开始上传')
},
//车前
select2(e) {
console.log('选择文件:', e);
//缓存文件
Hi._that.thumb_f_files = e.tempFiles;
},
progress2(e) {
console.log('上传中...');
console.log(e);
},
fail2(e) {
console.log('上传失败...');
console.log(e);
},
success2(e) {
console.log('上传成功...');
console.log(e);
var files = e.tempFiles;
var file = files[0];
var callback = 'thumb_f';
Hi._that.order_up[callback] = file.url;
uni.setStorageSync(callback, file.url);
},
recovery2() {
//还原,恢复使用刚上传的图片
uni.showToast({
title: "操作成功",
icon: "success"
});
var ls = uni.getStorageSync('thumb_f');
if (ls) Hi._that.order_up.thumb_f = ls;
},
reset2() {
//重置,使用最初的图片
uni.showToast({
title: "操作成功",
icon: "success"
});
Hi._that.order_up.thumb_f = '';
},
save2() {
var callback = 'thumb_f';
if (!Hi._that.order_up[callback]) {
uni.showToast({
title: "未选择照片",
icon: "error"
});
return false;
}
//仅提交该项数据
this.submit(callback);
},
//车尾
select3(e) {
console.log('选择文件:', e);
//缓存文件
Hi._that.thumb_b_files = e.tempFiles;
},
progress3(e) {
console.log('上传中...');
console.log(e);
},
fail3(e) {
console.log('上传失败...');
console.log(e);
},
success3(e) {
console.log('上传成功...');
console.log(e);
var files = e.tempFiles;
var file = files[0];
var callback = 'thumb_b';
Hi._that.order_up[callback] = file.url;
uni.setStorageSync(callback, file.url);
},
recovery3() {
//还原,恢复使用刚上传的图片
uni.showToast({
title: "操作成功",
icon: "success"
});
var ls = uni.getStorageSync('thumb_b');
if (ls) Hi._that.order_up.thumb_b = ls;
},
reset3() {
//重置,使用最初的图片
uni.showToast({
title: "操作成功",
icon: "success"
});
Hi._that.order_up.thumb_b = '';
},
save3() {
var callback = 'thumb_b';
if (!Hi._that.order_up[callback]) {
uni.showToast({
title: "未选择照片",
icon: "error"
});
return false;
}
//仅提交该项数据
this.submit(callback);
},
//车左
select4(e) {
console.log('选择文件:', e);
//缓存文件
Hi._that.thumb_l_files = e.tempFiles;
},
progress4(e) {
console.log('上传中...');
console.log(e);
},
fail4(e) {
console.log('上传失败...');
console.log(e);
},
success4(e) {
console.log('上传成功...');
console.log(e);
var files = e.tempFiles;
var file = files[0];
var callback = 'thumb_l';
Hi._that.order_up[callback] = file.url;
uni.setStorageSync(callback, file.url);
},
recovery4() {
//还原,恢复使用刚上传的图片
uni.showToast({
title: "操作成功",
icon: "success"
});
var ls = uni.getStorageSync('thumb_l');
if (ls) Hi._that.order_up.thumb_l = ls;
},
reset4() {
//重置,使用最初的图片
uni.showToast({
title: "操作成功",
icon: "success"
});
Hi._that.order_up.thumb_l = '';
},
save4() {
var callback = 'thumb_l';
if (!Hi._that.order_up[callback]) {
uni.showToast({
title: "未选择照片",
icon: "error"
});
return false;
}
//仅提交该项数据
this.submit(callback);
},
//车右
select5(e) {
console.log('选择文件:', e);
//缓存文件
Hi._that.thumb_r_files = e.tempFiles;
},
progress5(e) {
console.log('上传中...');
console.log(e);
},
fail5(e) {
console.log('上传失败...');
console.log(e);
},
success5(e) {
console.log('上传成功...');
console.log(e);
var files = e.tempFiles;
var file = files[0];
var callback = 'thumb_r';
Hi._that.order_up[callback] = file.url;
uni.setStorageSync(callback, file.url);
},
recovery5() {
//还原,恢复使用刚上传的图片
uni.showToast({
title: "操作成功",
icon: "success"
});
var ls = uni.getStorageSync('thumb_r');
if (ls) Hi._that.order_up.thumb_r = ls;
},
reset5() {
//重置,使用最初的图片
uni.showToast({
title: "操作成功",
icon: "success"
});
Hi._that.order_up.thumb_r = '';
},
save5() {
var callback = 'thumb_r';
if (!Hi._that.order_up[callback]) {
uni.showToast({
title: "未选择照片",
icon: "error"
});
return false;
}
//仅提交该项数据
this.submit(callback);
},
//多图同时上传限定只在APP端使用;
multiSelect(e) {
//点上传组件的加号选择图片的方式;该方式下选择临时图片后并不会将预览结果添加到fileLists中;
console.log('选择文件:', e);
// 缓存文件
// Hi._that.fileLists.push.apply(Hi._that.fileLists,e.tempFiles);
// console.log(Hi._that.fileLists);
Hi._that.thumbs_files = e.tempFiles;
// console.log(Hi._that.thumbs_files);
},
multiProgress(e) {
// console.log('多选上传进度>>>');
// console.log(e);
},
multiSuccess(e) {
//上传成功后会合并到对应的fileLists数据中
console.log('多选上传成功');
console.log(e);
var files = e.tempFiles;
var callback = 'thumbs';
var list = [];
for (let i in files) {
var f = files[i];
var t = f.url;
list.push(t);
}
Hi._that.order_up[callback] = list;
uni.setStorageSync(callback, list);
},
multiFail(e) {
console.log('多选上传失败');
console.log(e);
},
uploadThumbs() {
const files = Hi._that.thumbs_files;
if (!files) {
uni.showToast({
title: "请先选择照片",
icon: "error"
});
return false;
}
this.$refs.thumbs.upload();
},
saveThumbs() {
var callback = 'thumbs';
// console.log(Hi._that.order_up.thumbs);
// console.log('上传成功返回结果的待保存文件列表');
// console.log(Hi._that.order_up[callback]);
//先检测文件列表fileLists----eg:上传成功后又有删除了部分图片的情况,不能使用前面的上传成功返回结果作为此处待保存的数据
// console.log('有增/删后的文件显现列表');
// console.log(Hi._that.fileLists);
var files = Hi._that.fileLists;
var list = [];
var f, t;
for (let i in files) {
f = files[i];
t = f.url;
list.push(t);
}
Hi._that.order_up[callback] = list;
this.submit('thumbs');
},
//以下两个功能在启用自动上传后不启用 Start
multiSelectCover() {
//覆盖方式
uni.chooseImage({
count: 99, //限制99张但不是对所有客户端或浏览器都有效
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: function(res) {
// console.log(JSON.stringify(res.tempFilePaths));
var files = res.tempFiles;
var fs = [];
for (var i in files) {
var file = files[i];
var _fs = {
url: file.path,
extname: 'jpg',
name: ''
}
fs.push(_fs);
}
Hi._that.fileLists = fs; //用于呈现
Hi._that.tmpfiles = files; //替换储存待传
}
});
},
multiSelectAdd() {
//追加方式
uni.chooseImage({
count: 99, //限制99张但不是对所有客户端或浏览器都有效
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
sourceType: ['album'], //从相册选择
success: function(res) {
// console.log(JSON.stringify(res.tempFilePaths));
var files = res.tempFiles;
var fs = [];
for (var i in files) {
var file = files[i];
Hi._that.tmpfiles.push(file); //追加储存待传
var _fs = {
url: file.path,
extname: 'jpg',
name: ''
}
fs.push(_fs);
}
for (var j in Hi._that.fileLists) {
var _fs = Hi._that.fileLists[j];
fs.push(_fs);
}
Hi._that.fileLists = fs; //用于展示已选与已有
}
});
},
//以上两个功能在启用自动上传后不启用 End
saveAll() {
//多选上传的图片组数据为异步保存,要先做一次编排
var callback = 'thumbs';
var files = Hi._that.fileLists;
var list = [];
for (let i in files) {
var f = files[i];
var t = f.url;
list.push(t);
}
Hi._that.order_up[callback] = list;
this.submit('all');
},
//浮窗按钮相关操作
fabClick(e) {
console.log('点击了悬浮按钮')
},
trigger(e) {
var eindex = e.index;
var hasDraft = false;
var lsIndex = this.lsIndex + '-' + this.oid;
if (!e.item.diyfn) {
//全部保存
this.submit('all');
uni.setStorageSync(lsIndex, this.order_up);
} else {
uni.showToast({
title: '暂不支持',
icon: 'error'
})
}
},
submit: function(op) {
var _that = this;
return ctms.order.yanche(this.oid, this.order_up, op).then(
function(res) {
if (!res) {
return uni.showToast({
title: "提交失败!",
icon: "fail"
});
}
if (op == 'driving_lisence') {
Hi._that.driving_lisence.url = Hi._that.driving_lisence_files[0].url;
}
if (op == 'thumb_f') {
Hi._that.thumb_f.url = Hi._that.thumb_f_files[0].url;
}
if (op == 'thumb_b') {
Hi._that.thumb_b.url = Hi._that.thumb_b_files[0].url;
}
if (op == 'thumb_l') {
Hi._that.thumb_l.url = Hi._that.thumb_l_files[0].url;
}
if (op == 'thumb_r') {
Hi._that.thumb_r.url = Hi._that.thumb_r_files[0].url;
}
return uni.showToast({
title: "保存成功!",
icon: "success"
});
}
);
},
getOderDetail: function(e) {
var _that = this;
ctms.order.checkDetail(this.oid).then((res) => {
if (res) {
var order = res;
_that.oid = order.id;
order = _that.formatOrder(order, false);
_that.order = order;
uni.stopPullDownRefresh();
}
});
},
//order,订单详情原始数据; restore,是否重新存储
formatOrder: function(order, restore = false) {
if (order.driving_lisence) {
Hi._that.driving_lisence.url = order.driving_lisence_url;
}
if (order.thumb_f) {
Hi._that.thumb_f.url = order.thumb_f_url;
}
if (order.thumb_b) {
Hi._that.thumb_b.url = order.thumb_b_url;
}
if (order.thumb_r) {
Hi._that.thumb_r.url = order.thumb_r_url;
}
if (order.thumb_l) {
Hi._that.thumb_l.url = order.thumb_l_url;
}
if (order.thumbs) {
var f, l;
const t = [];
for (let fi in order.thumbs_url) {
f = order.thumbs_url[fi];
l = {
url: f.url,
extname: 'jpg',
name: 'thumbs',
_src: f.src
};
// console.log(l)
t.push(l);
}
Hi._that.fileLists = t;
}
// console.log(Hi._that.fileLists);
if (order.checker) {
Hi._that.order_up.checker = order.checker;
} else {
Hi._that.order_up.checker = Hi._that.userinfo.username;
}
if (order.car_extra) {
Hi._that.order_up.car_extra = order.car_extra;
}
if (order.start_km) {
Hi._that.order_up.start_km = order.start_km;
}
if (order.no_driving_lisence) {
Hi._that.order_up.is_driving_lisence = order
.no_driving_lisence; //确认行驶证未随车
}
if (restore) {
var lsIndex = Hi._that.orderLsIndex + '-' + Hi._that.oid;
uni.setStorageSync(lsIndex, order);
}
return order;
},
},
onLoad(o) {
Hi._that = this; //在部分函数内部无法再直接调用this所以改用该方法赋值后再调用效果等同于this
this.oid = o.oid;
this.h5_url = config.h5_view;
this.userinfo = ctms.user.getInfo();
var res = ctms.order.detail(this.oid);
if (res) {
this.order = res;
this.formatOrder(res, false);
} else {
this.getOderDetail();
}
},
onShow() {
},
onPullDownRefresh() {
this.getOderDetail();
uni.stopPullDownRefresh();
}
};
</script>
<style>
.example-body {
padding: 10px;
padding-top: 0;
}
.custom-image-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: space-between;
align-items: center;
}
.uni-form-item .title {
width: 150rpx;
text-align: justify;
text-align-last: justify;
}
.text {
font-size: 14px;
color: #333;
}
.btn[size='mini'] {
margin-right: 10rpx;
margin-top: 10rpx;
}
.btn-success {
background-color: #42b983;
color: #fff;
}
.btn-warning {
background-color: #fc8105;
color: #fff;
}
.btn-danger {
background-color: #f00;
color: #fff;
}
.btn-primary {
background-color: #0095f6;
color: #fff;
}
.uni-input {
border: #bbb solid 1rpx;
}
/*调整下上传组件样式*/
.icon-add {
background-color: #bbb;
}
.file-image {
width: 128rpx;
height: 128rpx;
}
.file-image>image {
width: 128rpx;
height: 128rpx;
}
.help-block {
display: block;
width: 100%;
color: #f00;
font-size: 1rem;
line-height: 1rem;
margin: 1.5rem;
}
</style>

View File

@ -0,0 +1,517 @@
<template>
<view class="content">
<uni-notice-bar show-icon scrollable text="平台上新季,全路线大力优惠,欢迎来询!!!。" />
<view class="order-form">
<!-- 自定义表单校验 -->
<uni-forms ref="customForm" :rules="formRules" :modelValue="FormData">
<uni-section title="您要发运的车辆信息" type="line">
<uni-forms-item label="品牌车型" name="car_title">
<uni-easyinput type="text" v-model="FormData.car_title" placeholder="填写品牌车型" />
</uni-forms-item>
<uni-forms-item label="车牌号" name="car_no">
<uni-easyinput type="text" v-model="FormData.car_no" placeholder="无车牌时可填写车架号后六位" />
</uni-forms-item>
<text class="uniui-h6 help-block">无车牌时可填写车架号(至少后六位)</text>
<uni-forms-item label="是否临牌" name="isTempCarno">
<uni-data-checkbox v-model="FormData.isTempCarno" :multiple="false" :localdata="isTempCarno" />
</uni-forms-item>
<uni-forms-item label="车辆保价(万元)" required name="car_value">
<uni-easyinput type="number" v-model="FormData.car_value" placeholder="单位:万元;默认20" />
</uni-forms-item>
<uni-forms-item label="计划日期" name="plan_date">
<uni-datetime-picker type="date" return-type="timestamp" v-model="FormData.plan_date" />
</uni-forms-item>
</uni-section>
<uni-section title="从哪里出发 - 运到哪儿去" type="line">
<uni-forms-item label="出发省份" required name="start_province">
<uni-data-picker placeholder="请选择省份" popup-title="请选择出发省份" :localdata="provinces"
v-model="FormData.start_province">
</uni-data-picker>
</uni-forms-item>
<uni-forms-item label="始发城市" required name="start_city">
<uni-easyinput v-model="FormData.start_city" placeholder="请填写出发城市名称" />
</uni-forms-item>
<uni-forms-item label="目标省份" required name="aim_province">
<uni-data-picker placeholder="请选择省份" popup-title="请选择运达省份" :localdata="provinces"
v-model="FormData.aim_province">
</uni-data-picker>
</uni-forms-item>
<uni-forms-item label="目标城市" required name="aim_city">
<uni-easyinput v-model="FormData.aim_city" placeholder="请填写目标运达城市名称" />
</uni-forms-item>
</uni-section>
<uni-section title="联系信息" type="line">
<uni-forms-item label="您的姓名" name="from_name">
<uni-easyinput v-model="FormData.from_name" placeholder="请输入姓名" />
</uni-forms-item>
<uni-forms-item label="手机号" required name="from_mobile">
<uni-easyinput v-model="FormData.from_mobile" placeholder="请输入发车人电话" />
</uni-forms-item>
</uni-section>
<uni-forms-item label="备注" name="remark">
<uni-easyinput type="textarea" v-model="FormData.remark" placeholder="对运单做一些备注,比如 从哪里提车的;根据实际情况" />
</uni-forms-item>
</uni-forms>
<view class="button-group">
<button type="primary" size="mini" @click="formCheck('customForm')">确认提交</button>
<button type="default" size="mini" @click="draft">我再想想</button>
</view>
<uni-fab ref="fab" :pattern="pattern" :content="content" :horizontal="horizontal" :vertical="vertical"
:direction="direction" @trigger="trigger" @fabClick="fabClick" />
</view>
<uni-notice-bar
text="温馨提示: 请不要随车放置 贵重小件物品(如 眼镜\无线充电器\数据线\U盘\手表\Zipporr火机等)、精密仪器设备(如 电脑等)、易燃易爆物品,车内不得放置违规违禁物品(如 燃料油\火机\酒精\散装酒等),否则司机有权拒载、平台有权拒单。" />
<uni-notice-bar text="炎热天气,不要随车装运水果,一定会闷坏的。" />
<text class="uniui-h6 help-block"></text>
</view>
</template>
<script>
import province from '@/common/province.js';
import letter from '@/common/letter.js';
import carP from '@/common/car-p.js';
import config from "@/config/ctms.config.js";
import store from '@/store/index.js';
import utils from "@/utils/common.js";
import ctms from '@/apis/ctms/index.js';
export default {
data() {
return {
userinfo: {},
oid: 0, //源订单
order: {},
NotNew: 0, //是否不新增 0 否(更新订单) 1 是(增加订单)
FormData: {
start_province: '', //默认 460000
start_city: '',
aim_province: '', //默认 230000
aim_city: '',
date: '', //计划发运日期
plan_date: '2017-04-03', //计划发运日期
car_value: 20, //单位万。默认含20万运输险
car_title: '',
carno: '', //车牌/架号
isTempCarno: 0,
from_name: '',
from_mobile: '',
remark: ''
},
//悬浮按钮
horizontal: 'right',
vertical: 'bottom',
direction: 'vertical', //horizontal水平展开vertical垂直展开
pattern: {
color: '#7A7E83',
backgroundColor: '#fff',
selectedColor: '#007AFF',
buttonColor: '#fd8008',
iconColor: '#fff'
},
content: [{
iconPath: '/static/fab/c5.png',
selectedIconPath: '/static/fab/c5.png',
text: '草稿-5',
active: false,
diyfn: '5' //自定义添加的一个字段
},
{
iconPath: '/static/fab/c4.png',
selectedIconPath: '/static/fab/c4.png',
text: '草稿-4',
active: false,
diyfn: '4' //自定义添加的一个字段
},
{
iconPath: '/static/fab/c3.png',
selectedIconPath: '/static/fab/c3.png',
text: '草稿-3',
active: false,
diyfn: '3' //自定义添加的一个字段
},
{
iconPath: '/static/fab/c2.png',
selectedIconPath: '/static/fab/c2.png',
text: '草稿-2',
active: false,
diyfn: '2' //自定义添加的一个字段
},
{
iconPath: '/static/fab/c1.png',
selectedIconPath: '/static/fab/c1.png',
text: '草稿-1',
active: false,
diyfn: '1' //自定义添加的一个字段
},
{
iconPath: '/static/fab/draft.png',
selectedIconPath: '/static/fab/draft-active.png',
text: '保存草稿',
active: false,
diyfn: false
},
],
// 单选性别数据源
sexs: [{
text: '男',
value: 0
}, {
text: '女',
value: 1
}, {
text: '保密',
value: 2
}],
//默认省份数据
provinces: [{
value: '460000',
text: "海南省"
},
{
value: '340000',
text: "安徽"
}
],
//是否临牌
isTempCarno: [{
text: '否',
value: 0
}, {
text: '是',
value: 1
}],
// 自定义表单校验规则
formRules: {
start_province: {
rules: [{
required: true,
errorMessage: '出发省份不能为空'
}]
},
aim_province: {
rules: [{
required: true,
errorMessage: '运达省份不能为空'
}]
},
start_city: {
rules: [{
required: true,
errorMessage: '出发城市不能为空'
}]
},
aim_city: {
rules: [{
required: true,
errorMessage: '运达城市不能为空'
}]
},
mobile: {
rules: [{
required: true,
errorMessage: '请填写手机号'
}]
},
},
}
},
onLoad(o) {
// console.log(province.listByTitle['海南省']); //显示海南代码
// console.log(o);
if (o.oid) {
this.oid = o.oid;
}
if (o.NotNew) {
this.NotNew = true;
uni.setNavigationBarTitle({
title: '更新咨询'
})
}
var user = ctms.user.getInfo();
this.userinfo = {
...this.userinfo,
...user
}
this.FormData.from_mobile = user.mobile;
this.FormData.from_name = user.username;
this.provinces = province.listDatacom;
this.setDate();
},
onReady() {
// 设置自定义表单校验规则,必须在节点渲染完毕后执行
this.$refs.customForm.setRules(this.formRules)
//取订单详情,如果有的话
if (this.oid) {
if (!this.getOderDetail(true)) this.getOderDetail(false);
}
},
onShow: function() {
},
onHide() {
this.draft(null); //界面隐藏时自动保存草稿
},
methods: {
//设置日期
setDate: function() {
var _that = this;
var timestamp = this.order.date ? this.order.date * 1000 : Date.now() + 7 * 24 * 3600 * 1000;
var time = new Date(timestamp);
var date = time.getFullYear() + '-' + (time.getMonth() + 1) + '-' + time.getDate();
_that.FormData.plan_date = date;
},
// 获取订单详情
getOderDetail: function(cache = null) {
/* cache 是否读取缓存 */
var _that = this;
return ctms.orderpre.detail(this.oid, cache).then((res) => {
if (res) {
if (!_that.NotNew) {
delete res['id']; //是新建而不是更新删除ID
}
_that.order = res;
_that.FormData = {
..._that.FormData,
..._that.order
};
_that.setDate()
return true;
} else {
return false;
}
});
},
//表单校验
formCheck(ref) {
this.$refs[ref].validate().then(res => {
// utils.debug(res);
this.formSubmit();
}).catch(err => {
utils.debug(err);
uni.showToast({
icon: 'error',
title: err['0'].errorMessage
})
})
},
formSubmit: function(e) {
uni.showLoading({
title: '网络请求中'
})
var FormData,
_that = this;
if (e) {
//直接使用表单内建的提交机制
// uitls.debug('form发生了submit事件携带数据为' + JSON.stringify(e.detail.value))
FormData = e.detail.value;
} else {
FormData = _that.FormData;
}
ctms.orderpre.create(FormData).then(
function(res) {
if (res) {
var oid = res.data.id;
ctms.orderpre.delDetail(oid)
uni.showModal({
title: '提交成功',
content: '是否前往查看详情',
success: function(res) {
//清空本次缓存,避免用户重复提交
ctms.orderpre.delDraft()
if (res.confirm) {
uni.navigateTo({
url: '../detail/detail?oid=' + oid
});
} else if (res.cancel) {
//重新载入页面
uni.redirectTo({
url: 'create'
});
}
}
})
} else {
uni.showToast({
title: "操作失败",
icon: "error"
});
}
}
);
uni.hideLoading();
},
//存储与取用草稿
/*TD草稿逻辑
当前页面正在录入的内容,视为默认草稿数据,即时更新、主动保存;
索引-1~5追加应用模板草稿或设置当前草稿为对应模板后期考虑加入固定模板
*/
draft(e) {
//e是索引后缀
ctms.orderpre.draft(this.FormData, e)
if (e !== null) {
uni.showToast({
title: '草稿已保存'
})
}
},
useDraft(e, data = null) {
var _that = this;
//e为缓存索引
uni.showModal({
title: '覆盖提醒',
content: '即将应用该草稿中的临时数据',
success: function(res) {
if (res.confirm) {
if (data) {
_that.FormData = data;
} else {
_that.FormData = ctms.orderpre.getDraft(e)
}
} else if (res.cancel) {
}
}
})
},
//浮窗按钮相关操作
fabClick(e) {
// utils.debug('点击了悬浮按钮')
},
trigger(e) {
//检查是否存在模板,有则提示应用,无则创建保存
var eindex = e.index;
this.content[e.index].active = !e.item.active;
var hasDraft = false;
if (!e.item.diyfn) {
//未设置这个difyfn字段的是“保存草稿”按钮
return this.draft();
}
var index = e.item.diyfn;
var res = ctms.orderpre.getDraft(index)
var _that = this;
if (!res) {
//该按钮对应的缓存不存在,追加模板
return uni.showModal({
title: '提示',
content: `${e.item.text}对应的草稿不存在,创建吗?`,
success: function(res) {
if (res.confirm) {
_that.content[e.index].active = true;
_that.draft(e.item.diyfn);
} else if (res.cancel) {
uni.showToast({
icon: 'error',
title: '操作已取消'
});
}
}
});
}
//缓存存在
return this.useDraft(e.item.diyfn, res);
}
}
}
</script>
<style>
.container {
/* #ifndef APP-NVUE */
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
/* #endif */
}
.order-form {
padding: 15px;
background-color: #fff;
}
.segmented-control {
margin-bottom: 15px;
}
.button-group {
margin-top: 15px;
display: flex;
justify-content: space-around;
}
.form-item {
display: flex;
align-items: center;
}
.button {
display: flex;
align-items: center;
height: 35px;
margin-left: 10px;
}
/*级联选择器*/
.data-pickerview {
height: 400px;
border: 1px #e5e5e5 solid;
}
.popper__arrow {
top: -6px;
left: 50%;
margin-right: 3px;
border-top-width: 0;
border-bottom-color: #EBEEF5;
}
.popper__arrow {
top: -6px;
left: 50%;
margin-right: 3px;
border-top-width: 0;
border-bottom-color: #EBEEF5;
}
/*自定义样式*/
.help-block {
display: block;
width: 100%;
color: #666666;
font-size: 0.8rem;
line-height: 1rem;
text-align: justify;
text-align-last: justify;
}
.uni-section {
margin-top: 0;
}
</style>

View File

@ -0,0 +1,50 @@
.container {
overflow: hidden;
}
.custom-cover {
flex: 1;
flex-direction: row;
position: relative;
}
.cover-content {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background-color: rgba($color: #000000, $alpha: 0.4);
display: flex;
flex-direction: row;
align-items: center;
padding-left: 15px;
font-size: 14px;
color: #fff;
}
.card-actions {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
height: 45px;
border-top: 1px #eee solid;
}
.card-actions-item {
display: flex;
flex-direction: row;
align-items: center;
}
.card-actions-item-text {
font-size: 12px;
color: #666;
margin-left: 5px;
}
.cover-image {
flex: 1;
height: 150px;
}
.no-border {
border-width: 0;
}

View File

@ -0,0 +1,152 @@
<template>
<view class="container">
<uni-section title="基础信息" type="line">
<uni-card :is-shadow="false">
<view class="uni-body">
<view>车辆{{order.car_title}} -- {{order.car_no}}</view>
<view>计划日期{{order.date_plan}}</view>
<view>起运地{{order.from_province}}-{{order.start_city}} =>
目的地{{order.to_province}}-{{order.aim_city}}</view>
</view>
</uni-card>
</uni-section>
<uni-section title="联系信息" type="line">
<uni-card :is-shadow="false">
<view class="uni-body">
<view>
联系人{{order.from_name}}
</view>
<view>
联系电话{{order.from_mobile}}
</view>
<view>
接待员{{order.receptionist}}
</view>
</view>
</uni-card>
</uni-section>
<uni-section title="费用信息" type="line">
<uni-card :is-shadow="false">
<view class="uni-body">
<view>{{order.price}} </view>
</view>
</uni-card>
</uni-section>
<uni-section title="我的备注" type="line">
<uni-card :is-shadow="false">
<view class="uni-body">
<view>{{order.remark}} </view>
</view>
</uni-card>
</uni-section>
<uni-section title="操作提示" type="line">
<uni-card :is-shadow="false">
<view class="uni-body">
<view>详情页首次打开时需要联网搜索运单信息</view>
<view>打开过一次的运单信息将会缓存在APP内一段时间在这期间即使手机没有网络也能查看</view>
<view>如果需要查看该运单的最新信息可通过下拉本页面进行刷新手机需要联网</view>
</view>
</uni-card>
</uni-section>
</view>
</template>
<script>
import config from "@/config/ctms.config.js";
import ctms from '@/apis/ctms/index.js';
export default {
data() {
return {
userinfo: {},
oid: 0,
order: {
id: 1,
car_id: 1,
car_number: '车牌号',
car_title: '车型号',
start_city: "起运城市",
from_province: '起运省份',
aim_city: "目的城市",
to_province: '目标省份',
signdate: '下单日期',
car_extra: '随车物品',
checker: '验车人',
receiver_name: '收车人姓名',
receiver_mobiles: '收车人电话',
sender_name: '发车人姓名',
sender_mobiles: '发车人电话',
},
h5_url: '',
}
},
methods: {
getOderDetail: function(cache = null) {
/* cache 是否读取缓存 */
var _that = this;
return ctms.orderpre.detail(this.oid, cache).then((res) => {
if (res) {
_that.order = res;
uni.showToast({
title: "查询完成!",
icon: "success"
});
uni.stopPullDownRefresh();
return true;
} else {
return false;
}
});
},
callTo(tel) {
uni.makePhoneCall({
phoneNumber: tel
})
}
},
onLoad(option) {
this.oid = option.oid;
if (!this.getOderDetail(true)) this.getOderDetail(false);
},
onShow: function() {
},
onPullDownRefresh() {
this.getOderDetail();
uni.stopPullDownRefresh();
},
//标题栏按钮响应,仅在APP-PLUS下支持
onNavigationBarButtonTap(e) {
//#ifdef APP-PLUS
uni.shareWithSystem({
summary: '运单【 ' + this.order.sn + ' 】摘要:' + this.order.signdate + ',由' + this.order
.from_province + this.order.start_city + '-->发往-->' + this.order.to_province + this.order
.aim_city + "的车辆:" + this.order.car_title + "--" + this.order.car_number + "。点击链接可查阅更多信息",
href: this.h5_url + "?oid=" + this.oid,
success() {
// 分享完成,请注意此时不一定是成功分享
},
fail() {
// 分享失败
}
})
//#endif
//#ifdef H5
var summary = '运单【 ' + this.order.sn + ' 】摘要:' + this.order.signdate + ',由' + this.order
.from_province + this.order.start_city + '-->发往-->' + this.order.to_province + this.order
.aim_city + "的车辆:" + this.order.car_title + "--" + this.order.car_number + "。点击链接可查阅更多信息:" + this
.h5_url + "?oid=" + this.oid;
uni.setClipboardData({
data: summary
})
//#endif
}
}
</script>
<style>
@import url("detail.css");
</style>

View File

@ -0,0 +1,54 @@
.container {
overflow: hidden;
}
.custom-cover {
flex: 1;
flex-direction: row;
position: relative;
}
.cover-content {
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 40px;
background-color: rgba($color: #000000, $alpha: 0.4);
display: flex;
flex-direction: row;
align-items: center;
padding-left: 15px;
font-size: 14px;
color: #fff;
}
.card-actions {
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
height: 45px;
border-top: 1px #eee solid;
}
.card-actions-item {
display: flex;
flex-direction: row;
align-items: center;
}
.card-actions-item-text {
font-size: 12px;
color: #666;
margin-left: 5px;
}
.cover-image {
flex: 1;
height: 150px;
}
.no-border {
border-width: 0;
}
.pagination{
margin:20px 20px;
}

View File

@ -0,0 +1,239 @@
<template>
<view class="container">
<uni-card v-if="!totalCount" title="查询结果" sub-title="" extra="" padding="10px 0">
<view class="uni-body uni-mt-5">
<view>
<text>没有查询到相关询价记录</text>
</view>
</view>
</uni-card>
<uni-section v-else :title="'询价单'+order.id" type="line" v-for="(order, index) in orders" :data-oid="order.id"
:key="index">
<uni-card title="基础卡片" sub-title="副标题" extra="额外信息" padding="10px 0">
<template v-slot:title>
<uni-list>
<uni-list-item :show-switch="false" :title="order.car_title + ' ' + order.car_no" />
</uni-list>
</template>
<view class="uni-body uni-mt-5">
<view>
<text>计划日期{{order.date_plan}}</text>
</view>
<view>
<text>起运地{{order.start_city}} => 目的地{{order.aim_city}}</text>
</view>
<view>
<text>价格{{order.price}} </text>
</view>
<view>
<text>状态{{order.status}} </text>
</view>
</view>
<view slot="actions" class="card-actions">
<view class="card-actions-item" @click="actionsCancel(order.id,index)" v-if="order.status_code>-1">
<uni-icons type="refresh-filled" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">取消</text>
</view>
<view class="card-actions-item" @click="actionsUpdate(order.id)">
<uni-icons type="compose" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">更新咨询</text>
</view>
<view class="card-actions-item" @click="actionsDetail(order.id)">
<uni-icons type="link" size="18" color="#999"></uni-icons>
<text class="card-actions-item-text">详情</text>
</view>
</view>
</uni-card>
</uni-section>
<view class="pagination">
<uni-pagination :show-icon="false" :total="totalCount" :pageSize='psize' v-model='page' title="分页栏"
@change="newPage" />
</view>
<uni-fab ref="fab" :pattern="fabs.pattern" :content="fabs.content" :horizontal="fabs.horizontal"
:vertical="fabs.vertical" :direction="fabs.direction" @trigger="fabTrigger" @fabClick="fabClick" />
</view>
</template>
<script>
import utils from "@/utils/common.js";
import ctms from '@/apis/ctms/index.js';
export default {
data() {
return {
userinfo: {},
orders: {},
totalCount: 0, //一共多少条数据
psize: 10,
page: 1,
//悬浮按钮
fabs: {
horizontal: 'left',
vertical: 'bottom',
direction: 'horizontal', //horizontal水平展开vertical垂直展开
pattern: {
color: '#7A7E83',
backgroundColor: '#fff',
selectedColor: '#007AFF',
buttonColor: '#fff',
iconColor: '#aaa'
},
content: [{
iconPath: '/static/fab/home.png',
selectedIconPath: '/static/fab/homeactive.png',
text: '首页',
active: false,
diyfn: 'home'
},
{
iconPath: '/static/fab/guanzhu.png',
selectedIconPath: '/static/fab/guanzhuactive.png',
text: '关注',
active: false,
diyfn: 'news'
},
{
iconPath: '/static/fab/me.png',
selectedIconPath: '/static/fab/meactive.png',
text: '用户',
active: false,
diyfn: 'user'
},
{
iconPath: '/static/fab/news.png',
selectedIconPath: '/static/fab/newsactive.png',
text: '公告',
active: false,
diyfn: 'notice'
}
]
}
}
},
methods: {
checkLogin() {
return ctms.user.getInfo();
},
actionsCancel(e, i) {
var _that = this;
return ctms.orderpre.cancel(e).then((res) => {
if (res) {
_that.orders[i].status_code = res.status_code;
uni.showToast({
title: "已取消",
icon: "success"
});
}
});
},
actionsDetail(e) {
uni.navigateTo({
url: '../detail/detail?oid=' + e
})
},
actionsUpdate(e) {
uni.navigateTo({
url: '../create/create?oid=' + e + '&NotNew=1'
})
},
//分页器动作
newPage(e) {
var page = e.current;
this.page = page;
var res = ctms.orderpre.list(this.page);
if (res) {
this.orders = res.orders;
} else {
this.checkOrder();
}
},
//刷新列表
checkOrder() {
var _that = this;
ctms.orderpre.list(null, this.page, this.psize).then(
function(res) {
if (res) {
_that.orders = res.orders;
_that.totalCount = res.total;
uni.showToast({
title: "查询完成!",
icon: "success"
});
} else {
_that.orders = {}
_that.totalCount = 0;
}
}
);
},
//浮窗按钮相关操作
fabClick(e) {
// utils.debug('点击了悬浮按钮')
},
fabTrigger(e) {
var eindex = e.index;
this.fabs.content[e.index].active = !e.item.active;
if (!e.item.diyfn) {
//未设置这个difyfn字段的无操作
return false;
}
var diyfn = e.item.diyfn,
dir = config.pageDir,
page;
switch (diyfn) {
case 'home':
page = 'tabbar/index/index';
return uni.reLaunch({
url: dir + page
})
break;
case 'news':
page = 'news/list/list';
break;
case 'user':
page = 'me/index';
break;
case 'notice':
page = 'tabbar/notice/index';
return uni.reLaunch({
url: dir + page
})
break;
}
return uni.navigateTo({
url: dir + page
})
}
},
onLoad() {
// this.checkLogin();
// utils.debug('询价记录列表页启动')
this.checkOrder()
},
onShow() {
},
onPullDownRefresh() {
this.page = 1;
this.checkOrder();
setTimeout(() => {
uni.stopPullDownRefresh();
}, 3000);
}
}
</script>
<style>
@import url("list.css");
@import url("../../statusBar.css");
</style>

View File

@ -0,0 +1,21 @@
<template>
<view class="content">
功能正在开发中
</view>
</template>
<script>
export default {
data() {
return {};
}
};
</script>
<style>
.content {
text-align: center;
height: 400upx;
margin-top: 200upx;
}
</style>

166
pages/ctms/scan/scan.vue Normal file
View File

@ -0,0 +1,166 @@
<template>
<view class="content">
</view>
<view class="tabbar-box-wrap">
<view class="tabbar-box">
<view class="tabbar-box-item" @click="scan">
<image class="box-image" src="@/static/img/tabbar/more/scan.png" mode="aspectFit"></image>
<text class="explain">扫码</text>
</view>
</view>
</view>
</template>
<script>
import config from "@/config/ctms.config.js";
export default {
data() {
return {
active: false
};
},
onLoad() {
},
onShow() {
setTimeout(() => {
this.active = true;
}, 500);
},
onHide() {
this.active = false;
},
methods: {
goToPage(url) {
if (!url) return;
url = config.pageDir + url;
uni.navigateTo({
url
});
},
tel() {
uni.makePhoneCall({
phoneNumber: config.kfPhone
})
},
scan() {
console.log('开始扫码')
uni.scanCode({
scanType: ['barCode', 'qrCode'],
success(res) {
console.log('扫码结果', res);
}
})
}
}
};
</script>
<style lang="scss" scoped>
.content {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
/* #ifdef H5 */
height: calc(100vh - var(--window-bottom) - var(--window-top));
/* #endif */
/* #ifndef H5 */
height: 100vh;
/* #endif */
transition: opacity 0.3s;
background-image: url('@/static/logo.png');
background-size: 30%;
background-repeat: no-repeat;
background-position: center;
opacity: 0.5;
&.active {
opacity: 1;
}
}
/* 创建一个伪元素来覆盖整个元素,并设置透明度 */
.content::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
/* 设置白色半透明遮罩 */
z-index: -1;
}
.tabbar-box-wrap {
position: absolute;
width: 100%;
padding: 50upx;
box-sizing: border-box;
bottom: 0;
left: 0;
.tabbar-box {
position: relative;
display: flex;
width: 100%;
background: #fff;
border-radius: 20upx;
padding: 15upx 20upx;
box-sizing: border-box;
z-index: 2;
box-shadow: 0px 2px 5px 2px rgba(0, 0, 0, 0.1);
&:after {
content: '';
position: absolute;
bottom: -16upx;
left: 0;
right: 0;
margin: auto;
width: 50upx;
height: 50upx;
transform: rotate(45deg);
background: #fff;
z-index: 1;
box-shadow: 2px 2px 5px 1px rgba(0, 0, 0, 0.1);
border-radius: 2px;
}
&:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #ffffff;
border-radius: 20upx;
z-index: 2;
}
.tabbar-box-item {
// position: relative;
width: 100%;
z-index: 3;
margin: 10upx;
color: $uni-color-subtitle;
text-align: center;
font-size: $uni-font-size-base;
.box-image {
width: 100%;
height: $uni-img-size-lg;
}
}
}
}
</style>

15
pages/ctms/statusBar.css Normal file
View File

@ -0,0 +1,15 @@
/*导航条配置*/
.status_bar {
height: var(--status-bar-height);
width: 100%;
position: fixed;
z-index: 99;
top: 0;
left: 0;
}
/*使用导航条需要调整占用高度*/
.container,
page {
padding-top: 44rpx;
}

View File

@ -0,0 +1,148 @@
<template>
<view class="content">
<!-- 轮播图 -->
<view class="uni-margin-wrap">
<swiper class="swiper" circular indicator-dots="true" autoplay="true" interval="2000" duration="500">
<swiper-item v-for="(item, index) in banner" :key="index">
<view class="swiper-item" @click="clickBannerItem(item)" :data-link="item.link">
<image class="swiper-image" :src="item.image" mode="aspectFill" :draggable="true" />
</view>
</swiper-item>
</swiper>
</view>
<image class="logo" src="@/static/logo.png"></image>
<view class="text-area">
<text class="title">安邮车联</text>
</view>
<view class="text-area">
<text class="title">运车助手</text>
</view>
</view>
</template>
<script>
import ctms from '@/apis/ctms/index.js';
import utils from "@/utils/common.js";
export default {
data() {
return {
current: 0,
swiperDotIndex: 0,
banner: [{
image: '/static/img/banner/banner.jpg',
link: ""
}]
}
},
methods: {
clickBannerItem(item) {
if (item.link) {
var link = item.link;
uni.navigateTo({
url: "/pages/common/webview/index?url=" + link
})
}
},
changeSwiper(e) {
this.current = e.detail.current
},
getBanner() {
ctms.ads.banner().then((res) => {
var _data = res;
if (_data) {
this.banner = _data;
}
});
},
checkSplash() {
var ls = "splashShowed";
var a = uni.getStorageSync(ls);
if (!a) {
uni.navigateTo({
url: "/pages/index/index"
})
}
}
},
onLoad: function() {
this.checkSplash();
},
onShow: function() {
this.getBanner();
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
<style lang="scss">
.uni-margin-wrap {
width: 100%;
}
.uni-padding-wrap {
width: 550rpx;
padding: 0 100rpx;
}
/*轮播幻灯*/
.swiper {
height: 300rpx;
position: relative;
}
.swiper-list {
margin-top: 40rpx;
margin-bottom: 0;
}
.swiper-item {
width: 100%;
display: block;
height: 300rpx;
line-height: 300rpx;
text-align: center;
}
.swiper-image {
width: 100%;
height: 300rpx;
}
/*滑动区*/
.swiper-box {
height: 370rpx;
background: #fff;
margin-top: 20rpx;
}
.swiper-box .wx-swiper-dots.wx-swiper-dots-horizontal {
padding-bottom: 10rpx;
}
</style>

View File

@ -0,0 +1,264 @@
<template>
<view class="container">
<view class="about">
<view class="content">
<view class="qrcode">
<image src="@/static/logo.png"></image>
<text class="tip">{{userinfo.username}}</text>
</view>
<view class="desc">
{{config.about.slogan}}
</view>
<view class="uni-card">
<view class="uni-list">
<view class="uni-list-cell-divider">
</view>
<!-- #ifndef APP-PLUS -->
<navigator v-for="item in menus" :url="item.url" class="uni-list-cell"
hover-class="uni-list-cell-hover">
<view class="uni-list-cell-navigate uni-navigate-right">
{{item.title}}
</view>
</navigator>
<!-- #endif -->
<!-- #ifdef APP-PLUS -->
<view v-for="item in menus" class="uni-list-cell" hover-class="uni-list-cell-hover"
@click="go(item.url)">
<view class="uni-list-cell-navigate uni-navigate-right">
{{item.title}}
</view>
</view>
<!-- #endif -->
</view>
</view>
<!-- #ifdef APP-PLUS -->
<button type="primary" @click="share">分享</button>
<!-- #endif -->
</view>
<!-- #ifdef APP-PLUS -->
<view class="version">
当前版本{{version}}
</view>
<!-- #endif -->
</view>
</view>
</template>
<script>
import utils from "@/utils/common.js";
import config from "@/config/ctms.config.js";
import ctms from '@/apis/ctms/index.js';
export default {
data() {
return {
userinfo: {},
menus: {
// cloud: {
// title: '我的资料',
// url: '/uni_modules/uni-id-pages/pages/userinfo/userinfo'
// },
orderpre: {
title: '我的询价',
url: '../../orderpre/list/list'
},
order: {
title: '运单记录',
url: '../../order/list/list'
},
news: {
title: '资讯报道',
url: '../../news/list/list'
},
// yinsi: {
// title: '隐私协议',
// url: '/pages/uni-agree/uni-agree'
// },
about: {
title: '关于App',
url: '../../about/about'
},
login: {
title: '切换登陆',
url: '../../login/login'
}
},
version: '',
config: {}
}
},
onLoad() {
var configApp = getApp().globalData.config;
//使用扩展运算符合并对象
var _cfg = {
...configApp,
...config
};
this.config = _cfg;
this.version = _cfg.version;
},
onShow() {
this.userinfo = ctms.user.getInfo();
},
methods: {
// #ifdef APP-PLUS
save() {
uni.showActionSheet({
itemList: ['保存图片到相册'],
success: () => {
plus.gallery.save(
'https://public.hiluker.com/luker_fm2.png',
function() {
uni.showToast({
title: '保存成功',
icon: 'none'
});
},
function() {
uni.showToast({
title: '保存失败,请重试!',
icon: 'none'
});
});
}
});
},
share(e) {
var msg = "运车助手"
plus.share.sendWithSystem();
uni.shareWithSystem({
summary: "安邮车联运车平台,一个专门服务于汽车托运的系统,致力于推动轿运市场标准化、现代化发展。",
href: "http://ctms.hiluker.cn",
success() {
// 分享完成,请注意此时不一定是成功分享
},
fail() {
// 分享失败
}
})
},
// #endif
go(e) {
uni.navigateTo({
url: e
});
}
}
}
</script>
<style>
page,
view {
display: flex;
}
page {
min-height: 100%;
background-color: #FFFFFF;
}
image {
width: 360rpx;
height: 360rpx;
}
.about {
flex-direction: column;
flex: 1;
}
.content {
flex: 1;
padding: 30rpx;
flex-direction: column;
justify-content: center;
}
.qrcode {
display: flex;
align-items: center;
flex-direction: column;
}
.qrcode .tip {
margin-top: 20rpx;
}
.desc {
margin-top: 30rpx;
display: block;
}
.code {
color: #e96900;
background-color: #f8f8f8;
}
button {
width: 100%;
margin-top: 40rpx;
}
.version {
height: 80rpx;
line-height: 80rpx;
justify-content: center;
color: #ccc;
}
.source {
margin-top: 30rpx;
flex-direction: column;
}
.source-list {
flex-direction: column;
}
.link {
color: #007AFF;
}
.uni-list-cell-navigate {
position: unset;
}
navigator {
color: #000000;
}
.uni-navigator.uni-list-cell-navigate.uni-navigate-right:after {
font-family: uniicons;
content: '\e583';
position: relative;
right: 0.75rem;
top: 50%;
color: #bbb;
transform: translateY(-50%);
width: 15rpx;
height: 24rpx;
}
.uni-list .uni-list-cell:last-child::after {
height: 1px;
}
.uni-list-cell::after {
position: absolute;
z-index: 3;
right: 0;
bottom: 0;
left: 0.9375rem;
height: 1px;
content: '';
transform: scaleY(.5);
background-color: #c8c7cc;
}
</style>

View File

@ -0,0 +1,203 @@
<template>
<view class="content" :class="active">
</view>
<view class="tabbar-box-wrap">
<view class="tabbar-box">
<view class="tabbar-box-item" @click="goToPage('order/create/create')">
<image class="box-image" src="@/static/img/tabbar/more/edit.png" mode="aspectFit"></image>
<text class="explain">在线下单</text>
</view>
<view class="tabbar-box-item" @click="tel()">
<image class="box-image" src="@/static/img/tabbar/more/qa.png" mode="aspectFit"></image>
<text class="explain">电话沟通</text>
</view>
<!-- #ifdef APP -->
<!-- <view class="tabbar-box-item" @click="scan">
<image class="box-image" src="@/static/img/tabbar/more/scan.png" mode="aspectFit"></image>
<text class="explain">扫码</text>
</view> -->
<!-- #endif -->
<view class="tabbar-box-item" @click="goToPage('orderpre/create/create')">
<image class="box-image" src="@/static/img/tabbar/more/search.png" mode="aspectFit"></image>
<text class="explain">询问价格</text>
</view>
</view>
</view>
</template>
<script>
import config from "@/config/ctms.config.js";
import hi from '@/common/util.js';
export default {
data() {
return {
active: false
};
},
onLoad() {},
onShow() {
// setTimeout(() => {
this.active = true;
// }, 500);
},
onHide() {
this.active = false;
},
methods: {
goToPage(url) {
if (!url) return;
url = config.pageDir + url;
uni.navigateTo({
url
});
},
tel() {
var phone = config.kfPhone;
// hi.tel(phone);
uni.makePhoneCall({
phoneNumber: phone
})
},
//扫码
scan() {
var _that = this;
uni.scanCode({
scanType: ['barCode', 'qrCode'],
success(res) {
console.log('扫码结果', res);
_that.scanRes(res);
},
fail() {
uni.showToast({
title: '扫码错误'
})
}
})
},
//扫码结果处理
scanRes(res) {
var _r = res.result;
//'https://u.wechat.com/ME4no24MU8DO0ark5TS5PEc' 微信个人二维码
// https://w.url.cn/s/AKB4Eje?cak=GvVLZD6AkOhHn_usbiFQxQ 微信发票二维码
// https://qr.4pyun.com/discount?token=5381321504173D00AD1866439E6A39D6 瑞都停车场优惠券二维码
var _path = res.path; //二维码携带的路径
///storage/emulated/0/Android/data/cn.hiluker.ctmsclient/apps/__UNI__B63B6BD/doc/uniapp_temp/compressed/1722789622562_mmexport1722789546405.jpg
if (_r.substring(0, 4) === 'http') {
console.log('应该跳转', _r)
uni.navigateTo({
url: '/pages/common/webview/index?url=' + _r,
});
}
}
}
};
</script>
<style lang="scss" scoped>
.content {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
/* #ifdef H5 */
height: calc(100vh - var(--window-bottom) - var(--window-top));
/* #endif */
/* #ifndef H5 */
height: 100vh;
/* #endif */
transition: opacity 0.3s;
background-image: url('@/static/logo.png');
background-size: 30%;
background-repeat: no-repeat;
background-position: center;
opacity: 0.5;
&.active {
opacity: 1;
}
}
/* 创建一个伪元素来覆盖整个元素,并设置透明度 */
.content::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
/* 设置白色半透明遮罩 */
z-index: -1;
}
.tabbar-box-wrap {
position: absolute;
width: 100%;
padding: 50upx;
box-sizing: border-box;
bottom: 0;
left: 0;
.tabbar-box {
position: relative;
display: flex;
width: 100%;
background: #fff;
border-radius: 20upx;
padding: 15upx 20upx;
box-sizing: border-box;
z-index: 2;
box-shadow: 0px 2px 5px 2px rgba(0, 0, 0, 0.1);
&:after {
content: '';
position: absolute;
bottom: -16upx;
left: 0;
right: 0;
margin: auto;
width: 50upx;
height: 50upx;
transform: rotate(45deg);
background: #fff;
z-index: 1;
box-shadow: 2px 2px 5px 1px rgba(0, 0, 0, 0.1);
border-radius: 2px;
}
&:before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #ffffff;
border-radius: 20upx;
z-index: 2;
}
.tabbar-box-item {
// position: relative;
width: 100%;
z-index: 3;
margin: 10upx;
color: $uni-color-subtitle;
text-align: center;
font-size: $uni-font-size-base;
.box-image {
width: 100%;
height: $uni-img-size-lg;
}
}
}
}
</style>

View File

@ -0,0 +1,83 @@
<template>
<view class="container">
<view v-if="!totalCount" class="content">
暂时没有消息通知
</view>
<uni-collapse v-else v-model="showIndexs">
<uni-collapse-item :name='"notice-"+index' :title='""+(index+1)+""+notice.title'
v-for="(notice,index) in notices" :data-nid="notice.id" :key="index" thumb="./static/logo.png">
<uni-list>
<uni-list-item :title="notice.content" :note="'更新于 : '+notice.updateTime"></uni-list-item>
</uni-list>
</uni-collapse-item>
</uni-collapse>
<view class="pagination">
<uni-pagination :show-icon="false" :total="totalCount" :pageSize='psize' v-model='page' title="分页栏"
@change="newPage" />
</view>
</view>
</template>
<script>
import utils from "@/utils/common.js";
import ctms from '@/apis/ctms/index.js';
export default {
data() {
return {
showIndexs: [],
notices: {},
totalCount: 0,
psize: 10,
page: 1
}
},
onLoad() {
this.checkNotice()
},
onPullDownRefresh() {
this.page = 1;
this.checkNotice();
setTimeout(() => {
uni.stopPullDownRefresh();
}, 3000);
},
methods: {
//刷新列表
checkNotice() {
var _that = this;
ctms.notice.list(this.page, this.psize).then(
function(res) {
if (res) {
_that.notices = res.notices;
for (var index in res.notices) {
if (res.notices[index]['is_show']) {
_that.showIndexs.push('notice-' + index);
}
}
_that.totalCount = res.total;
} else {
_that.orders = {}
_that.totalCount = 0;
}
}
);
},
//分页器动作
newPage(e) {
var page = e.current;
this.page = page;
this.checkNotice();
}
}
}
</script>
<style>
.content {
text-align: center;
height: 400upx;
margin-top: 200upx;
}
</style>

View File

@ -0,0 +1,211 @@
<template>
<view class="content">
<view class="uni-common-mt uni-form">
<form @submit="formSubmit" @reset="formReset">
<view class="uni-form-item ">
<view class="title">车牌号:</view>
<input class="uni-input" name="carno" v-model="search.carno"
:placeholder="'车牌号或车架号,如 '+demoCarno" />
</view>
<view class="uni-form-item ">
<view class="title">手机号:</view>
<input class="uni-input" name="phone" readonly="readonly" disabled="disabled" :value="search.phone"
type="text" placeholder="发车人或收车人的手机号" />
</view>
<view class="uni-form-item" v-if="false">
<view class="title">运单号:</view>
<input class="uni-input" name="ordersn" v-model="search.ordersn" type="text"
placeholder="完整的运单号码" />
</view>
<view class="uni-form-item">
<view class="help-block">
如果搜索不出结果可尝试检查一下搜索条件是否正确无误
</view>
</view>
<uni-notice-bar text="手机号为自动获取您登陆时使用的手机号,如果需要更换查询用的手机号,请退出账号并使用新手机号登陆."></uni-notice-bar>
<view class="uni-btn-v">
<button class="btn btn-success" form-type="submit">查询</button>
<button class="btn btn-error" type="default" @click="reset">重置</button>
</view>
</form>
</view>
</view>
</template>
<script>
import config from "@/config/ctms.config.js";
import store from '@/store/index.js';
import utils from "@/utils/common.js";
import ctms from '@/apis/ctms/index.js';
export default {
data() {
return {
userinfo: {},
search: {
carno: '',
phone: '',
ordersn: ''
},
demoCarno: config.demoCarno,
}
},
computed: {
},
methods: {
checkLogin() {
return ctms.user.checkLogin()
},
formSubmit: function(e) {
var _that = this;
// utils.debug('form发生了submit事件携带数据为' + JSON.stringify(e.detail.value))
//进行表单检查
var formData = e.detail.value;
ctms.order.search(formData).then(
function(res) {
if (res) {
uni.showToast({
title: "查询完成!",
icon: "success"
});
_that.goTo('order/list/list');
} else {
uni.showToast({
title: "查询结束,没有数据!",
icon: "success"
});
}
}
);
},
formReset: function(e) {
// utils.debug('清空数据')
},
reset: function() {
this.search = {};
this.search.phone = this.userinfo.mobile;
},
goTo(page) {
page = config.pageDir + page;
uni.navigateTo({
url: page
});
}
},
onLoad() {
var user = ctms.user.getInfo();
this.userinfo = user;
this.search.phone = user.mobile;
},
onShow: function() {}
}
</script>
<style>
body {
background-color: #e6e6e60e;
}
radio,
checkbox,
switch {
transform: scale(1.5);
margin-left: 1rem;
margin-right: 1rem;
margin-top: 36rpx;
}
input {
margin-left: 1rem;
margin-right: 1rem;
margin-top: 66rpx;
border-bottom: 1upx #333 dashed;
}
.uni-input {
padding: 0;
}
.content {
padding-bottom: 50rpx;
}
.header {
text-align: center;
}
.header>image {
width: 300rpx;
height: 300rpx;
}
.uni-form {
width: 94%;
margin: 0rpx 3% 0 3%;
}
.uni-form-item {
width: 100%;
display: inline-flex;
height: 96rpx;
line-height: 96rpx;
}
.uni-form-item .title,
.uni-form-item .data {}
/**不生效**/
.uni-form-item .title {
width: 150rpx;
padding: 40rpx 20rpx;
text-align: justify;
text-align-last: justify;
}
.uni-form .uni-btn-v {
margin-top: 50rpx;
}
.radio {
width: auto;
}
.btn {
margin: 40rpx 30rpx;
}
.btn-success {
background-color: #09BB07;
color: #fff;
}
.btn-error {
background-color: #fc0107;
color: #fff;
}
.footer {
display: block;
/* width: 100%; */
font-size: 1rem;
height: 1rem;
line-height: 1.5rem;
margin: 1.5rem;
}
.help-block {
display: block;
width: 100%;
color: #666666;
font-size: 0.8rem;
line-height: 1rem;
margin: 1.5rem;
}
</style>

167
pages/index/index.vue Normal file
View File

@ -0,0 +1,167 @@
<template>
<!-- 直接使用做好的开屏广告组件 -->
<!-- <m-start-ad :list="kaipingAds" /> -->
<view class="midTop">
<uni-badge class="rbt uni-badge-right-margin" :text="leftSecond" type="info" size="normal" absolute="rightTop"
:offset="[-3, -3]">
<view class="box" @click="timeup"><text class="box-text">点击<br>跳过</text></view>
</uni-badge>
</view>
<view class="uni-margin-wrap">
<swiper class="swiper" circular indicator-dots="true" autoplay="true" interval="2000" duration="500">
<swiper-item v-for="item in kaipingAds">
<view class="swiper-item">
<image :src="item"></image>
</view>
</swiper-item>
</swiper>
</view>
</template>
<script>
import ctms from '@/apis/ctms/index.js';
import config from '@/app.config.js';
export default {
data() {
return {
timer: null,
second: 6,
leftSecond: 0,
kaipingAds: {
0: "/static/img/kp/kp1.png"
},
ls: "splashShowed"
}
},
watch: {
// leftSecond(val) {
// if (val <= 0) {
// this.timeup()
// clearInterval(this.timer)
// }
// }
},
mounted() {
// let splashShowed = uni.getStorageSync(this.ls);
// if (splashShowed) {
// return this.timeup();
// }
// if (this.hasTabbar) {
// uni.hideTabBar()
// }
// const timer = setInterval(() => {
// if (this.leftSecond == 0) {
// clearInterval(this.timer)
// this.leftSecond = this.second;
// return this.timeup();
// }
// this.leftSecond--;
// }, 1000);
// this.timer = timer;
},
methods: {
timeup() {
//开屏倒计时结束,清除计时器
this.leftSecond = 0;
uni.setStorageSync(this.ls, true)
clearTimeout(this.timer)
var url = config.mainPage || "/pages/uni-starter/ucenter/ucenter"
uni.reLaunch({
url: url
})
},
getAds: function() {
ctms.ads.splash().then((res) => {
var _data = res;
if (_data) {
this.kaipingAds = _data;
}
});
}
},
onLoad: function() {
this.getAds();
if (config.isDebug) {
this.second = 60; //调试期间将时长设置为60秒
}
this.leftSecond = this.second;
let splashShowed = uni.getStorageSync(this.ls); //查看是否显示过开屏
if (splashShowed) {
return this.timeup();
}
if (this.hasTabbar) {
uni.hideTabBar()
}
const timer = setInterval(() => {
if (this.leftSecond == 0) {
clearInterval(this.timer)
this.leftSecond = this.second;
return this.timeup();
}
this.leftSecond--;
}, 1000);
this.timer = timer;
},
onUnload() {
clearInterval(this.timer)
}
}
</script>
<style>
.midTop {
position: fixed;
flex-direction: row;
text-align: center;
align-items: right;
justify-content: center;
z-index: 99;
}
.midTop .rbt {
position: fixed;
right: 100rpx;
top: 164rpx;
}
.box {
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
background-color: #00000050;
color: #fff;
font-size: 12px;
}
.box-text {
text-align: center;
color: #fff;
font-size: 12px;
}
/*———swiper———*/
.swiper {
height: 100vh;
}
.swiper-item {
display: block;
height: 100vh;
line-height: 10vh;
text-align: center;
}
.swiper-item>image {
height: 100vh;
}
.swiper-list {
margin-top: 0;
margin-bottom: 0;
}
</style>

View File

@ -0,0 +1,140 @@
<template>
<view class="page">
<view>
<text class="title">个人信息保护指引</text>
</view>
<view class="text-item">
<text class="tl">1.在浏览使用时,我们会收集、使用设备标识信息用于推荐。</text>
</view>
<view class="text-item">
<text class="tl">2.我们可能会申请位置权限,用于演示 uni-app 的地图、定位能力。</text>
</view>
<view class="text-item">
<text class="tl">3.你可以查看完整版</text>
</view>
<view class="text-item flex-r">
<text class="tl hl" @click="openprotocol">《用户协议》</text>
<text class="tl"> 和 </text>
<text class="tl hl" @click="openPrivacyPolicy">《隐私政策》</text>
</view>
<view class="text-item">
<text class="tl">以便了解我们收集、使用、共享、存储信息的情况,以及对信息的保护措施。</text>
</view>
<view class="text-item">
<text class="service">如果你同意请点击下面的按钮以接受我们的服务</text>
</view>
<view class="text-item confirm">
<button class="btn-privacy" type="primary" @click="agree">同意</button>
<button class="btn-privacy btn-disagree" @click="disagree">暂不使用</button>
</view>
<view class="exit-area">
</view>
</view>
</template>
<script>
import config from '@/app.config.js';
const {
about
} = config
export default {
data() {
return {}
},
onLoad() {
this._canBack = false;
},
onBackPress() {
return !this._canBack;
},
methods: {
openprotocol(e) {
uni.navigateTo({
url: "/pages/common/webview/index?url=" + about.agreements.serviceUrl
})
},
openPrivacyPolicy(e) {
uni.navigateTo({
url: "/pages/common/webview/index?url=" + about.agreements.privacyUrl
})
},
agree(e) {
uni.setStorageSync("userprotocol", 1);
this._canBack = true;
setTimeout(() => {
uni.navigateBack({
animationDuration: 0
});
}, 100)
},
disagree() {
// #ifdef APP-PLUS
plus.runtime.quit();
// #endif
// #ifdef H5
uni.showModal({
content: '确定退出本应用?',
cancelText: "退出",
confirmText: "取消",
success: (e) => {
if (!e.confirm) {
window.location.href = "about:blank";
window.close();
}
}
});
// #endif
}
}
}
</script>
<style>
.page {
padding: 80px 30px;
}
.title {
font-size: 18px;
line-height: 30px;
margin-bottom: 20px;
}
.flex-r {
flex-direction: row;
flex-wrap: wrap;
}
.text-item {
margin-bottom: 5px;
}
.tl {
font-size: 14px;
line-height: 20px;
}
.hl {
color: #007AFF;
}
.service {
font-size: 16px;
line-height: 20px;
margin-top: 20px;
}
.confirm {
margin-top: 50px;
flex-direction: row;
}
.btn-privacy {
flex: 1;
}
.btn-disagree {
margin-left: 20px;
}
</style>

View File

@ -0,0 +1,11 @@
export default function(){
console.log(uni.getSystemInfoSync().platform)
let userprotocol = uni.getStorageSync('userprotocol');
console.log('userprotocol',userprotocol);
if(!userprotocol){
uni.navigateTo({
url:'/pages/uni-agree/uni-agree',
animationType:"none"
})
}
}

View File

@ -0,0 +1,385 @@
<template>
<view class="article">
<!-- #ifdef APP-PLUS -->
<uni-nav-bar :statusBar="true" :border="false"></uni-nav-bar>
<!-- #endif -->
<view class="article-title">{{ title }}</view>
<unicloud-db v-slot:default="{data, loading, error, options}" :options="formData"
collection="uni-cms-articles,uni-id-users" :field="field" :getone="true" :where="where" :manual="true"
ref="detail" foreignKey="uni-cms-articles.user_id" @load="loadData">
<template v-if="!loading && data">
<uni-list :border="false">
<uni-list-item thumbSize="lg" :thumb="data.image">
<!-- 通过body插槽定义作者信息内容 -->
<template v-slot:body>
<view class="header-content">
<view class="uni-title">
{{data.user_id && data.user_id[0] && data.user_id[0].nickname || '未知'}}
</view>
</view>
</template>
<template v-slot:footer>
<view class="footer">
<view class="uni-note">更新于
<uni-dateformat :date="data.last_modify_date" format="yyyy-MM-dd hh:mm"
:threshold="[60000, 2592000000]" />
</view>
</view>
</template>
</uni-list-item>
</uni-list>
<view class="banner">
<!-- 文章开头缩略图 -->
<image class="banner-img" :src="data.thumbnail" mode="widthFix"></image>
<!-- 文章摘要 -->
<view class="banner-title">
<text class="uni-ellipsis">{{data.excerpt}}</text>
</view>
</view>
<view class="article-content">
<rich-text :nodes="data.content"></rich-text>
</view>
</template>
</unicloud-db>
</view>
</template>
<script>
// #ifdef APP
import UniShare from '@/uni_modules/uni-share/js_sdk/uni-share.js';
import uniNavBar from '@/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue';
const uniShare = new UniShare()
// #endif
const db = uniCloud.database();
const readNewsLog = db.collection('read-news-log')
export default {
// #ifdef APP
components: {
"uni-nav-bar": uniNavBar
},
onBackPress({
from
}) {
if (from == 'backbutton') {
if (uniShare.isShow) {
this.$nextTick(function() {
console.log(uniShare);
uniShare.hide()
})
}
return uniShare.isShow;
}
},
// #endif
data() {
return {
// 当前显示 _id
id: "",
title: 'title',
// 数据表名
// 查询字段,多个字段用 , 分割
field: 'user_id.nickname,user_id._id,avatar,excerpt,last_modify_date,comment_count,like_count,title,content',
formData: {
noData: '<p style="text-align:center;color:#666">详情加载中...</p>'
}
}
},
computed: {
uniStarterConfig() {
return getApp().globalData.config
},
where() {
//拼接where条件 查询条件 ,更多详见 https://uniapp.dcloud.net.cn/uniCloud/unicloud-db?id=jsquery
return `_id =="${this.id}"`
}
},
onLoad(event) {
//获取真实新闻id通常 id 来自上一个页面
if (event.id) {
this.id = event.id
}
//若上一页传递了标题过来,则设置导航栏标题
if (event.title) {
this.title = event.title
uni.setNavigationBarTitle({
title: event.title
})
}
},
onReady() {
// 开始加载数据,修改 where 条件后才开始去加载 clinetDB 的数据 ,需要等组件渲染完毕后才开始执行 loadData所以不能再 onLoad 中执行
if (this.id) { // ID 不为空,则发起查询
this.$refs.detail.loadData()
} else {
uni.showToast({
icon: 'none',
title: this.$t('listDetail.newsErr')
})
}
},
onNavigationBarButtonTap(event) {
if (event.type == 'share') {
this.shareClick();
}
},
methods: {
$log(...args) {
console.log('args', ...args, this.id)
},
setReadNewsLog() {
let item = {
"article_id": this.id,
"last_time": Date.now()
},
readNewsLog = uni.getStorageSync('readNewsLog') || [],
index = -1;
readNewsLog.forEach(({
article_id
}, i) => {
if (article_id == item.article_id) {
index = i
}
})
if (index === -1) {
readNewsLog.push(item)
} else {
readNewsLog.splice(index, 1, item)
}
uni.setStorageSync('readNewsLog', readNewsLog)
console.log(readNewsLog);
},
setFavorite() {
if (uniCloud.getCurrentUserInfo().tokenExpired < Date.now()) {
return console.log('未登录用户');
}
let article_id = this.id,
last_time = Date.now();
console.log({
article_id,
last_time
});
readNewsLog.where(`"article_id" == "${article_id}" && "user_id"==$env.uid`)
.update({
last_time
})
.then(({
result: {
updated
}
}) => {
console.log('updated', updated);
if (!updated) {
readNewsLog.add({
article_id
}).then(e => {
console.log(e);
}).catch(err => {
console.log(err);
})
}
}).catch(err => {
console.log(err);
})
},
loadData(data) {
//如果上一页未传递标题过来(如搜索直达详情),则从新闻详情中读取标题
if (this.title == '' && data[0].title) {
this.title = data[0].title
uni.setNavigationBarTitle({
title: data[0].title
});
}
this.setReadNewsLog();
},
/**
* followClick
* 点击关注
*/
followClick() {
uni.showToast({
title: this.$t('listDetail.follow'),
icon: 'none'
});
},
/**
* 分享该文章
*/
// #ifdef APP
shareClick() {
let {
_id,
title,
excerpt,
avatar
} = this.$refs.detail.dataList
console.log(JSON.stringify({
_id,
title,
excerpt,
avatar
}));
uniShare.show({
content: { //公共的分享类型type、链接herf、标题title、summary描述、imageUrl缩略图
type: 0,
href: this.uniStarterConfig.h5.url +
`/#/pages/uni-starter/list/detail?id=${_id}&title=${title}`,
title: this.title,
summary: excerpt,
imageUrl: avatar +
'?x-oss-process=image/resize,m_fill,h_100,w_100' //压缩图片解决在ios端分享图过大导致的图片失效问题
},
menus: [{
"img": "/static/app-plus/sharemenu/wechatfriend.png",
"text": this.$t('common.wechatFriends'),
"share": {
"provider": "weixin",
"scene": "WXSceneSession"
}
},
{
"img": "/static/app-plus/sharemenu/wechatmoments.png",
"text": this.$t('common.wechatBbs'),
"share": {
"provider": "weixin",
"scene": "WXSceneTimeline"
}
},
{
"img": "/static/app-plus/sharemenu/mp_weixin.png",
"text": this.$t('common.wechatApplet'),
"share": {
provider: "weixin",
scene: "WXSceneSession",
type: 5,
miniProgram: {
id: this.uniStarterConfig.mp.weixin.id,
path: `/pages/uni-starter/list/detail?id=${_id}&title=${title}`,
webUrl: this.uniStarterConfig.h5.url +
`/#/pages/uni-starter/list/detail?id=${_id}&title=${title}`,
type: 0
},
}
},
{
"img": "/static/app-plus/sharemenu/weibo.png",
"text": this.$t('common.weibo'),
"share": {
"provider": "sinaweibo"
}
},
{
"img": "/static/app-plus/sharemenu/qq.png",
"text": "QQ",
"share": {
"provider": "qq"
}
},
{
"img": "/static/app-plus/sharemenu/copyurl.png",
"text": this.$t('common.copy'),
"share": "copyurl"
},
{
"img": "/static/app-plus/sharemenu/more.png",
"text": this.$t('common.more'),
"share": "shareSystem"
}
],
cancelText: this.$t('common.cancelShare'),
}, e => { //callback
console.log(e);
})
}
// #endif
}
}
</script>
<style scoped>
.header-content {
flex: 1;
display: flex;
flex-direction: column;
font-size: 14px;
}
/* 标题 */
.uni-title {
display: flex;
margin-bottom: 5px;
font-size: 14px;
font-weight: bold;
color: #3b4144;
}
/* 描述 额外文本 */
.uni-note {
color: #999;
font-size: 12px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
}
.footer {
display: flex;
align-items: center;
}
.footer-button {
display: flex;
align-items: center;
font-size: 12px;
height: 30px;
color: #fff;
background-color: #ff5a5f;
}
.banner {
position: relative;
margin: 0 15px;
height: 180px;
overflow: hidden;
}
.banner-img {
position: absolute;
width: 100%;
}
.banner-title {
display: flex;
align-items: center;
position: absolute;
padding: 0 15px;
width: 100%;
bottom: 0;
height: 30px;
font-size: 14px;
color: #fff;
background: rgba(0, 0, 0, 0.4);
overflow: hidden;
box-sizing: border-box;
}
.uni-ellipsis {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.article-title {
padding: 20px 15px;
padding-bottom: 0;
}
.article-content {
padding: 15px;
font-size: 15px;
overflow: hidden;
}
</style>

View File

@ -0,0 +1,256 @@
<template>
<view class="pages">
<!-- #ifndef H5 -->
<statusBar></statusBar>
<!-- #endif -->
<!-- 搜索功能 -->
<view class="uni-search-box">
<uni-search-bar v-model="keyword" ref="searchBar" radius="100" cancelButton="none" disabled
:placeholder="inputPlaceholder" />
<view class="cover-search-bar" @click="searchClick"></view>
</view>
<unicloud-db ref='udb' v-slot:default="{data,pagination,hasMore, loading, error, options}" @error="onqueryerror"
:collection="colList" :page-size="10">
<!-- 基于 uni-list 的页面布局 field="user_id.nickname"-->
<uni-list class="uni-list" :border="false" :style="{height:listHight}">
<!-- 作用于app端nvue页面的下拉加载 -->
<!-- #ifdef APP-NVUE -->
<refreshBox @refresh="refresh" :loading="loading"></refreshBox>
<!-- #endif -->
<!-- 列表渲染 -->
<uni-list-item :to="'./detail?id='+item._id+'&title='+item.title" v-for="(item,index) in data"
:key="index">
<!-- 通过header插槽定义列表左侧图片 -->
<template v-slot:header>
<image class="avatar" :src="item.avatar" mode="aspectFill"></image>
</template>
<!-- 通过body插槽定义布局 -->
<template v-slot:body>
<view class="main">
<text class="title">{{item.title}}</text>
<view class="info">
<text class="author">{{item.user_id[0]?item.user_id[0].nickname:''}}</text>
<uni-dateformat class="last_modify_date" :date="item.last_modify_date"
format="yyyy-MM-dd" :threshold="[60000, 2592000000]" />
</view>
</view>
</template>
</uni-list-item>
<!-- 加载状态:上拉加载更多,加载中,没有更多数据了,加载错误 -->
<!-- #ifdef APP-PLUS -->
<uni-list-item>
<template v-slot:body>
<!-- #endif -->
<uni-load-state @networkResume="refresh" :state="{data,pagination,hasMore, loading, error}"
@loadMore="loadMore">
</uni-load-state>
<!-- #ifdef APP-PLUS -->
</template>
</uni-list-item>
<!-- #endif -->
</uni-list>
</unicloud-db>
</view>
</template>
<script>
let cdbRef;
import statusBar from "@/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar";
import Gps from '@/uni_modules/json-gps/js_sdk/gps.js';
const gps = new Gps();
const db = uniCloud.database();
const articleDBName = 'opendb-news-articles';
const userDBName = 'uni-id-users';
export default {
components: {
statusBar,
},
computed: {
// 根据当前语言返回不同的搜索框占位符
inputPlaceholder(e) {
if (uni.getStorageSync('CURRENT_LANG') == "en") {
return 'Please enter the search content'
} else {
return '请输入搜索内容'
}
},
// 连表查询,返回两个集合的查询结果
colList() {
return [
db.collection(articleDBName).where(this.where).field('thumbnail,title,publish_date,user_id')
.getTemp(), // 文章集合
db.collection(userDBName).field('_id,nickname').getTemp() // 用户集合
]
}
},
data() {
return {
where: '"article_status" == 1',
keyword: "",
showRefresh: false,
listHight: 0
}
},
watch: {
keyword(keyword, oldValue) {
let where = '"article_status" == 1 '
if (keyword) {
this.where = where + `&& /${keyword}/.test(title)`;
} else {
this.where = where;
}
}
},
async onReady() {
// #ifdef APP-NVUE
/* 可用窗口高度 - 搜索框高 - 状态栏高 */
this.listHight = uni.getSystemInfoSync().windowHeight - uni.getSystemInfoSync().statusBarHeight - 50 +
'px';
// #endif
// #ifndef APP-NVUE
this.listHight = 'auto'
// #endif
cdbRef = this.$refs.udb
},
async onShow() {
this.keyword = getApp().globalData.searchText
getApp().globalData.searchText = ''
//这里仅演示如何在onShow生命周期获取设备位置并在设备或者应用没有权限时自动引导。设置完毕自动重新获取。
//你可以基于他做自己的业务,比如:根据距离由近到远排序列表数据等
// uni.showLoading({
// title:"获取定位中"
// });
//默认h5端不获取定位
// #ifndef H5
let location = await gps.getLocation({
geocode: true
})
// console.log(location);
// #endif
// if(location){
// uni.showToast({
// title: JSON.stringify(location),
// icon: 'none'
// });
// }
// uni.hideLoading()
},
methods: {
searchClick(e) { //点击搜索框
uni.hideKeyboard();
uni.navigateTo({
url: './search/search',
animationType: 'fade-in'
});
},
retry() {
this.refresh()
},
refresh() {
cdbRef.loadData({
clear: true
}, () => {
uni.stopPullDownRefresh()
// #ifdef APP-NVUE
this.showRefresh = false
// #endif
console.log('end');
})
console.log('refresh');
},
loadMore() {
cdbRef.loadMore()
},
onqueryerror(e) {
console.error(e);
},
onpullingdown(e) {
console.log(e);
this.showRefresh = true
if (e.pullingDistance > 100) {
this.refresh()
}
}
},
// #ifndef APP-NVUE
onPullDownRefresh() {
this.refresh()
},
onReachBottom() {
this.loadMore()
}
// #endif
}
</script>
<style scoped>
/* #ifndef APP-NVUE */
view {
display: flex;
box-sizing: border-box;
flex-direction: column;
}
/* #endif */
.pages {
background-color: #FFFFFF;
}
.avatar {
width: 200rpx;
height: 200rpx;
margin-right: 10rpx;
}
.main {
justify-content: space-between;
flex: 1;
}
.title {
font-size: 16px;
}
.info {
flex-direction: row;
justify-content: space-between;
}
.author,
.last_modify_date {
font-size: 14px;
color: #999999;
}
.uni-search-box {
background-color: #FFFFFF;
position: sticky;
height: 50px;
top: 0;
left: 0;
/* #ifndef APP-PLUS */
z-index: 9;
/* #endif */
/* #ifdef MP-WEIXIN */
width: 580rpx;
/* #endif */
}
.cover-search-bar {
height: 50px;
position: relative;
top: -50px;
margin-bottom: -50px;
/* #ifndef APP-NVUE */
z-index: 999;
/* #endif */
}
</style>

View File

@ -0,0 +1,505 @@
<template>
<view class="container">
<view class="search-container">
<!-- 搜索框 -->
<view class="search-container-bar">
<!-- #ifdef APP-PLUS -->
<uni-icons class="search-icons" :color="iconColor" size="22" type="mic-filled" @click="speech" />
<!-- #endif -->
<!-- :cancelText="keyBoardPopup ? '取消' : '搜索'" -->
<uni-search-bar ref="searchBar" style="flex:1;" radius="100" v-model="searchText" :focus="focus" :placeholder="hotWorld"
clearButton="auto" cancelButton="always" @clear="clear" @confirm="confirm" @cancel="cancel" />
</view>
</view>
<view class="search-body">
<!-- 搜索历史 -->
<view class="word-container" v-if="localSearchList.length">
<view class="word-container_header">
<text class="word-container_header-text">搜索历史</text>
<uni-icons v-if="!localSearchListDel" @click="localSearchListDel = true" class="search-icons" style="padding-right: 0;"
:color="iconColor" size="18" type="trash"></uni-icons>
<view v-else class="flex-center flex-row" style="font-weight: 500;justify-content: space-between;">
<text style="font-size: 22rpx;color: #666;padding-top:4rpx;padding-bottom:4rpx;padding-right:20rpx;" @click="LocalSearchListClear">全部删除</text>
<text style="font-size: 22rpx;color: #c0402b;padding-top:4rpx;padding-bottom:4rpx;padding-left:20rpx;" @click="localSearchListDel = false">完成</text>
</view>
</view>
<view class="word-container_body">
<view class="flex-center flex-row word-container_body-text" v-for="(word,index) in localSearchList" :key="index"
@click="LocalSearchlistItemClick(word,index)">
<text class="word-display" :key="word">{{word}}</text>
<uni-icons v-if="localSearchListDel" size="12" type="closeempty" />
</view>
</view>
</view>
<!-- 搜索发现 -->
<view class="word-container">
<view class="word-container_header">
<view class="flex-center flex-row">
<text class="word-container_header-text">搜索发现</text>
<uni-icons v-if="!netHotListIsHide" class="search-icons" :color="iconColor" size="14" type="reload" @click="searchHotRefresh"></uni-icons>
</view>
<uni-icons class="search-icons" style="padding-right: 0;" :color="iconColor" size="18" :type="netHotListIsHide ? 'eye-slash' : 'eye'"
@click="netHotListIsHide = !netHotListIsHide"></uni-icons>
</view>
<unicloud-db ref="udb" #default="{data, loading, error, options}" field="content" collection="opendb-search-hot"
orderby="create_date desc,count desc" page-data="replace" :page-size="10">
<text v-if="loading && !netHotListIsHide" class="word-container_body-info">正在加载...</text>
<view v-else class="word-container_body">
<template v-if="!netHotListIsHide">
<text v-if="error" class="word-container_body-info">{{error.message}}</text>
<template v-else>
<text v-for="(word,index) in data" class="word-container_body-text" :key="index" @click="search(word.content)">{{word.content}}</text>
</template>
</template>
<view v-else style="flex:1;">
<text class="word-container_body-info">当前搜索发现已隐藏</text>
</view>
</view>
</unicloud-db>
</view>
</view>
<!-- 搜索联想 -->
<view class="search-associative" v-if="associativeShow">
<uni-list>
<uni-list-item v-for="(item,index) in associativeList" :key="item._id" :ellipsis="1" :title="item.name" @click="associativeClick(item)" show-extra-icon
clickable :extra-icon="{size:18,color:iconColor,type:'search'}" >
</uni-list-item>
</uni-list>
</view>
</view>
</template>
<script>
/**
* 云端一体搜索模板
* @description uniCloud云端一体搜索模板自带下拉候选、历史搜索、热搜。无需再开发服务器代码
*/
const searchLogDbName = 'opendb-search-log'; // 搜索记录数据库
const mallGoodsDbName = 'opendb-news-articles'; // 文章数据库
const associativeSearchField = 'title'; // 联想时,搜索框值检索数据库字段名
const associativeField = '_id,title'; // 联想列表每一项携带的字段
const localSearchListKey = '__local_search_history'; // 本地历史存储字段名
// 数组去重
const arrUnique = arr => {
for (let i = arr.length - 1; i >= 0; i--) {
const curIndex = arr.indexOf(arr[i]);
const lastIndex = arr.lastIndexOf(arr[i])
curIndex != lastIndex && arr.splice(lastIndex, 1)
}
return arr
} // 节流
// 防抖
function debounce(fn, interval, isFirstAutoRun) {
/**
*
* @param {要执行的函数} fn
* @param {在操作多长时间后可再执行,第一次立即执行} interval
*/
var _self = fn;
var timer = null;
var first = true;
if (isFirstAutoRun) {
_self();
}
return function() {
var args = arguments;
var _me = this;
if (first) {
first = false;
_self.apply(_me, args);
}
if (timer) {
clearTimeout(timer)
// return false;
}
timer = setTimeout(function() {
clearTimeout(timer);
timer = null;
_self.apply(_me, args);
}, interval || 200);
}
}
export default {
data() {
return {
mallGoodsDbName,
searchLogDbName,
statusBarHeight:'0px',
localSearchList: uni.getStorageSync(localSearchListKey),
localSearchListDel: false,
netHotListIsHide: false,
searchText: '',
iconColor: '#999999',
associativeList: [],
keyBoardPopup: false,
hotWorld: 'DCloud', // 搜索热词,如果没有输入即回车,则搜索热词,但是不会加入搜索记录
focus: true, // 是否自动聚焦
speechEngine: 'iFly' // 语音识别引擎 iFly 讯飞 baidu 百度
}
},
created() {
this.db = uniCloud.database();
this.searchLogDb = this.db.collection(this.searchLogDbName);
this.mallGoodsDb = this.db.collection(this.mallGoodsDbName);
// #ifndef H5
uni.onKeyboardHeightChange((res) => {
this.keyBoardPopup = res.height !== 0;
})
// #endif
this.searchText = getApp().globalData.searchText;
},
computed: {
associativeShow() {
return this.searchText && this.associativeList.length;
}
},
onLoad() {
//#ifdef APP-PLUS
this.statusBarHeight = `${uni.getSystemInfoSync().statusBarHeight}px`;
//#endif
},
methods: {
clear(res) {
console.log("res: ", res);
},
confirm(res) {
// 键盘确认
this.search(res.value);
},
cancel(res) {
uni.hideKeyboard();
this.searchText = '';
this.loadList();
},
search(value) {
if (!value && !this.hotWorld) {
return;
}
if (value) {
if (this.searchText !== value) {
this.searchText = value
}
this.localSearchListManage(value);
this.searchLogDbAdd(value)
} else if (this.hotWorld) {
this.searchText = this.hotWorld
}
uni.hideKeyboard();
this.loadList(this.searchText);
},
localSearchListManage(word) {
let list = uni.getStorageSync(localSearchListKey);
if (list.length) {
this.localSearchList.unshift(word);
arrUnique(this.localSearchList);
if (this.localSearchList.length > 10) {
this.localSearchList.pop();
}
} else {
this.localSearchList = [word];
}
uni.setStorageSync(localSearchListKey, this.localSearchList);
},
LocalSearchListClear() {
uni.showModal({
content: "确认清空搜索历史吗",
confirmText: "删除",
confirmColor: 'red',
cancelColor: '#808080',
success: res => {
if (res.confirm) {
this.localSearchListDel = false;
this.localSearchList = [];
uni.removeStorageSync(localSearchListKey)
}
}
});
},
LocalSearchlistItemClick(word, index) {
if (this.localSearchListDel) {
this.localSearchList.splice(index, 1);
uni.setStorageSync(localSearchListKey, this.localSearchList);
if (!this.localSearchList.length) {
this.localSearchListDel = false;
}
return;
}
this.search(word);
},
searchHotRefresh() {
this.$refs.udb.refresh();
},
speech() {
// #ifdef APP-PLUS
plus.speech.startRecognize({
engine: this.speechEngine,
punctuation: false, // 标点符号
timeout: 10000
}, word => {
word = word instanceof Array ? word[0] : word;
this.search(word)
}, err => {
console.error("语音识别错误: ", err);
});
// #endif
},
searchLogDbAdd(value) {
/*
在此处存搜索记录,如果登录则需要存 user_id若未登录则存device_id
*/
this.getDeviceId().then(device_id => {
this.searchLogDb.add({
// user_id: device_id,
device_id,
content: value,
create_date: Date.now()
})
})
},
getDeviceId() {
return new Promise((resolve, reject) => {
const uniId = uni.getStorageSync('uni_id');
if (!uniId) {
// #ifdef APP-PLUS
plus.device.getInfo({
success: (deviceInfo) => {
resolve(deviceInfo.uuid)
},
fail: () => {
resolve(uni.getSystemInfoSync().system + '_' + Math.random().toString(36).substr(2))
}
});
// #endif
// #ifndef APP-PLUS
resolve(uni.getSystemInfoSync().system + '_' + Math.random().toString(36).substr(2))
// #endif
} else {
resolve(uniId)
}
})
},
associativeClick(item) {
/**
* 注意:这里用户根据自己的业务需要,选择跳转的页面即可
*/
console.log("associativeClick: ", item);
this.loadList(item.title);
},
loadList(text = '') {
getApp().globalData.searchText = text;
uni.switchTab({
url:'/pages/list/list'
})
},
backPage(){
uni.navigateBack();
}
},
watch: {
searchText: debounce(function(value) {
if (value) {
this.mallGoodsDb.where({
[associativeSearchField]: new RegExp(value, 'gi'),
}).field(associativeField).get().then(res => {
this.associativeList = res.result.data;
})
} else {
this.associativeList.length = 0;
getApp().globalData.searchText = '';
}
}, 100)
}
}
</script>
<style>
/* #ifndef APP-NVUE */
page {
height: 100%;
flex: 1;
}
/* #endif */
</style>
<style lang="scss" scoped>
$search-bar-height:52px;
$word-container_header-height:72rpx;
.status-bar{
background-color: #fff;
}
.container {
/* #ifndef APP-NVUE */
height: 100%;
/* #endif */
flex: 1;
background-color: #f7f7f7;
}
.search-body {
background-color: #fff;
border-bottom-right-radius: 10px;
border-bottom-left-radius: 10px;
}
@mixin uni-flex {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
}
@mixin words-display {
font-size: 26rpx;
color: #666;
}
.flex-center {
@include uni-flex;
justify-content: center;
align-items: center;
}
.flex-row {
@include uni-flex;
flex-direction: row;
}
/* #ifdef APP-PLUS */
/* #ifndef APP-NVUE || VUE3*/
::v-deep
/* #endif */
.uni-searchbar {
padding-left: 0;
}
/* #endif */
/* #ifndef APP-NVUE || VUE3*/
::v-deep
/* #endif */
.uni-searchbar__box {
border-width: 0;
}
/* #ifndef APP-NVUE || VUE3 */
::v-deep
/* #endif */
.uni-input-placeholder {
font-size: 28rpx;
}
.search-container {
height: $search-bar-height;
@include uni-flex;
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
background-color: #fff;
@at-root {
#{&}-bar {
@include uni-flex;
flex-direction: row;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
right: 0;
}
}
}
.search-associative {
/* #ifndef APP-NVUE */
overflow-y: auto;
/* #endif */
position: absolute;
top: $search-bar-height;
left: 0;
right: 0;
bottom: 0;
background-color: #fff;
margin-top: 10rpx;
padding-left: 10rpx;
padding-right: 10rpx;
}
.search-icons {
padding: 16rpx;
}
.word-display {
@include words-display;
}
.word-container {
padding: 20rpx;
@at-root {
#{&}_header {
@include uni-flex;
height: $word-container_header-height;
line-height: $word-container_header-height;
flex-direction: row;
justify-content: space-between;
align-items: center;
@at-root {
#{&}-text {
color: #3e3e3e;
font-size: 30rpx;
font-weight: bold;
}
}
}
#{&}_body {
@include uni-flex;
flex-wrap: wrap;
flex-direction: row;
@at-root {
#{&}-text {
@include uni-flex;
@include words-display;
justify-content: center;
align-items: center;
background-color: #f6f6f6;
padding: 10rpx 20rpx;
margin: 20rpx 30rpx 0 0;
border-radius: 30rpx;
/* #ifndef APP-NVUE */
box-sizing: border-box;
/* #endif */
text-align: center;
}
#{&}-info {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
flex: 1;
text-align: center;
font-size: 26rpx;
color: #808080;
margin-top: 20rpx;
}
}
}
}
}
</style>

View File

@ -0,0 +1,223 @@
<template>
<scroll-view :scroll-y="true" v-if="!loading">
<view class="meta">
<view class="title">
<text class="text">{{ articleDetail.title }}</text>
</view>
<view class="excerpt">
<text class="text">{{ articleDetail.excerpt }}</text>
</view>
<view class="author">
<template v-if="articleDetail.user_id != null">
<text class="at">{{ articleDetail.user_id?.nickname ?? '' }}</text>
<text class="split">·</text>
</template>
<text class="date">{{ publishTime(articleDetail.publish_date as number) }}</text>
</view>
</view>
<view class="content" v-if="articleDetail.content != null">
<template v-for="(block, index) in articleDetail.content" :key="index">
<view v-if="block.type == 'mediaVideo'">
<video
style="width: 300px; height: 200px; margin: 0 auto 20px;"
:src="(block.data as UTSJSONObject).getJSON('attributes')!.getString('src')!"
:poster="(block.data as UTSJSONObject).getJSON('attributes')!.getString('poster')!"
></video>
</view>
<view v-if="block.type == 'divider'" class="divider"></view>
<view v-if="block.type == 'unlockContent'" class="unlock-content">
<button @click="unlockContent">请观看广告后解锁全文</button>
</view>
<rich-text v-if="block.type == 'rich-text'" :selectable="false" :nodes="block.data" @itemclick="richTextItemClick"></rich-text>
<render-image-component v-if="block.type == 'image'" :deltaOp="block.data" @image-preview="onImagePreview"></render-image-component>
</template>
</view>
</scroll-view>
</template>
<script lang="uts">
import translatePublishTime from "@/uni_modules/uni-cms-article/common/publish-time";
import RenderImageComponent from '@/uni_modules/uni-cms-article/components/render-article-detail/image.uvue'
type Author = {
_id: string
nickname: string
}
type Content = {
type: string
data: any
}
type Article = {
_id: string | null
title: string | null
content: Content[] | null
excerpt: string | null
publish_date: number | null
user_id: Author | null
thumbnail: string[] | null
content_images: string[] | null
}
const db = uniCloud.databaseForJQL()
const articleDBName = 'uni-cms-articles'
const userDBName = 'uni-id-users'
export default {
components: {
RenderImageComponent
},
data() {
return {
loading: true,
id: "", // 文章ID
title: "", // 文章标题
articleDetail: {} as Article, // 文章详情
// 广告相关配置
adpId: "", // TODO: 请填写广告位ID
watchAdUniqueType: "device" // TODO: 观看广告的唯一标识类型,可选值为 user 或者 deviceuser 表示用户唯一device 表示设备唯一
}
},
computed: {
where(): string {
//拼接where条件 查询条件 ,更多详见 https://uniapp.dcloud.net.cn/uniCloud/unicloud-db?id=jsquery
return `_id =="${this.id}"`
},
collection(): any[] {
return [
db.collection(articleDBName).where(this.where).field('user_id,thumbnail,excerpt,publish_date,title,content').getTemp(),
db.collection(userDBName).field('_id, nickname').getTemp()
]
}
},
onLoad(event: OnLoadOptions) {
if (event.has('id')) {
this.id = event.get('id') as string
this.load()
}
if (event.has('title')) {
uni.setNavigationBarTitle({
title: event.get('title') as string
})
}
},
methods: {
async load (): Promise<void> {
uni.showLoading({
title: "加载中..."
})
const articledb = db.collection(articleDBName).where(this.where).field('user_id,thumbnail,excerpt,publish_date,title,content').getTemp()
const userdb = db.collection(userDBName).field('_id, nickname').getTemp()
const res = await db.collection(articledb, userdb).get()
this.loadData(res.data)
this.loading = false
uni.hideLoading()
},
// 格式化发布时间
publishTime(timestamp: number): string {
return translatePublishTime(timestamp)
},
loadData(data: UTSJSONObject[]) {
if (data.length <= 0) return
const detail = data[0]
const user_id = detail.getArray<Author>('user_id')!;
this.articleDetail = {
title: detail.getString('title'),
content: detail.getArray<Content>('content'),
excerpt: detail.getString('excerpt'),
publish_date: detail.getNumber('publish_date'),
thumbnail: detail.getArray<string>('thumbnail'),
user_id: user_id.length > 0 ? user_id[0]: null,
content_images: detail.getArray<string>('content_images')
} as Article
this.title = detail.getString('title')!
uni.setNavigationBarTitle({
title: this.title
})
},
unlockContent () {
uni.showModal({
content: 'uni-app-x 暂不支持观看广告解锁全文',
showCancel: false
})
},
richTextItemClick (e: RichTextItemClickEvent) {
if (e.detail.href != null) {
uni.navigateTo({
url: `/uni_modules/uni-cms-article/pages/webview/webview?url=${encodeURIComponent(e.detail.href as string)}`
})
}
},
onImagePreview (url: string) {
const contentImages = this.articleDetail.content_images != null ? this.articleDetail.content_images: [] as string[]
uni.previewImage({
current: url, // 当前显示图片的http链接
urls: contentImages as string[] // 需要预览的图片http链接列表
})
}
}
}
</script>
<style scoped lang="scss">
.meta {
padding: 20rpx 30rpx 0;
position: relative;
z-index: 1;
.title {
.text {
font-size: 40rpx;
line-height: 66rpx;
font-weight: bold;
color: #333;
}
}
.excerpt {
margin-top: 10rpx;
.text {
font-size: 26rpx;
line-height: 40rpx;
color: #999;
}
}
.author {
display: flex;
align-items: center;
justify-content: flex-start;
flex-direction: row;
margin-top: 20rpx;
.at,
.split,
.date {
font-size: 26rpx;
color: #ccc;
}
.split {
margin: 0 10rpx;
}
}
}
.content {
margin-top: 40rpx;
padding: 0 30rpx 80rpx;
}
.divider {
height: 1px;
width: 100%;
background: rgba(0, 0, 0, 0.1);
}
</style>

View File

@ -0,0 +1,217 @@
<template>
<unicloud-db v-slot:default="{data, loading, error, options}" :collection="collection" :options="formData"
:getone="true" :where="where" :manual="true" ref="detail" foreignKey="uni-cms-articles.user_id"
@load="loadData"
class="article">
<template v-if="!loading && data">
<view class="meta">
<view class="title">
<text class="text">{{ data.title }}</text>
</view>
<view class="excerpt">
<text class="text">{{ data.excerpt }}</text>
</view>
<view class="author">
<template v-if="data.user_id[0]">
<text class="at">{{ data.user_id[0].nickname || '' }}</text>
<text class="split">·</text>
</template>
<text class="date">{{ publishTime(data.publish_date) }}</text>
</view>
</view>
<render-article-detail
:content="data.content"
:content-images="data.content_images"
:ad-config="{ adpId, watchAdUniqueType }"
></render-article-detail>
</template>
<view class="detail-loading" v-else>
<uni-icons type="spinner-cycle" size="35px"/>
</view>
</unicloud-db>
</template>
<script>
import uniNavBar from '@/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue';
import renderArticleDetail from "@/uni_modules/uni-cms-article/components/render-article-detail/index.vue";
import translatePublishTime from "@/uni_modules/uni-cms-article/common/publish-time";
const db = uniCloud.database()
const articleDBName = 'uni-cms-articles'
const userDBName = 'uni-id-users'
export default {
components: {
uniNavBar,
renderArticleDetail
},
data() {
return {
id: "", // 文章ID
title: "", // 文章标题
formData: {}, // 表单数据
// 广告相关配置
adpId: "", // TODO: 请填写广告位ID
watchAdUniqueType: "device" // TODO: 观看广告的唯一标识类型,可选值为 user 或者 deviceuser 表示用户唯一device 表示设备唯一
}
},
computed: {
where() {
//拼接where条件 查询条件 ,更多详见 https://uniapp.dcloud.net.cn/uniCloud/unicloud-db?id=jsquery
return `_id =="${this.id}"`
},
collection() {
return [
db.collection(articleDBName).where(this.where).field('user_id,thumbnail,excerpt,publish_date,title,content').getTemp(),
db.collection(userDBName).field('_id, nickname').getTemp()
]
}
},
onReady() {
// 开始加载数据,修改 where 条件后才开始去加载 clinetDB 的数据 ,需要等组件渲染完毕后才开始执行 loadData所以不能再 onLoad 中执行
if (this.id) { // ID 不为空,则发起查询
this.$refs.detail.loadData()
} else {
uni.showToast({
icon: 'none',
title: 'id 不能为空'
})
}
},
onLoad(event) {
//获取文章id通常 id 来自上一个页面
if (event.id) {
this.id = event.id
}
// 监听解锁内容事件
uni.$on('onUnlockContent', this.onUnlockContent)
},
onUnload() {
// 页面卸载时,移除监听事件
uni.$off('onUnlockContent', this.onUnlockContent)
},
onPageScroll(e) {
// 根据滚动位置判断是否显示导航栏
if (e.scrollTop > 100) {
uni.setNavigationBarTitle({
title: this.title
})
} else {
uni.setNavigationBarTitle({
title: ''
})
}
},
methods: {
// 将时间戳转换为可读的时间格式
publishTime(timestamp) {
return translatePublishTime(timestamp)
},
// 将文章加入阅读历史
setReadHistory() {
// 获取阅读历史缓存,如果不存在则为空数组
const historyCache = uni.getStorageSync('readHistory') || []
// 过滤掉当前文章的阅读历史
const readHistory = historyCache.filter(item => item.article_id !== this.id)
// 将当前文章的阅读历史添加到数组最前面
readHistory.unshift({
article_id: this.id,
last_time: Date.now()
})
// 将更新后的阅读历史缓存到本地
uni.setStorageSync('readHistory', readHistory)
},
// 加载数据
loadData(data) {
// 设置文章标题
this.title = data.title
// 将文章添加进阅读历史
this.setReadHistory()
},
// 监听解锁内容事件,解锁内容后重新加载数据
async onUnlockContent() {
this.$refs.detail.loadData()
}
}
}
</script>
<style scoped lang="scss">
/* #ifdef APP-NVUE */
.article {
background-color: #fff;
}
/* #endif */
@mixin cp {
padding: 0 30rpx;
}
.detail-loading {
margin: 100rpx auto 0;
width: 35px;
height: 35px;
animation: rotate360 2s linear infinite;
}
@keyframes rotate360 {
0% {
transform: rotate(0deg);
transform-origin: center center;
}
100% {
transform: rotate(360deg);
transform-origin: center center;
}
}
.meta {
@include cp;
position: relative;
z-index: 1;
padding-top: 20rpx;
.title {
.text {
font-size: 40rpx;
line-height: 66rpx;
font-weight: bold;
color: #333;
}
}
.excerpt {
margin-top: 10rpx;
.text {
font-size: 26rpx;
line-height: 40rpx;
color: #999;
}
}
.author {
display: flex;
align-items: center;
justify-content: flex-start;
flex-direction: row;
margin-top: 20rpx;
.at,
.split,
.date {
font-size: 26rpx;
color: #ccc;
}
.split {
margin: 0 10rpx;
}
}
}
</style>

View File

@ -0,0 +1,255 @@
<template>
<unicloud-db v-slot:default="{loading, error, options}" :collection="collection" :options="formData"
:getone="true" :where="where" :manual="true" ref="detail" foreignKey="uni-cms-articles.user_id"
@load="loadData"
class="article">
<template v-if="!loading && articleData">
<view class="preview-tip">此页面仅用于临时预览文章链接将会在短期内失效</view>
<view class="meta">
<view class="title">
<text class="text">{{ articleData.title }}</text>
</view>
<view class="excerpt">
<text class="text">{{ articleData.excerpt }}</text>
</view>
<view class="author">
<template v-if="articleData.user_id && articleData.user_id[0]">
<text class="at">{{ articleData.user_id[0].nickname || '' }}</text>
<text class="split">·</text>
</template>
<text class="date">{{ publishTime(articleData.publish_date) }}</text>
</view>
</view>
<render-article-detail
:content="articleData.content"
:content-images="articleData.content_images"
:ad-config="{ adpId, watchAdUniqueType }"
></render-article-detail>
</template>
<view class="detail-loading" v-else>
<uni-icons type="spinner-cycle" size="35px"/>
</view>
</unicloud-db>
</template>
<script>
import uniNavBar from '@/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue';
import renderArticleDetail from "@/uni_modules/uni-cms-article/components/render-article-detail/index.vue";
import translatePublishTime from "@/uni_modules/uni-cms-article/common/publish-time";
const db = uniCloud.database()
const articleDBName = 'uni-cms-articles'
const userDBName = 'uni-id-users'
export default {
components: {
uniNavBar,
renderArticleDetail
},
data() {
return {
id: "", // 文章ID
title: "", // 文章标题
secret: "", // 文章预览密钥
formData: {}, // 表单数据
articleData: null, // 文章数据
// 广告相关配置
adpId: "", // TODO: 请填写广告位ID
watchAdUniqueType: "device" // TODO: 观看广告的唯一标识类型,可选值为 user 或者 deviceuser 表示用户唯一device 表示设备唯一
}
},
computed: {
where() {
//拼接where条件 查询条件 ,更多详见 https://uniapp.dcloud.net.cn/uniCloud/unicloud-db?id=jsquery
return `_id =="${this.id}" && preview_secret =="${this.secret}"`
},
collection() {
return [
db.collection(articleDBName).where(this.where).field('user_id,thumbnail,excerpt,publish_date,title,content,preview_secret,preview_expired,article_status').getTemp(),
db.collection(userDBName).field('_id, nickname').getTemp()
]
}
},
onReady() {
// 开始加载数据,修改 where 条件后才开始去加载 clinetDB 的数据 ,需要等组件渲染完毕后才开始执行 loadData所以不能再 onLoad 中执行
if (this.id) { // ID 不为空,则发起查询
this.$refs.detail.loadData()
} else {
uni.showToast({
icon: 'none',
title: 'id 不能为空'
})
}
},
onLoad(event) {
//获取文章id通常 id 来自上一个页面
if (event.id) {
this.id = event.id
this.secret = event.secret
}
// 监听解锁内容事件
uni.$on('onUnlockContent', this.onUnlockContent)
},
onUnload() {
// 页面卸载时,移除监听事件
uni.$off('onUnlockContent', this.onUnlockContent)
},
onPageScroll(e) {
// 根据滚动位置判断是否显示导航栏
if (e.scrollTop > 100) {
uni.setNavigationBarTitle({
title: this.title
})
} else {
uni.setNavigationBarTitle({
title: ''
})
}
},
methods: {
// 将时间戳转换为可读的时间格式
publishTime(timestamp) {
return translatePublishTime(timestamp)
},
// 加载数据
loadData(data) {
if (!data) {
return uni.showModal({
content: "文章不存在/预览密钥不存在",
showCancel: false,
success: () => {
// #ifdef H5
window.close()
// #endif
// #ifndef H5
uni.navigateBack()
// #endif
}
})
}
// 文章已发布,跳转到文章详情页
if (data.article_status === 1) {
uni.showToast({
icon: 'none',
title: '文章已发布'
})
uni.redirectTo({
url: `/uni_modules/uni-cms-article/pages/detail/detail?id=${this.id}`
})
return
}
// 预览已过期,提示用户
if (data.preview_expired < Date.now()) {
return uni.showModal({
content: "预览已失效",
showCancel: false,
success: () => {
// #ifdef H5
window.close()
// #endif
// #ifndef H5
uni.navigateBack()
// #endif
}
})
}
// 设置文章标题
this.title = data.title
this.articleData = data
},
// 监听解锁内容事件,解锁内容后重新加载数据
async onUnlockContent() {
this.$refs.detail.loadData()
}
}
}
</script>
<style scoped lang="scss">
/* #ifdef APP-NVUE */
.article {
background-color: #fff;
}
/* #endif */
@mixin cp {
padding: 0 30rpx;
}
.detail-loading {
margin: 100rpx auto 0;
width: 35px;
height: 35px;
animation: rotate360 2s linear infinite;
}
@keyframes rotate360 {
0% {
transform: rotate(0deg);
transform-origin: center center;
}
100% {
transform: rotate(360deg);
transform-origin: center center;
}
}
.meta {
@include cp;
position: relative;
z-index: 1;
padding-top: 20rpx;
.title {
.text {
font-size: 40rpx;
line-height: 66rpx;
font-weight: bold;
color: #333;
}
}
.excerpt {
margin-top: 10rpx;
.text {
font-size: 26rpx;
line-height: 40rpx;
color: #999;
}
}
.author {
display: flex;
align-items: center;
justify-content: flex-start;
flex-direction: row;
margin-top: 20rpx;
.at,
.split,
.date {
font-size: 26rpx;
color: #ccc;
}
.split {
margin: 0 10rpx;
}
}
}
.preview-tip {
font-size: 13px;
color: #333;
background: #fcd791;
padding: 10px;
}
</style>

Some files were not shown because too many files have changed in this diff Show More