184 changed files with 13494 additions and 0 deletions
Split View
Diff Options
-
10.gitignore
-
20.hbuilderx/launch.json
-
65App.vue
-
3README copy.md
-
34apis/addressApi.js
-
379apis/commonApi.js
-
79apis/mineApi.js
-
275common/css/reset.scss
-
501components/qn-easyinput/qn-easyinput.vue
-
95components/qn-input-number/qn-input-number.vue
-
95components/qn-mask/qn-mask.vue
-
5components/scroll-list/images.js
-
696components/scroll-list/scroll-list.vue
-
110enums/index.js
-
8env/index.js
-
12jsconfig.json
-
29main.js
-
192manifest.json
-
12package-lock.json
-
13package.json
-
103pages.json
-
313pages/address/index.vue
-
41pages/h5-page/index.vue
-
35pages/h5-view/index.vue
-
25pages/index/index.vue
-
192pages/login/index.vue
-
25pages/mine/index.vue
-
87pages/page-view/index.vue
-
114pages/pay-result/index.vue
-
151pages/pay/components/FileItem.vue
-
82pages/pay/components/OrderInfo.vue
-
454pages/pay/components/OtherItem.vue
-
77pages/pay/components/officialAccountPopup.vue
-
24pages/pay/index.vue
-
20prettier.config.js
-
25static/icon/iconfont.css
-
BINstatic/icon/iconfont.ttf
-
BINstatic/imgs/general/add-icon.png
-
BINstatic/imgs/general/baiduPan-icon.png
-
BINstatic/imgs/general/blue-arrow-down.png
-
BINstatic/imgs/general/blue-plus-icon.png
-
BINstatic/imgs/general/camera-icon.png
-
BINstatic/imgs/general/cart-icon.png
-
BINstatic/imgs/general/close-circle-icon.png
-
BINstatic/imgs/general/close-icon.png
-
BINstatic/imgs/general/coupon-txt-icon.png
-
BINstatic/imgs/general/customer-service-icon.png
-
BINstatic/imgs/general/default-fn-logo.png
-
BINstatic/imgs/general/doc-icon.png
-
BINstatic/imgs/general/down-act-icon.png
-
BINstatic/imgs/general/down-icon.png
-
BINstatic/imgs/general/down.png
-
BINstatic/imgs/general/eye-icon.png
-
BINstatic/imgs/general/folder-icon.png
-
BINstatic/imgs/general/gesture.png
-
BINstatic/imgs/general/hand-up-icon.gif
-
BINstatic/imgs/general/jinShan-icon.png
-
BINstatic/imgs/general/local-icon.png
-
BINstatic/imgs/general/logo-icon.png
-
BINstatic/imgs/general/not-support-icon.png
-
BINstatic/imgs/general/order-success-icon.png
-
BINstatic/imgs/general/pdf-icon.png
-
BINstatic/imgs/general/plus-icon.png
-
BINstatic/imgs/general/ppt-icon.png
-
BINstatic/imgs/general/qn-txt.png
-
BINstatic/imgs/general/question-mask-icon.png
-
BINstatic/imgs/general/reduce-icon.png
-
BINstatic/imgs/general/right-arrow-blue.png
-
BINstatic/imgs/general/right-arrow.png
-
BINstatic/imgs/general/select-icon-small.png
-
BINstatic/imgs/general/select-icon.png
-
BINstatic/imgs/general/selected-icon-small.png
-
BINstatic/imgs/general/selected-icon.png
-
BINstatic/imgs/general/share.png
-
BINstatic/imgs/general/tenCent-icon.png
-
BINstatic/imgs/general/top-arrow-icon.png
-
BINstatic/imgs/general/txt-bg.png
-
BINstatic/imgs/general/up-act-icon.png
-
BINstatic/imgs/general/up-arrow-icon.png
-
BINstatic/imgs/general/up-icon.png
-
BINstatic/imgs/general/upload-tip.png
-
BINstatic/imgs/general/uploading.gif
-
BINstatic/imgs/general/wx-icon.png
-
BINstatic/imgs/index/customer-service-icon.png
-
BINstatic/imgs/index/horn-icon.png
-
BINstatic/imgs/index/hot-icon.gif
-
BINstatic/imgs/index/index-community-icon.png
-
BINstatic/imgs/index/index-coupon-icon.png
-
BINstatic/imgs/index/index-library-icon.png
-
BINstatic/imgs/index/index-luck-draw-icon.png
-
BINstatic/imgs/index/index-sign-in-icon.png
-
BINstatic/imgs/index/send-icon.gif
-
BINstatic/imgs/tabbar/category-blue.png
-
BINstatic/imgs/tabbar/category-gray.png
-
BINstatic/imgs/tabbar/index-blue.png
-
BINstatic/imgs/tabbar/index-gray.png
-
BINstatic/imgs/tabbar/mine-blue.png
-
BINstatic/imgs/tabbar/mine-gray.png
-
BINstatic/imgs/tabbar/order-blue.png
-
BINstatic/imgs/tabbar/order-gray.png
@ -0,0 +1,10 @@ |
|||
.vscode/settings.json |
|||
/unpackage/dist |
|||
/unpackage/cache |
|||
/unpackage/release |
|||
/unpackage/debug |
|||
|
|||
.vscode/ |
|||
|
|||
.DS_Store |
|||
/**/.DS_Store |
|||
@ -0,0 +1,20 @@ |
|||
{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ |
|||
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 |
|||
"version": "0.0", |
|||
"configurations": [{ |
|||
"app-plus" : |
|||
{ |
|||
"launchtype" : "local" |
|||
}, |
|||
"default" : |
|||
{ |
|||
"launchtype" : "local" |
|||
}, |
|||
"mp-weixin" : |
|||
{ |
|||
"launchtype" : "local" |
|||
}, |
|||
"type" : "uniCloud" |
|||
} |
|||
] |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
<script> |
|||
import { silentLogin } from '@/apis/mineApi' |
|||
import { getUserAccountInfo } from '@/apis/commonApi' |
|||
export default { |
|||
methods: { |
|||
handleLogin() { |
|||
getUserAccountInfo().then(({ openId, tmpAuthToken }) => { |
|||
this.$store.commit('setOpenId', openId) |
|||
silentLogin({ authCode: tmpAuthToken }).then((res) => { |
|||
if (this.$store.state.userInfo.userId !== res.userId) { |
|||
let userInfo = { |
|||
userId: res.userId, |
|||
name: res.nickName || '', |
|||
avatar: res.avatarUrl || '', |
|||
mobile: '' |
|||
} |
|||
this.$store.commit('setUserInfo', userInfo) |
|||
} |
|||
this.$store.commit('setToken', res.token) |
|||
}) |
|||
}) |
|||
} |
|||
}, |
|||
onLaunch: function () { |
|||
const updateManager = uni.getUpdateManager() |
|||
this.handleLogin() |
|||
updateManager.onCheckForUpdate(function (res) { |
|||
// 请求完新版本信息的回调 |
|||
console.log(res.hasUpdate) |
|||
}) |
|||
|
|||
updateManager.onUpdateReady(function (res) { |
|||
uni.showModal({ |
|||
title: '更新提示', |
|||
content: '新版本已经准备好,是否重启应用?', |
|||
success(res) { |
|||
if (res.confirm) { |
|||
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启 |
|||
updateManager.applyUpdate() |
|||
} |
|||
} |
|||
}) |
|||
}) |
|||
|
|||
updateManager.onUpdateFailed(function (res) { |
|||
// 新的版本下载失败 |
|||
}) |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
/*每个页面公共css */ |
|||
@import url('./common/css/reset.scss'); |
|||
@import '@/static/icon/iconfont.css'; |
|||
page { |
|||
height: 100%; |
|||
} |
|||
/* uni-dialog标题样式 */ |
|||
.uni-dialog-title-text { |
|||
font-size: 32rpx !important; |
|||
color: #323233 !important; |
|||
font-weight: 500 !important; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,3 @@ |
|||
# 飞鸟快印微信小程序 |
|||
|
|||
uni-app |
|||
@ -0,0 +1,34 @@ |
|||
import http from '@/utils/http/index.js' |
|||
|
|||
/** |
|||
* 获取用户地址列表 |
|||
* @param {object} data 参数 userId |
|||
*/ |
|||
export function getAddressList(data = {}) { |
|||
return http.get({ |
|||
url: `/wukong-fast-print/get/personal-shipping-address/list`, |
|||
data |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 保存或修改用户地址列表 |
|||
* @param {object} data 参数 id |
|||
*/ |
|||
export function changeAddress(data = {}) { |
|||
return http.post({ |
|||
url: `/wukong-fast-print/save/personal-shipping-address`, |
|||
data |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 删除用户地址 |
|||
* @param {object} data 参数 id |
|||
*/ |
|||
export function deleteAddress(data = {}) { |
|||
return http.post({ |
|||
url: `/wukong-fast-print/delete/my-address`, |
|||
data |
|||
}) |
|||
} |
|||
@ -0,0 +1,379 @@ |
|||
import http from '@/utils/http/index.js' |
|||
import store from '@/store/index' |
|||
import { XAPPID} from '@/enums/index.js' |
|||
import { wxAuthorize } from '@/apis/mineApi.js' |
|||
|
|||
let priceMap = null |
|||
|
|||
/** |
|||
* 获取价目表 |
|||
* @param {boolean} refresh 是否刷新 |
|||
* @returns |
|||
*/ |
|||
export function getPriceMap(refresh = false) { |
|||
return new Promise((resolve) => { |
|||
if (!refresh && priceMap) { |
|||
resolve(priceMap) |
|||
} else { |
|||
http.get({ url: '/wukong-fast-print/get/printing/file/marked/price/by' }).then((res) => { |
|||
priceMap = res |
|||
resolve(res) |
|||
}) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
let postageMap = null |
|||
/** |
|||
* 获取邮费 |
|||
* @param {boolean} refresh 是否刷新 |
|||
* @returns |
|||
*/ |
|||
export function getPostagePrice(refresh = true, goodsId = '') { |
|||
return new Promise((resolve) => { |
|||
if (!refresh && postageMap) { |
|||
resolve(postageMap) |
|||
} else { |
|||
let data = { goodsId } |
|||
let params = goodsId ? { url: '/wukong-fast-print/get/postage/conditions', data } : { url: '/wukong-fast-print/get/postage/conditions' } |
|||
http.get(params).then((res) => { |
|||
postageMap = res |
|||
resolve(res) |
|||
}) |
|||
} |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 获取OSS上传信息 |
|||
* @returns |
|||
*/ |
|||
export function getOssInfo() { |
|||
return http.get({ |
|||
url: '/wukong-fast-print/getOssSign' |
|||
}) |
|||
} |
|||
|
|||
let loading = false |
|||
let resolveQueue = [] |
|||
let rejectQueue = [] |
|||
/** |
|||
* 获取用户tmpAuthToken和openId |
|||
* @return {Promise} |
|||
*/ |
|||
export function getUserAccountInfo() { |
|||
if (loading) { |
|||
return new Promise((resolve, reject) => { |
|||
resolveQueue.push(resolve) |
|||
rejectQueue.push(reject) |
|||
}) |
|||
} |
|||
loading = true |
|||
return new Promise((resolve, reject) => { |
|||
uni.login({ |
|||
provider: 'weixin', |
|||
success: (loginRes) => { |
|||
let code = loginRes.code |
|||
getSession({ authCode: code }) |
|||
.then((res) => { |
|||
resolve(res) |
|||
resolveQueue.forEach((fn) => { |
|||
fn(res) |
|||
}) |
|||
}) |
|||
.catch((err) => { |
|||
reject(err) |
|||
rejectQueue.forEach((fn) => { |
|||
fn(err) |
|||
}) |
|||
}) |
|||
.finally(() => { |
|||
loading = false |
|||
resolveQueue = [] |
|||
rejectQueue = [] |
|||
}) |
|||
}, |
|||
fail: (err) => { |
|||
reject(err) |
|||
rejectQueue.forEach((fn) => { |
|||
fn(err) |
|||
}) |
|||
loading = false |
|||
resolveQueue = [] |
|||
rejectQueue = [] |
|||
} |
|||
}) |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 获取微信小程序认证会话 |
|||
* @param {object} data 参数 authCode |
|||
*/ |
|||
export function getSession(data = {}) { |
|||
return http.post( |
|||
{ |
|||
url: `/uec/get/wechat-applet-session`, |
|||
data |
|||
}, |
|||
{ hideLoading: true } |
|||
) |
|||
} |
|||
// wx登陆生成器缓存
|
|||
let loginGenerator = {} |
|||
// wx会话缓存
|
|||
let session = {} |
|||
/** |
|||
* 微信小程序登陆 |
|||
* @param {object} data |
|||
* @returns {(login:Function,getSession:Function)} |
|||
*/ |
|||
export function wxLoginGenerate() { |
|||
if (loginGenerator.login && loginGenerator.getSession) { |
|||
if (Date.now() > session.expireTime) { |
|||
loginGenerator.getSession() |
|||
} |
|||
return loginGenerator |
|||
} |
|||
let completed = false |
|||
function getSession() { |
|||
getUserAccountInfo() |
|||
.then(({ tmpAuthToken, openId, expireTime }) => { |
|||
expireTime = expireTime.replace(/-/g, '/') |
|||
store.commit('setOpenId', openId) |
|||
session = { tmpAuthToken, openId, expireTime: new Date(expireTime) } |
|||
completed = true |
|||
}) |
|||
.catch((err) => { |
|||
console.log(err) |
|||
completed = false |
|||
}) |
|||
} |
|||
getSession() |
|||
function login() { |
|||
return new Promise((resolve, reject) => { |
|||
if (!completed) { |
|||
reject('未获取到会话,请再次点击登陆') |
|||
return |
|||
} |
|||
if (Date.now() > session.expireTime) { |
|||
getSession() |
|||
reject('会话已失效,请再次点击登陆') |
|||
return |
|||
} |
|||
uni.getUserProfile({ |
|||
desc: '获取你的昵称、头像', |
|||
success: (res) => { |
|||
let iv = res.iv |
|||
let encryptedData = res.encryptedData |
|||
uni.showLoading({ |
|||
title: '加载中' |
|||
}) |
|||
wxAuthorize({ iv, encryptedData, tmpAuthToken: session.tmpAuthToken }) |
|||
.then((info) => { |
|||
let userInfo = { |
|||
name: res.userInfo.nickName, |
|||
userId: info.userId, |
|||
avatar: res.userInfo.avatarUrl, |
|||
mobile: '' |
|||
} |
|||
store.commit('setUserInfo', userInfo) |
|||
store.commit('setToken', info.token) |
|||
resolve(userInfo) |
|||
}) |
|||
.catch(() => { |
|||
reject('获取用户信息异常,请联系客服') |
|||
}) |
|||
.finally(() => { |
|||
uni.hideLoading() |
|||
}) |
|||
}, |
|||
fail: () => { |
|||
reject('请同意昵称和头像信息的授权') |
|||
} |
|||
}) |
|||
}) |
|||
} |
|||
loginGenerator = { login, getSession } |
|||
return loginGenerator |
|||
} |
|||
|
|||
/** |
|||
* 获取当前账号的企业实名认证地址 |
|||
* @param {object} data 参数 enterpriseId |
|||
*/ |
|||
export function getVerifyUrl(data = {}) { |
|||
return http.post({ url: '/yyt-uec/get/fdd-enterprise-verify-url?enterpriseId=' + data.enterpriseId, data }) |
|||
} |
|||
|
|||
/** |
|||
* 生成担保合同的签约地址,同意纸盘商只需要签约一次即可 |
|||
* @param {object} data 参数 mallSupplierId |
|||
*/ |
|||
export function getGuaranteeContract(data = {}) { |
|||
return http.post({ |
|||
url: `/yyt-uec/create/supplier/guarantee-contract?mallSupplierId=${data.mallSupplierId}&customerEnterpriseId=${data.customerEnterpriseId}`, |
|||
data |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 转换合同成图片 |
|||
* @param {object} data 图片地址链接 fileUrl |
|||
*/ |
|||
export function transformFileToImg(data) { |
|||
return http.get({ |
|||
url: '/document/get/enterprise-documents/file-image-base64', |
|||
data: data |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 获取快递列表 |
|||
* @param {object} data |
|||
*/ |
|||
export function getPostageList(data) { |
|||
return http.get({ |
|||
url: '/wukong-fast-print/get/printing/express/type', |
|||
data: data |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 获取网盘链接地址 |
|||
* @param {object} data |
|||
*/ |
|||
export function getBandingLink(data) { |
|||
return http.get({ |
|||
url: '/uec/user/get/baidu-pan/authorize-page', |
|||
data: data |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 获取当前账号企业的飞算额度 |
|||
* @param {object} data 参数 enterpriseId |
|||
*/ |
|||
export function getFsCredit(data = {}) { |
|||
return http.get({ |
|||
url: '/yyt-uec/credit/get/enterprise-feisuan-credit', |
|||
data |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 获取当前账号企业的被担保的月结额度 |
|||
* @param {object} data 参数 enterpriseId supplierId |
|||
*/ |
|||
export function getMonthCredit(data = {}) { |
|||
return http.get({ url: '/yyt-uec/customer/get/supplier-credit', data }) |
|||
} |
|||
|
|||
/** |
|||
* 推送客户绑定 |
|||
* |
|||
*/ |
|||
export function pushCustomerBind(cid, platformType = 'android', appId = XAPPID) { |
|||
return http.post({ |
|||
url: '/base-paper-trading/user/binding/geTui/cid', |
|||
data: { cid, appId, platformType } |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 推送客户绑定 |
|||
* |
|||
*/ |
|||
export function pushCustomerOff(cid, platformType = 'android', appId = XAPPID) { |
|||
return http.post({ |
|||
url: '/base-paper-trading/user/geTui/offline', |
|||
data: { cid, appId, platformType } |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 营业执照OCR识别 photoUrl |
|||
*/ |
|||
export function getLicenseOcr(data = {}) { |
|||
return http.post({ |
|||
url: '/base-paper-trading/ocr/business-license', |
|||
data: data |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 身份证正面OCR识别 image |
|||
*/ |
|||
export function getFrontIdCardOcr(data = {}) { |
|||
return http.post({ |
|||
url: '/base-paper-trading/ocr/id-card/face', |
|||
data: data |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 飞鸟快印绑定代销商 |
|||
* @param {object} data storeUserId |
|||
*/ |
|||
export function bindingStore(data = {}) { |
|||
return http.post( |
|||
{ |
|||
url: '/wukong-fast-print/user/create/distribution-relation', |
|||
data: data |
|||
}, |
|||
{ hideLoading: true } |
|||
) |
|||
} |
|||
|
|||
/** |
|||
* 获取二维码绑定的userId |
|||
* @param {object} data host QrCodeRecordId |
|||
*/ |
|||
export function getQrCodeRecordId(data = {}) { |
|||
return http.get( |
|||
{ |
|||
url: '/uec/verify/qrcode', |
|||
data |
|||
}, |
|||
{ hideLoading: true } |
|||
) |
|||
} |
|||
|
|||
/** |
|||
* 获取半天妖客户经理列表 |
|||
* @param {object} data host QrCodeRecordId |
|||
*/ |
|||
export function getBTAreaList() { |
|||
return http.get( |
|||
{ |
|||
url: '/wukong-fast-print/get/ban/tian/yao/area/customer/manager/list' |
|||
}, |
|||
{ hideLoading: true } |
|||
) |
|||
} |
|||
|
|||
/** |
|||
* 获取活动海报 |
|||
*/ |
|||
export function getPoster(data = {}) { |
|||
return http.get({ |
|||
url: '/uec/fission/get/poster', |
|||
data |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 用户修改用户昵称和头像 |
|||
* @param {*} data |
|||
* @returns |
|||
*/ |
|||
export function changeUserInfo(data = {}) { |
|||
return http.post({ |
|||
url: '/uec/user/update/user-info', |
|||
data: data |
|||
}) |
|||
} |
|||
|
|||
export function uploadAvatar(path) { |
|||
return http.uploadFile({ data: { filePath: path } }) |
|||
} |
|||
@ -0,0 +1,79 @@ |
|||
import http from '@/utils/http/index.js' |
|||
|
|||
/** |
|||
* 微信登录认证获取token |
|||
* @param {object} data 参数 encryptedData iv tmpAuthToken |
|||
*/ |
|||
export function wxAuthorize(data = {}) { |
|||
return http.post({ |
|||
url: `/uec/authorize/by-wechat-applet/without-regest`, |
|||
data |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 微信小程序静默登录 |
|||
* @param {object} data 参数 authCode |
|||
*/ |
|||
export function silentLogin(data = {}) { |
|||
return http.post( |
|||
{ |
|||
url: `/uec/authorize/by-wechat-applet/without-regest/unlogin`, |
|||
data |
|||
}, |
|||
{ hideLoading: true } |
|||
) |
|||
} |
|||
|
|||
/** |
|||
* 获取用户代理商状态 |
|||
* @param {object} data 参数 |
|||
*/ |
|||
export function getStoreState(data = {}) { |
|||
return http.get( |
|||
{ |
|||
url: `/wukong-fast-print/get/agency/shop/status`, |
|||
data |
|||
}, |
|||
{ hideLoading: true } |
|||
) |
|||
} |
|||
|
|||
/** |
|||
* 获取代理商佣金统计 |
|||
* @param {object} data 参数 |
|||
*/ |
|||
export function getStoreStatistics(data = {}) { |
|||
return http.get( |
|||
{ |
|||
url: `/wukong-fast-print/get/agency/commission/statistics`, |
|||
data |
|||
}, |
|||
{ hideLoading: true } |
|||
) |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 提交店铺申请 |
|||
* @param {object} data 参数 |
|||
*/ |
|||
export function makeStoreApplication(data = {}) { |
|||
return http.post({ |
|||
url: `/wukong-fast-print/submit/agency/store/apply`, |
|||
data |
|||
}) |
|||
} |
|||
|
|||
/** |
|||
* 获取代理商佣金统计 |
|||
* @param {object} data 参数 |
|||
*/ |
|||
export function getPreferentialCardList(data = {}) { |
|||
return http.get( |
|||
{ |
|||
url: `/wukong-fast-print/get/preferential/card/list`, |
|||
data |
|||
} |
|||
) |
|||
} |
|||
@ -0,0 +1,275 @@ |
|||
page { |
|||
font-size: $uni-font-size-base; |
|||
line-height: 1; |
|||
background-color: #f7f8fa; |
|||
-webkit-overflow-scrolling: touch; /* 使ios列表滑动流畅*/ |
|||
} |
|||
// 标签重置 |
|||
page, |
|||
view, |
|||
input, |
|||
text, |
|||
form, |
|||
navigator, |
|||
rich-text, |
|||
picker, |
|||
scroll-view, |
|||
cover-view, |
|||
open-data { |
|||
box-sizing: border-box; |
|||
} |
|||
rich-text, |
|||
open-data, |
|||
form { |
|||
display: block; |
|||
} |
|||
|
|||
view, |
|||
image, |
|||
text { |
|||
box-sizing: border-box; |
|||
flex-shrink: 0; |
|||
} |
|||
// flex快捷类 |
|||
.flex-row { |
|||
display: flex; |
|||
flex-direction: row; |
|||
} |
|||
|
|||
.flex-col { |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.justify-start { |
|||
display: flex; |
|||
justify-content: flex-start; |
|||
} |
|||
|
|||
.justify-center { |
|||
display: flex; |
|||
justify-content: center; |
|||
} |
|||
|
|||
.justify-end { |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
} |
|||
|
|||
.justify-evenly { |
|||
display: flex; |
|||
justify-content: space-evenly; |
|||
} |
|||
|
|||
.justify-around { |
|||
display: flex; |
|||
justify-content: space-around; |
|||
} |
|||
|
|||
.justify-between { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
} |
|||
|
|||
.items-start { |
|||
display: flex; |
|||
align-items: flex-start; |
|||
} |
|||
|
|||
.items-center { |
|||
display: flex; |
|||
align-items: center; |
|||
} |
|||
|
|||
.items-end { |
|||
display: flex; |
|||
align-items: flex-end; |
|||
} |
|||
.text-ellipsis { |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
white-space: nowrap; |
|||
} |
|||
|
|||
cover-view { |
|||
line-height: 1.5; |
|||
white-space: normal; |
|||
} |
|||
// 隐藏滑动条 |
|||
*::webkit-scrollbar { |
|||
display: none; |
|||
} |
|||
// 重置按钮样式 |
|||
button::after { |
|||
border: 0; |
|||
} |
|||
|
|||
/* 清除浮动 */ |
|||
.clearfix:after { |
|||
content: '.'; |
|||
display: block; |
|||
height: 0; |
|||
clear: both; |
|||
visibility: hidden; |
|||
} |
|||
// 两行省略号 |
|||
.u-line-2 { |
|||
-webkit-line-clamp: 2; |
|||
overflow: hidden; |
|||
word-break: break-all; |
|||
text-overflow: ellipsis; |
|||
display: -webkit-box; // 弹性伸缩盒 |
|||
-webkit-box-orient: vertical; // 设置伸缩盒子元素排列方式 |
|||
} |
|||
|
|||
// flex 快捷类 |
|||
.flex-row-start-start { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: flex-start; |
|||
justify-content: flex-start; |
|||
} |
|||
.flex-row-start-center { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: flex-start; |
|||
justify-content: center; |
|||
} |
|||
.flex-row-start-end { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: flex-start; |
|||
justify-content: flex-end; |
|||
} |
|||
.flex-row-start-space { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: flex-start; |
|||
justify-content: space-between; |
|||
} |
|||
.flex-row-center-start { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
justify-content: flex-start; |
|||
} |
|||
.flex-row-center-center { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
.flex-row-center-end { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
justify-content: flex-end; |
|||
} |
|||
.flex-row-center-space { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
} |
|||
.flex-row-end-start { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: flex-end; |
|||
justify-content: flex-start; |
|||
} |
|||
.flex-row-end-center { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: flex-end; |
|||
justify-content: center; |
|||
} |
|||
.flex-row-end-end { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: flex-end; |
|||
justify-content: flex-end; |
|||
} |
|||
.flex-row-end-space { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: flex-end; |
|||
justify-content: space-between; |
|||
} |
|||
|
|||
.flex-col-start-start { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: flex-start; |
|||
justify-content: flex-start; |
|||
} |
|||
.flex-col-start-center { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: flex-start; |
|||
justify-content: center; |
|||
} |
|||
.flex-col-start-end { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: flex-start; |
|||
justify-content: flex-end; |
|||
} |
|||
.flex-col-start-space { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: flex-start; |
|||
justify-content: space-between; |
|||
} |
|||
.flex-col-center-start { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: flex-start; |
|||
} |
|||
.flex-col-center-center { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: center; |
|||
} |
|||
.flex-col-center-end { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: flex-end; |
|||
} |
|||
.flex-col-center-space { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
} |
|||
.flex-col-end-start { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: flex-end; |
|||
justify-content: flex-start; |
|||
} |
|||
.flex-col-end-center { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: flex-end; |
|||
justify-content: center; |
|||
} |
|||
.flex-col-end-end { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: flex-end; |
|||
justify-content: flex-end; |
|||
} |
|||
.flex-col-end-space { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: flex-end; |
|||
justify-content: space-between; |
|||
} |
|||
// flex 快捷子类 |
|||
.flex-base { |
|||
flex-grow: 0; |
|||
flex-shrink: 0; |
|||
} |
|||
@ -0,0 +1,501 @@ |
|||
<template> |
|||
<view class="uni-easyinput" :class="{ 'uni-easyinput-error': msg }" :style="{ color: inputBorder && msg ? '#e43d33' : styles.color }"> |
|||
<view |
|||
class="uni-easyinput__content" |
|||
:class="{ 'is-input-border': inputBorder, 'is-input-error-border': inputBorder && msg, 'is-textarea': type === 'textarea', 'is-disabled': disabled }" |
|||
:style="{ |
|||
'border-color': inputBorder && msg ? '#dd524d' : styles.borderColor, |
|||
'background-color': disabled ? styles.disableColor : '' |
|||
}" |
|||
> |
|||
<uni-icons v-if="prefixIcon" class="content-clear-icon" :type="prefixIcon" color="#c0c4cc" @click="onClickIcon('prefix')"></uni-icons> |
|||
<textarea |
|||
v-if="type === 'textarea'" |
|||
class="uni-easyinput__content-textarea" |
|||
:class="{ 'input-padding': inputBorder }" |
|||
:name="name" |
|||
:value="val" |
|||
:placeholder="placeholder" |
|||
:placeholderStyle="placeholderStyle" |
|||
:disabled="disabled" |
|||
placeholder-class="uni-easyinput__placeholder-class" |
|||
:maxlength="inputMaxlength" |
|||
:focus="focused" |
|||
:autoHeight="autoHeight" |
|||
@input="onInput" |
|||
@blur="onBlur" |
|||
@focus="onFocus" |
|||
@confirm="onConfirm" |
|||
></textarea> |
|||
<input |
|||
v-else |
|||
:type="type === 'password' ? 'text' : type" |
|||
class="uni-easyinput__content-input" |
|||
:style="{ |
|||
'padding-right': type === 'password' || clearable || prefixIcon ? '' : '10px', |
|||
'padding-left': prefixIcon ? '' : '10px', |
|||
'text-align': text |
|||
}" |
|||
:name="name" |
|||
:value="val" |
|||
:password="!showPassword && type === 'password'" |
|||
:placeholder="placeholder" |
|||
:placeholderStyle="placeholderStyle" |
|||
placeholder-class="uni-easyinput__placeholder-class" |
|||
:disabled="disabled" |
|||
:maxlength="inputMaxlength" |
|||
:focus="focused" |
|||
:confirmType="confirmType" |
|||
@focus="onFocus" |
|||
@blur="onBlur" |
|||
@input="onInput" |
|||
@confirm="onConfirm" |
|||
/> |
|||
<template v-if="type === 'password' && passwordIcon"> |
|||
<uni-icons |
|||
v-if="val != ''" |
|||
class="content-clear-icon" |
|||
:class="{ 'is-textarea-icon': type === 'textarea' }" |
|||
:type="showPassword ? 'eye-slash-filled' : 'eye-filled'" |
|||
:size="18" |
|||
color="#c0c4cc" |
|||
@click="onEyes" |
|||
></uni-icons> |
|||
</template> |
|||
<template v-else-if="suffixIcon"> |
|||
<uni-icons v-if="suffixIcon" class="content-clear-icon" :type="suffixIcon" color="#c0c4cc" @click="onClickIcon('suffix')"></uni-icons> |
|||
</template> |
|||
<template v-else> |
|||
<uni-icons |
|||
class="content-clear-icon" |
|||
:class="{ 'is-textarea-icon': type === 'textarea' }" |
|||
type="clear" |
|||
:size="clearSize" |
|||
v-if="clearable && val && !disabled" |
|||
color="#c0c4cc" |
|||
@click="onClear" |
|||
></uni-icons> |
|||
</template> |
|||
<slot name="right"></slot> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
/** |
|||
* Easyinput 输入框 |
|||
* @description 此组件可以实现表单的输入与校验,包括 "text" 和 "textarea" 类型。 |
|||
* @tutorial https://ext.dcloud.net.cn/plugin?id=3455 |
|||
* @property {String} value 输入内容 |
|||
* @property {String } type 输入框的类型(默认text) password/text/textarea/.. |
|||
* @value text 文本输入键盘 |
|||
* @value textarea 多行文本输入键盘 |
|||
* @value password 密码输入键盘 |
|||
* @value number 数字输入键盘,注意iOS上app-vue弹出的数字键盘并非9宫格方式 |
|||
* @value idcard 身份证输入键盘,信、支付宝、百度、QQ小程序 |
|||
* @value digit 带小数点的数字键盘 ,App的nvue页面、微信、支付宝、百度、头条、QQ小程序支持 |
|||
* @property {Boolean} clearable 是否显示右侧清空内容的图标控件,点击可清空输入框内容(默认true) |
|||
* @property {Boolean} autoHeight 是否自动增高输入区域,type为textarea时有效(默认true) |
|||
* @property {String } placeholder 输入框的提示文字 |
|||
* @property {String } placeholderStyle placeholder的样式(内联样式,字符串),如"color: #ddd" |
|||
* @property {Boolean} focus 是否自动获得焦点(默认false) |
|||
* @property {Boolean} disabled 是否禁用(默认false) |
|||
* @property {Number } maxlength 最大输入长度,设置为 -1 的时候不限制最大长度(默认140) |
|||
* @property {String } confirmType 设置键盘右下角按钮的文字,仅在type="text"时生效(默认done) |
|||
* @property {Number } clearSize 清除图标的大小,单位px(默认15) |
|||
* @property {String} prefixIcon 输入框头部图标 |
|||
* @property {String} suffixIcon 输入框尾部图标 |
|||
* @property {Boolean} trim 是否自动去除两端的空格 |
|||
* @value both 去除两端空格 |
|||
* @value left 去除左侧空格 |
|||
* @value right 去除右侧空格 |
|||
* @value start 去除左侧空格 |
|||
* @value end 去除右侧空格 |
|||
* @value all 去除全部空格 |
|||
* @value none 不去除空格 |
|||
* @property {Boolean} inputBorder 是否显示input输入框的边框(默认true) |
|||
* @property {Boolean} passwordIcon type=password时是否显示小眼睛图标 |
|||
* @property {Object} styles 自定义颜色 |
|||
* @event {Function} input 输入框内容发生变化时触发 |
|||
* @event {Function} focus 输入框获得焦点时触发 |
|||
* @event {Function} blur 输入框失去焦点时触发 |
|||
* @event {Function} confirm 点击完成按钮时触发 |
|||
* @event {Function} iconClick 点击图标时触发 |
|||
* @example <uni-easyinput v-model="mobile"></uni-easyinput> |
|||
*/ |
|||
|
|||
export default { |
|||
name: 'uni-easyinput', |
|||
emits: ['click', 'iconClick', 'update:modelValue', 'input', 'focus', 'blur', 'confirm'], |
|||
model: { |
|||
prop: 'modelValue', |
|||
event: 'update:modelValue' |
|||
}, |
|||
props: { |
|||
name: String, |
|||
value: [Number, String], |
|||
modelValue: [Number, String], |
|||
type: { |
|||
type: String, |
|||
default: 'text' |
|||
}, |
|||
clearable: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
autoHeight: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
placeholder: String, |
|||
placeholderStyle: String, |
|||
focus: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
disabled: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
maxlength: { |
|||
type: [Number, String], |
|||
default: 140 |
|||
}, |
|||
confirmType: { |
|||
type: String, |
|||
default: 'done' |
|||
}, |
|||
clearSize: { |
|||
type: [Number, String], |
|||
default: 15 |
|||
}, |
|||
inputBorder: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
prefixIcon: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
suffixIcon: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
trim: { |
|||
type: [Boolean, String], |
|||
default: true |
|||
}, |
|||
passwordIcon: { |
|||
type: Boolean, |
|||
default: true |
|||
}, |
|||
styles: { |
|||
type: Object, |
|||
default() { |
|||
return { |
|||
color: '#333', |
|||
disableColor: '#F7F6F6', |
|||
borderColor: '#e5e5e5' |
|||
} |
|||
} |
|||
}, |
|||
errorMessage: { |
|||
type: [String, Boolean], |
|||
default: '' |
|||
}, |
|||
// 文字位置 left|center|right |
|||
text: { |
|||
type: String, |
|||
default: 'left' |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
focused: false, |
|||
errMsg: '', |
|||
val: '', |
|||
showMsg: '', |
|||
border: false, |
|||
isFirstBorder: false, |
|||
showClearIcon: false, |
|||
showPassword: false |
|||
} |
|||
}, |
|||
computed: { |
|||
msg() { |
|||
return this.errorMessage || this.errMsg |
|||
}, |
|||
// 因为uniapp的input组件的maxlength组件必须要数值,这里转为数值,用户可以传入字符串数值 |
|||
inputMaxlength() { |
|||
return Number(this.maxlength) |
|||
} |
|||
}, |
|||
watch: { |
|||
value(newVal) { |
|||
this.resetValue(newVal) |
|||
}, |
|||
modelValue(newVal) { |
|||
this.resetValue(newVal) |
|||
}, |
|||
focus() { |
|||
this.$nextTick(() => { |
|||
this.focused = this.focus |
|||
}) |
|||
} |
|||
}, |
|||
created() { |
|||
if (!this.value) { |
|||
this.val = this.modelValue |
|||
} |
|||
if (!this.modelValue) { |
|||
this.val = this.value |
|||
} |
|||
this.form = this.getForm('uniForms') |
|||
this.formItem = this.getForm('uniFormsItem') |
|||
if (this.form && this.formItem) { |
|||
if (this.formItem.name) { |
|||
if (!this.is_reset) { |
|||
this.is_reset = false |
|||
this.formItem.setValue(this.val) |
|||
} |
|||
this.rename = this.formItem.name |
|||
this.form.inputChildrens.push(this) |
|||
} |
|||
} |
|||
}, |
|||
mounted() { |
|||
this.$nextTick(() => { |
|||
this.focused = this.focus |
|||
}) |
|||
}, |
|||
methods: { |
|||
/** |
|||
* 监听value 和 modelValue 变化 |
|||
*/ |
|||
resetValue(newVal) { |
|||
if (this.errMsg) this.errMsg = '' |
|||
this.val = newVal |
|||
if (this.form && this.formItem && !this.is_reset) { |
|||
this.is_reset = false |
|||
this.formItem.setValue(newVal) |
|||
} |
|||
}, |
|||
onClickIcon(type) { |
|||
this.$emit('iconClick', type) |
|||
}, |
|||
/** |
|||
* 获取父元素实例 |
|||
*/ |
|||
getForm(name = 'uniForms') { |
|||
let parent = this.$parent |
|||
let parentName = parent.$options.name |
|||
while (parentName !== name) { |
|||
parent = parent.$parent |
|||
if (!parent) return false |
|||
parentName = parent.$options.name |
|||
} |
|||
return parent |
|||
}, |
|||
|
|||
onEyes() { |
|||
this.showPassword = !this.showPassword |
|||
}, |
|||
onInput(event) { |
|||
let value = event.detail.value |
|||
// 判断是否去除空格 |
|||
if (this.trim) { |
|||
if (typeof this.trim === 'boolean' && this.trim) { |
|||
value = this.trimStr(value) |
|||
} |
|||
if (typeof this.trim === 'string') { |
|||
value = this.trimStr(value, this.trim) |
|||
} |
|||
} |
|||
if (this.errMsg) this.errMsg = '' |
|||
this.val = value |
|||
this.$emit('input', value) |
|||
this.$emit('update:modelValue', value) |
|||
}, |
|||
|
|||
onFocus(event) { |
|||
this.$emit('focus', event) |
|||
}, |
|||
onBlur(event) { |
|||
this.$emit('blur', event) |
|||
}, |
|||
onConfirm(e) { |
|||
this.$emit('confirm', e.detail.value) |
|||
}, |
|||
onClear() { |
|||
this.val = '' |
|||
this.$emit('input', '') |
|||
this.$emit('update:modelValue', '') |
|||
}, |
|||
fieldClick() { |
|||
this.$emit('click') |
|||
}, |
|||
trimStr(str, pos = 'both') { |
|||
if (pos === 'both') { |
|||
return str.trim() |
|||
} else if (pos === 'left') { |
|||
return str.trimLeft() |
|||
} else if (pos === 'right') { |
|||
return str.trimRight() |
|||
} else if (pos === 'start') { |
|||
return str.trimStart() |
|||
} else if (pos === 'end') { |
|||
return str.trimEnd() |
|||
} else if (pos === 'all') { |
|||
return str.replace(/\s+/g, '') |
|||
} else if (pos === 'none') { |
|||
return str |
|||
} |
|||
return str |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
$uni-error: #e43d33; |
|||
$uni-border-1: #dcdfe6 !default; |
|||
.uni-easyinput { |
|||
/* #ifndef APP-NVUE */ |
|||
width: 100%; |
|||
/* #endif */ |
|||
flex: 1; |
|||
position: relative; |
|||
text-align: left; |
|||
color: #333; |
|||
font-size: 14px; |
|||
} |
|||
|
|||
.uni-easyinput__content { |
|||
flex: 1; |
|||
/* #ifndef APP-NVUE */ |
|||
width: 100%; |
|||
display: flex; |
|||
box-sizing: border-box; |
|||
min-height: 21px; |
|||
height: 100%; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
align-items: center; |
|||
} |
|||
|
|||
.uni-easyinput__content-input { |
|||
/* #ifndef APP-NVUE */ |
|||
width: auto; |
|||
/* #endif */ |
|||
position: relative; |
|||
overflow: hidden; |
|||
flex: 1; |
|||
line-height: 1; |
|||
font-size: 14px; |
|||
} |
|||
.uni-easyinput__placeholder-class { |
|||
color: #999; |
|||
font-size: 12px; |
|||
font-weight: 200; |
|||
} |
|||
.is-textarea { |
|||
align-items: flex-start; |
|||
} |
|||
|
|||
.is-textarea-icon { |
|||
margin-top: 5px; |
|||
} |
|||
|
|||
.uni-easyinput__content-textarea { |
|||
position: relative; |
|||
overflow: hidden; |
|||
flex: 1; |
|||
line-height: 1.5; |
|||
font-size: 14px; |
|||
padding-top: 6px; |
|||
padding-bottom: 10px; |
|||
height: 80px; |
|||
/* #ifndef APP-NVUE */ |
|||
min-height: 80px; |
|||
width: auto; |
|||
/* #endif */ |
|||
} |
|||
|
|||
.input-padding { |
|||
padding-left: 10px; |
|||
} |
|||
|
|||
.content-clear-icon { |
|||
padding: 0 5px; |
|||
} |
|||
|
|||
.label-icon { |
|||
margin-right: 5px; |
|||
margin-top: -1px; |
|||
} |
|||
|
|||
// 显示边框 |
|||
.is-input-border { |
|||
/* #ifndef APP-NVUE */ |
|||
display: flex; |
|||
box-sizing: border-box; |
|||
/* #endif */ |
|||
flex-direction: row; |
|||
align-items: center; |
|||
border: 1px solid $uni-border-1; |
|||
border-radius: 4px; |
|||
} |
|||
|
|||
.uni-error-message { |
|||
position: absolute; |
|||
bottom: -17px; |
|||
left: 0; |
|||
line-height: 12px; |
|||
color: $uni-error; |
|||
font-size: 12px; |
|||
text-align: left; |
|||
} |
|||
|
|||
.uni-error-msg--boeder { |
|||
position: relative; |
|||
bottom: 0; |
|||
line-height: 22px; |
|||
} |
|||
|
|||
.is-input-error-border { |
|||
border-color: $uni-error; |
|||
.uni-easyinput__placeholder-class { |
|||
color: mix(#fff, $uni-error, 50%); |
|||
} |
|||
} |
|||
|
|||
.uni-easyinput--border { |
|||
margin-bottom: 0; |
|||
padding: 10px 15px; |
|||
// padding-bottom: 0; |
|||
border-top: 1px #eee solid; |
|||
} |
|||
|
|||
.uni-easyinput-error { |
|||
padding-bottom: 0; |
|||
} |
|||
|
|||
.is-first-border { |
|||
/* #ifndef APP-NVUE */ |
|||
border: none; |
|||
/* #endif */ |
|||
/* #ifdef APP-NVUE */ |
|||
border-width: 0; |
|||
/* #endif */ |
|||
} |
|||
|
|||
.is-disabled { |
|||
border-color: red; |
|||
background-color: #f7f6f6; |
|||
color: #d5d5d5; |
|||
.uni-easyinput__placeholder-class { |
|||
color: #d5d5d5; |
|||
font-size: 12px; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,95 @@ |
|||
<template> |
|||
<view class="wrapper"> |
|||
<view class="minus-box" @tap="minusTap"> |
|||
<uni-icons size="16" custom-prefix="iconfont" type="icon-Less" color="#007AFF"></uni-icons> |
|||
</view> |
|||
<view style="padding: 0rpx 4rpx"> |
|||
<qn-easyinput |
|||
:inputBorder="false" |
|||
class="quantity-input" |
|||
style="height: 64rpx" |
|||
:clearable="false" |
|||
type="number" |
|||
:value="value" |
|||
placeholder="请输入" |
|||
@blur="blur" |
|||
@confirm="confirm" |
|||
@input="input" |
|||
></qn-easyinput> |
|||
</view> |
|||
<view class="minus-box" @tap="addTap"><uni-icons size="16" type="plusempty" color="#007AFF"></uni-icons></view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
quantity: { |
|||
type: [Number, String], |
|||
default: 0 |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
value: 0 |
|||
} |
|||
}, |
|||
watch: { |
|||
quantity: { |
|||
handler(nv, ov) { |
|||
this.value = nv |
|||
}, |
|||
immediate: true |
|||
} |
|||
}, |
|||
methods: { |
|||
input(value) { |
|||
this.$emit('input', value) |
|||
}, |
|||
blur(e) { |
|||
this.$emit('change', e.detail.value) |
|||
}, |
|||
confirm(value) { |
|||
if (value.trim()) { |
|||
this.$emit('change', value) |
|||
} |
|||
}, |
|||
minusTap() { |
|||
if (this.value == 0) { |
|||
return |
|||
} |
|||
this.value-- |
|||
this.$emit('change', this.value) |
|||
}, |
|||
addTap() { |
|||
this.value++ |
|||
this.$emit('change', this.value) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.wrapper { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
.minus-box { |
|||
width: 64rpx; |
|||
height: 64rpx; |
|||
line-height: 64rpx; |
|||
text-align: center; |
|||
background: #f2f3f5; |
|||
border-radius: 8rpx; |
|||
color: #007aff; |
|||
} |
|||
.quantity-input { |
|||
width: 120rpx; |
|||
height: 64rpx; |
|||
background: #f2f3f5; |
|||
/deep/ .uni-easyinput__content { |
|||
min-height: 64rpx; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,95 @@ |
|||
<template> |
|||
<view class="mask" @click="hide" v-if="visible"> |
|||
<view class="flex-col items-center group_7" @click.stop="() => {}" v-if="codeUrl"> |
|||
<image :src="imgStamp['service-bg']" class="image_12" /> |
|||
<view class="group_8"> |
|||
<view class="flex-col items-center image-wrapper_1"> |
|||
<image :src="codeUrl" :show-menu-by-longpress="true" class="image_13" /> |
|||
</view> |
|||
<text class="text_10">{{ text }}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { imgStamp } from '@/enums/index' |
|||
export default { |
|||
props: { |
|||
codeUrl: { |
|||
type: String, |
|||
default: '' |
|||
}, |
|||
text: { |
|||
type: String, |
|||
default: '' |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
visible: false, |
|||
imgStamp: Object.freeze(imgStamp) |
|||
} |
|||
}, |
|||
methods: { |
|||
show() { |
|||
this.visible = true |
|||
}, |
|||
hide() { |
|||
this.visible = false |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.mask { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
background-color: rgba(0, 0, 0, 0.6); |
|||
z-index: 100; |
|||
display: flex; |
|||
justify-content: center; |
|||
align-items: center; |
|||
.group_7 { |
|||
width: 588rpx; |
|||
position: relative; |
|||
.image_12 { |
|||
width: 588rpx; |
|||
height: 646rpx; |
|||
} |
|||
.group_8 { |
|||
display: flex; |
|||
flex-direction: column; |
|||
align-items: center; |
|||
width: 440rpx; |
|||
position: absolute; |
|||
top: 56rpx; |
|||
left: 50%; |
|||
transform: translateX(-50%); |
|||
.image-wrapper_1 { |
|||
padding: 20rpx 0 22rpx; |
|||
background-color: #ffffff; |
|||
width: 402rpx; |
|||
.image_13 { |
|||
border-radius: 16rpx; |
|||
width: 360rpx; |
|||
height: 360rpx; |
|||
} |
|||
} |
|||
.text_10 { |
|||
margin-top: 40rpx; |
|||
color: #4f270d; |
|||
font-size: 36rpx; |
|||
font-family: 'PingFangSC-Medium'; |
|||
font-weight: 500; |
|||
line-height: 50rpx; |
|||
// letter-spacing: 14rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,5 @@ |
|||
export default { |
|||
empty: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHoAAABoCAYAAAA+R+R0AAAG50lEQVR4Xu2df1PURhjHn71fOQ8ZsKIoWioWsHcOLU49O53OqbwDfQm+AugraN+B+grad1D7CkDPzrSeHbAM54+2YLHiyGAL43DclSTb2UgwQC7Zu01ySfbJPzdym2ef5/vJdzeX7KwE8JBCASJFlVgkIGhJLgIEjaAlUUCSMtHRCFoSBSQpEx2NoCVRQJIy0dEBgi5XqtOlYmEiwC53u0LQAalersxfBUhOA2gTpeLYTEDdIuighUbQQSsecH/vAJvHO0eb/wrS2Th0+wiezckAYAF9oLOZoOZsBO0jaBYaHe2zwGELj3N02Ij4lA+Ctgg7PTvbO3Hhwrr56ZPmHQuLv6MBgMFNqcocAPkOgN4oFQtnOkYkhh2H6masXFn4FoB8Qym5cflS/vsY6t2xkkIDmjk6qSrPgZIpAvpU6dL58Y6pEsOOQwM6htqGqiQEHSoc/iWDoP3TNlSREXSocPiXDIL2T9tQRUbQocLhXzII2j9tQxUZQYcKh3/JIGj/tA1VZGlAsydvaS1zk1JiPEMnhD7fTv73NXuJEioiPiUjBeifHiyM64TMJBKkK3com2Ja1rbqqq7TzQSlV7+6dH7OJ31DEzZ2oO89rF4jFCatChOAz0kikTt3diB5KKsYX23VG/B0cUWjul6jAL9a21MCty9fLNwJDSUPEokV6B3IP6TTSVXJZAznskNJp+B4Xw+YkM2/M9iraxvQ2FZ3pdyqN3RN0xOUwPU4wY4U6PKD6iQQuOZwgY9n0qme/PCHJJlMtO2Dueoi6Dplc3fTIZ0CzGkquT3xZf552x0FeGJkQN9/+Pg3SulYJp1SD2Xfu9Wq1WatDtmsAqNDA0ISPltagXq9AV25rG2czVpDVzUtAUDXVTVxIQqwIwH6fqU6RQFuDg70weDAsaYQ55/+BVuNbch/fBpEHP3o8RL0dndBfvh0075WXv8Diy9eAxC4XbpYmBK6sgI42TPQd39hq0MArnxx3vj08ihXqjNKJl0qfjrsOB6/WX8Lj//4GzKZtDEvt3PU6g3QNN2AfLS32zHEz7PPmLPLpWLBae12O2l4fo5noHcWq4MfC9IZ6J7u3JWxcx+5CsBgM7eJHAP9H7hCZvHZCLLxtnYXQYuobTm3FdAedckVRhrQbLhOJMgVO1V0nd71ahhH0FzXnWMjoaEbQePQLX4J4tDtqYZCjrZmEpabMU/VcQkmzRxt1cHvn1e8d90I2l4Bzxztp8B4MyauLoIW0FDKoVtAL9dTvXJ0vbENvy+9goH+I3D0iPNTL9ekZH1gwiNMu228Ar38cg2WV9bAeGZ+qq/ddHbPQ0cLS7g3AIIWF1SqOboVR2+8rUFPd85RYXS0+AW4JwKPo2cXluBwLgtDg8chlUzaZsADWtU0mH/yAti77fzwKce5HEEHDJrBqTz603i9yBYLjA6dsF008OZf9hrzJRztPQz5kYPvmhlcBpnFUzJpGPtkELJKumk1CDpg0Kw7BunZ0ivYrDUMR48MnTjgRjYczz9ZNu66zw7278ny9doGLC2vGpC7cooBudnIYJ6IoDsAmnXJIC0urxoL/tgxMnQS+vt69mTD2uwHaDqdNWSLCEeHTnJVgKC5ZOJvxDNHW6MZy3yWV22da9er6XS7C8MpSwTNz5CrZaugWVD2cMRpfuXq2KURgvZCRUuMdkB7nIJtOATtscoIWlxQqR6YiMu1NwI62mNF0dHigqKjBTQUcbSfCzXsSkLQHQLt59IrBC0A1e5UEUcjaBtF4zJHB7U8Gh3dYUcjaBcAcXG0tUwcumM8dCNoCR2NP68kcbTHtwuu4QL7HX2vUr1DgNwCoJOlYuG6a2b4UqMViVzbBgba3J6CAvx4uVhw2nDmQNLsZiyrpEsXx5x3PHCt1uMGUu544KZh+cHCHBCyTgHGtVTjTCs79r3fw+SYsSY7DIe0e5i4ic9272M79Jmfbu33f79zoXymZFJqVrHflajVmO22N3clogAbmkrGcVeidpVsct6Os1sa9j1O4X04AnPqNrkVBcgs6cDmaN8Ex8BcCiBoLpmi3whBR58hVwUImkum6DdC0NFnyFWBEOi9/9s5V39SNCoVx2ashVp12v+d2Y5Hy2bn8ojaNuid12yh3wOTRwQf2syYW2Ue1EmbOHghVKcBgEfL3bit5tw2aNYRz1XYakJxaB8rR8cBiEw1CDlaJqGiXiuCjjpBzvwRNKdQUW+GoKNOkDP/UIJ2WhbL6tq/F7i5opKzZk+bebkvuaeJ7QuGoAXVRdCCAuLp3ioQSkd7WyJGYwogaEmuAwSNoCVRQJIy0dEIWhIFJCkTHY2gJVFAkjLR0QhaEgUkKRMdjaAlUUCSMtHRkoD+H39JyZZ6zcs+AAAAAElFTkSuQmCC', |
|||
success: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCIgdmlld0JveD0iMCAwIDQ4IDQ4IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgZmlsbD0id2hpdGUiIGZpbGwtb3BhY2l0eT0iMC4wMSIvPjxwYXRoIGQ9Ik0xMCAyNEwyMCAzNEw0MCAxNCIgc3Ryb2tlPSIjMzAzMTMzIiBzdHJva2Utd2lkdGg9IjMiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjwvc3ZnPg==', |
|||
error: 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCIgdmlld0JveD0iMCAwIDQ4IDQ4IiBmaWxsPSJub25lIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHdpZHRoPSI0OCIgaGVpZ2h0PSI0OCIgZmlsbD0id2hpdGUiIGZpbGwtb3BhY2l0eT0iMC4wMSIvPjxwYXRoIGQ9Ik0xNCAxNEwzNCAzNCIgc3Ryb2tlPSIjMzAzMTMzIiBzdHJva2Utd2lkdGg9IjMiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjxwYXRoIGQ9Ik0xNCAzNEwzNCAxNCIgc3Ryb2tlPSIjMzAzMTMzIiBzdHJva2Utd2lkdGg9IjMiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCIvPjwvc3ZnPg==' |
|||
} |
|||
@ -0,0 +1,696 @@ |
|||
<template> |
|||
<view class="scroll-list-wrap" :style="[scrollListWrapStyle]"> |
|||
<scroll-view |
|||
class="scroll-view" |
|||
:class="[elClass]" |
|||
:style="[listWrapStyle]" |
|||
scroll-y |
|||
scroll-anchoring |
|||
enable-back-to-top |
|||
:scroll-top="scrollTop" |
|||
:lower-threshold="defaultOption.lowerThreshold" |
|||
@scroll="handleScroll" |
|||
@touchend="handleTouchEnd" |
|||
@touchmove.prevent.stop="handleTouchMove" |
|||
@touchstart="handleTouchStart" |
|||
@scrolltolower="handleScrolltolower" |
|||
> |
|||
<view class="scroll-content" :style="[scrollContentStyle]"> |
|||
<view class="pull-down-wrap"> |
|||
<slot name="pulldown" v-if="$slots.pulldown"></slot> |
|||
<view class="refresh-view" :style="[refreshViewStyle]" v-else> |
|||
<view |
|||
class="pull-down-animation" |
|||
:class="{ refreshing: refreshing }" |
|||
:style="[pullDownAnimationStyle]" |
|||
></view> |
|||
<text class="pull-down-text" :style="[pullDownTextStyle]">{{ |
|||
refreshStateText |
|||
}}</text> |
|||
</view> |
|||
</view> |
|||
<view class="empty-wrap" v-if="showEmpty"> |
|||
<slot name="empty" v-if="$slots.empty"></slot> |
|||
<view class="empty-view flex-col-center-center" v-else> |
|||
<image |
|||
class="empty-image" |
|||
:src="defaultOption.emptyImage || images.empty" |
|||
mode="aspectFit" |
|||
></image> |
|||
<text class="empty-text" :style="[emptyTextStyle]">{{ emptyText }}</text> |
|||
</view> |
|||
</view> |
|||
<view class="list-content"><slot></slot></view> |
|||
<view class="pull-up-wrap" v-if="showPullUp"> |
|||
<slot name="pullup" v-if="$slots.pullup"></slot> |
|||
<view class="load-view" v-else> |
|||
<view |
|||
class="pull-up-animation" |
|||
v-if="loading" |
|||
:style="[pullUpAnimationStyle]" |
|||
></view> |
|||
<text class="pull-up-text" :style="[pullUpTextStyle]">{{ |
|||
loadStateText |
|||
}}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</scroll-view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import images from "./images.js"; |
|||
export default { |
|||
name: "scroll-list", |
|||
props: { |
|||
// 配置信息 |
|||
option: { |
|||
type: Object, |
|||
default: () => ({}), |
|||
}, |
|||
}, |
|||
data() { |
|||
return { |
|||
defaultOption: { |
|||
page: 1, // 分页 |
|||
size: 15, // 分页大小 |
|||
auto: true, // 自动加载 |
|||
height: null, // 组件高度 |
|||
disabled: false, // 禁用 |
|||
background: "", // 背景颜色属性 |
|||
emptyImage: "", // 空数据提示图片 |
|||
offsetBottom: 0, // 底部高度补偿 |
|||
pullDownSpeed: 0.5, // 下拉速率 |
|||
lowerThreshold: 40, // 距离底部上拉加载距离 |
|||
refresherThreshold: 80, // 距离顶部下拉刷新距离 |
|||
refreshDelayed: 800, // 刷新延迟 |
|||
refreshFinishDelayed: 800, // 刷新完成后的延迟 |
|||
safeArea: false, // 是否开启安全区域适配 |
|||
emptyTextColor: "#82848a", // 空提示文字颜色 |
|||
loadTextColor: "#82848a", // 上拉加载文字颜色 |
|||
loadIconColor: "#82848a", // 上拉加载图标颜色 |
|||
refresherTextColor: "#82848a", // 下拉刷新文字颜色 |
|||
refresherIconColor: "#82848a", // 下拉刷新图标颜色 |
|||
emptyText: "暂无列表~", // 空数据提示文字 |
|||
loadingText: "正在加载中~", // 加载中文字 |
|||
loadFailText: "加载失败啦~", // 加载失败文字 |
|||
noMoreText: "没有更多啦~", // 没有更多文字 |
|||
refreshingText: "正在刷新~", // 正在刷新文字 |
|||
refreshFailText: "刷新失败~", // 刷新失败文字 |
|||
refreshSuccessText: "刷新成功~", // 刷新成功文字 |
|||
pulldownText: "下拉刷新~", // 下拉中的文字 |
|||
pulldownFinishText: "松开刷新~", // 下拉完成的文字 |
|||
}, |
|||
images, // 内置图片 |
|||
elClass: "", // 组件动态class |
|||
windowInfo: {}, // 窗口信息 |
|||
scrollTop: 0, // 距离顶部滚动高度 |
|||
scrollViewTop: -1, // 滚动视图顶部位置 |
|||
scrollViewHeight: 0, // 滚动视图高度 |
|||
currentPage: 1, // 当前分页页码 |
|||
currentSize: 15, // 当前分页大小 |
|||
currentScrollTop: 0, // 当前滚动高度 |
|||
emptyText: "暂无列表~", |
|||
loadStateText: "正在加载中~", // 加载状态文字 |
|||
refreshStateText: "下拉刷新~", // 刷新状态文字 |
|||
loadDisabled: false, // 是否禁用上拉加载 |
|||
loading: false, // 是否加载中 |
|||
refreshing: false, // 是否刷新中 |
|||
refreshFinish: false, // 是否刷新完成 |
|||
pulldowning: false, // 是否正在下拉 |
|||
pullDownHeight: 0, // 下拉高度 |
|||
showEmpty: false, // 是否显示空数据提示 |
|||
showPullUp: false, // 是否显示上拉加载 |
|||
showPullDown: false, // 是否显示下拉刷新 |
|||
}; |
|||
}, |
|||
methods: { |
|||
// 组件初始化 |
|||
handleInit() { |
|||
// 合并配置 |
|||
this.defaultOption = Object.assign(this.defaultOption, this.option); |
|||
this.showEmpty = !this.defaultOption.auto; |
|||
this.currentPage = this.defaultOption.page; |
|||
this.currentSize = this.defaultOption.size; |
|||
this.emptyText = this.defaultOption.emptyText; |
|||
this.loadStateText = this.defaultOption.loadingText; |
|||
this.refreshStateText = this.defaultOption.pulldownText; |
|||
// 计算高度 |
|||
this.queryRect("." + this.elClass).then((rect) => { |
|||
// 设置组件顶部位置 |
|||
this.scrollViewTop = rect.top; |
|||
// 判断是否自动加载 |
|||
if (this.defaultOption.auto) this.load(); |
|||
}); |
|||
}, |
|||
// 加载数据 |
|||
load() { |
|||
if (this.defaultOption.disabled || this.loading || this.loadDisabled) return; |
|||
// 开启正在加载 |
|||
this.loading = true; |
|||
// 设置正在加载状态文字 |
|||
this.loadStateText = this.defaultOption.loadingText; |
|||
// 显示上拉加载 |
|||
this.showPullUp = true; |
|||
// 分页参数 |
|||
let paging = { page: this.currentPage, size: this.currentSize }; |
|||
// 触发load事件 |
|||
this.$emit("load", paging); |
|||
}, |
|||
// 加载成功 |
|||
loadSuccess(data = {}) { |
|||
// 解构数据 |
|||
const { list, total } = data; |
|||
// 判断列表是否是数组 |
|||
if (Array.isArray(list)) { |
|||
// 判断列表长度 |
|||
if (list.length) { |
|||
// 判断列表长度和列表总数是否相同 |
|||
if (list.length >= total) { |
|||
// 设置禁用上拉加载 |
|||
this.loadDisabled = true; |
|||
// 加载状态文字 |
|||
this.loadStateText = this.defaultOption.noMoreText; |
|||
} else { |
|||
// 关闭禁用上拉加载 |
|||
this.loadDisabled = false; |
|||
// 设置分页参数 |
|||
this.currentPage++; |
|||
// 加载状态为加载中 |
|||
this.loadStateText = this.defaultOption.loadingText; |
|||
// 加载计算 |
|||
this.loadCompute(); |
|||
} |
|||
// 显示上拉加载 |
|||
this.showPullUp = true; |
|||
// 隐藏空数据提示 |
|||
this.showEmpty = false; |
|||
} else { |
|||
// 设置禁用上拉加载 |
|||
this.loadDisabled = true; |
|||
// 隐藏上拉加载 |
|||
this.showPullUp = false; |
|||
// 隐藏上拉加载 |
|||
this.showPullUp = false; |
|||
// 显示空数据提示 |
|||
this.showEmpty = true; |
|||
} |
|||
// 关闭正在加载 |
|||
this.loading = false; |
|||
// 触发加载成功事件 |
|||
this.$emit("loadSuccess", list); |
|||
} else { |
|||
// 不是数组类型当作加载失败处理 |
|||
this.loadFail(); |
|||
console.error("the list must be a array"); |
|||
} |
|||
}, |
|||
// 加载失败 |
|||
loadFail() { |
|||
// 关闭正在加载 |
|||
this.loading = false; |
|||
// 关闭空数据提示 |
|||
this.showEmpty = false; |
|||
// 显示上拉加载 |
|||
this.showPullUp = true; |
|||
// 加载状态为加载失败 |
|||
this.loadStateText = this.defaultOption.loadFailText; |
|||
// 触发加载失败事件 |
|||
this.$emit("loadFail"); |
|||
}, |
|||
// 刷新数据 |
|||
refresh() { |
|||
// 如果是下拉刷新 |
|||
if (this.pullDownHeight == this.defaultOption.refresherThreshold) { |
|||
// 关闭正在加载 |
|||
this.loading = false; |
|||
// 隐藏上拉加载 |
|||
this.showPullUp = false; |
|||
} else { |
|||
// 开启正在加载 |
|||
this.loading = true; |
|||
// 隐藏空数据提示 |
|||
this.showEmpty = false; |
|||
// 显示上拉加载 |
|||
this.showPullUp = true; |
|||
// 设置正在刷新状态文字 |
|||
this.loadStateText = this.defaultOption.refreshingText; |
|||
} |
|||
// 设置刷新未完成 |
|||
this.refreshFinish = false; |
|||
// 开启正在刷新 |
|||
this.refreshing = true; |
|||
// 设置正在刷新状态文字 |
|||
this.refreshStateText = this.defaultOption.refreshingText; |
|||
// 设置分页参数 |
|||
this.currentPage = 1; |
|||
this.currentSize = this.defaultOption.size; |
|||
let paging = { page: this.currentPage, size: this.currentSize }; |
|||
// 触发refresh事件 |
|||
setTimeout(() => { |
|||
this.$emit("refresh", paging); |
|||
}, this.defaultOption.refreshDelayed); |
|||
}, |
|||
// 刷新成功 |
|||
refreshSuccess(data) { |
|||
// 解构数据 |
|||
const { list, total } = data; |
|||
// 判断列表是否是数组 |
|||
if (Array.isArray(list)) { |
|||
// 判断列表长度 |
|||
if (list.length) { |
|||
// 判断列表长度和列表总数是否相同 |
|||
if (list.length >= total) { |
|||
// 设置禁用上拉加载 |
|||
this.loadDisabled = true; |
|||
// 设置没有更多状态文字 |
|||
this.loadStateText = this.defaultOption.noMoreText; |
|||
} else { |
|||
// 设置分页参数 |
|||
this.currentPage++; |
|||
// 关闭禁用上拉加载 |
|||
this.loadDisabled = false; |
|||
// 设置加载中状态文字 |
|||
this.loadStateText = this.defaultOption.loadingText; |
|||
// 开启自动加载 |
|||
this.defaultOption.auto = true; |
|||
// 加载计算 |
|||
this.loadCompute(); |
|||
} |
|||
// 关闭空数据提示 |
|||
this.showEmpty = false; |
|||
// 显示上拉加载 |
|||
this.showPullUp = true; |
|||
} else { |
|||
// 设置禁用上拉加载 |
|||
this.loadDisabled = true; |
|||
// 隐藏上拉加载 |
|||
this.showPullUp = false; |
|||
// 显示空数据提示 |
|||
this.showEmpty = true; |
|||
// 设置没有更多状态文字 |
|||
this.loadStateText = this.defaultOption.noMoreText; |
|||
} |
|||
// 关闭正在加载 |
|||
this.loading = false; |
|||
// 设置刷新成功状态文字 |
|||
this.refreshStateText = this.defaultOption.refreshSuccessText; |
|||
// 关闭正在刷新 |
|||
this.refreshing = false; |
|||
// 关闭正在下拉 |
|||
this.pulldowning = false; |
|||
// 触发刷新成功事件 |
|||
this.$emit("refreshSuccess", list); |
|||
setTimeout(() => { |
|||
// 设置刷新完成 |
|||
this.refreshFinish = true; |
|||
// 重置下拉高度 |
|||
this.pullDownHeight = 0; |
|||
// 隐藏下拉刷新 |
|||
this.showPullDown = false; |
|||
this.$emit("refreshSuccess"); |
|||
}, this.defaultOption.refreshFinishDelayed); |
|||
} else { |
|||
// 不是数组类型当作刷新失败处理 |
|||
this.refreshFail(); |
|||
console.error("the list must be a array"); |
|||
} |
|||
}, |
|||
// 刷新失败 |
|||
refreshFail() { |
|||
// 设置加载失败状态文字 |
|||
this.loadStateText = this.defaultOption.refreshFailText; |
|||
// 设置刷新失败状态文字 |
|||
this.refreshStateText = this.defaultOption.refreshFailText; |
|||
// 关闭正在加载 |
|||
this.loading = false; |
|||
// 显示下拉加载 |
|||
this.showPullUp = true; |
|||
// 关闭正在刷新 |
|||
this.refreshing = false; |
|||
// 关闭正在下拉 |
|||
this.pulldowning = false; |
|||
// 延迟执行刷新完成后状态 |
|||
setTimeout(() => { |
|||
// 设置刷新完成 |
|||
this.refreshFinish = true; |
|||
// 重置下拉高度 |
|||
this.pullDownHeight = 0; |
|||
// 隐藏下拉刷新 |
|||
this.showPullDown = false; |
|||
// 触发刷新失败事件 |
|||
this.$emit("refreshError"); |
|||
}, this.defaultOption.refreshFinishDelayed); |
|||
}, |
|||
// 加载计算 |
|||
loadCompute() { |
|||
// 判断是否自动加载 |
|||
if (this.defaultOption.auto) { |
|||
// 延迟执行下否者可能会高度计算错误 |
|||
setTimeout(() => { |
|||
this.$nextTick(() => { |
|||
this.queryRect(".list-content").then((rect) => { |
|||
if (rect.height <= this.scrollViewHeight) { |
|||
this.load(); |
|||
} |
|||
}); |
|||
}); |
|||
}, 100); |
|||
} |
|||
}, |
|||
// 上拉触底事件 |
|||
handleScrolltolower(e) { |
|||
if (this.loadDisabled) return; |
|||
this.$emit("scrolltolower", e); |
|||
this.load(); |
|||
}, |
|||
// 滚动事件 |
|||
handleScroll(event) { |
|||
this.currentScrollTop = event.detail.scrollTop; |
|||
this.$emit("scroll", event.detail); |
|||
}, |
|||
// 触摸按下处理 |
|||
handleTouchStart(event) { |
|||
if (this.defaultOption.disabled) return; |
|||
this.currentTouchStartY = event.touches[0].clientY; |
|||
this.$emit("touchStart", event); |
|||
}, |
|||
// 触摸按下滑动处理 |
|||
handleTouchMove(event) { |
|||
if (this.defaultOption.disabled || this.currentScrollTop) return; |
|||
if (event.touches[0].clientY >= this.currentTouchStartY) { |
|||
this.pulldowning = true; |
|||
this.showPullDown = true; |
|||
let pullDownDistance = |
|||
(event.touches[0].clientY - this.currentTouchStartY) * |
|||
this.defaultOption.pullDownSpeed; |
|||
this.pullDownHeight = |
|||
pullDownDistance > this.defaultOption.refresherThreshold |
|||
? this.defaultOption.refresherThreshold |
|||
: pullDownDistance; |
|||
this.refreshStateText = |
|||
this.pullDownHeight >= this.defaultOption.refresherThreshold |
|||
? this.defaultOption.pulldownFinishText |
|||
: this.defaultOption.pulldownText; |
|||
this.$emit("touchMove", event); |
|||
} |
|||
}, |
|||
// 触摸松开处理 |
|||
handleTouchEnd(event) { |
|||
if (this.defaultOption.disabled) return; |
|||
// 当下拉高度小于下拉阈值 |
|||
if (this.pullDownHeight < this.defaultOption.refresherThreshold) { |
|||
// 关闭正在下拉 |
|||
this.pulldowning = false; |
|||
// 重置下拉高度 |
|||
this.pullDownHeight = 0; |
|||
// 隐藏下拉刷新 |
|||
this.showPullDown = false; |
|||
// 触发下拉中断事件 |
|||
this.$emit("refreshStop"); |
|||
} else { |
|||
this.refresh(); |
|||
} |
|||
// 触发下拉触摸松开事件 |
|||
this.$emit("touchEnd", event); |
|||
}, |
|||
// 更新组件 |
|||
updateScrollView() { |
|||
if (this.defaultOption.height) { |
|||
this.scrollViewHeight = uni.upx2px(this.defaultOption.height); |
|||
} else { |
|||
this.scrollViewHeight = this.windowInfo.windowHeight - this.scrollViewTop; |
|||
} |
|||
this.scrollViewObserve(); |
|||
}, |
|||
// 监听列表高度变化 |
|||
listContentObserve() { |
|||
this.disconnectObserve("_listContentObserve"); |
|||
const listContentObserve = this.createIntersectionObserver({ |
|||
thresholds: [0, 0.5, 1], |
|||
}); |
|||
listContentObserve.relativeToViewport({ |
|||
// #ifdef H5 |
|||
top: -(this.windowInfo.windowTop + rect.top), |
|||
// #endif |
|||
// #ifndef H5 |
|||
top: -rect.top, |
|||
// #endif |
|||
}); |
|||
}, |
|||
// 监听组件位置变化 |
|||
scrollViewObserve() { |
|||
this.disconnectObserve("_scrollViewObserve"); |
|||
this.$nextTick(() => { |
|||
this.queryRect("." + this.elClass).then((rect) => { |
|||
const scrollViewObserve = this.createIntersectionObserver({ |
|||
thresholds: [0, 0.5, 1], |
|||
}); |
|||
scrollViewObserve.relativeToViewport({ |
|||
// #ifdef H5 |
|||
top: -(this.windowInfo.windowTop + rect.top), |
|||
// #endif |
|||
// #ifndef H5 |
|||
top: -rect.top, |
|||
// #endif |
|||
}); |
|||
scrollViewObserve.observe("." + this.elClass, (position) => { |
|||
// #ifdef H5 |
|||
this.scrollViewTop = |
|||
position.boundingClientRect.top - this.windowInfo.windowTop; |
|||
// #endif |
|||
// #ifndef H5 |
|||
this.scrollViewTop = position.boundingClientRect.top; |
|||
// #endif |
|||
}); |
|||
this._scrollViewObserve = scrollViewObserve; |
|||
}); |
|||
}); |
|||
}, |
|||
// 断开监听组件 |
|||
disconnectObserve(observerName) { |
|||
const observer = this[observerName]; |
|||
observer && observer.disconnect(); |
|||
}, |
|||
// 查询dom节点信息 |
|||
queryRect(selector, all) { |
|||
return new Promise((resolve) => { |
|||
uni |
|||
.createSelectorQuery() |
|||
.in(this) |
|||
[all ? "selectAll" : "select"](selector) |
|||
.boundingClientRect((rect) => { |
|||
if (all && Array.isArray(rect) && rect.length) { |
|||
resolve(rect); |
|||
} |
|||
if (!all && rect) { |
|||
resolve(rect); |
|||
} |
|||
}) |
|||
.exec(); |
|||
}); |
|||
}, |
|||
// 16进制转RGB |
|||
hexToRgb(hex) { |
|||
const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i; |
|||
hex = hex.replace(shorthandRegex, (m, r, g, b) => { |
|||
return r + r + g + g + b + b; |
|||
}); |
|||
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); |
|||
return result |
|||
? { |
|||
r: parseInt(result[1], 16), |
|||
g: parseInt(result[2], 16), |
|||
b: parseInt(result[3], 16), |
|||
} |
|||
: null; |
|||
}, |
|||
}, |
|||
computed: { |
|||
scrollListWrapStyle() { |
|||
return { |
|||
background: this.defaultOption.background, |
|||
}; |
|||
}, |
|||
// 组件容器样式 |
|||
listWrapStyle() { |
|||
let style = {}; |
|||
const { offsetBottom } = this.defaultOption; |
|||
style.height = this.scrollViewHeight - uni.upx2px(offsetBottom) + "px"; |
|||
if (this.defaultOption.safeArea) |
|||
style.paddingBottom = "env(safe-area-inset-bottom) !important"; |
|||
return style; |
|||
}, |
|||
// 滚动内容样式 |
|||
scrollContentStyle() { |
|||
const style = {}; |
|||
const { pullDownHeight, pulldowning, showPullDown } = this; |
|||
style.transform = showPullDown |
|||
? `translateY(${pullDownHeight}px)` |
|||
: `translateY(0px)`; |
|||
style.transition = pulldowning |
|||
? `transform 100ms ease-out` |
|||
: `transform 200ms cubic-bezier(0.19,1.64,0.42,0.72)`; |
|||
return style; |
|||
}, |
|||
// 下拉刷新样式 |
|||
refreshViewStyle() { |
|||
const style = {}; |
|||
const { showPullDown } = this; |
|||
style.opacity = showPullDown ? 1 : 0; |
|||
return style; |
|||
}, |
|||
// 下拉中动画样式 |
|||
pullDownAnimationStyle() { |
|||
const style = {}; |
|||
const { refresherIconColor, refresherThreshold } = this.defaultOption; |
|||
const { refreshing, pullDownHeight } = this; |
|||
const { r, g, b } = this.hexToRgb(refresherIconColor); |
|||
const rate = pullDownHeight / refresherThreshold; |
|||
style.borderColor = `rgba(${r},${g},${b},0.2)`; |
|||
style.borderTopColor = refresherIconColor; |
|||
if (!refreshing) { |
|||
style.transform = `rotate(${360 * rate}deg)`; |
|||
style.transition = "transform 100ms linear"; |
|||
} |
|||
return style; |
|||
}, |
|||
pullDownTextStyle() { |
|||
const style = {}; |
|||
const { refresherTextColor } = this.defaultOption; |
|||
style.color = refresherTextColor; |
|||
return style; |
|||
}, |
|||
// 上拉中动画样式 |
|||
pullUpAnimationStyle() { |
|||
const style = {}; |
|||
const { loadIconColor } = this.defaultOption; |
|||
const { r, g, b } = this.hexToRgb(loadIconColor); |
|||
style.borderColor = `rgba(${r},${g},${b},0.2)`; |
|||
style.borderTopColor = loadIconColor; |
|||
return style; |
|||
}, |
|||
// 上拉中文字样式 |
|||
pullUpTextStyle() { |
|||
const style = {}; |
|||
const { loadTextColor } = this.defaultOption; |
|||
style.color = loadTextColor; |
|||
return style; |
|||
}, |
|||
// 空数据提示文字样式 |
|||
emptyTextStyle() { |
|||
const style = {}; |
|||
const { emptyTextColor } = this.defaultOption; |
|||
style.color = emptyTextColor; |
|||
return style; |
|||
}, |
|||
}, |
|||
watch: { |
|||
scrollViewTop(val) { |
|||
this.updateScrollView(); |
|||
}, |
|||
}, |
|||
created() { |
|||
this.elClass = "scroll-view-" + this._uid; |
|||
this.windowInfo = uni.getSystemInfoSync(); |
|||
}, |
|||
mounted() { |
|||
this.handleInit(); |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.scroll-list-wrap { |
|||
box-sizing: border-box; |
|||
.scroll-view { |
|||
position: relative; |
|||
.scroll-content { |
|||
height: 100%; |
|||
display: flex; |
|||
// will-change: transform; |
|||
flex-direction: column; |
|||
.pull-down-wrap { |
|||
left: 0; |
|||
width: 100%; |
|||
display: flex; |
|||
padding: 30rpx 0; |
|||
position: absolute; |
|||
align-items: flex-end; |
|||
justify-content: center; |
|||
transform: translateY(-100%); |
|||
.refresh-view { |
|||
display: flex; |
|||
justify-content: center; |
|||
.pull-down-animation { |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
border-width: 4rpx; |
|||
border-style: solid; |
|||
border-radius: 50%; |
|||
&.refreshing { |
|||
animation: spin 0.5s linear infinite; |
|||
} |
|||
@keyframes spin { |
|||
to { |
|||
transform: rotate(360deg); |
|||
} |
|||
} |
|||
} |
|||
.pull-down-text { |
|||
margin-left: 10rpx; |
|||
} |
|||
} |
|||
} |
|||
.empty-wrap { |
|||
top: 0; |
|||
left: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
display: flex; |
|||
position: absolute; |
|||
align-items: center; |
|||
flex-direction: column; |
|||
.empty-view { |
|||
// margin: auto; |
|||
display: flex; |
|||
align-items: center; |
|||
margin-bottom: 400rpx; |
|||
flex-direction: column; |
|||
.empty-image { |
|||
width: 600rpx; |
|||
height: 600rpx; |
|||
} |
|||
.empty-text { |
|||
color: #606266; |
|||
margin-top: 20rpx; |
|||
} |
|||
} |
|||
} |
|||
.pull-up-wrap { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
.load-view { |
|||
padding: 20rpx 0; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: center; |
|||
.pull-up-animation { |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
border-width: 4rpx; |
|||
border-style: solid; |
|||
border-radius: 50%; |
|||
animation: spin 0.5s linear infinite; |
|||
} |
|||
.pull-up-text { |
|||
margin-left: 10rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,110 @@ |
|||
import env from '@/env/index.js' |
|||
const urlEnv = env === 'production' ? '' : `-${env}` |
|||
|
|||
export const XAPPID = '503258978847966413' |
|||
|
|||
// 统一支付接口
|
|||
export const PAY_URL = `https://api-client-psc${urlEnv}.qniao.cn/payment-settlement-center/pay` |
|||
|
|||
/** |
|||
* 上传地址 |
|||
*/ |
|||
export const uploadUrl = { |
|||
image: `https://api-client-yyt${urlEnv}.qniao.cn/yyt-uec/file-uploading/upload/image`, |
|||
file: `https://api-client-yyt${urlEnv}.qniao.cn/yyt-uec/file-uploading/upload/file`, |
|||
// video: `https://api-client-yyt${urlEnv}.qniao.cn/yyt-uec/file-uploading/upload/file?type=mp4`
|
|||
video: `https://api-client-yyt${urlEnv}.qniao.cn/yyt-uec/file-uploading/upload/video/file?type=mp4`, |
|||
printFile: `https://api-ops-yyt${urlEnv}.qniao.cn/wukong-fast-print/printing-file/upload/file` |
|||
} |
|||
|
|||
/** |
|||
* 文件类型 图片:1,视频:2 |
|||
*/ |
|||
export const fileType = { |
|||
IMG: 1, |
|||
VIDEO: 2 |
|||
} |
|||
|
|||
/** |
|||
* 收货地址是否默认 1:默认 0:非默认 |
|||
*/ |
|||
export const addressType = { |
|||
DEFAULT: true, |
|||
NOT_DEFAULT: false |
|||
} |
|||
|
|||
/** |
|||
* 支付方式 1:微信支付 2:月结支付 4:飞算支付 |
|||
*/ |
|||
export const paymentMethodEnum = { |
|||
WECHAT_PAY: 1, |
|||
MONTHLY_PAY: 2, |
|||
FLY_PAY: 4 |
|||
} |
|||
|
|||
export const paymentMethodMap = { |
|||
[paymentMethodEnum.WECHAT_PAY]: '微信支付', |
|||
[paymentMethodEnum.MONTHLY_PAY]: '月结支付', |
|||
[paymentMethodEnum.FLY_PAY]: '飞算支付' |
|||
} |
|||
|
|||
/** |
|||
* 订单状态 0:全部 40001:待付款 40002:待确认 40003:生产中 40004:运输中 40005:已完成 40009:待揽收 40006:已取消 40007:退款中 |
|||
*/ |
|||
export const orderStatus = { |
|||
ALL: 0, |
|||
WAIT_PAY: 40001, |
|||
WAIT_CONFIRM: 40002, |
|||
PRINTING: 40003, |
|||
TRANSPORTING: 40004, |
|||
COMPLETED: 40005, |
|||
WAIT_COLLECT: 40009, |
|||
CANCELLED: 40006, |
|||
REFUND: 40007, |
|||
REFUNDED: 40008 |
|||
} |
|||
|
|||
/** |
|||
* 订单全部状态 40001:待付款 40002:待确认 40003:生产中 40004:运输中 40005:已完成 40007:退款中 40008:已退款 40009:待揽收 40006:已取消 |
|||
*/ |
|||
export const orderStatusMap = { |
|||
40001: '待付款', |
|||
40002: '待确认', |
|||
40003: '生产中', |
|||
40004: '运输中', |
|||
40005: '已完成', |
|||
40007: '退款中', |
|||
40008: '已退款', |
|||
40006: '已取消', |
|||
40009: '待发货' |
|||
} |
|||
/** |
|||
* 物料状态 20003:已发货 20004:已完成 20005:已取消 |
|||
*/ |
|||
export const suppliesOrderItemStatus = { |
|||
TRANSPORTING: 20003, |
|||
COMPLETED: 20004, |
|||
CANCEL: 20005 |
|||
} |
|||
/** |
|||
* 解决oss图片缓存问题 |
|||
*/ |
|||
let images = { |
|||
'service-bg': `https://qncloud.oss-cn-shenzhen.aliyuncs.com/wukong-printer-wx/service-bg.png` |
|||
} |
|||
|
|||
function splicingTimestamps(obj) { |
|||
for (let key in obj) { |
|||
obj[key] = obj[key] + `?timeStamp=${Date.now()}` |
|||
} |
|||
return obj |
|||
} |
|||
|
|||
export const imgStamp = Object.freeze(splicingTimestamps(images)) |
|||
|
|||
/** |
|||
* 全局事件key |
|||
*/ |
|||
export const cacheKey = { |
|||
ORDER_PARAM: 'orderParam' // 订单列表查询参数参数
|
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
/** |
|||
* @description 唯一环境变量 |
|||
*/ |
|||
const env = 'test' |
|||
// const env = 'dev'
|
|||
// const env = 'production'
|
|||
|
|||
export default env |
|||
@ -0,0 +1,12 @@ |
|||
{ |
|||
"compilerOptions": { |
|||
"baseUrl": ".", |
|||
"paths": { |
|||
"@/*": ["./*"], |
|||
"/*": ["./*"] |
|||
}, |
|||
"target": "ES6" |
|||
}, |
|||
"include": ["./**/*"], |
|||
"exclude": ["./uni_modules"] |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
import App from './App' |
|||
import store from './store' |
|||
import Vue from 'vue' |
|||
import { Monitor } from '@/utils/monitor/index' |
|||
import { XAPPID } from '@/enums/index.js' |
|||
import env from '@/env/index.js' |
|||
import vueWxRouter from '@/utils/vueWxRouter' |
|||
|
|||
const urlEnv = env === 'production' ? '' : `-${env}` |
|||
// # ifdef MP-WEIXIN
|
|||
// const monitor = new Monitor({
|
|||
// url: `https://api-client-yyt${urlEnv}.qniao.cn/wukong-fast-print/vue/error/message`,
|
|||
// timeout: 5000,
|
|||
// method: 'POST',
|
|||
// env,
|
|||
// header: { 'X-APP-ID': XAPPID }
|
|||
// })
|
|||
// monitor.init()
|
|||
// # endif
|
|||
|
|||
Vue.config.productionTip = false |
|||
// Vue.prototype.$store = store
|
|||
App.mpType = 'app' |
|||
Vue.use(vueWxRouter) |
|||
const app = new Vue({ |
|||
...App, |
|||
store |
|||
}) |
|||
app.$mount() |
|||
@ -0,0 +1,192 @@ |
|||
{ |
|||
"name" : "飞鸟快印", |
|||
"appid" : "__UNI__EBBA73E", |
|||
"description" : "", |
|||
"versionName" : "1.0.0", |
|||
"versionCode" : 100, |
|||
"transformPx" : false, |
|||
"networkTimeout" : { |
|||
"request" : 6000 |
|||
}, |
|||
/* 5+App特有相关 */ |
|||
"app-plus" : { |
|||
"usingComponents" : true, |
|||
"nvueStyleCompiler" : "uni-app", |
|||
"compilerVersion" : 3, |
|||
"splashscreen" : { |
|||
"alwaysShowBeforeRender" : true, |
|||
"waiting" : true, |
|||
"autoclose" : true, |
|||
"delay" : 0 |
|||
}, |
|||
"compatible" : { |
|||
"ignoreVersion" : true |
|||
}, |
|||
/* 模块配置 */ |
|||
"modules" : { |
|||
"iBeacon" : {}, |
|||
"Share" : {}, |
|||
"Payment" : {} |
|||
}, |
|||
/* 应用发布信息 */ |
|||
"distribute" : { |
|||
/* android打包配置 */ |
|||
"android" : { |
|||
"permissions" : [ |
|||
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>", |
|||
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>", |
|||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.BLUETOOTH\"/>", |
|||
"<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\"/>", |
|||
"<uses-permission android:name=\"android.permission.CAMERA\"/>", |
|||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.INTERNET\"/>", |
|||
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>", |
|||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>", |
|||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>", |
|||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>", |
|||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>", |
|||
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>", |
|||
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>", |
|||
"<uses-permission android:name=\"android.permission.BLUETOOTH\"/>", |
|||
"<uses-permission android:name=\"android.permission.BLUETOOTH_ADMIN\"/>" |
|||
], |
|||
"abiFilters" : [ "armeabi-v7a", "x86" ] |
|||
}, |
|||
/* ios打包配置 */ |
|||
"ios" : { |
|||
"privacyDescription" : { |
|||
"NSPhotoLibraryUsageDescription" : "该应用需要读取你的相册,以便为你编辑信息", |
|||
"NSPhotoLibraryAddUsageDescription" : "该应用需要读取你的相册,以便为你保存信息", |
|||
"NSCameraUsageDescription" : "该应用需要使用你的摄像头,以便为你编辑信息", |
|||
"NSLocationWhenInUseUsageDescription" : "该应用需要你的地理位置,以便为你提供当前位置附近印包厂信息", |
|||
"NSLocationAlwaysUsageDescription" : "该应用需要你的地理位置,以便为你提供当前位置附近印包厂信息", |
|||
"NSLocationAlwaysAndWhenInUseUsageDescription" : "该应用需要你的地理位置,以便为你提供当前位置附近印包厂信息" |
|||
}, |
|||
"idfa" : false |
|||
}, |
|||
/* SDK配置 */ |
|||
"sdkConfigs" : { |
|||
"maps" : { |
|||
"amap" : { |
|||
"appkey_ios" : "0182ee2a9fdd5fd3ef6a8bd5a2f98325", |
|||
"appkey_android" : "877848546f7f3717101a17c33e1d4df3" |
|||
} |
|||
}, |
|||
"payment" : { |
|||
"weixin" : { |
|||
"__platform__" : [ "ios", "android" ], |
|||
"appid" : "wx6c66084e2de41575", |
|||
"UniversalLinks" : "https://apple-app-yyt-printpackage.qniao.cn/" |
|||
} |
|||
}, |
|||
"ad" : {}, |
|||
"geolocation" : { |
|||
"amap" : { |
|||
"__platform__" : [ "ios", "android" ], |
|||
"appkey_ios" : "0182ee2a9fdd5fd3ef6a8bd5a2f98325", |
|||
"appkey_android" : "877848546f7f3717101a17c33e1d4df3" |
|||
} |
|||
}, |
|||
"share" : { |
|||
"weixin" : { |
|||
"appid" : "wx6c66084e2de41575", |
|||
"UniversalLinks" : "https://apple-app-yyt-printpackage.qniao.cn/" |
|||
} |
|||
}, |
|||
"push" : { |
|||
"unipush" : {} |
|||
} |
|||
}, |
|||
"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", |
|||
"iosStyle" : "common" |
|||
} |
|||
}, |
|||
"uniStatistics" : { |
|||
"enable" : true |
|||
}, |
|||
"nativePlugins" : {} |
|||
}, |
|||
/* 快应用特有相关 */ |
|||
"quickapp" : {}, |
|||
/* 小程序特有相关 */ |
|||
"mp-weixin" : { |
|||
"appid" : "wx74a65d2467a4d8ab", |
|||
"setting" : { |
|||
"urlCheck" : false, |
|||
"minified" : true |
|||
}, |
|||
"usingComponents" : true, |
|||
"plugins" : { |
|||
"materialPlugin" : { |
|||
"version" : "1.0.5", |
|||
"provider" : "wx4d2deeab3aed6e5a" |
|||
}, |
|||
"live-player-plugin" : { |
|||
"version" : "1.3.5", |
|||
"provider" : "wx2b03c6e691cd7370" |
|||
} |
|||
}, |
|||
"permission" : {}, |
|||
"requiredPrivateInfos" : [ "chooseAddress" ], |
|||
"lazyCodeLoading" : "requiredComponents" |
|||
}, |
|||
"navigateToMiniProgramAppIDList" : [ "wx654ce96a7324e76f" ], |
|||
"mp-alipay" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"mp-baidu" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"mp-toutiao" : { |
|||
"usingComponents" : true |
|||
}, |
|||
"uniStatistics" : { |
|||
"enable" : false |
|||
}, |
|||
"vueVersion" : "2", |
|||
"h5" : { |
|||
"router" : { |
|||
"mode" : "history" |
|||
}, |
|||
"devServer" : { |
|||
"port" : 9090 |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
{ |
|||
"name": "canvas 生成海报", |
|||
"version": "3.2.2", |
|||
"lockfileVersion": 2, |
|||
"requires": true, |
|||
"packages": { |
|||
"": { |
|||
"name": "canvas 生成海报", |
|||
"version": "3.2.2" |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
{ |
|||
"id": "hch-poster", |
|||
"name": "canvas 生成海报", |
|||
"version": "3.2.2", |
|||
"description": "分享弹窗,生成海报并支持保存,支持多端(H5,微信小程序,支付宝小程序,百度小程序,字节跳动小程序,QQ小程序)", |
|||
"keywords": [ |
|||
"分享", |
|||
"海报", |
|||
"自定义图片", |
|||
"小程序码", |
|||
"商城商品分享海报。" |
|||
] |
|||
} |
|||
@ -0,0 +1,103 @@ |
|||
{ |
|||
"pages": [ |
|||
{ |
|||
"path": "pages/index/index", |
|||
"style": { |
|||
"navigationBarTitleText": "首页", |
|||
"enablePullDownRefresh": false, |
|||
"navigationStyle": "custom" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/mine/index", |
|||
"style": { |
|||
"navigationBarTitleText": "个人中心", |
|||
"enablePullDownRefresh": false, |
|||
"navigationStyle": "custom" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/address/index", |
|||
"style": { |
|||
"navigationBarTitleText": "我的地址", |
|||
"enablePullDownRefresh": false, |
|||
"navigationStyle": "custom" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/pay/index", |
|||
"style": { |
|||
"navigationBarTitleText": "支付", |
|||
"enablePullDownRefresh": false, |
|||
"navigationStyle": "custom" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/pay-result/index", |
|||
"style": { |
|||
"navigationBarTitleText": "支付结果", |
|||
"enablePullDownRefresh": false, |
|||
"navigationStyle": "custom" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/h5-view/index", |
|||
"style": { |
|||
"navigationBarTitleText": "统一的H5落地页", |
|||
"enablePullDownRefresh": false, |
|||
"navigationStyle": "custom" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/h5-page/index", |
|||
"style": { |
|||
"navigationBarTitleText": "飞鸟快印", |
|||
"enablePullDownRefresh": false, |
|||
"navigationStyle": "custom" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/login/index", |
|||
"style": { |
|||
"navigationBarTitleText": "登陆", |
|||
"enablePullDownRefresh": false, |
|||
"navigationStyle": "custom" |
|||
} |
|||
}, |
|||
{ |
|||
"path": "pages/page-view/index", |
|||
"style": { |
|||
"navigationBarTitleText": "飞鸟快印", |
|||
"enablePullDownRefresh": false, |
|||
"navigationStyle": "custom" |
|||
} |
|||
} |
|||
], |
|||
"globalStyle": { |
|||
"navigationBarTextStyle": "black", |
|||
"navigationBarTitleText": "uni-app", |
|||
"navigationBarBackgroundColor": "#F8F8F8", |
|||
"backgroundColor": "#F8F8F8", |
|||
"backgroundColorTop": "#FFFFFF" |
|||
}, |
|||
"tabBar": { |
|||
"color": "#888", |
|||
"selectedColor": "#007AFF", |
|||
"borderStyle": "white", |
|||
"backgroundColor": "#f9f9f9", |
|||
"list": [ |
|||
{ |
|||
"pagePath": "pages/index/index", |
|||
"iconPath": "static/imgs/tabbar/index-gray.png", |
|||
"selectedIconPath": "static/imgs/tabbar/index-blue.png", |
|||
"text": "首页" |
|||
}, |
|||
{ |
|||
"pagePath": "pages/mine/index", |
|||
"iconPath": "static/imgs/tabbar/mine-gray.png", |
|||
"selectedIconPath": "static/imgs/tabbar/mine-blue.png", |
|||
"text": "我的" |
|||
} |
|||
] |
|||
} |
|||
} |
|||
@ -0,0 +1,313 @@ |
|||
<template> |
|||
<view class="content"> |
|||
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed title="我的地址"></uni-nav-bar> |
|||
<view class="flex-col group_5"> |
|||
<view class="flex-col list" v-if="list.length > 0"> |
|||
<view class="list-item flex-col" :key="item.id" v-for="item in list"> |
|||
<view class="top-group flex-col" @click="selectAddress(item)"> |
|||
<view class="justify-between"> |
|||
<text class="text_4">{{ item.receiver }} {{ item.receiverMobile }}</text> |
|||
<view class="select-button" v-show="showSelectedTip">选择</view> |
|||
</view> |
|||
<text class="text_6">{{ item.provinceName || '' }}{{ item.cityName || '' }}{{ item.districtName || '' }}{{ item.detail || '' }}</text> |
|||
</view> |
|||
<view class="bottom-group justify-between"> |
|||
<view class="left-group flex-row view_4" :class="{ selected: item.isDefault }" @click="setDefault(item)"> |
|||
<image class="icon" :src="item.isDefault ? '/static/imgs/general/selected-icon.png' : '/static/imgs/general/select-icon.png'"></image> |
|||
<text class="text_8">设为默认</text> |
|||
</view> |
|||
<text class="text_10 text_11" @click="remove(item)">删除</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<image v-else :src="imgStamp['empty-file']" class="image_6" /> |
|||
<view class="flex-col items-center fixed" @click="getAuth"> |
|||
<text>导入微信收货地址</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { go2, back, setCache } from '@/utils/hook.js' |
|||
import { getAddressList, changeAddress, deleteAddress } from '@/apis/addressApi' |
|||
import { addressType, imgStamp, cacheKey } from '@/enums/index' |
|||
export default { |
|||
data() { |
|||
return { |
|||
prePage: 'mine', |
|||
list: [], |
|||
imgStamp: Object.freeze(imgStamp), |
|||
hasAuth: false // 是否有授权 |
|||
} |
|||
}, |
|||
onShow() { |
|||
getAddressList().then((res) => { |
|||
this.list = res |
|||
}) |
|||
}, |
|||
onLoad(options) { |
|||
if (options.from) { |
|||
this.prePage = options.from |
|||
} |
|||
uni.getSetting({ |
|||
success: (res) => { |
|||
if (res.authSetting['scope.address']) { |
|||
console.log('已授权') |
|||
this.hasAuth = true |
|||
} |
|||
}, |
|||
fail: (err) => { |
|||
console.log(err) |
|||
} |
|||
}) |
|||
}, |
|||
computed: { |
|||
showSelectedTip() { |
|||
return ['print-pay'].includes(this.prePage) |
|||
} |
|||
}, |
|||
methods: { |
|||
go2, |
|||
back, |
|||
selectAddress(item) { |
|||
let reg_tel = /^(13\d|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18\d|19[0-35-9])\d{8}$/ |
|||
if (!reg_tel.test(item.receiverMobile)) { |
|||
uni.showModal({ |
|||
content: '手机号码格式错误', |
|||
title: '提示', |
|||
duration: 1000 |
|||
}) |
|||
return |
|||
} |
|||
if (this.prePage == 'print-pay') { |
|||
setCache(cacheKey.SELECT_ADDRESS, item) |
|||
back() |
|||
} |
|||
}, |
|||
setDefault(item) { |
|||
if (item.isDefault) { |
|||
return |
|||
} |
|||
changeAddress({ ...item, isDefault: addressType.DEFAULT }).then(() => { |
|||
getAddressList().then((res) => { |
|||
this.list = res |
|||
}) |
|||
}) |
|||
}, |
|||
// 获取授权 |
|||
getAuth() { |
|||
uni.authorize({ |
|||
scope: 'scope.address', |
|||
success: () => { |
|||
this.hasAuth = true |
|||
this.importAddress() |
|||
}, |
|||
fail: () => { |
|||
this.hasAuth = false |
|||
uni.showModal({ |
|||
title: '提示', |
|||
content: '您未授权微信地址,无法使用该功能。是否打开授权?', |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
uni.openSetting({ |
|||
success: (result) => { |
|||
if (result.authSetting['scope.address']) { |
|||
this.hasAuth = true |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
}) |
|||
}, |
|||
// 导入微信收货地址 |
|||
importAddress() { |
|||
uni.chooseAddress({ |
|||
success: (res) => { |
|||
if (!res.userName || res.userName.trim() == '') { |
|||
uni.showModal({ |
|||
content: '导入的地址收货人名称不能为空', |
|||
title: '提示' |
|||
}) |
|||
return |
|||
} |
|||
if (!res.telNumber || res.telNumber.trim() == '') { |
|||
uni.showModal({ |
|||
content: '导入的地址收货人电话不能为空', |
|||
title: '提示' |
|||
}) |
|||
return |
|||
} |
|||
let reg_tel = /^(13\d|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18\d|19[0-35-9])\d{8}$/ |
|||
if (!reg_tel.test(res.telNumber)) { |
|||
uni.showModal({ |
|||
content: '手机号码格式错误', |
|||
title: '提示', |
|||
duration: 1000 |
|||
}) |
|||
return |
|||
} |
|||
let address = { |
|||
cityName: res.cityName, |
|||
detail: res.detailInfo, |
|||
districtName: res.countyName, |
|||
isDefault: addressType.DEFAULT, |
|||
provinceName: res.provinceName, |
|||
receiver: res.userName, |
|||
receiverMobile: res.telNumber, |
|||
postalCode: res.postalCode |
|||
} |
|||
changeAddress(address).then(() => { |
|||
getAddressList().then((res) => { |
|||
this.list = res |
|||
if (this.list.length == 1 && this.prePage == 'print-pay') { |
|||
setCache(cacheKey.SELECT_ADDRESS, this.list[0]) |
|||
back() |
|||
} |
|||
}) |
|||
}) |
|||
}, |
|||
fail: (err) => { |
|||
console.error('err', err) |
|||
uni.showModal({ |
|||
title: '提示', |
|||
content: '导入地址失败,请同意授权或更新微信后再试' |
|||
}) |
|||
} |
|||
}) |
|||
}, |
|||
remove(item) { |
|||
uni.showModal({ |
|||
title: '提示', |
|||
content: '确定要删除该地址吗?', |
|||
success: (res) => { |
|||
if (res.confirm) { |
|||
deleteAddress({ id: item.id }).then(() => { |
|||
const addressObj = { |
|||
id: null, |
|||
receiver: '', |
|||
receiverMobile: '', |
|||
provinceName: '', |
|||
cityName: '', |
|||
districtName: '', |
|||
streetName: '', |
|||
detail: '' |
|||
} |
|||
setCache(cacheKey.SELECT_ADDRESS, addressObj) |
|||
getAddressList().then((res) => { |
|||
this.list = res |
|||
}) |
|||
}) |
|||
} |
|||
} |
|||
}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.content { |
|||
width: 750rpx; |
|||
} |
|||
.group_5 { |
|||
padding: 0 0 84rpx; |
|||
height: 100vh; |
|||
overflow-y: auto; |
|||
position: relative; |
|||
.image_6 { |
|||
position: absolute; |
|||
top: 20%; |
|||
left: 70rpx; |
|||
right: 70rpx; |
|||
width: 609rpx; |
|||
height: 453rpx; |
|||
} |
|||
.list { |
|||
margin: 0 32rpx; |
|||
.list-item { |
|||
padding: 0 24rpx; |
|||
background-color: rgb(255, 255, 255); |
|||
border-radius: 16rpx; |
|||
margin-top: 20rpx; |
|||
.top-group { |
|||
padding: 27rpx 0 29rpx; |
|||
.text_4 { |
|||
color: rgb(51, 51, 51); |
|||
font-size: 30rpx; |
|||
font-weight: 500; |
|||
line-height: 42rpx; |
|||
white-space: nowrap; |
|||
} |
|||
.select-button { |
|||
width: 100rpx; |
|||
height: 42rpx; |
|||
padding: 0rpx 8rpx; |
|||
text-align: center; |
|||
color: white; |
|||
font-size: 26rpx; |
|||
line-height: 42rpx; |
|||
white-space: nowrap; |
|||
background-color: #007aff; |
|||
border-radius: 6rpx; |
|||
} |
|||
.text_6 { |
|||
margin-right: 31rpx; |
|||
margin-top: 16rpx; |
|||
color: rgb(51, 51, 51); |
|||
font-size: 28rpx; |
|||
line-height: 40rpx; |
|||
text-align: left; |
|||
} |
|||
} |
|||
.bottom-group { |
|||
padding: 20rpx 0; |
|||
color: rgb(136, 136, 136); |
|||
font-size: 28rpx; |
|||
line-height: 40rpx; |
|||
white-space: nowrap; |
|||
border-top: solid 2rpx rgb(216, 216, 216); |
|||
.icon { |
|||
margin: 4rpx 0; |
|||
border-radius: 50%; |
|||
width: 32rpx; |
|||
height: 32rpx; |
|||
} |
|||
.left-group { |
|||
font-size: 28rpx; |
|||
line-height: 40rpx; |
|||
white-space: nowrap; |
|||
.text_8 { |
|||
margin-left: 12rpx; |
|||
} |
|||
} |
|||
.selected { |
|||
color: rgb(0, 122, 255); |
|||
} |
|||
.text_10 { |
|||
color: rgb(136, 136, 136); |
|||
font-size: 28rpx; |
|||
line-height: 40rpx; |
|||
white-space: nowrap; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.fixed { |
|||
padding: 20rpx 0; |
|||
color: rgb(255, 255, 255); |
|||
font-size: 32rpx; |
|||
line-height: 45rpx; |
|||
white-space: nowrap; |
|||
background-color: rgb(0, 122, 255); |
|||
border-radius: 20rpx; |
|||
position: fixed; |
|||
left: 32rpx; |
|||
right: 32rpx; |
|||
bottom: 90rpx; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,41 @@ |
|||
<template> |
|||
<view class="content"> |
|||
<uni-nav-bar |
|||
left-icon="back" |
|||
@clickLeft="back" |
|||
statusBar |
|||
fixed |
|||
:title="title" |
|||
></uni-nav-bar> |
|||
<web-view :src="url"></web-view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { go2, back } from "@/utils/hook.js"; |
|||
export default { |
|||
data() { |
|||
return { |
|||
title: "", |
|||
url: "", |
|||
}; |
|||
}, |
|||
onLoad(options) { |
|||
this.title = options.title; |
|||
this.url = options.url; |
|||
}, |
|||
methods: { |
|||
go2, |
|||
back, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.content { |
|||
width: 750rpx; |
|||
} |
|||
.img { |
|||
width: 750rpx; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,35 @@ |
|||
<template> |
|||
<view class="content"> |
|||
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed :title="title"></uni-nav-bar> |
|||
<image :show-menu-by-longpress="true" :src="url" class="img" mode="widthFix"></image> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { go2, back } from '@/utils/hook.js' |
|||
export default { |
|||
data() { |
|||
return { |
|||
title: '', |
|||
url: '' |
|||
} |
|||
}, |
|||
onLoad(options) { |
|||
this.title = options.title |
|||
this.url = options.url |
|||
}, |
|||
methods: { |
|||
go2, |
|||
back |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.content { |
|||
width: 750rpx; |
|||
} |
|||
.img { |
|||
width: 750rpx; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,25 @@ |
|||
<template> |
|||
<view class="content"> |
|||
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed title="首页"></uni-nav-bar> |
|||
home |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { go2, back } from '@/utils/hook.js' |
|||
export default { |
|||
data() { |
|||
return {} |
|||
}, |
|||
methods: { |
|||
go2, |
|||
back |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.content { |
|||
width: 750rpx; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,192 @@ |
|||
<template> |
|||
<view class="content"> |
|||
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed title="飞鸟快印"></uni-nav-bar> |
|||
<view class="flex-col group_5"> |
|||
<view class="group_6"> |
|||
<view class="section_3"><!--*--></view> |
|||
<view class="justify-center group_7"> |
|||
<image src="/static/imgs/general/logo-icon.png" class="image_6" /> |
|||
<text class="text_4">飞鸟快印</text> |
|||
</view> |
|||
</view> |
|||
<view class="flex-col group_8"> |
|||
<text class="text_5">手机里的打印店</text> |
|||
<view class="justify-center"> |
|||
<button class="avatar-wrapper" open-type="chooseAvatar" @chooseavatar="onChooseAvatar"> |
|||
<image class="avatar" :src="avatarUrl"></image> |
|||
</button> |
|||
</view> |
|||
<view class="nick-form"> |
|||
<view style="width: 100rpx">昵称:</view> |
|||
<input type="nickname" class="weui-input" placeholder="请输入昵称" v-model="nickname" /> |
|||
</view> |
|||
<view class="flex-col items-center button" @tap="signIn"><text class="text_6">注册账号</text></view> |
|||
</view> |
|||
<view class="section_4"><!--*--></view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { go2, back } from '@/utils/hook.js' |
|||
import { changeUserInfo, uploadAvatar } from '@/apis/commonApi' |
|||
|
|||
const defaultAvatarUrl = 'https://qncloud.oss-cn-shenzhen.aliyuncs.com/wukong-printer-wx/default-avatar-add.png' |
|||
export default { |
|||
data() { |
|||
return { |
|||
params: {}, |
|||
target: '', |
|||
avatarUrl: defaultAvatarUrl, |
|||
nickname: '' |
|||
} |
|||
}, |
|||
onLoad(options) { |
|||
this.target = options.target |
|||
this.params = JSON.parse(options.data || '{}') |
|||
}, |
|||
methods: { |
|||
go2, |
|||
back, |
|||
signIn() { |
|||
if (this.avatarUrl == defaultAvatarUrl || !this.avatarUrl) { |
|||
uni.showToast({ |
|||
title: '请选择头像', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
if (!this.nickname || !this.nickname.trim()) { |
|||
uni.showToast({ |
|||
title: '请输入昵称', |
|||
icon: 'none' |
|||
}) |
|||
return |
|||
} |
|||
uploadAvatar(this.avatarUrl).then((res) => { |
|||
if (res) { |
|||
res = JSON.parse(res) |
|||
} |
|||
if (res.data) { |
|||
changeUserInfo({ avatar: res.data, nickname: this.nickname }).then(() => { |
|||
// 更新全局用户信息 |
|||
let changeMap = [ |
|||
{ key: 'avatar', value: res.data }, |
|||
{ key: 'name', value: this.nickname } |
|||
] |
|||
this.$store.commit('changeUserInfo', changeMap) |
|||
this.nextPage() |
|||
}) |
|||
} |
|||
}) |
|||
}, |
|||
onChooseAvatar(e) { |
|||
const { avatarUrl } = e.detail |
|||
this.avatarUrl = avatarUrl |
|||
}, |
|||
nextPage() { |
|||
go2(this.target, this.params, true) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.content { |
|||
width: 750rpx; |
|||
} |
|||
.group_5 { |
|||
padding: 42rpx 0 316rpx; |
|||
flex: 1 1 auto; |
|||
overflow-y: auto; |
|||
overflow-x: hidden; |
|||
.group_6 { |
|||
width: 750rpx; |
|||
.section_3 { |
|||
background-image: linear-gradient(149.4deg, #007aff26 0%, #007aff26 2.73%, #ffffff26 98.65%, #ffffff26 100%); |
|||
border-radius: 0 50% 50% 0; |
|||
width: 288rpx; |
|||
height: 288rpx; |
|||
position: absolute; |
|||
transform: translateX(-50%); |
|||
} |
|||
.group_7 { |
|||
margin-top: 90rpx; |
|||
width: 750rpx; |
|||
.image_6 { |
|||
margin: 10rpx 0 9rpx; |
|||
flex-shrink: 0; |
|||
width: 75rpx; |
|||
height: 75rpx; |
|||
} |
|||
.text_4 { |
|||
margin-left: 21rpx; |
|||
color: #000000; |
|||
font-size: 80rpx; |
|||
font-family: '.AppleSystemUIFont'; |
|||
line-height: 94rpx; |
|||
} |
|||
} |
|||
} |
|||
.group_8 { |
|||
margin: 28rpx 0 0; |
|||
.text_5 { |
|||
align-self: center; |
|||
color: #000000; |
|||
font-size: 30rpx; |
|||
font-family: 'PingFangSC-Regular'; |
|||
line-height: 42rpx; |
|||
letter-spacing: 34rpx; |
|||
margin-left: 34rpx; |
|||
} |
|||
.button { |
|||
padding: 23rpx 0 20rpx; |
|||
margin: 120rpx 32rpx 0; |
|||
background-color: #28c445; |
|||
border-radius: 44rpx; |
|||
.text_6 { |
|||
color: #ffffff; |
|||
font-size: 32rpx; |
|||
font-family: 'PingFangSC-Medium'; |
|||
font-weight: 500; |
|||
line-height: 45rpx; |
|||
} |
|||
} |
|||
} |
|||
.section_4 { |
|||
margin-left: 562rpx; |
|||
margin-top: 282rpx; |
|||
align-self: flex-start; |
|||
background-image: linear-gradient(149.4deg, #007aff26 0%, #007aff26 2.73%, #ffffff26 98.65%, #ffffff26 100%); |
|||
border-radius: 50%; |
|||
width: 288rpx; |
|||
height: 288rpx; |
|||
} |
|||
} |
|||
.avatar-wrapper { |
|||
width: 150rpx; |
|||
height: 150rpx; |
|||
margin-top: 140rpx; |
|||
border-radius: 50%; |
|||
overflow: hidden; |
|||
padding: 0; |
|||
.avatar { |
|||
width: 150rpx; |
|||
height: 150rpx; |
|||
} |
|||
} |
|||
.weui-input { |
|||
width: 400rpx; |
|||
height: 80rpx; |
|||
} |
|||
.nick-form { |
|||
margin-top: 32rpx; |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
justify-content: center; |
|||
width: 750rpx; |
|||
border-top: 1px solid #e5e5e5; |
|||
border-bottom: 1px solid #e5e5e5; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,25 @@ |
|||
<template> |
|||
<view class="content"> |
|||
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed title="个人中心"></uni-nav-bar> |
|||
mine |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { go2, back } from '@/utils/hook.js' |
|||
export default { |
|||
data() { |
|||
return {} |
|||
}, |
|||
methods: { |
|||
go2, |
|||
back |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.content { |
|||
width: 750rpx; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,87 @@ |
|||
<template> |
|||
<view> |
|||
<web-view :src="url"></web-view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { go2, back } from "@/utils/hook.js"; |
|||
import { makeSocket } from "@/utils/index.js"; |
|||
export default { |
|||
data() { |
|||
return { |
|||
url: "", |
|||
socket: null, |
|||
params: null, |
|||
socketFlag: false, |
|||
}; |
|||
}, |
|||
onLoad(option) { |
|||
if (option) { |
|||
this.url = decodeURIComponent(option.url); |
|||
this.params = option.params ? JSON.parse(option.params) : ""; |
|||
// 默认不创建socket连接 |
|||
this.socketFlag = option.socketFlag || false; |
|||
} else { |
|||
uni.showToast({ |
|||
title: "参数错误", |
|||
icon: "none", |
|||
complete: () => { |
|||
setTimeout(() => { |
|||
back(); |
|||
}, 1000); |
|||
}, |
|||
}); |
|||
} |
|||
}, |
|||
onShow() { |
|||
if (this.socketFlag) { |
|||
this.initSocket(); |
|||
} |
|||
}, |
|||
onHide() { |
|||
console.log("onHide"); |
|||
this.destroySocket(); |
|||
}, |
|||
onUnload() { |
|||
console.log("onUnload"); |
|||
this.destroySocket(); |
|||
}, |
|||
methods: { |
|||
initSocket() { |
|||
makeSocket({ pageInfo: "page-view", retry: true }).then((res) => { |
|||
this.destroySocket(); |
|||
this.socket = res; |
|||
this.socket.onMessage(this.getMessage); |
|||
}); |
|||
}, |
|||
/** |
|||
* @param {Object} data {data:{},type:''} |
|||
*/ |
|||
getMessage(data) { |
|||
// 供应商担保协议回调 |
|||
if (data.type === "guaranteeSuccess") { |
|||
go2("fs-credit", { ...this.params }, true); |
|||
} |
|||
// 订单合同签署成功 |
|||
if (data.type == "ybkClientTCSignSuccess") { |
|||
go2("order-detail", { orderId: data.data.orderId }, true); |
|||
} |
|||
// 签约成功 |
|||
if (data.type == "signSuccess") { |
|||
// go2('order-detail', { id: data.orderId }, true) |
|||
} |
|||
// 实名认证成功 |
|||
if (data.type == "certificatedSuccess") { |
|||
go2("mine"); |
|||
} |
|||
}, |
|||
destroySocket() { |
|||
if (this.socket) { |
|||
this.socket.close(); |
|||
this.socket = null; |
|||
} |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
@ -0,0 +1,114 @@ |
|||
<template> |
|||
<view class="content"> |
|||
<uni-nav-bar statusBar fixed title="支付结果"></uni-nav-bar> |
|||
<view class="flex-col group_5"> |
|||
<view class="flex-col section_3"> |
|||
<view class="flex-col items-center"> |
|||
<image src="/static/imgs/general/order-success-icon.png" class="image_7" /> |
|||
</view> |
|||
<view class="flex-col items-center group_9"> |
|||
<text class="text_6">支付成功</text> |
|||
<text class="text_7">付款¥ {{ price }}</text> |
|||
</view> |
|||
<view class="flex-col items-center text-wrapper" @click="jump" |
|||
><text class="text_8">查看订单</text></view |
|||
> |
|||
<view class="flex-col items-center group_10"> |
|||
<image |
|||
v-show="imgUrl" |
|||
:show-menu-by-longpress="true" |
|||
:src="imgUrl" |
|||
class="image_9" |
|||
mode="widthFix" |
|||
/> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { go2, back } from "@/utils/hook.js"; |
|||
import { imgStamp } from "@/enums/index"; |
|||
export default { |
|||
data() { |
|||
return { |
|||
imgStamp, |
|||
type: "success", |
|||
imgUrl: "", |
|||
price: 0, |
|||
}; |
|||
}, |
|||
onLoad(options) { |
|||
this.type = options.type; |
|||
this.imgUrl = options.imgUrl; |
|||
this.price = options.price; |
|||
}, |
|||
methods: { |
|||
go2, |
|||
back, |
|||
jump() { |
|||
go2("order"); |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.content { |
|||
width: 750rpx; |
|||
} |
|||
.group_5 { |
|||
padding: 20rpx 0 786rpx; |
|||
flex: 1 1 auto; |
|||
overflow-y: auto; |
|||
.section_3 { |
|||
margin: 0 32rpx; |
|||
padding: 48rpx 24rpx 8rpx; |
|||
background-color: rgb(255, 255, 255); |
|||
border-radius: 10rpx; |
|||
.group_9 { |
|||
margin-top: 40rpx; |
|||
.text_6 { |
|||
color: rgb(51, 51, 51); |
|||
font-size: 34rpx; |
|||
font-family: "PingFangSC-Medium"; |
|||
font-weight: 500; |
|||
line-height: 48rpx; |
|||
} |
|||
.text_7 { |
|||
margin-top: 16rpx; |
|||
color: rgb(85, 85, 85); |
|||
font-size: 24rpx; |
|||
font-family: "PingFangSC-Regular"; |
|||
line-height: 33rpx; |
|||
} |
|||
} |
|||
.text-wrapper { |
|||
margin-top: 47rpx; |
|||
padding: 11rpx 0; |
|||
align-self: center; |
|||
background-color: rgb(255, 255, 255); |
|||
border-radius: 32rpx; |
|||
width: 196rpx; |
|||
border: solid 1rpx rgb(151, 151, 151); |
|||
.text_8 { |
|||
color: rgb(85, 85, 85); |
|||
font-size: 28rpx; |
|||
font-family: "PingFangSC-Regular"; |
|||
line-height: 40rpx; |
|||
} |
|||
} |
|||
.group_10 { |
|||
padding: 48rpx 0; |
|||
.image_9 { |
|||
width: 638rpx; |
|||
} |
|||
} |
|||
.image_7 { |
|||
width: 151rpx; |
|||
height: 86rpx; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,151 @@ |
|||
<template> |
|||
<view class="file-info"> |
|||
<view class="title">商品信息</view> |
|||
<view class="file-content"> |
|||
<view class="justify-between"> |
|||
<image src="/static/imgs/general/pdf-icon.png" class="image"></image> |
|||
<view class="file-content-right"> |
|||
<view class="flex-row-center-space" style="width: 100%"> |
|||
<text class="file-title">文件打印</text> |
|||
<text class="price">¥{{ fileItem.price || 0 }}</text> |
|||
</view> |
|||
<view class="tip">共{{ fileItem.fileNumber || 0 }}个文档</view> |
|||
</view> |
|||
</view> |
|||
<view class="postage"> |
|||
<text class="label">快递方式</text> |
|||
<view class="flex-col-end-start"> |
|||
<text class="label">圆通快递</text> |
|||
<text class="tip">24小时内发货(15:00前下单当天发货,节假日看公告)</text> |
|||
</view> |
|||
</view> |
|||
<view class="form"> |
|||
<view class="form-item"> |
|||
<text class="label">订单备注</text> |
|||
<input class="value" v-model="form.remark" placeholder="填写备注" /> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
fileItem: { |
|||
type: Object, |
|||
default: () => ({}) |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
form: { |
|||
remark: '' |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
checkForm() { |
|||
return true |
|||
}, |
|||
getForm() { |
|||
if (!this.checkForm()) { |
|||
uni.showToast({ |
|||
title: '请填写完成信息', |
|||
icon: 'none' |
|||
}) |
|||
return { |
|||
status: 'fail', |
|||
value: null |
|||
} |
|||
} |
|||
return { |
|||
status: 'success', |
|||
value: this.form |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.file-info { |
|||
background-color: #fff; |
|||
width: 100%; |
|||
.title { |
|||
padding: 24rpx; |
|||
font-size: 30rpx; |
|||
color: rgb(0, 0, 0); |
|||
text-align: left; |
|||
border-bottom: 1px solid rgb(221, 221, 221); |
|||
} |
|||
.file-content { |
|||
padding: 32rpx 24rpx 24rpx; |
|||
.file-content-right { |
|||
flex: 1; |
|||
margin-left: 24rpx; |
|||
.tip { |
|||
font-size: 24rpx; |
|||
color: rgb(136, 136, 136); |
|||
margin-top: 16rpx; |
|||
text-align: left; |
|||
} |
|||
} |
|||
.image { |
|||
margin-left: 28rpx; |
|||
width: 60rpx; |
|||
height: 68rpx; |
|||
} |
|||
.file-title { |
|||
font-size: 32rpx; |
|||
color: rgb(51, 51, 51); |
|||
width: 400rpx; |
|||
overflow: hidden; |
|||
text-overflow: ellipsis; |
|||
} |
|||
.price { |
|||
font-size: 26rpx; |
|||
color: rgb(255, 0, 0); |
|||
} |
|||
.postage { |
|||
margin-top: 32rpx; |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
align-items: flex-start; |
|||
.tip { |
|||
font-size: 22rpx; |
|||
color: rgb(136, 136, 136); |
|||
margin-top: 16rpx; |
|||
text-align: left; |
|||
} |
|||
} |
|||
.form { |
|||
margin-top: 32rpx; |
|||
.form-item { |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
.label { |
|||
font-size: 28rpx; |
|||
color: rgb(51, 51, 51); |
|||
} |
|||
.value { |
|||
font-size: 28rpx; |
|||
color: rgb(153, 153, 153); |
|||
text-align: right; |
|||
width: 500rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.label { |
|||
font-size: 28rpx; |
|||
color: rgb(51, 51, 51); |
|||
} |
|||
.red { |
|||
color: rgb(255, 0, 0); |
|||
} |
|||
</style> |
|||
@ -0,0 +1,82 @@ |
|||
<template> |
|||
<view class="order-info"> |
|||
<view class="title">订单明细</view> |
|||
<view class="order-content"> |
|||
<view class="form"> |
|||
<text class="label">商品金额</text> |
|||
<text class="value">¥ {{ orderInfo.goodPrice || 0 }}</text> |
|||
</view> |
|||
<view class="form"> |
|||
<text class="label">运费</text> |
|||
<text class="value">¥ {{ orderInfo.postagePrice || 0 }}</text> |
|||
</view> |
|||
<view class="form" v-for="(item, index) in orderInfo.preferentialItems" :key="index"> |
|||
<text class="label">{{ item.name }}</text> |
|||
<text class="value red">- ¥ {{ item.price }}</text> |
|||
</view> |
|||
</view> |
|||
<view class="total black"> |
|||
总计: |
|||
<text class="red" style="margin-left: 20rpx">¥{{ orderInfo.totalPrice || 0 }}</text> |
|||
</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
props: { |
|||
orderInfo: { |
|||
type: Object, |
|||
default: () => ({}) |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.order-info { |
|||
width: 100%; |
|||
background-color: #fff; |
|||
.title { |
|||
padding: 24rpx; |
|||
font-size: 30rpx; |
|||
color: rgb(0, 0, 0); |
|||
text-align: left; |
|||
border-bottom: 1px solid rgb(221, 221, 221); |
|||
} |
|||
.order-content { |
|||
padding: 32rpx 24rpx 0; |
|||
.form { |
|||
display: flex; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
margin-bottom: 32rpx; |
|||
.label { |
|||
font-size: 28rpx; |
|||
color: rgb(51, 51, 51); |
|||
} |
|||
.value { |
|||
font-size: 28rpx; |
|||
color: rgb(51, 51, 51); |
|||
} |
|||
.red { |
|||
color: rgb(255, 0, 0); |
|||
} |
|||
} |
|||
} |
|||
.total { |
|||
width: 100%; |
|||
padding: 24rpx; |
|||
text-align: right; |
|||
border-top: 1px solid rgb(238, 238, 238); |
|||
font-size: 28rpx; |
|||
|
|||
.black { |
|||
color: rgb(51, 51, 51); |
|||
} |
|||
.red { |
|||
color: rgb(255, 0, 0); |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,454 @@ |
|||
<template> |
|||
<view class="goods-info"> |
|||
<view class="title">商品信息</view> |
|||
<view class="goods-content"> |
|||
<view v-for="(goods, i) in goodsList" :key="i"> |
|||
<view class="flex-row group_9"> |
|||
<image :src="goods.productImgUrl" class="image_7" /> |
|||
<view class="flex-col items-start group_10"> |
|||
<view class="flex-col group_11"> |
|||
<text class="text_12">{{ goods.productName }}</text> |
|||
<text class="text_13">¥{{ goods.listUnitPrice }}/{{ goods.skuDesc }}/{{ goods.quantity }}个</text> |
|||
</view> |
|||
<text class="text_14">¥{{ goods.totalAmount }}</text> |
|||
</view> |
|||
</view> |
|||
<view class="remark" v-if="goods.remark"> |
|||
<text class="remark-label">商品备注:</text> |
|||
<text class="remark-content">{{ goods.remark || '' }}</text> |
|||
</view> |
|||
</view> |
|||
<view class="postage"> |
|||
<text class="label">温馨提示</text> |
|||
<view class="flex-col-end-start"> |
|||
<!-- <text class="label">{{ hasArea ? '下单后三天内发货' : '定制商品需要三到五天的制作工期' }}</text> --> |
|||
<text class="label">定制商品需要三到五天的制作工期</text> |
|||
<text class="tip">详情可资讯客服</text> |
|||
</view> |
|||
</view> |
|||
<view class="form"> |
|||
<!-- 半天妖的区域选择 --> |
|||
<!-- <view v-if="hasArea" class="form-item"> |
|||
<text class="label">下单区域</text> |
|||
<view class="box" @click="showArea"> |
|||
<text v-show="areaName">{{ areaName }} {{ areaProvince }} {{ areaCity }}</text> |
|||
<image src="/static/imgs/general/right-arrow.png" style="width: 32rpx; height: 32rpx" v-show="!areaInfo"></image> |
|||
</view> |
|||
</view> --> |
|||
<view class="form-item"> |
|||
<text class="label">订单备注</text> |
|||
<input class="value" v-model="form.remark" placeholder="填写备注" /> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
<!-- <uni-popup ref="areaPopup" type="bottom" background-color="#fff"> |
|||
<view class="popup-content"> |
|||
<view v-show="areaName"> |
|||
<view class="title-content"> |
|||
<text>{{ areaName }}</text> |
|||
<text style="margin-left: 32rpx">{{ areaProvince }}</text> |
|||
<text style="margin-left: 32rpx">{{ areaCity }}</text> |
|||
</view> |
|||
</view> |
|||
<view v-show="!areaName"> |
|||
<view class="title-content"> |
|||
<text>请选择区域</text> |
|||
</view> |
|||
</view> |
|||
<view class="scroll-title"> |
|||
<view class="left">经理</view> |
|||
<view class="center">省</view> |
|||
<view class="right">市</view> |
|||
</view> |
|||
<view class="scroll-content"> |
|||
<view class="left"> |
|||
<view v-for="item in areaList" :key="item.id" class="item" @click="selectName(item.name)"> |
|||
<text :class="{ selected: item.name === areaName }">{{ item.name }}</text> |
|||
</view> |
|||
</view> |
|||
<view class="center"> |
|||
<view v-for="item in curProvinceList" :key="item.provinceCode" class="item" @click="selectProvince(item.provinceName)"> |
|||
<text :class="{ selected: item.provinceName === areaProvince }">{{ item.provinceName }}</text> |
|||
</view> |
|||
</view> |
|||
<view class="right"> |
|||
<view class="item" v-for="city in curCityList" :key="city.cityCode" @click="selectCity(city.cityName)"> |
|||
<text :class="{ selected: city.cityName === areaCity }">{{ city.cityName }}</text> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</view> |
|||
</uni-popup> --> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { getBTAreaList } from '@/apis/commonApi.js' |
|||
export default { |
|||
props: { |
|||
goodsList: { |
|||
type: Array, |
|||
default: () => [ |
|||
// { |
|||
// productImgUrl: 'https://qncloudtest.oss-cn-shenzhen.aliyuncs.com/common/14189212646949759.png', |
|||
// productName: '网红便当蛋糕提拉米苏包装盒子', |
|||
// listUnitPrice: 0.01, |
|||
// skuDesc: '毕业季/水金款', |
|||
// quantity: 100, |
|||
// totalAmount: 1, |
|||
// remark: '备注' |
|||
// }, |
|||
// { |
|||
// productImgUrl: 'https://qncloudtest.oss-cn-shenzhen.aliyuncs.com/common/14189212646949759.png', |
|||
// productName: '网红便当蛋糕提拉米苏包装盒子', |
|||
// listUnitPrice: 0.01, |
|||
// skuDesc: '毕业季/水金款', |
|||
// quantity: 100, |
|||
// totalAmount: 1, |
|||
// remark: '备注' |
|||
// } |
|||
] |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
form: { |
|||
remark: '' |
|||
} |
|||
// areaList: [], |
|||
// curProvinceList: [], |
|||
// curCityList: [], |
|||
// areaName: '', |
|||
// areaProvince: '', |
|||
// areaCity: '' |
|||
} |
|||
}, |
|||
// computed: { |
|||
// hasArea() { |
|||
// let target = this.goodsList.find((item) => item.type === 'bty') |
|||
// return !!target |
|||
// } |
|||
// }, |
|||
// mounted() { |
|||
// this.getAreaList() |
|||
// }, |
|||
// watch: { |
|||
// hasArea(val) { |
|||
// if (val) { |
|||
// this.getAreaList() |
|||
// } |
|||
// }, |
|||
// // 区域经理 |
|||
// areaName(val) { |
|||
// this.areaCity = '' |
|||
// this.areaProvince = '' |
|||
// if (!val) { |
|||
// this.curProvinceList = [] |
|||
// this.curCityList = [] |
|||
// return |
|||
// } |
|||
// let target = this.areaList.find((item) => item.name === val) |
|||
// if (!target) { |
|||
// this.curProvinceList = [] |
|||
// this.curCityList = [] |
|||
// return |
|||
// } |
|||
// this.curProvinceList = target.provinces || [] |
|||
// }, |
|||
// areaProvince(val) { |
|||
// this.areaCity = '' |
|||
// if (!val) { |
|||
// this.curCityList = [] |
|||
// return |
|||
// } |
|||
// let target = this.curProvinceList.find((item) => item.provinceName === val) |
|||
// if (!target) { |
|||
// this.curCityList = [] |
|||
// return |
|||
// } |
|||
// this.curCityList = target.cities || [] |
|||
// }, |
|||
// areaCity(val) { |
|||
// if (!val) { |
|||
// return |
|||
// } |
|||
// this.$refs.areaPopup.close() |
|||
// } |
|||
// }, |
|||
methods: { |
|||
// getAreaList() { |
|||
// getBTAreaList().then((res) => { |
|||
// this.areaList = res |
|||
// }) |
|||
// }, |
|||
// getBtyRemark() { |
|||
// let target = this.goodsList[0] |
|||
// let index = target.productName.lastIndexOf('半天妖') |
|||
// return target.productName.substring(index + 3) + '版本名称' |
|||
// }, |
|||
// selectName(name) { |
|||
// if (this.areaName === name) { |
|||
// this.areaName = '' |
|||
// } else { |
|||
// this.areaName = name |
|||
// } |
|||
// }, |
|||
// selectProvince(name) { |
|||
// if (this.areaProvince === name) { |
|||
// this.areaProvince = '' |
|||
// } else { |
|||
// this.areaProvince = name |
|||
// } |
|||
// }, |
|||
// selectCity(name) { |
|||
// if (this.areaCity === name) { |
|||
// this.areaCity = '' |
|||
// return |
|||
// } |
|||
// this.areaCity = name |
|||
// }, |
|||
// checkForm() { |
|||
// if (this.hasArea) { |
|||
// if (!this.areaCity) { |
|||
// uni.showToast({ |
|||
// title: '请选择下单区域', |
|||
// icon: 'none' |
|||
// }) |
|||
// return false |
|||
// } |
|||
// if (!this.form.remark) { |
|||
// uni.showToast({ |
|||
// title: '请输入' + this.getBtyRemark(), |
|||
// icon: 'none' |
|||
// }) |
|||
// return false |
|||
// } |
|||
// } |
|||
// return true |
|||
// }, |
|||
getForm() { |
|||
// if (!this.checkForm()) { |
|||
// return { |
|||
// status: 'fail', |
|||
// value: null |
|||
// } |
|||
// } |
|||
// let form = { ...this.form } |
|||
// if (this.hasArea) { |
|||
// let extraRemark = `经理:${this.areaName}; ${this.areaProvince}省; ${this.areaCity}市; 订单备注:` |
|||
// form.remark = extraRemark + form.remark |
|||
// } |
|||
return { |
|||
status: 'success', |
|||
value: this.form |
|||
} |
|||
} |
|||
// showArea() { |
|||
// this.$refs.areaPopup.open('bottom') |
|||
// } |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.goods-info { |
|||
background-color: #fff; |
|||
width: 100%; |
|||
.title { |
|||
padding: 24rpx; |
|||
font-size: 30rpx; |
|||
color: rgb(0, 0, 0); |
|||
text-align: left; |
|||
border-bottom: 1px solid rgb(221, 221, 221); |
|||
} |
|||
.goods-content { |
|||
padding: 32rpx 24rpx 24rpx; |
|||
.group_9 { |
|||
margin-top: 20rpx; |
|||
padding: 0rpx 24rpx; |
|||
.image_7 { |
|||
border-radius: 16rpx; |
|||
width: 180rpx; |
|||
height: 180rpx; |
|||
} |
|||
.group_10 { |
|||
margin-left: 12rpx; |
|||
flex: 1 1 auto; |
|||
.group_11 { |
|||
width: 420rpx; |
|||
.text_12 { |
|||
color: #333333; |
|||
font-size: 32rpx; |
|||
font-family: 'PingFangSC-Medium'; |
|||
font-weight: 500; |
|||
line-height: 45rpx; |
|||
text-align: left; |
|||
} |
|||
.text_13 { |
|||
margin-top: 10rpx; |
|||
align-self: flex-start; |
|||
color: #888888; |
|||
font-size: 22rpx; |
|||
font-family: 'PingFangSC-Medium'; |
|||
font-weight: 500; |
|||
line-height: 30rpx; |
|||
} |
|||
} |
|||
.text_14 { |
|||
margin-top: 13rpx; |
|||
color: #ff0000; |
|||
font-size: 26rpx; |
|||
font-family: 'PingFangSC-Medium'; |
|||
font-weight: 500; |
|||
line-height: 37rpx; |
|||
} |
|||
} |
|||
} |
|||
.remark { |
|||
display: flex; |
|||
margin-top: 16rpx; |
|||
line-height: 40rpx; |
|||
padding-left: 24rpx; |
|||
.remark-label { |
|||
display: inline-block; |
|||
color: #888888; |
|||
font-size: 24rpx; |
|||
} |
|||
.remark-content { |
|||
display: inline-block; |
|||
color: #333333; |
|||
font-size: 24rpx; |
|||
width: 520rpx; |
|||
} |
|||
} |
|||
.image { |
|||
margin-left: 28rpx; |
|||
width: 60rpx; |
|||
height: 68rpx; |
|||
} |
|||
.postage { |
|||
margin-top: 32rpx; |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
align-items: flex-start; |
|||
.tip { |
|||
font-size: 22rpx; |
|||
color: rgb(136, 136, 136); |
|||
margin-top: 16rpx; |
|||
text-align: left; |
|||
} |
|||
} |
|||
.form { |
|||
margin-top: 32rpx; |
|||
.form-item { |
|||
margin-top: 32rpx; |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
.label { |
|||
font-size: 28rpx; |
|||
color: rgb(51, 51, 51); |
|||
} |
|||
.box { |
|||
font-size: 28rpx; |
|||
color: rgb(153, 153, 153); |
|||
text-align: right; |
|||
width: 500rpx; |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: flex-end; |
|||
} |
|||
.value { |
|||
font-size: 28rpx; |
|||
color: rgb(153, 153, 153); |
|||
text-align: right; |
|||
width: 500rpx; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
.label { |
|||
font-size: 28rpx; |
|||
color: rgb(51, 51, 51); |
|||
} |
|||
.red { |
|||
color: rgb(255, 0, 0); |
|||
} |
|||
.popup-content { |
|||
width: 750rpx; |
|||
height: 800rpx; |
|||
border-radius: 16rpx 16rpx 0 0; |
|||
background-color: #fff; |
|||
overflow: hidden; |
|||
.title-content { |
|||
width: 100%; |
|||
padding: 0 32rpx; |
|||
height: 92rpx; |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: center; |
|||
align-items: center; |
|||
font-size: 32rpx; |
|||
color: rgb(51, 51, 51); |
|||
} |
|||
.scroll-title { |
|||
width: 100%; |
|||
height: 92rpx; |
|||
display: flex; |
|||
flex-direction: row; |
|||
justify-content: space-between; |
|||
align-items: center; |
|||
font-size: 28rpx; |
|||
color: rgb(51, 51, 51); |
|||
.left { |
|||
width: 250rpx; |
|||
text-align: center; |
|||
} |
|||
.center { |
|||
width: 250rpx; |
|||
text-align: center; |
|||
} |
|||
.right { |
|||
width: 250rpx; |
|||
text-align: center; |
|||
} |
|||
} |
|||
.scroll-content { |
|||
width: 750rpx; |
|||
height: 508rpx; |
|||
padding-bottom: 32rpx; |
|||
border-top: 1px solid rgba(221, 221, 221, 0.5); |
|||
display: flex; |
|||
align-items: flex-start; |
|||
.left { |
|||
width: 250rpx; |
|||
height: 508rpx; |
|||
overflow-y: auto; |
|||
} |
|||
.center { |
|||
width: 250rpx; |
|||
height: 508rpx; |
|||
overflow-y: auto; |
|||
} |
|||
.right { |
|||
width: 250rpx; |
|||
height: 508rpx; |
|||
overflow-y: auto; |
|||
} |
|||
.item { |
|||
width: 100%; |
|||
font-size: 28rpx; |
|||
line-height: 70rpx; |
|||
color: rgb(51, 51, 51); |
|||
height: 70rpx; |
|||
text-align: center; |
|||
} |
|||
.selected { |
|||
color: #007aff; |
|||
} |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,77 @@ |
|||
<template> |
|||
<view class="off-account-container"> |
|||
<uni-popup ref="offAccountPopup" > |
|||
<view class="content"> |
|||
<view class="title">扫码领取优惠券</view> |
|||
<view class="desc1"> |
|||
长按扫描二维码,关注公众号,免费获取优惠券一张<br>仅限首次关注公众号用户。 |
|||
</view> |
|||
<image class="ercode-img" show-menu-by-longpress src="https://qncloud.oss-cn-shenzhen.aliyuncs.com/wukong-printer-wx/gzh-ercode.png" alt=""> |
|||
<view class="desc2">长按扫码二维码关注</view> |
|||
</view> |
|||
<image @click="close" class="close-img" src="/static/imgs/general/close-icon.png" alt=""> |
|||
</uni-popup> |
|||
</view> |
|||
</template> |
|||
<script> |
|||
import uniPopup from '@/uni_modules/uni-popup/components/uni-popup/uni-popup.vue' |
|||
export default { |
|||
components: { uniPopup }, |
|||
methods: { |
|||
open() { |
|||
this.$refs.offAccountPopup.open('bottom') |
|||
}, |
|||
close() { |
|||
this.$refs.offAccountPopup.close() |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.off-account-container { |
|||
width: 750rpx; |
|||
text-align: center; |
|||
background-color: #ffffff; |
|||
.content { |
|||
width: 750rpx; |
|||
height: 614rpx; |
|||
box-sizing: content-box; |
|||
position: relative; |
|||
background-color: #ffffff; |
|||
border-radius: 20rpx 20rpx 0rpx 0rpx; |
|||
color: #333333; |
|||
.title { |
|||
font-weight: 500; |
|||
font-size: 36rpx; |
|||
line-height: 50rpx; |
|||
margin-top: 32rpx; |
|||
display: inline-block; |
|||
} |
|||
.desc1 { |
|||
width: 644rpx; |
|||
display: inline-block; |
|||
font-size: 28rpx; |
|||
margin-top: 31rpx; |
|||
line-height: 40rpx; |
|||
} |
|||
.ercode-img { |
|||
width: 272rpx; |
|||
height: 272rpx; |
|||
margin-top: 49rpx; |
|||
} |
|||
.desc2 { |
|||
margin-top: 24rpx; |
|||
font-weight: 500; |
|||
font-size: 32rpx; |
|||
} |
|||
} |
|||
.close-img { |
|||
width: 24rpx; |
|||
height: 24rpx; |
|||
position: absolute; |
|||
top: 45rpx; |
|||
right: 32rpx; |
|||
} |
|||
} |
|||
</style> |
|||
@ -0,0 +1,24 @@ |
|||
<template> |
|||
<view class="content"> |
|||
<uni-nav-bar left-icon="back" @clickLeft="back" statusBar fixed title="支付"></uni-nav-bar> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { go2, back } from '@/utils/hook.js' |
|||
export default { |
|||
data() { |
|||
return {} |
|||
}, |
|||
methods: { |
|||
go2, |
|||
back |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss" scoped> |
|||
.content { |
|||
width: 750rpx; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,20 @@ |
|||
module.exports = { |
|||
printWidth: 160, |
|||
semi: false, |
|||
vueIndentScriptAndStyle: true, |
|||
singleQuote: true, |
|||
endOfLine: 'lf', |
|||
tabWidth: 2, |
|||
useTabs: false, |
|||
quoteProps: 'preserve', |
|||
bracketSpacing: true, |
|||
trailingComma: 'none', |
|||
// 解决标签结尾 > 格式化到下一行的问题,htmlWhitespaceSensitivity不能为 strict
|
|||
jsxBracketSameLine: false, |
|||
jsxSingleQuote: false, |
|||
arrowParens: 'always', |
|||
insertPragma: false, |
|||
requirePragma: false, |
|||
proseWrap: 'never', |
|||
htmlWhitespaceSensitivity: 'ignore' |
|||
} |
|||
@ -0,0 +1,25 @@ |
|||
@font-face { |
|||
font-family: "iconfont"; /* Project id 3120523 */ |
|||
src: url('/static/icon/iconfont.ttf') format('truetype'); |
|||
} |
|||
|
|||
.iconfont { |
|||
font-family: "iconfont" !important; |
|||
font-size: 16px; |
|||
font-style: normal; |
|||
-webkit-font-smoothing: antialiased; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
} |
|||
|
|||
.icon-Less:before { |
|||
content: "\e734"; |
|||
} |
|||
|
|||
.icon-m_dow_arrow:before { |
|||
content: "\e600"; |
|||
} |
|||
|
|||
.icon-required:before { |
|||
content: "\e60e"; |
|||
} |
|||
|
|||
Some files were not shown because too many files changed in this diff
Write
Preview
Loading…
Cancel
Save