17 changed files with 1031 additions and 51 deletions
-
2colorui/main.css
-
BINcomponents/amount/DINPro-Medium.ttf
-
220components/amount/_util/animate.js
-
22components/amount/_util/dom.js
-
18components/amount/_util/env.js
-
76components/amount/_util/formate-value.js
-
2components/amount/_util/index.js
-
139components/amount/index.vue
-
110components/amount/number-capital.js
-
24components/me-tabs/me-tabs.vue
-
52components/my-uni-modal-bottom/my-uni-modal-bottom.vue
-
70components/my-uni-modal/my-uni-modal.vue
-
6main.js
-
6pages.json
-
105pages/order/index.vue
-
162pages/order/order-item.vue
-
68project.config.json
@ -0,0 +1,220 @@ |
|||||
|
import {root} from './env' |
||||
|
|
||||
|
/* istanbul ignore file */ |
||||
|
const Animate = (global => { |
||||
|
/* istanbul ignore next */ |
||||
|
const time = |
||||
|
Date.now || |
||||
|
(() => { |
||||
|
return +new Date() |
||||
|
}) |
||||
|
const desiredFrames = 60 |
||||
|
const millisecondsPerSecond = 1000 |
||||
|
|
||||
|
let running = {} |
||||
|
let counter = 1 |
||||
|
|
||||
|
return { |
||||
|
/** |
||||
|
* A requestAnimationFrame wrapper / polyfill. |
||||
|
* |
||||
|
* @param callback {Function} The callback to be invoked before the next repaint. |
||||
|
* @param root {HTMLElement} The root element for the repaint |
||||
|
*/ |
||||
|
requestAnimationFrame: (() => { |
||||
|
// Check for request animation Frame support
|
||||
|
const requestFrame = |
||||
|
global.requestAnimationFrame || |
||||
|
global.webkitRequestAnimationFrame || |
||||
|
global.mozRequestAnimationFrame || |
||||
|
global.oRequestAnimationFrame |
||||
|
let isNative = !!requestFrame |
||||
|
|
||||
|
if (requestFrame && !/requestAnimationFrame\(\)\s*\{\s*\[native code\]\s*\}/i.test(requestFrame.toString())) { |
||||
|
isNative = false |
||||
|
} |
||||
|
|
||||
|
if (isNative) { |
||||
|
return (callback, root) => { |
||||
|
requestFrame(callback, root) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const TARGET_FPS = 60 |
||||
|
let requests = {} |
||||
|
let requestCount = 0 |
||||
|
let rafHandle = 1 |
||||
|
let intervalHandle = null |
||||
|
let lastActive = +new Date() |
||||
|
|
||||
|
return callback => { |
||||
|
const callbackHandle = rafHandle++ |
||||
|
|
||||
|
// Store callback
|
||||
|
requests[callbackHandle] = callback |
||||
|
requestCount++ |
||||
|
|
||||
|
// Create timeout at first request
|
||||
|
if (intervalHandle === null) { |
||||
|
intervalHandle = setInterval(() => { |
||||
|
const time = +new Date() |
||||
|
const currentRequests = requests |
||||
|
|
||||
|
// Reset data structure before executing callbacks
|
||||
|
requests = {} |
||||
|
requestCount = 0 |
||||
|
|
||||
|
for (const key in currentRequests) { |
||||
|
if (currentRequests.hasOwnProperty(key)) { |
||||
|
currentRequests[key](time) |
||||
|
lastActive = time |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Disable the timeout when nothing happens for a certain
|
||||
|
// period of time
|
||||
|
if (time - lastActive > 2500) { |
||||
|
clearInterval(intervalHandle) |
||||
|
intervalHandle = null |
||||
|
} |
||||
|
}, 1000 / TARGET_FPS) |
||||
|
} |
||||
|
|
||||
|
return callbackHandle |
||||
|
} |
||||
|
})(), |
||||
|
|
||||
|
/** |
||||
|
* Stops the given animation. |
||||
|
* |
||||
|
* @param id {Integer} Unique animation ID |
||||
|
* @return {Boolean} Whether the animation was stopped (aka, was running before) |
||||
|
*/ |
||||
|
stop(id) { |
||||
|
const cleared = running[id] != null |
||||
|
cleared && (running[id] = null) |
||||
|
return cleared |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Whether the given animation is still running. |
||||
|
* |
||||
|
* @param id {Integer} Unique animation ID |
||||
|
* @return {Boolean} Whether the animation is still running |
||||
|
*/ |
||||
|
isRunning(id) { |
||||
|
return running[id] != null |
||||
|
}, |
||||
|
|
||||
|
/** |
||||
|
* Start the animation. |
||||
|
* |
||||
|
* @param stepCallback {Function} Pointer to function which is executed on every step. |
||||
|
* Signature of the method should be `function(percent, now, virtual) { return continueWithAnimation; }` |
||||
|
* @param verifyCallback {Function} Executed before every animation step. |
||||
|
* Signature of the method should be `function() { return continueWithAnimation; }` |
||||
|
* @param completedCallback {Function} |
||||
|
* Signature of the method should be `function(droppedFrames, finishedAnimation) {}` |
||||
|
* @param duration {Integer} Milliseconds to run the animation |
||||
|
* @param easingMethod {Function} Pointer to easing function |
||||
|
* Signature of the method should be `function(percent) { return modifiedValue; }` |
||||
|
* @param root {Element ? document.body} Render root, when available. Used for internal |
||||
|
* usage of requestAnimationFrame. |
||||
|
* @return {Integer} Identifier of animation. Can be used to stop it any time. |
||||
|
*/ |
||||
|
start(stepCallback, verifyCallback, completedCallback, duration, easingMethod, root) { |
||||
|
const start = time() |
||||
|
let lastFrame = start |
||||
|
let percent = 0 |
||||
|
let dropCounter = 0 |
||||
|
const id = counter++ |
||||
|
|
||||
|
if (!root) { |
||||
|
// root = document.body
|
||||
|
} |
||||
|
|
||||
|
// Compacting running db automatically every few new animations
|
||||
|
if (id % 20 === 0) { |
||||
|
const newRunning = {} |
||||
|
for (const usedId in running) { |
||||
|
newRunning[usedId] = true |
||||
|
} |
||||
|
running = newRunning |
||||
|
} |
||||
|
|
||||
|
// This is the internal step method which is called every few milliseconds
|
||||
|
const step = virtual => { |
||||
|
// Normalize virtual value
|
||||
|
const render = virtual !== true |
||||
|
|
||||
|
// Get current time
|
||||
|
const now = time() |
||||
|
|
||||
|
// Verification is executed before next animation step
|
||||
|
if (!running[id] || (verifyCallback && !verifyCallback(id))) { |
||||
|
running[id] = null |
||||
|
completedCallback && |
||||
|
completedCallback(desiredFrames - dropCounter / ((now - start) / millisecondsPerSecond), id, false) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// For the current rendering to apply let's update omitted steps in memory.
|
||||
|
// This is important to bring internal state variables up-to-date with progress in time.
|
||||
|
if (render) { |
||||
|
const droppedFrames = Math.round((now - lastFrame) / (millisecondsPerSecond / desiredFrames)) - 1 |
||||
|
for (let j = 0; j < Math.min(droppedFrames, 4); j++) { |
||||
|
step(true) |
||||
|
dropCounter++ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Compute percent value
|
||||
|
if (duration) { |
||||
|
percent = (now - start) / duration |
||||
|
if (percent > 1) { |
||||
|
percent = 1 |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Execute step callback, then...
|
||||
|
let value = easingMethod ? easingMethod(percent) : percent |
||||
|
value = isNaN(value) ? 0 : value |
||||
|
if ((stepCallback(value, now, render) === false || percent === 1) && render) { |
||||
|
running[id] = null |
||||
|
completedCallback && |
||||
|
completedCallback( |
||||
|
desiredFrames - dropCounter / ((now - start) / millisecondsPerSecond), |
||||
|
id, |
||||
|
percent === 1 || duration == null, |
||||
|
) |
||||
|
} else if (render) { |
||||
|
lastFrame = now |
||||
|
this.requestAnimationFrame(step, root) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Mark as running
|
||||
|
running[id] = true |
||||
|
|
||||
|
// Init first step
|
||||
|
this.requestAnimationFrame(step, root) |
||||
|
|
||||
|
// Return unique animation ID
|
||||
|
return id |
||||
|
}, |
||||
|
} |
||||
|
})(root) |
||||
|
|
||||
|
export const easeOutCubic = pos => { |
||||
|
return Math.pow(pos - 1, 3) + 1 |
||||
|
} |
||||
|
|
||||
|
export const easeInOutCubic = pos => { |
||||
|
if ((pos /= 0.5) < 1) { |
||||
|
return 0.5 * Math.pow(pos, 3) |
||||
|
} |
||||
|
|
||||
|
return 0.5 * (Math.pow(pos - 2, 3) + 2) |
||||
|
} |
||||
|
|
||||
|
export default Animate |
||||
@ -0,0 +1,22 @@ |
|||||
|
import {inBrowser} from './env' |
||||
|
|
||||
|
class Dom { |
||||
|
appendChild() {} |
||||
|
removeChild() {} |
||||
|
querySelector() {} |
||||
|
addEventListener() {} |
||||
|
removeEventListener() {} |
||||
|
} |
||||
|
|
||||
|
const dom = new Dom() |
||||
|
let mdDocument = dom |
||||
|
let mdBody = dom |
||||
|
|
||||
|
mdDocument.body = mdBody |
||||
|
|
||||
|
if (inBrowser) { |
||||
|
// mdDocument = window.document
|
||||
|
// mdBody = document.body
|
||||
|
} |
||||
|
|
||||
|
export {mdDocument, mdBody, dom} |
||||
@ -0,0 +1,18 @@ |
|||||
|
import Vue from 'vue' |
||||
|
|
||||
|
// Development environment
|
||||
|
export const isProd = process.env.NODE_ENV === 'production' |
||||
|
|
||||
|
// Browser environment sniffing
|
||||
|
export const inBrowser = !Vue.prototype.$isServer |
||||
|
export const UA = inBrowser |
||||
|
export const isAndroid = UA |
||||
|
export const isIOS = UA |
||||
|
export const root = typeof window !== 'undefined' ? window : global |
||||
|
|
||||
|
|
||||
|
// export const inBrowser = !Vue.prototype.$isServer || typeof window !== 'undefined'
|
||||
|
// export const UA = inBrowser && window.navigator.userAgent.toLowerCase()
|
||||
|
// export const isAndroid = UA && UA.indexOf('android') > 0
|
||||
|
// export const isIOS = UA && /iphone|ipad|ipod|ios/.test(UA)
|
||||
|
// export const root = typeof window !== 'undefined' ? window : global
|
||||
@ -0,0 +1,76 @@ |
|||||
|
export function formatValueByGapRule(gapRule, value, gap = ' ', range, isAdd = 1) { |
||||
|
const arr = value ? value.split('') : [] |
||||
|
let showValue = '' |
||||
|
const rule = [] |
||||
|
gapRule.split('|').some((n, j) => { |
||||
|
rule[j] = +n + (rule[j - 1] ? +rule[j - 1] : 0) |
||||
|
}) |
||||
|
let j = 0 |
||||
|
arr.some((n, i) => { |
||||
|
// Remove the excess part
|
||||
|
if (i > rule[rule.length - 1] - 1) { |
||||
|
return |
||||
|
} |
||||
|
if (i > 0 && i === rule[j]) { |
||||
|
showValue = showValue + gap + n |
||||
|
j++ |
||||
|
} else { |
||||
|
showValue = showValue + '' + n |
||||
|
} |
||||
|
}) |
||||
|
let adapt = 0 |
||||
|
rule.some((n, j) => { |
||||
|
if (range === +n + 1 + j) { |
||||
|
adapt = 1 * isAdd |
||||
|
} |
||||
|
}) |
||||
|
range = typeof range !== 'undefined' ? (range === 0 ? 0 : range + adapt) : showValue.length |
||||
|
return {value: showValue, range: range} |
||||
|
} |
||||
|
|
||||
|
export function formatValueByGapStep(step, value, gap = ' ', direction = 'right', range, isAdd = 1, oldValue = '') { |
||||
|
if (value.length === 0) { |
||||
|
return {value, range} |
||||
|
} |
||||
|
|
||||
|
const arr = value && value.split('') |
||||
|
let _range = range |
||||
|
let showValue = '' |
||||
|
|
||||
|
if (direction === 'right') { |
||||
|
for (let j = arr.length - 1, k = 0; j >= 0; j--, k++) { |
||||
|
const m = arr[j] |
||||
|
showValue = k > 0 && k % step === 0 ? m + gap + showValue : m + '' + showValue |
||||
|
} |
||||
|
if (isAdd === 1) { |
||||
|
// 在添加的情况下,如果添加前字符串的长度减去新的字符串的长度为2,说明多了一个间隔符,需要调整range
|
||||
|
if (oldValue.length - showValue.length === -2) { |
||||
|
_range = range + 1 |
||||
|
} |
||||
|
} else { |
||||
|
// 在删除情况下,如果删除前字符串的长度减去新的字符串的长度为2,说明少了一个间隔符,需要调整range
|
||||
|
if (oldValue.length - showValue.length === 2) { |
||||
|
_range = range - 1 |
||||
|
} |
||||
|
// 删除到最开始,range 保持 0
|
||||
|
if (_range <= 0) { |
||||
|
_range = 0 |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
arr.some((n, i) => { |
||||
|
showValue = i > 0 && i % step === 0 ? showValue + gap + n : showValue + '' + n |
||||
|
}) |
||||
|
const adapt = range % (step + 1) === 0 ? 1 * isAdd : 0 |
||||
|
_range = typeof range !== 'undefined' ? (range === 0 ? 0 : range + adapt) : showValue.length |
||||
|
} |
||||
|
|
||||
|
return {value: showValue, range: _range} |
||||
|
} |
||||
|
|
||||
|
export function trimValue(value, gap = ' ') { |
||||
|
value = typeof value === 'undefined' ? '' : value |
||||
|
const reg = new RegExp(gap, 'g') |
||||
|
value = value.toString().replace(reg, '') |
||||
|
return value |
||||
|
} |
||||
@ -0,0 +1,2 @@ |
|||||
|
export * from './env' |
||||
|
export * from './dom' |
||||
@ -0,0 +1,139 @@ |
|||||
|
<template> |
||||
|
<text class="md-amount" :class="{numerical: !isCapital}"> |
||||
|
<text v-if="!isCapital">{{ formatValue | doPrecision(legalPrecision, isRoundUp) | doFormat(hasSeparator, separator) }}</text> |
||||
|
<text v-else> {{ formatValue | doPrecision(4, isRoundUp) | doCapital }} </text> |
||||
|
</text> |
||||
|
</template> |
||||
|
|
||||
|
<script>
import {noop, inBrowser} from './_util' |
||||
|
import Animate from './_util/animate' |
||||
|
|
||||
|
import {formatValueByGapStep} from './_util/formate-value' |
||||
|
import numberCapital from './number-capital' |
||||
|
|
||||
|
export default { |
||||
|
name: 'md-amount', |
||||
|
|
||||
|
filters: { |
||||
|
doPrecision(value, precision, isRoundUp) { |
||||
|
const exponentialForm = Number(`${value}e${precision}`) |
||||
|
const rounded = isRoundUp ? Math.round(exponentialForm) : Math.floor(exponentialForm) |
||||
|
return Number(`${rounded}e-${precision}`).toFixed(precision) |
||||
|
}, |
||||
|
doFormat(value, hasSeparator, separator) { |
||||
|
if (!hasSeparator) { |
||||
|
return value |
||||
|
} |
||||
|
|
||||
|
const numberParts = value.split('.') |
||||
|
const integerValue = numberParts[0] |
||||
|
const decimalValue = numberParts[1] || '' |
||||
|
const formateValue = formatValueByGapStep(3, integerValue, separator, 'right', 0, 1) |
||||
|
return decimalValue ? `${formateValue.value}.${decimalValue}` : `${formateValue.value}` |
||||
|
}, |
||||
|
doCapital(value) { |
||||
|
return numberCapital(value) |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
props: { |
||||
|
value: { |
||||
|
type: Number, |
||||
|
default: 0, |
||||
|
}, |
||||
|
precision: { |
||||
|
type: Number, |
||||
|
default: 2, |
||||
|
}, |
||||
|
isRoundUp: { |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
hasSeparator: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
separator: { |
||||
|
type: String, |
||||
|
default: ',', |
||||
|
}, |
||||
|
isAnimated: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
transition: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
isCapital: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
duration: { |
||||
|
type: Number, |
||||
|
default: 1000, |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
data() { |
||||
|
return { |
||||
|
formatValue: 0, |
||||
|
isMounted: false, |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
watch: { |
||||
|
value: { |
||||
|
handler(val, oldVal) { |
||||
|
/* istanbul ignore if */ |
||||
|
if (!inBrowser && !this.isMounted) { |
||||
|
this.formatValue = val |
||||
|
return |
||||
|
} |
||||
|
if (this.isAnimated || this.transition) { |
||||
|
this.$_doAnimateDisplay(oldVal, val) |
||||
|
} else { |
||||
|
this.formatValue = val |
||||
|
} |
||||
|
}, |
||||
|
immediate: true, |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
computed: { |
||||
|
legalPrecision() { |
||||
|
return this.precision > 0 ? this.precision : 0 |
||||
|
}, |
||||
|
}, |
||||
|
|
||||
|
mounted() { |
||||
|
this.isMounted = true |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
// MARK: private methods |
||||
|
$_doAnimateDisplay(fromValue = 0, toValue = 0) { |
||||
|
/* istanbul ignore next */ |
||||
|
const step = percent => { |
||||
|
if (percent === 1) { |
||||
|
this.formatValue = toValue |
||||
|
return |
||||
|
} |
||||
|
this.formatValue = fromValue + (toValue - fromValue) * percent |
||||
|
} |
||||
|
|
||||
|
/* istanbul ignore next */ |
||||
|
const verify = id => id |
||||
|
Animate.start(step, verify, noop, this.duration) |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
.md-amount{ |
||||
|
&.numerical{ |
||||
|
font-family: font-family-number |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,110 @@ |
|||||
|
const cnNums = ['\u96f6', '\u58f9', '\u8d30', '\u53c1', '\u8086', '\u4f0d', '\u9646', '\u67d2', '\u634c', '\u7396'] |
||||
|
|
||||
|
// 拾 \u62fe 佰 \u4f70 仟 \u4edf
|
||||
|
const cnIntRadice = ['', '\u62fe', '\u4f70', '\u4edf'] |
||||
|
|
||||
|
// 万 \u4e07 亿 \u4ebf 兆 \u5146
|
||||
|
const cnIntUnits = ['', '\u4e07', '\u4ebf', '兆'] |
||||
|
|
||||
|
// 角 \u89d2 分 \u5206 毫 \u6beb 厘 \u5398
|
||||
|
const cnDecUnits = ['\u89d2', '\u5206', '\u6beb', '\u5398'] |
||||
|
const cnInteger = '\u6574' // 整 \u6574
|
||||
|
const cnIntLast = '\u5143' // 元 \u5143
|
||||
|
|
||||
|
const cnNegative = '\u8d1f' // 负
|
||||
|
|
||||
|
// Maximum number
|
||||
|
const maxNum = 999999999999999.9999 |
||||
|
|
||||
|
export default function(number) { |
||||
|
let negative |
||||
|
// Integral part
|
||||
|
let integerNum |
||||
|
// Decimal part
|
||||
|
let decimalNum |
||||
|
// Capital number
|
||||
|
let capitalStr = '' |
||||
|
|
||||
|
let parts |
||||
|
|
||||
|
/* istanbul ignore if */ |
||||
|
if (number === '') { |
||||
|
return '' |
||||
|
} |
||||
|
|
||||
|
number = parseFloat(number) |
||||
|
|
||||
|
if (number < 0) { |
||||
|
negative = true |
||||
|
number = Math.abs(number) |
||||
|
} |
||||
|
|
||||
|
/* istanbul ignore if */ |
||||
|
if (number >= maxNum) { |
||||
|
return '' |
||||
|
} |
||||
|
|
||||
|
/* istanbul ignore if */ |
||||
|
if (number === 0) { |
||||
|
capitalStr = cnNums[0] + cnIntLast + cnInteger |
||||
|
return capitalStr |
||||
|
} |
||||
|
|
||||
|
// Convert to String
|
||||
|
number += '' |
||||
|
|
||||
|
if (number.indexOf('.') === -1) { |
||||
|
integerNum = number |
||||
|
decimalNum = '' |
||||
|
} else { |
||||
|
parts = number.split('.') |
||||
|
integerNum = parts[0] |
||||
|
decimalNum = parts[1].substr(0, 4) |
||||
|
} |
||||
|
|
||||
|
// Convert integer part
|
||||
|
if (parseInt(integerNum, 10) > 0) { |
||||
|
let zeroCount = 0 |
||||
|
for (let i = 0, IntLen = integerNum.length; i < IntLen; i++) { |
||||
|
const n = integerNum.substr(i, 1) |
||||
|
const p = IntLen - i - 1 |
||||
|
const q = p / 4 |
||||
|
const m = p % 4 |
||||
|
if (n === '0') { |
||||
|
zeroCount++ |
||||
|
} else { |
||||
|
if (zeroCount > 0) { |
||||
|
capitalStr += cnNums[0] |
||||
|
} |
||||
|
zeroCount = 0 |
||||
|
capitalStr += cnNums[parseInt(n)] + cnIntRadice[m] |
||||
|
} |
||||
|
if (m === 0 && zeroCount < 4) { |
||||
|
capitalStr += cnIntUnits[q] |
||||
|
} |
||||
|
} |
||||
|
capitalStr += cnIntLast |
||||
|
} |
||||
|
|
||||
|
// Convert decimal part
|
||||
|
if (decimalNum !== '') { |
||||
|
for (let i = 0, decLen = decimalNum.length; i < decLen; i++) { |
||||
|
const n = decimalNum.substr(i, 1) |
||||
|
if (n !== '0') { |
||||
|
capitalStr += cnNums[Number(n)] + cnDecUnits[i] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* istanbul ignore if */ |
||||
|
if (capitalStr === '') { |
||||
|
capitalStr += cnNums[0] + cnIntLast + cnInteger |
||||
|
} else if (decimalNum === '') { |
||||
|
capitalStr += cnInteger |
||||
|
} |
||||
|
|
||||
|
if (negative) { |
||||
|
capitalStr = `${cnNegative}${capitalStr}` |
||||
|
} |
||||
|
return capitalStr |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
<template> |
||||
|
<!-- 底部弹窗 --> |
||||
|
<view class="cu-modal bottom-modal" :class="modalShow?'show':''" @tap="hideModal"> |
||||
|
<view class="cu-dialog"> |
||||
|
<view> |
||||
|
<view v-for="(item,index) in content" :key="index" class="solid-bottom padding-tb text-black" @tap="BtnClick(index)"> |
||||
|
{{item.text}} |
||||
|
</view> |
||||
|
<view style="background-color: #efefef; height: 10rpx;"></view> |
||||
|
<view class="text-gray padding-tb" @tap="hideModal">取消</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
props: { |
||||
|
content: { |
||||
|
type: Array, |
||||
|
|
||||
|
default: () => { |
||||
|
return [] |
||||
|
}, |
||||
|
}, |
||||
|
modalShow: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
//确认 |
||||
|
BtnClick(index) { |
||||
|
this.$emit('determine', index) |
||||
|
}, |
||||
|
//隐藏弹窗 |
||||
|
hideModal() { |
||||
|
this.$emit('hideModal') |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
|
||||
|
</style> |
||||
@ -0,0 +1,70 @@ |
|||||
|
<template> |
||||
|
<!-- 弹窗 --> |
||||
|
<view class="cu-modal" :class="modalShow?'show':''"> |
||||
|
<view class="cu-dialog"> |
||||
|
<view class="cu-bar bg-white justify-end"> |
||||
|
<view class="content">{{title}}</view> |
||||
|
<view class="action" @tap="hideModal"> |
||||
|
<text class="cuIcon-close text-red"></text> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="padding-xl text-gray"> |
||||
|
{{content}} |
||||
|
</view> |
||||
|
<view class="cu-bar bg-white justify-end"> |
||||
|
<view class="action"> |
||||
|
<button class="cu-btn line-gray text-orange" @tap="hideModal" v-if="isSancel">取消</button> |
||||
|
<button class="cu-btn bg-gradual-red margin-left text-white" @tap="BtnClick">{{btnText}}</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
props: { |
||||
|
title: { |
||||
|
type: String, |
||||
|
default: '温馨提示', |
||||
|
}, |
||||
|
content: { |
||||
|
type: String, |
||||
|
default: '', |
||||
|
}, |
||||
|
btnText: { |
||||
|
type: String, |
||||
|
default: '确定', |
||||
|
}, |
||||
|
modalShow: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
}, |
||||
|
//是否显示取消按钮 |
||||
|
isSancel: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
|
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
methods: { |
||||
|
//确认 |
||||
|
BtnClick() { |
||||
|
this.$emit('determine') |
||||
|
}, |
||||
|
//隐藏弹窗 |
||||
|
hideModal() { |
||||
|
this.$emit('hideModal') |
||||
|
}, |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
|
||||
|
</style> |
||||
@ -1,58 +1,85 @@ |
|||||
<template> |
<template> |
||||
<view class="content"> |
|
||||
|
<view> |
||||
|
|
||||
|
<!-- 当设置tab-width,指定每个tab宽度时,则不使用flex布局,改用水平滑动 --> |
||||
|
<view class="padding-lr"> |
||||
|
<me-tabs style="border-top: 1px solid #f7f7f7;box-sizing:content-box;border-radius: 10px;" v-model="tabIndex" :tabs="tabs" :fixed="true"></me-tabs> |
||||
|
</view> |
||||
|
<swiper :style="{height: height}" :current="tabIndex" @change="swiperChange"> |
||||
|
<swiper-item v-for="(tab,i) in tabs" :key="i"> |
||||
|
<mescroll-item :i="i" :index="tabIndex" :tabs="tabs"></mescroll-item> |
||||
|
</swiper-item> |
||||
|
</swiper> |
||||
</view> |
</view> |
||||
</template> |
</template> |
||||
|
|
||||
<script> |
<script> |
||||
|
import MescrollItem from "./order-item.vue"; |
||||
export default { |
export default { |
||||
|
components: { |
||||
|
MescrollItem |
||||
|
}, |
||||
data() { |
data() { |
||||
return { |
return { |
||||
title: 'Hello' |
|
||||
|
height: "400px", // 需要固定swiper的高度 |
||||
|
tabs: [{ |
||||
|
name: '全部', |
||||
|
type: 'all' |
||||
|
}, { |
||||
|
name: '待付款', |
||||
|
type: 'delivered' |
||||
|
}, { |
||||
|
name: '已付款', |
||||
|
type: 'receiving' |
||||
|
}, |
||||
|
{ |
||||
|
name: '已完成', |
||||
|
type: 'complete' |
||||
|
}], |
||||
|
tabIndex: 0, // 当前tab的下标 |
||||
|
assetsType: '' //账户类型 |
||||
} |
} |
||||
}, |
}, |
||||
onLoad() { |
|
||||
|
|
||||
|
onLoad(e) { |
||||
|
this.assetsType = e.type |
||||
|
this.tabIndex = this.assetsType === 'all' ? 0 : this.assetsType === 'delivered' ? 1 : this.assetsType === 'receiving' ? 2 : 0 |
||||
|
// 需要固定swiper的高度 |
||||
|
this.height = (uni.getSystemInfoSync().windowHeight -30) + 'px' |
||||
}, |
}, |
||||
methods: { |
|
||||
|
|
||||
|
methods: { |
||||
|
// 轮播菜单 |
||||
|
swiperChange(e) { |
||||
|
this.tabIndex = e.detail.current |
||||
|
}, |
||||
|
//返回 |
||||
|
back() { |
||||
|
if (this.assetsType === 'all2') { |
||||
|
// #ifdef H5 |
||||
|
window.history.go(-2) |
||||
|
// #endif |
||||
|
|
||||
|
// #ifndef H5 |
||||
|
uni.navigateBack({ |
||||
|
delta: 2 |
||||
|
}); |
||||
|
// #endif |
||||
|
} else { |
||||
|
// #ifdef H5 |
||||
|
window.history.go(-1) |
||||
|
// #endif |
||||
|
|
||||
|
// #ifndef H5 |
||||
|
uni.navigateBack({ |
||||
|
delta: 1 |
||||
|
}); |
||||
|
// #endif |
||||
|
} |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
</script> |
</script> |
||||
|
|
||||
<style lang="scss" scoped> |
|
||||
.content { |
|
||||
display: flex; |
|
||||
flex-direction: column; |
|
||||
align-items: center; |
|
||||
justify-content: center; |
|
||||
padding: 40rpx; |
|
||||
} |
|
||||
|
|
||||
.logo { |
|
||||
height: 200rpx; |
|
||||
width: 200rpx; |
|
||||
margin-top: 100rpx; |
|
||||
margin-left: auto; |
|
||||
margin-right: auto; |
|
||||
margin-bottom: 50rpx; |
|
||||
} |
|
||||
|
<style> |
||||
|
|
||||
.text-area { |
|
||||
display: flex; |
|
||||
justify-content: center; |
|
||||
} |
|
||||
|
|
||||
.title { |
|
||||
font-size: 28rpx; |
|
||||
color: $u-content-color; |
|
||||
} |
|
||||
|
|
||||
.button-demo { |
|
||||
margin-top: 80rpx; |
|
||||
} |
|
||||
|
|
||||
.link-demo { |
|
||||
margin-top: 80rpx; |
|
||||
} |
|
||||
</style> |
</style> |
||||
@ -0,0 +1,162 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
<mescroll-uni ref="mescrollRef" @init="mescrollInit" height="100%" top="0" :down="downOption" @down="downCallback" |
||||
|
:up="upOption" @up="upCallback"> |
||||
|
<!-- 数据列表 --> |
||||
|
<view class="padding-bottom-xl"> |
||||
|
|
||||
|
<block v-for="(item, index) in assetsFlow" :key="index"> |
||||
|
<view class="margin-top bg-white"> |
||||
|
<view class="flex justify-between align-start solid-bottom padding-tb-sm padding-lr"> |
||||
|
<image src="@/static/tu.png" mode="aspectFill" style="width: 150rpx; height: 150rpx;"></image> |
||||
|
<view class="flex-sub padding-left-sm"> |
||||
|
<view class="bref-box margin-top-xs"> |
||||
|
网红辣椒棒 魔鬼辣椒挑战全网第一辣 网红优惠季 |
||||
|
</view> |
||||
|
<text class="block margin-top-sm text-gray text-sm">网红辣椒棒 500g <text class="margin-left text-gray">x1</text></text> |
||||
|
|
||||
|
<view class="flex justify-between margin-top-sm"> |
||||
|
<view class="text-red text-price text-lg"> |
||||
|
<amount :value="Number(19.90 || 0)" :is-round-up="false" :precision="2" :duration="800" transition></amount> |
||||
|
</view> |
||||
|
<view> |
||||
|
<button v-if="i==1" class="cu-btn line-gray round margin-left-sm" @tap="orderClick(item,'modalShowCancel')">取消订单</button> |
||||
|
<button v-if="i==2" class="cu-btn line-red round margin-left-sm" @tap="$routerGo('/pages/shop/returngoods?id=1')">我要退货</button> |
||||
|
<button v-if="i==2" class="cu-btn line-black round margin-left-sm" @tap="orderClick(item,'modalShowConfirm')">确认收货</button> |
||||
|
<button v-if="i !=1 && i != 2" class="cu-btn line-orange round margin-left-sm" @tap="orderClick(item,'modalShowDel')">立即付款</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="padding-lr padding-tb-sm order-bottom"> |
||||
|
<text class="cuIcon-fold bg-white order-ico"></text> |
||||
|
<view class="flex justify-between align-center"> |
||||
|
<view style="color: #777777;">2021-6-17 12:37:54</view> |
||||
|
<view class="flex align-center justify-end"> |
||||
|
实付: |
||||
|
<view class="text-price text-red text-xl"> |
||||
|
<amount :value="Number(19.90 || 0)" :is-round-up="false" :precision="2" :duration="800" transition></amount> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</block> |
||||
|
</view> |
||||
|
|
||||
|
</mescroll-uni> |
||||
|
|
||||
|
<!-- 取消订单 --> |
||||
|
<my-uni-modal title="取消订单" content="您确定要取消该订单吗?" btnText="取消订单" :modalShow="modalShowCancel" @determine="cancelDetermine" |
||||
|
@hideModal="modalShowCancel=false" /> |
||||
|
|
||||
|
<!-- 删除订单 --> |
||||
|
<my-uni-modal title="删除订单" content="您确定要删除该订单吗?" btnText="删除订单" :modalShow="modalShowDel" @determine="delDetermine" |
||||
|
@hideModal="modalShowDel=false" /> |
||||
|
|
||||
|
<!-- 确认收货 --> |
||||
|
<my-uni-modal title="确认收货" content="请确认您已经收到商品在点击确认收货,以免造成损失." btnText="确认收货" :modalShow="modalShowConfirm" |
||||
|
@determine="confirmDetermine" @hideModal="modalShowConfirm=false" /> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import MescrollMixin from "@/components/mescroll-uni/mescroll-mixins.js"; |
||||
|
import MescrollMoreItemMixin from "@/components/mescroll-uni/mixins/mescroll-more-item.js"; |
||||
|
export default { |
||||
|
mixins: [MescrollMixin, MescrollMoreItemMixin], // 注意此处还需使用MescrollMoreItemMixin (必须写在MescrollMixin后面) |
||||
|
data() { |
||||
|
return { |
||||
|
modalShowCancel: false, //取消订单 |
||||
|
modalShowDel: false, //删除订单 |
||||
|
modalShowConfirm: false, //确认收货 |
||||
|
|
||||
|
orderItem: {}, |
||||
|
|
||||
|
downOption: { |
||||
|
auto: false |
||||
|
}, |
||||
|
upOption: { |
||||
|
auto: false |
||||
|
}, |
||||
|
assetsFlow: 10 |
||||
|
} |
||||
|
}, |
||||
|
props: { |
||||
|
i: Number, // 每个tab页的专属下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义) |
||||
|
index: { // 当前tab的下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义) |
||||
|
type: Number, |
||||
|
default () { |
||||
|
return 0 |
||||
|
} |
||||
|
}, |
||||
|
tabs: { // 为了请求数据,演示用,可根据自己的项目判断是否要传 |
||||
|
type: Array, |
||||
|
default () { |
||||
|
return [] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
orderClick(item, type) { |
||||
|
this.orderItem = item |
||||
|
this[type] = true |
||||
|
}, |
||||
|
|
||||
|
//取消订单 |
||||
|
cancelDetermine() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
//删除订单 |
||||
|
delDetermine() { |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
//确认收货 |
||||
|
confirmDetermine() { |
||||
|
this.$toast('已成功收货') |
||||
|
}, |
||||
|
//资产流水 |
||||
|
getAssetsFlow(pageNum) { |
||||
|
setTimeout(() => { |
||||
|
this.mescroll.endBySize(10, 10); |
||||
|
}, 1000) |
||||
|
|
||||
|
}, |
||||
|
|
||||
|
/*下拉刷新的回调 */ |
||||
|
downCallback() { |
||||
|
// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 ) |
||||
|
this.mescroll.resetUpScroll() |
||||
|
}, |
||||
|
/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */ |
||||
|
upCallback(page) { |
||||
|
this.getAssetsFlow(page.num); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.bref-box { |
||||
|
text-overflow: -o-ellipsis-lastline; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
display: -webkit-box; |
||||
|
-webkit-line-clamp: 2; |
||||
|
-webkit-box-orient: vertical; |
||||
|
} |
||||
|
|
||||
|
.order-bottom { |
||||
|
position: relative; |
||||
|
|
||||
|
.order-ico { |
||||
|
position: absolute; |
||||
|
right: 50rpx; |
||||
|
top: -19rpx; |
||||
|
color: rgba(0, 0, 0, 0.1) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
</style> |
||||
@ -0,0 +1,68 @@ |
|||||
|
{ |
||||
|
"description": "项目配置文件", |
||||
|
"packOptions": { |
||||
|
"ignore": [] |
||||
|
}, |
||||
|
"setting": { |
||||
|
"bundle": false, |
||||
|
"userConfirmedBundleSwitch": false, |
||||
|
"urlCheck": true, |
||||
|
"scopeDataCheck": false, |
||||
|
"coverView": true, |
||||
|
"es6": true, |
||||
|
"postcss": true, |
||||
|
"compileHotReLoad": false, |
||||
|
"preloadBackgroundData": false, |
||||
|
"minified": true, |
||||
|
"autoAudits": false, |
||||
|
"newFeature": false, |
||||
|
"uglifyFileName": false, |
||||
|
"uploadWithSourceMap": true, |
||||
|
"useIsolateContext": true, |
||||
|
"nodeModules": false, |
||||
|
"enhance": false, |
||||
|
"useCompilerModule": true, |
||||
|
"userConfirmedUseCompilerModuleSwitch": false, |
||||
|
"useMultiFrameRuntime": true, |
||||
|
"useApiHook": true, |
||||
|
"useApiHostProcess": true, |
||||
|
"showShadowRootInWxmlPanel": true, |
||||
|
"packNpmManually": false, |
||||
|
"enableEngineNative": false, |
||||
|
"packNpmRelationList": [], |
||||
|
"minifyWXSS": true |
||||
|
}, |
||||
|
"compileType": "miniprogram", |
||||
|
"libVersion": "2.17.3", |
||||
|
"appid": "wx8f7c9e12f8fb8c14", |
||||
|
"projectname": "miniprogram-1", |
||||
|
"debugOptions": { |
||||
|
"hidedInDevtools": [] |
||||
|
}, |
||||
|
"scripts": {}, |
||||
|
"staticServerOptions": { |
||||
|
"baseURL": "", |
||||
|
"servePath": "" |
||||
|
}, |
||||
|
"isGameTourist": false, |
||||
|
"condition": { |
||||
|
"search": { |
||||
|
"list": [] |
||||
|
}, |
||||
|
"conversation": { |
||||
|
"list": [] |
||||
|
}, |
||||
|
"game": { |
||||
|
"list": [] |
||||
|
}, |
||||
|
"plugin": { |
||||
|
"list": [] |
||||
|
}, |
||||
|
"gamePlugin": { |
||||
|
"list": [] |
||||
|
}, |
||||
|
"miniprogram": { |
||||
|
"list": [] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue