123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541 |
- <template>
- <view class="product-choose-add">
- <view class="content-title">
- 产品信息
- </view>
- <view class="content-body">
- <template v-if="productList.length > 0">
- <view class="list">
- <view
- v-for="(item, index) in productList"
- :key="index"
- class="list-item">
- <view class="product-info">
- <text class="name">
- {{ item.name }}
- </text>
- <text class="special">
- {{ item.subtotal }}元
- </text>
- </view>
- <view class="product-desc">
- <view class="box">
- <text class="icon">
- ¥
- </text>
- <input
- v-model="item.salesPrice"
- type="number"
- class="input-core"
- maxlength="8"
- @input="handleChange('salesPrice', index, $event)">
- </view>
- <view class="num-box">
- <view class="sub-icon active" @click="handleChangeNum(index, -1)">
- -
- </view>
- <input v-model="item.num" type="number" class="input-core" maxlength="8" @input="handleChange('num', index, $event)">
- <view class="plus-icon active" @click="handleChangeNum(index, 1)">
- +
- </view>
- </view>
- <view class="box rate">
- <input
- v-model="item.discount"
- type="number"
- class="input-core"
- @input="handleChange('discount', index, $event)">
- <text class="rate-icon">
- %
- </text>
- </view>
- <view class="del-product" @click="delProduct(index)">
- <image
- :src="$static('images/icon/icon_delete.png')"
- class="del" />
- </view>
- </view>
- </view>
- </view>
- <view class="total-box">
- <!-- #ifdef MP-WEIXIN -->
- <view class="total-item">
- 产品 :<text class="num">
- {{ totalCount }}
- </text>
- </view>
- <view class="total-item">
- 总金额 :<text class="num">
- {{ totalMoney }}
- </text>
- </view>
- <!-- #endif -->
- <view class="total">
- <text>整单折扣</text>
- <input
- v-model="discountRate"
- type="number"
- class="input-core"
- @input="handleChange('discountRate', -1, $event)">
- <text class="rate-icon">
- %
- </text>
- </view>
- </view>
- </template>
- <template v-else>
- <view :style="{backgroundImage: bgUrl('images/no_data.png')}" class="no-data">
- 请选择产品
- </view>
- </template>
- </view>
- <!-- #ifndef MP-WEIXIN -->
- <view class="content-footer">
- <view class="total">
- 产品 :<text class="num">
- {{ totalCount }}
- </text>
- </view>
- <view class="total">
- 总金额 :<text class="num">
- {{ totalMoney }}
- </text>
- </view>
- <view class="control">
- <button class="choose-button" @click="handleChoose">
- 添加产品
- </button>
- </view>
- </view>
-
- <uni-popup ref="popup" type="dialog">
- <uni-popup-dialog
- :content="dialogMsg"
- type="warning"
- @confirm="handleDialogConfirm" />
- </uni-popup>
- <!-- #endif -->
- </view>
- </template>
- <script>
- import {
- multiOperation,
- addOperation,
- subOperation,
- divideOperation
- } from '@/utils/lib.js'
- import { deepCopy } from '@/utils/lib.js'
- export default {
- name: 'ProductChooseAdd',
- props: {
- defaultValue: {
- type: Object,
- default: () => {}
- }
- },
- data() {
- return {
- guid: null,
- productList: [],
- totalCount: 0,
- totalMoney: 0,
- discountRate: 0,
- dialogMsg: '',
- productIndex: null
- }
- },
- watch: {
- defaultValue: {
- handler() {
- console.log('change')
- const obj = this.defaultValue || {}
- this.productList = deepCopy(obj.product || [])
- this.discountRate = obj.discountRate || 0
- this.totalMoney = obj.totalPrice || 0
- this.calcMoney(true)
- },
- deep: true,
- immediate: true
- }
- },
- created() {
- this.guid = this.$guid()
- },
- methods: {
- bgUrl(val) {
- return `url(${this.$static(val)})`
- },
- handleChoose() {
- const bridge = getApp().globalData.selectedValBridge
- bridge.product = {
- guid: this.guid,
- title: '选择产品',
- defaultVal: []
- }
- uni.$on('selected-product', this.selectedProduct)
- this.$Router.navigateTo({
- url: '/pages_common/selectList/product',
- query: {}
- })
- },
- selectedProduct(data) {
- if (this.guid === data.guid) {
- console.log('product list: ', data)
- // this.$emit('input', this.optionsList)
- // this.$emit('change', {
- // index: this.index,
- // field: this.field,
- // value: this.optionsList
- // })
- this.renderList(data.data)
- }
- uni.$off('selected-product')
- },
- renderList(list, flag = false) {
- const arr = []
- let keyArr = ['categoryId', 'categoryName', 'price', 'productId', 'unit']
- list.forEach(item => {
- const salesPrice = flag ? item.salesPrice : item.price
- const product = {
- name: item.name || item.productName || '',
- num: flag ? parseInt(item.num) : 1,
- salesPrice: salesPrice,
- subtotal: flag ? (Number(salesPrice) * item.num) : item.price,
- discount: item.discount || 0
- }
- keyArr.forEach(key => {
- product[key] = item[key]
- })
- let index = this.productList.findIndex(o => {
- return o.productId === product.productId
- })
- if (index !== -1) {
- this.handleChangeNum(index, 1)
- } else {
- arr.push(product)
- }
- })
- this.productList = this.productList.concat(arr)
- this.calcMoney()
- },
- /**
- * 改变数量
- * @param index
- * @param step
- */
- handleChangeNum(index, step) {
- const item = this.productList[index]
- item.num = Number(item.num)
- item.num += step
- if (item.num <= 0) {
- this.productList.splice(index, 1)
- }
- this.calcMoney()
- },
- handleChange(field, index, event) {
- // console.log('change: ', field, event)
- // console.log('change:- ', this.productList[index])
- if (index === -1) {
- this.calcMoney()
- return
- }
- const item = this.productList[index]
- if (field === 'salesPrice') {
- // item.discount = Number(100 - (item.salesPrice / item.price * 100).toFixed(2))
- // 计算折扣比率
- let r = divideOperation(item.salesPrice, item.price)
- r = multiOperation(r, 100)
- r = subOperation(100, r).toFixed(2)
- item.discount = Number(r)
- console.log('dis', item.discount)
- } else if (field === 'discount') {
- // 计算售价
- let r = subOperation(100, item.discount)
- r = multiOperation(item.price, r)
- r = (r / 100).toFixed(2)
- item.salesPrice = r
- }
- this.calcMoney()
- },
- /**
- * 保留小数点后两位
- * @param {String} val
- */
- formatFloatNumber(val) {
- let valueStr = String(val)
- if (isNaN(Number(val))) {
- valueStr = valueStr.slice(0, -1)
- this.formatFloatNumber(valueStr)
- }
- valueStr = valueStr.replace(/[^0-9.]/g, '')
- let arr = valueStr.split('.')
- if (arr[1] && arr[1].length > 2) {
- val = valueStr.slice(0, -1)
- this.formatFloatNumber(val)
- }
- return val
- },
- /**
- * 计算总价
- */
- calcMoney(isDefault = false) {
- this.totalCount = 0
- this.totalMoney = 0
- this.productList.forEach(item => {
- item.num = Number(item.num)
- item.subtotal = multiOperation(item.salesPrice, item.num)
- this.totalCount += item.num
- this.totalMoney = addOperation(this.totalMoney, item.subtotal)
- })
- this.totalMoney = multiOperation(this.totalMoney, subOperation(100, this.discountRate)) / 100
- this.totalMoney = this.totalMoney.toFixed(2)
- if (!isDefault) {
- this.$emit('change', {
- list: this.productList,
- totalMoney: this.totalMoney,
- totalCount: this.totalCount
- })
- }
- },
- getForm() {
- return {
- product: this.productList || [],
- discountRate: this.discountRate || 0,
- totalPrice: this.totalMoney
- }
- },
-
- delProduct(index) {
- this.productIndex = index
- this.dialogMsg = '确认删除该产品吗?'
- this.$refs.popup.open()
- },
-
- handleDialogConfirm(next) {
- const item = this.productList[this.productIndex]
- item.num = Number(item.num)
- this.productList.splice(this.productIndex, 1)
- next()
- },
- }
- }
- </script>
- <style scoped lang="scss">
- .input-core {
- width: 100%;
- height: 46rpx;
- border: 1rpx solid $border-color;
- line-height: 1;
- font-size: 26rpx;
- text-align: left;
- display: block;
- }
- .product-choose-add {
- padding-bottom: 120rpx;
- .content-title {
- width: 100%;
- font-size: 24rpx;
- color: $gray;
- padding: 20rpx 30rpx;
- // margin-left: -30px;
- background-color: $container-bg;
- }
- .content-body {
- width: 100%;
- background-color: white;
- overflow-y: scroll;
- .list {
- padding: 0 30rpx;
- .list-item {
- padding: 32rpx 0;
- border-bottom: 1rpx solid $border-color;
- .product-info {
- display: flex;
- align-items: center;
- justify-content: space-between;
- .name {
- flex: 1;
- font-size: 32rpx;
- color: $dark;
- }
- .special {
- font-size: 32rpx;
- color: $warning;
- }
- }
- .product-desc {
- display: flex;
- align-items: center;
- justify-content: space-between;
- .box {
- position: relative;
- height: 46rpx;
- margin-top: 20rpx;
- @include left;
- .input-core {
- width: 180rpx;
- padding-left: 46rpx;
- }
- .icon {
- position: absolute;
- top: 0;
- left: 0;
- width: 46rpx;
- height: 46rpx;
- font-size: 24rpx;
- color: $theme-color;
- @include center;
- }
- .rate-icon {
- font-size: 24rpx;
- margin-left: 5rpx;
- }
- &.rate .input-core {
- padding: 0;
- text-align: center;
- }
- }
- .del-product {
- width: 46rpx;
- height: 46rpx;
- margin-top: 20rpx;
- .del {
- width: 26rpx;
- height: 26rpx;
- }
- }
- .num-box {
- width: 200rpx;
- margin-top: 20rpx;
- @include left;
- .sub-icon, .plus-icon {
- width: 46rpx;
- height: 46rpx;
- font-size: 24rpx;
- color: $theme-color;
- border: 1rpx solid $border-color;
- @include center;
- }
- .sub-icon {
- border-right: 0 none;
- }
- .plus-icon {
- border-left: 0 none;
- }
- .input-core {
- flex: 1;
- text-align: center;
- }
- }
- }
- }
- }
- .total {
- font-size: 26rpx;
- color: $gray;
- @include right;
- .input-core {
- width: 180rpx;
- margin-left: 30rpx;
- text-align: center;
- }
- .rate-icon {
- font-size: 24rpx;
- margin-left: 5rpx;
- }
- }
- }
- .total-box {
- width: 100%;
- font-size: $wk-font-sm;
- background-color: white;
- padding: 30rpx;
- flex-wrap: wrap;
- @include left;
- .total-item:first-child {
- margin-right: 30rpx;
- }
- .total {
- flex: 1;
- padding: 0 0 0 15rpx;
- .input-core {
- width: 100rpx;
- }
- }
- .num {
- color: $warning;
- margin-left: 20rpx;
- }
- }
- .content-footer {
- position: fixed;
- left: 0;
- bottom: 0;
- z-index: 10;
- width: 100%;
- height: 120rpx;
- background-color: white;
- box-shadow: 0 0 10rpx #E5E5E5;
- padding: 0 30rpx;
- @include left;
- .total {
- font-size: 28rpx;
- color: $dark;
- margin-right: 36rpx;
- .num {
- color: $warning;
- margin-left: 20rpx;
- }
- }
- .control {
- flex: 1;
- @include right;
- .choose-button {
- width: 200rpx;
- height: 80rpx;
- font-size: 30rpx;
- color: white;
- background-color: $theme-color;
- @include center;
- }
- }
- }
- }
- .no-data {
- width: 100%;
- text-align: center;
- font-size: 26rpx;
- color: #BBBBBB;
- background-position: center 50rpx;
- background-repeat: no-repeat;
- background-size: 25%;
- padding-top: 270rpx;
- padding-bottom: 30rpx;
- }
- </style>
|