feat(商品)
This commit is contained in:
parent
1c71006dc5
commit
d5e3d34e0f
43
pages.json
43
pages.json
|
@ -12,14 +12,35 @@
|
||||||
"path": "pages/index/redirect"
|
"path": "pages/index/redirect"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/index/order",
|
"path": "pages/index/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "订单"
|
"navigationBarTitleText": "首页"
|
||||||
},
|
},
|
||||||
"meta": {
|
"meta": {
|
||||||
"auth": true
|
"auth": true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/index/order",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "订单",
|
||||||
|
"enablePullDownRefresh": true
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"auth": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/index/product",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "产品",
|
||||||
|
"enablePullDownRefresh": true
|
||||||
|
},
|
||||||
|
|
||||||
|
"meta": {
|
||||||
|
"auth": false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/index/my",
|
"path": "pages/index/my",
|
||||||
"style": {
|
"style": {
|
||||||
|
@ -38,15 +59,6 @@
|
||||||
"auth": false
|
"auth": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"path": "pages/index/index",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "首页"
|
|
||||||
},
|
|
||||||
"meta": {
|
|
||||||
"auth": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"path": "pages/index/login",
|
"path": "pages/index/login",
|
||||||
"style": {
|
"style": {
|
||||||
|
@ -55,15 +67,6 @@
|
||||||
"meta": {
|
"meta": {
|
||||||
"auth": false
|
"auth": false
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"path": "pages/index/product",
|
|
||||||
"style": {
|
|
||||||
"navigationBarTitleText": "产品"
|
|
||||||
},
|
|
||||||
"meta": {
|
|
||||||
"auth": false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"subPackages": [
|
"subPackages": [
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<pb-layout navbar="inner" tabbar="/pages/index/index" :bgStyle="bgStyle">
|
<pb-layout navbar="inner" tabbar="/pages/index/index" :bgStyle="bgStyle">
|
||||||
<view class="dashboard-module ss-p-x-30">
|
<view class="dashboard-module ss-p-x-30">
|
||||||
<view class="merchant-info flex align-center">
|
<view class="merchant-info flex align-center">
|
||||||
<image class="logo" :src="merchantInfo.logo" mode="aspectFill"></image>
|
<image class="logo" :src="merchantInfo?.logo" mode="aspectFill"></image>
|
||||||
|
|
||||||
<view class="detail flex flex-column justify-center gap-10">
|
<view class="detail flex flex-column justify-center gap-10">
|
||||||
<view class="name ss-font-26">{{ merchantInfo.name }}</view>
|
<view class="name ss-font-26">{{ merchantInfo.name }}</view>
|
||||||
|
@ -22,8 +22,8 @@
|
||||||
<button class="right-btn ss-reset-button">查看详情</button>
|
<button class="right-btn ss-reset-button">查看详情</button>
|
||||||
</view>
|
</view>
|
||||||
<view class="des ss-m-t-20">
|
<view class="des ss-m-t-20">
|
||||||
总销售额{{ state.statistic.totalSalesAmount }}元 | 成功退款{{ state.statistic.refundCount }}笔 |
|
总销售额 {{ state.statistic.totalSalesAmount }} 元 | 成功退款 {{ state.statistic.refundCount }} 笔 |
|
||||||
退款金额{{ state.statistic.refundAmount }}元
|
退款金额 {{ state.statistic.refundAmount }} 元
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
|
|
@ -1,215 +1,215 @@
|
||||||
<template>
|
<template>
|
||||||
<pb-layout navbar="inner" tabbar="/pages/index/my" :bgStyle="bgStyle">
|
<pb-layout navbar="inner" tabbar="/pages/index/my" :bgStyle="bgStyle">
|
||||||
<view class="my-module ss-p-x-30">
|
<view class="my-module ss-p-x-30">
|
||||||
<view class="user-info flex align-center">
|
<view class="user-info flex align-center">
|
||||||
<image class="avatar" :src="userInfo.avatar || '/static/default_avatar.png'" mode="aspectFill"></image>
|
<image class="avatar" :src="userInfo.avatar || '/static/default_avatar.png'" mode="aspectFill"></image>
|
||||||
|
|
||||||
<view class="detail flex flex-column justify-center gap-10">
|
<view class="detail flex flex-column justify-center gap-10">
|
||||||
<view class="name ss-font-26">{{ userInfo.nickname }}</view>
|
<view class="name ss-font-26">{{ userInfo.nickname }}</view>
|
||||||
<view class="description ss-font-26">{{ userInfo.mobile }}</view>
|
<view class="description ss-font-26">{{ userInfo.mobile }}</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="statistic ss-m-t-24">
|
<view class="statistic ss-m-t-24">
|
||||||
<view class="title ss-font-24 ss-m-b-20"> 账户余额 </view>
|
<view class="title ss-font-24 ss-m-b-20"> 账户余额 </view>
|
||||||
<view class="remain flex justify-between align-center">
|
<view class="remain flex justify-between align-center">
|
||||||
<view class="left flex align-center">
|
<view class="left flex align-center">
|
||||||
<view class="unit self-start">¥</view>
|
<view class="unit self-start">¥</view>
|
||||||
<view class="sremain ss-font-60">{{ remain }}</view>
|
<view class="sremain ss-font-60">{{ remain }}</view>
|
||||||
</view>
|
</view>
|
||||||
<button @click="peach.$router.go('/pages/user/wallet/money')" class="right-btn ss-reset-button">
|
<button @click="peach.$router.go('/pages/user/wallet/money')" class="right-btn ss-reset-button">
|
||||||
查看详情
|
查看详情
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
<view class="cent ss-m-t-20"> 总获取积分 {{ userInfo.point }} </view>
|
<view class="cent ss-m-t-20"> 总获取积分 {{ userInfo.point }} </view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="menu ss-m-t-70">
|
<view class="menu ss-m-t-70">
|
||||||
<view class="title ss-m-b-30">我的服务</view>
|
<view class="title ss-m-b-30">我的服务</view>
|
||||||
<view class="items">
|
<view class="items">
|
||||||
<view class="item" v-for="item in state.menus" :key="item.name" @click="navService(item)">
|
<view class="item" v-for="item in state.menus" :key="item.name" @click="navService(item)">
|
||||||
<image class="icon" :src="item.icon" mode="aspectFill"></image>
|
<image class="icon" :src="item.icon" mode="aspectFill"></image>
|
||||||
<view class="label">{{ item.name }}</view>
|
<view class="label">{{ item.name }}</view>
|
||||||
</view>
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
<view class="ss-p-x-30 bottom">
|
||||||
</view>
|
<button class="ss-reset-button login-btn-start" @tap="logOut">退出登录</button>
|
||||||
<view class="ss-p-x-30 bottom">
|
</view>
|
||||||
<button class="ss-reset-button login-btn-start" @tap="logOut">退出登录</button>
|
</pb-layout>
|
||||||
</view>
|
|
||||||
</pb-layout>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import $store from '@/peach/store'
|
import AuthUtil from '@/peach/api/member/auth'
|
||||||
import peach from '@/peach'
|
import peach from '@/peach'
|
||||||
|
|
||||||
const bgStyle = {
|
const bgStyle = {
|
||||||
backgroundImage: '/static/bg-page.png',
|
backgroundImage: '/static/bg-page.png',
|
||||||
imageType: 'local',
|
imageType: 'local',
|
||||||
backgroundColor: '#fff',
|
backgroundColor: '#fff',
|
||||||
}
|
}
|
||||||
|
|
||||||
const state = ref({
|
const state = ref({
|
||||||
menus: [
|
menus: [
|
||||||
{
|
{
|
||||||
name: '余额提现',
|
name: '余额提现',
|
||||||
icon: '/static/withdraw.png',
|
icon: '/static/withdraw.png',
|
||||||
path: '/pages/user/wallet/withdraw',
|
path: '/pages/user/wallet/withdraw',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '购买积分',
|
name: '购买积分',
|
||||||
icon: '/static/buycent.png',
|
icon: '/static/buycent.png',
|
||||||
path: '/pages/user/point/buy',
|
path: '/pages/user/point/buy',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '分发积分',
|
name: '分发积分',
|
||||||
icon: '/static/dispensecent.png',
|
icon: '/static/dispensecent.png',
|
||||||
path: '/pages/user/point/share',
|
path: '/pages/user/point/share',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: '提现规则',
|
name: '提现规则',
|
||||||
icon: '/static/rule.png',
|
icon: '/static/rule.png',
|
||||||
path: '',
|
path: '',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
const userStore = $store('user')
|
const userStore = peach.$store('user')
|
||||||
|
|
||||||
const remain = computed(() => {
|
const remain = computed(() => {
|
||||||
return userStore.userWallet?.balance
|
return userStore.userWallet?.balance
|
||||||
})
|
})
|
||||||
|
|
||||||
const userInfo = computed(() => {
|
const userInfo = computed(() => {
|
||||||
return userStore.userInfo
|
return userStore.userInfo
|
||||||
})
|
})
|
||||||
|
|
||||||
function navService(item) {
|
function navService(item) {
|
||||||
peach.$router.go(item.path)
|
peach.$router.go(item.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
function logOut() {
|
function logOut() {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
content: '确认退出账号?',
|
content: '确认退出账号?',
|
||||||
success: async function (res) {
|
success: async function (res) {
|
||||||
if (!res.confirm) {
|
if (!res.confirm) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
await AuthUtil.logout()
|
await AuthUtil.logout()
|
||||||
peach.$store('user').logout()
|
userStore.logOut()
|
||||||
peach.$router.go('/pages/index/login')
|
peach.$router.go('/pages/index/login')
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.my-module {
|
.my-module {
|
||||||
.user-info {
|
.user-info {
|
||||||
.avatar {
|
.avatar {
|
||||||
width: 80rpx;
|
width: 80rpx;
|
||||||
height: 80rpx;
|
height: 80rpx;
|
||||||
margin-right: 20rpx;
|
margin-right: 20rpx;
|
||||||
}
|
|
||||||
|
|
||||||
.detail {
|
|
||||||
.name {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
color: #fff;
|
|
||||||
opacity: 0.4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.statistic {
|
|
||||||
height: 200rpx;
|
|
||||||
background-color: #fffefe;
|
|
||||||
opacity: 0.9;
|
|
||||||
border-radius: 26rpx;
|
|
||||||
padding: 31rpx 40rpx;
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-weight: 500;
|
|
||||||
color: var(--ui-TC);
|
|
||||||
font-size: 24rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remain {
|
|
||||||
.left {
|
|
||||||
font-weight: 600;
|
|
||||||
flex: 1;
|
|
||||||
color: var(--ui-BG-Main);
|
|
||||||
|
|
||||||
.unit {
|
|
||||||
position: relative;
|
|
||||||
top: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-btn {
|
|
||||||
width: 161rpx;
|
|
||||||
height: 63rpx;
|
|
||||||
background-color: var(--ui-BG-Main);
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.cent {
|
|
||||||
color: var(--ui-TC-2);
|
|
||||||
font-size: 24rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu {
|
|
||||||
.title {
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.items {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(4, 1fr);
|
|
||||||
gap: 30rpx 30rpx;
|
|
||||||
|
|
||||||
.item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
gap: 23rpx;
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
width: 94rpx;
|
|
||||||
height: 94rpx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.label {
|
.detail {
|
||||||
font-size: 22rpx;
|
.name {
|
||||||
color: #0c0c0cff;
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
color: #fff;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.statistic {
|
||||||
|
height: 200rpx;
|
||||||
|
background-color: #fffefe;
|
||||||
|
opacity: 0.9;
|
||||||
|
border-radius: 26rpx;
|
||||||
|
padding: 31rpx 40rpx;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--ui-TC);
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remain {
|
||||||
|
.left {
|
||||||
|
font-weight: 600;
|
||||||
|
flex: 1;
|
||||||
|
color: var(--ui-BG-Main);
|
||||||
|
|
||||||
|
.unit {
|
||||||
|
position: relative;
|
||||||
|
top: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-btn {
|
||||||
|
width: 161rpx;
|
||||||
|
height: 63rpx;
|
||||||
|
background-color: var(--ui-BG-Main);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cent {
|
||||||
|
color: var(--ui-TC-2);
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
.title {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.items {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
gap: 30rpx 30rpx;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 23rpx;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 94rpx;
|
||||||
|
height: 94rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #0c0c0cff;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.bottom {
|
.bottom {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 70px;
|
bottom: 70px;
|
||||||
width: calc(100% - 60rpx);
|
width: calc(100% - 60rpx);
|
||||||
|
|
||||||
.login-btn-start {
|
.login-btn-start {
|
||||||
height: 82rpx;
|
height: 82rpx;
|
||||||
line-height: normal;
|
line-height: normal;
|
||||||
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
|
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
|
||||||
border-radius: 28rpx;
|
border-radius: 28rpx;
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -124,7 +124,7 @@
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import OrderApi from '@/peach/api/trade/order'
|
import OrderApi from '@/peach/api/trade/order'
|
||||||
import { onLoad, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app'
|
import { onLoad, onShow, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app'
|
||||||
import { fen2yuan, formatOrderColor, formatOrderStatus, handleOrderButtons } from '@/peach/hooks/useGoods'
|
import { fen2yuan, formatOrderColor, formatOrderStatus, handleOrderButtons } from '@/peach/hooks/useGoods'
|
||||||
import peach from '@/peach'
|
import peach from '@/peach'
|
||||||
import _, { isEmpty } from 'lodash'
|
import _, { isEmpty } from 'lodash'
|
||||||
|
@ -223,6 +223,10 @@ onLoad(async (options) => {
|
||||||
if (options.type) {
|
if (options.type) {
|
||||||
state.value.currentTab = options.type
|
state.value.currentTab = options.type
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(async () => {
|
||||||
|
resetPagination(state.value.pagination)
|
||||||
await getOrderList()
|
await getOrderList()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
:data="item"
|
:data="item"
|
||||||
:topRadius="10"
|
:topRadius="10"
|
||||||
:bottomRadius="10"
|
:bottomRadius="10"
|
||||||
|
@refresh="refresh"
|
||||||
@click="peach.$router.go('/pages/product/manageGoods', { id: item.id, mark: 'detail' })"
|
@click="peach.$router.go('/pages/product/manageGoods', { id: item.id, mark: 'detail' })"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
|
@ -42,7 +43,7 @@
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
import { onLoad, onShow, onReachBottom, onPullDownRefresh } from '@dcloudio/uni-app'
|
||||||
import GoodApi from '@/peach/api/trade/goods'
|
import GoodApi from '@/peach/api/trade/goods'
|
||||||
import peach from '@/peach'
|
import peach from '@/peach'
|
||||||
import _ from 'lodash'
|
import _ from 'lodash'
|
||||||
|
@ -93,6 +94,7 @@ function addGoods() {
|
||||||
selectedProperty: null,
|
selectedProperty: null,
|
||||||
goodsInfo: null,
|
goodsInfo: null,
|
||||||
skus: null,
|
skus: null,
|
||||||
|
specType: false,
|
||||||
})
|
})
|
||||||
peach.$router.go('/pages/product/manageGoods', {
|
peach.$router.go('/pages/product/manageGoods', {
|
||||||
title: '添加商品',
|
title: '添加商品',
|
||||||
|
@ -107,13 +109,28 @@ function loadMore() {
|
||||||
getList()
|
getList()
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoad(async (options) => {
|
function refresh() {
|
||||||
|
resetPagination(state.value.pagination)
|
||||||
getList()
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
onShow(async () => {
|
||||||
|
resetPagination(state.value.pagination)
|
||||||
|
await getList()
|
||||||
})
|
})
|
||||||
|
|
||||||
onReachBottom(() => {
|
onReachBottom(() => {
|
||||||
loadMore()
|
loadMore()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
onPullDownRefresh(() => {
|
||||||
|
resetPagination(state.value.pagination)
|
||||||
|
getList()
|
||||||
|
setTimeout(function () {
|
||||||
|
uni.stopPullDownRefresh()
|
||||||
|
}, 800)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -124,6 +141,7 @@ onReachBottom(() => {
|
||||||
bottom: 70px;
|
bottom: 70px;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
font-size: 80rpx;
|
font-size: 80rpx;
|
||||||
|
z-index: 999;
|
||||||
}
|
}
|
||||||
|
|
||||||
.goods-list-box {
|
.goods-list-box {
|
||||||
|
|
|
@ -97,7 +97,7 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
const formData = ref({})
|
const formData = ref({})
|
||||||
const specType = computed(() => peach.$store('trade').goodsInfo?.specType || false)
|
const specType = computed(() => peach.$store('trade').specType)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.skus,
|
() => props.skus,
|
||||||
|
|
|
@ -1,136 +1,122 @@
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed } from 'vue'
|
||||||
import { onLoad } from "@dcloudio/uni-app";
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
import peach from "@/peach";
|
import peach from '@/peach'
|
||||||
import GoodsApi from "@/peach/api/trade/goods";
|
import GoodsApi from '@/peach/api/trade/goods'
|
||||||
import { SPEC_TYPE, SKU_RULE_CONFIG } from "./config";
|
import { SPEC_TYPE, SKU_RULE_CONFIG } from './config'
|
||||||
|
|
||||||
const pickerRef = ref(null);
|
const pickerRef = ref(null)
|
||||||
|
|
||||||
// 多属性商品 sku 列表
|
// 多属性商品 sku 列表
|
||||||
const skus = ref([]);
|
const skus = ref([])
|
||||||
|
|
||||||
const propertyList = ref([]);
|
// 已选中商品规格的规格属性和值
|
||||||
|
const propertyList = ref([])
|
||||||
|
|
||||||
const goodsPropertyList = ref([]);
|
const goodsPropertyList = ref([])
|
||||||
|
|
||||||
const propertyListRef = ref(null);
|
const propertyListRef = ref(null)
|
||||||
|
|
||||||
const canEdit = computed(() => peach.$store("trade").canEdit);
|
const canEdit = computed(() => peach.$store('trade').canEdit)
|
||||||
|
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
specType: true,
|
specType: true,
|
||||||
specText: SPEC_TYPE[0].label,
|
specText: SPEC_TYPE[0].label,
|
||||||
});
|
})
|
||||||
|
|
||||||
async function showPropertyList() {
|
async function showPropertyList() {
|
||||||
await getGoodsProperty();
|
await getGoodsProperty()
|
||||||
propertyListRef.value.onOpen();
|
propertyListRef.value.onOpen()
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRDPickerConfirm(e) {
|
function onRDPickerConfirm(e) {
|
||||||
formData.value.specType = SPEC_TYPE[e.value[0]].value;
|
formData.value.specType = SPEC_TYPE[e.value[0]].value
|
||||||
formData.value.specText = SPEC_TYPE[e.value[0]].label;
|
formData.value.specText = SPEC_TYPE[e.value[0]].label
|
||||||
|
|
||||||
// 如果商品规格不一致,则需要重新初始化 sku 列表
|
// 如果商品规格不一致,则需要重新初始化 sku 列表
|
||||||
initSku();
|
initSku()
|
||||||
|
|
||||||
peach.$store("trade").specType = SPEC_TYPE[e.value[0]].value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function pickerProperty() {
|
function pickerProperty() {
|
||||||
if (canEdit.value) {
|
if (canEdit.value) {
|
||||||
let index = formData.value.specType ? 1 : 0;
|
let index = formData.value.specType ? 1 : 0
|
||||||
|
|
||||||
console.log(index);
|
pickerRef.value.onOpen([index])
|
||||||
|
}
|
||||||
pickerRef.value.onOpen([index]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function onPropertyConfirm(e) {
|
async function onPropertyConfirm(e) {
|
||||||
await getGoodsProperty();
|
await getGoodsProperty()
|
||||||
console.log(e);
|
console.log(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
function onConfirm() {
|
function onConfirm() {
|
||||||
console.log(skus.value);
|
console.log(skus.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getGoodsProperty() {
|
async function getGoodsProperty() {
|
||||||
let { data } = await GoodsApi.getHistoryProperty();
|
let { data } = await GoodsApi.getHistoryProperty()
|
||||||
|
|
||||||
// 把 propertyList 中 id 相同的属性合并,并去重
|
// 此处处理商品详情情况下,多规格属性
|
||||||
propertyList.value = peach.$store("trade").selectedProperty;
|
// 把 propertyList 中 id 相同的属性合并,并去重
|
||||||
|
propertyList.value = peach.$store('trade').selectedProperty || []
|
||||||
|
|
||||||
console.log(propertyList.value);
|
|
||||||
|
|
||||||
if (propertyList.value) {
|
|
||||||
// 根据已经选择数据,设置默认选中
|
// 根据已经选择数据,设置默认选中
|
||||||
data.forEach((item) => {
|
data.forEach((item) => {
|
||||||
// 判断属性是否已经选中
|
// 判断属性是否已经选中
|
||||||
let propertyParent = propertyList.value.find(
|
let propertyParent = propertyList.value.find((sitem) => sitem?.id === item.id)
|
||||||
(sitem) => sitem?.id === item.id
|
|
||||||
);
|
|
||||||
|
|
||||||
item.checked = propertyParent ? true : false;
|
item.checked = propertyParent ? true : false
|
||||||
|
|
||||||
// 如果属性已经选中,查询子类中是否有选中
|
// 如果属性已经选中,查询子类中是否有选中
|
||||||
if (item.checked) {
|
if (item.checked) {
|
||||||
item.propertyValues.forEach((child) => {
|
item.propertyValues.forEach((child) => {
|
||||||
let childResult = propertyParent?.children.some(
|
let childResult = propertyParent?.children.some((schild) => schild === child.id)
|
||||||
(schild) => schild === child.id
|
child.checked = childResult ? true : false
|
||||||
);
|
})
|
||||||
child.checked = childResult ? true : false;
|
}
|
||||||
});
|
})
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
goodsPropertyList.value = data;
|
goodsPropertyList.value = data
|
||||||
} else {
|
|
||||||
goodsPropertyList.value = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(goodsPropertyList.value);
|
console.log(goodsPropertyList.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeSubProperty() {
|
function changeSubProperty() {
|
||||||
// 修改子属性状态,需要同步更新 skus 的显示
|
// 修改子属性状态,需要同步更新 skus 的显示
|
||||||
console.log(goodsPropertyList.value);
|
console.log(goodsPropertyList.value)
|
||||||
// 过滤父属性 checked 选项,深拷贝避免后面循环改变元数据内容
|
// 过滤父属性 checked 选项,深拷贝避免后面循环改变元数据内容
|
||||||
let temp = JSON.parse(
|
let temp = JSON.parse(JSON.stringify(goodsPropertyList.value.filter((item) => item.checked)))
|
||||||
JSON.stringify(goodsPropertyList.value.filter((item) => item.checked))
|
temp.forEach((item) => {
|
||||||
);
|
item.propertyValues = item.propertyValues.filter((child) => child.checked)
|
||||||
temp.forEach((item) => {
|
})
|
||||||
item.propertyValues = item.propertyValues.filter((child) => child.checked);
|
|
||||||
});
|
|
||||||
|
|
||||||
let result = temp.map((item) => {
|
let result = temp.map((item) => {
|
||||||
return item.propertyValues.map((child) => ({
|
return item.propertyValues.map((child) => ({
|
||||||
propertyId: item.id,
|
propertyId: item.id,
|
||||||
propertyName: item.name,
|
propertyName: item.name,
|
||||||
valueId: child.id,
|
valueId: child.id,
|
||||||
valueName: child.name,
|
valueName: child.name,
|
||||||
}));
|
}))
|
||||||
});
|
})
|
||||||
|
|
||||||
let tempSkus = [];
|
let tempSkus = []
|
||||||
|
|
||||||
for (let item of reduceArr(result)) {
|
for (let item of reduceArr(result)) {
|
||||||
let obj = {
|
let obj = {
|
||||||
picUrl: "",
|
picUrl: '',
|
||||||
barCode: "",
|
barCode: '',
|
||||||
price: 0,
|
price: 0,
|
||||||
marketPrice: 0,
|
marketPrice: 0,
|
||||||
costPrice: 0,
|
costPrice: 0,
|
||||||
stock: 0,
|
stock: 0,
|
||||||
weight: 0,
|
weight: 0,
|
||||||
volume: 0,
|
volume: 0,
|
||||||
properties: item,
|
properties: item,
|
||||||
};
|
}
|
||||||
tempSkus.push(obj);
|
tempSkus.push(obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
skus.value = tempSkus;
|
skus.value = tempSkus
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -140,32 +126,35 @@ function changeSubProperty() {
|
||||||
* @returns {Type}
|
* @returns {Type}
|
||||||
*/
|
*/
|
||||||
function initSku() {
|
function initSku() {
|
||||||
// 单规格
|
// 单规格
|
||||||
if (!formData.value.specType) {
|
if (!formData.value.specType) {
|
||||||
let obj = {
|
let obj = {
|
||||||
picUrl: "",
|
picUrl: '',
|
||||||
barCode: "",
|
barCode: '',
|
||||||
price: 0,
|
price: 0,
|
||||||
marketPrice: 0,
|
marketPrice: 0,
|
||||||
costPrice: 0,
|
costPrice: 0,
|
||||||
stock: 0,
|
stock: 0,
|
||||||
weight: null,
|
weight: null,
|
||||||
volume: null,
|
volume: null,
|
||||||
properties: [
|
properties: [
|
||||||
{
|
{
|
||||||
propertyId: 0,
|
propertyId: 0,
|
||||||
propertyName: "默认",
|
propertyName: '默认',
|
||||||
valueId: 0,
|
valueId: 0,
|
||||||
valueName: "默认",
|
valueName: '默认',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
}
|
||||||
|
|
||||||
skus.value = [obj];
|
skus.value = [obj]
|
||||||
} else {
|
} else {
|
||||||
// 多规格
|
// 初始化已选中规格,属性和格式化后的结果
|
||||||
skus.value = [];
|
propertyList.value = []
|
||||||
}
|
goodsPropertyList.value = []
|
||||||
|
// 多规格
|
||||||
|
skus.value = []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -175,126 +164,127 @@ function initSku() {
|
||||||
* @returns {Type}
|
* @returns {Type}
|
||||||
*/
|
*/
|
||||||
function submitProperty() {
|
function submitProperty() {
|
||||||
try {
|
try {
|
||||||
validateSku(skus.value);
|
validateSku(skus.value)
|
||||||
peach.$store("trade").skus = skus.value;
|
peach.$store('trade').$patch({
|
||||||
peach.$router.back();
|
skus: skus.value,
|
||||||
} catch (e) {
|
specType: formData.value.specType,
|
||||||
console.log(skus.value);
|
})
|
||||||
console.log(e, "校验失败");
|
peach.$router.back()
|
||||||
}
|
} catch (e) {
|
||||||
|
console.log(skus.value)
|
||||||
|
console.log(e, '校验失败')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateSku(skus) {
|
function validateSku(skus) {
|
||||||
let warningInfo = "请检查商品各行相关属性配置,";
|
let warningInfo = '请检查商品各行相关属性配置,'
|
||||||
let validateStatue = true;
|
let validateStatue = true
|
||||||
let skusValue = skus ?? peach.$store("trade").skus;
|
let skusValue = skus ?? peach.$store('trade').skus
|
||||||
|
|
||||||
// 判断如果是多规格,并且 skusValue 为空 [],则提示
|
// 判断如果是多规格,并且 skusValue 为空 [],则提示
|
||||||
if (formData.value.specType && skusValue.length < 1) {
|
if (formData.value.specType && skusValue.length < 1) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: "请选择商品规格",
|
title: '请选择商品规格',
|
||||||
icon: "none",
|
icon: 'none',
|
||||||
duration: 4000,
|
duration: 4000,
|
||||||
});
|
})
|
||||||
throw new Error("请选择商品规格");
|
throw new Error('请选择商品规格')
|
||||||
}
|
|
||||||
for (const sku of skusValue) {
|
|
||||||
for (const rule of SKU_RULE_CONFIG) {
|
|
||||||
const arg = getValue(sku, rule.name);
|
|
||||||
if (!rule.rule(arg)) {
|
|
||||||
validateStatue = false;
|
|
||||||
warningInfo += rule.message;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!validateStatue) {
|
for (const sku of skusValue) {
|
||||||
uni.showToast({
|
for (const rule of SKU_RULE_CONFIG) {
|
||||||
title: warningInfo,
|
const arg = getValue(sku, rule.name)
|
||||||
icon: "none",
|
if (!rule.rule(arg)) {
|
||||||
duration: 4000,
|
validateStatue = false
|
||||||
});
|
warningInfo += rule.message
|
||||||
throw new Error(warningInfo);
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!validateStatue) {
|
||||||
|
uni.showToast({
|
||||||
|
title: warningInfo,
|
||||||
|
icon: 'none',
|
||||||
|
duration: 4000,
|
||||||
|
})
|
||||||
|
throw new Error(warningInfo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getValue(obj, arg) {
|
function getValue(obj, arg) {
|
||||||
const keys = arg.split(".");
|
const keys = arg.split('.')
|
||||||
let value = obj;
|
let value = obj
|
||||||
for (const key of keys) {
|
for (const key of keys) {
|
||||||
if (value && typeof value === "object" && key in value) {
|
if (value && typeof value === 'object' && key in value) {
|
||||||
value = value[key];
|
value = value[key]
|
||||||
} else {
|
} else {
|
||||||
value = undefined;
|
value = undefined
|
||||||
break;
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return value
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function reduceArr(arr) {
|
function reduceArr(arr) {
|
||||||
return arr.reduce((acc, cur) => {
|
return arr.reduce((acc, cur) => {
|
||||||
let tempAcc = [];
|
let tempAcc = []
|
||||||
|
|
||||||
if (acc.length < 1) {
|
if (acc.length < 1) {
|
||||||
cur.forEach((item, index) => {
|
cur.forEach((item, index) => {
|
||||||
if (tempAcc[index]) {
|
if (tempAcc[index]) {
|
||||||
tempAcc[index].push(item);
|
tempAcc[index].push(item)
|
||||||
|
} else {
|
||||||
|
tempAcc[index] = [item]
|
||||||
|
}
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
tempAcc[index] = [item];
|
acc.forEach((item, index) => {
|
||||||
}
|
cur.forEach((sitem, sindex) => {
|
||||||
});
|
tempAcc.push([...item, sitem])
|
||||||
} else {
|
})
|
||||||
acc.forEach((item, index) => {
|
})
|
||||||
cur.forEach((sitem, sindex) => {
|
|
||||||
tempAcc.push([...item, sitem]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (cur.length < 1) {
|
if (cur.length < 1) {
|
||||||
tempAcc = acc;
|
tempAcc = acc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tempAcc;
|
return tempAcc
|
||||||
}, []);
|
}, [])
|
||||||
}
|
}
|
||||||
|
|
||||||
const specType = computed(
|
const specType = computed(() => peach.$store('trade').specType)
|
||||||
() => peach.$store("trade").goodsInfo?.specType || false
|
|
||||||
);
|
|
||||||
|
|
||||||
function initial() {
|
function initial() {
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
formData.value.specType = specType.value ? true : false;
|
formData.value.specType = specType.value
|
||||||
formData.value.specText = SPEC_TYPE[specType.value ? 1 : 0].label;
|
formData.value.specText = SPEC_TYPE[specType.value ? 1 : 0].label
|
||||||
skus.value = JSON.parse(JSON.stringify(peach.$store("trade").skus));
|
skus.value = JSON.parse(JSON.stringify(peach.$store('trade').skus))
|
||||||
// 如果新增商品 sku,并且是单规格,初始化 sku
|
// 如果新增商品 sku,并且是单规格,初始化 sku
|
||||||
|
|
||||||
if (!skus.value) {
|
if (!skus.value) {
|
||||||
initSku();
|
initSku()
|
||||||
}
|
}
|
||||||
if (specType.value) {
|
if (specType.value) {
|
||||||
getGoodsProperty();
|
getGoodsProperty()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
initial,
|
initial,
|
||||||
canEdit,
|
canEdit,
|
||||||
skus,
|
skus,
|
||||||
pickerRef,
|
pickerRef,
|
||||||
pickerProperty,
|
pickerProperty,
|
||||||
validateSku,
|
validateSku,
|
||||||
onConfirm,
|
onConfirm,
|
||||||
submitProperty,
|
submitProperty,
|
||||||
propertyListRef,
|
propertyListRef,
|
||||||
formData,
|
formData,
|
||||||
onRDPickerConfirm,
|
onRDPickerConfirm,
|
||||||
onPropertyConfirm,
|
onPropertyConfirm,
|
||||||
propertyList,
|
propertyList,
|
||||||
showPropertyList,
|
showPropertyList,
|
||||||
goodsPropertyList,
|
goodsPropertyList,
|
||||||
changeSubProperty,
|
changeSubProperty,
|
||||||
};
|
}
|
||||||
|
|
|
@ -120,7 +120,6 @@
|
||||||
placeholderStyle="color:#8a8a8a"
|
placeholderStyle="color:#8a8a8a"
|
||||||
:inputBorder="false"
|
:inputBorder="false"
|
||||||
v-model="formData.deliveryText"
|
v-model="formData.deliveryText"
|
||||||
:disabled="!canEdit"
|
|
||||||
placeholder="请选择配送方式"
|
placeholder="请选择配送方式"
|
||||||
disabled
|
disabled
|
||||||
>
|
>
|
||||||
|
@ -129,9 +128,18 @@
|
||||||
</template>
|
</template>
|
||||||
</uni-easyinput>
|
</uni-easyinput>
|
||||||
</uni-forms-item>
|
</uni-forms-item>
|
||||||
<uni-forms-item label="商品详情">
|
<uni-forms-item label="虚拟销量" name="virtualSalesCount" required>
|
||||||
|
<uni-easyinput
|
||||||
|
v-model="formData.virtualSalesCount"
|
||||||
|
type="number"
|
||||||
|
:disabled="!canEdit"
|
||||||
|
placeholder="请输入虚拟销量"
|
||||||
|
/>
|
||||||
|
</uni-forms-item>
|
||||||
|
<uni-forms-item label="商品详情" required>
|
||||||
<piaoyiEditor
|
<piaoyiEditor
|
||||||
:values="richValues"
|
:values="richValues"
|
||||||
|
@changes="saveContens"
|
||||||
:maxlength="3000"
|
:maxlength="3000"
|
||||||
:readOnly="richReadOnly"
|
:readOnly="richReadOnly"
|
||||||
:photoUrl="photoUrl"
|
:photoUrl="photoUrl"
|
||||||
|
@ -161,7 +169,7 @@ import GoodsApi from '@/peach/api/trade/goods'
|
||||||
import piaoyiEditor from '@/uni_modules/piaoyi-editor/components/piaoyi-editor/piaoyi-editor.vue'
|
import piaoyiEditor from '@/uni_modules/piaoyi-editor/components/piaoyi-editor/piaoyi-editor.vue'
|
||||||
import peach from '@/peach'
|
import peach from '@/peach'
|
||||||
import { baseUrl, apiPath } from '@/peach/config'
|
import { baseUrl, apiPath } from '@/peach/config'
|
||||||
import { handleTree } from '@/peach/utils'
|
import { handleTree, floatToFixed2, convertToInteger } from '@/peach/utils'
|
||||||
import { validateSku } from './js/sku'
|
import { validateSku } from './js/sku'
|
||||||
|
|
||||||
const bgStyle = {
|
const bgStyle = {
|
||||||
|
@ -198,12 +206,16 @@ const formData = ref({
|
||||||
'http://101.43.181.163:9001/mall-backend/8f11e372520501531d06bfce15ea97bbecead41c5e4a36d15d7e40af85729ff3.png',
|
'http://101.43.181.163:9001/mall-backend/8f11e372520501531d06bfce15ea97bbecead41c5e4a36d15d7e40af85729ff3.png',
|
||||||
],
|
],
|
||||||
name: '测试商品',
|
name: '测试商品',
|
||||||
categoryId: [],
|
categoryId: 91,
|
||||||
categoryText: '',
|
categoryText: '',
|
||||||
brandId: '',
|
brandId: 4,
|
||||||
keyword: '香酥鸭,但家',
|
keyword: '香酥鸭,但家',
|
||||||
deliveryTypes: [],
|
deliveryTypes: [3],
|
||||||
deliveryText: '',
|
deliveryText: '',
|
||||||
|
sort: 0,
|
||||||
|
giveIntegral: 0,
|
||||||
|
virtualSalesCount: 0,
|
||||||
|
subCommissionType: false,
|
||||||
introduction: '但家贵阳香酥鸭现榨香酥鸭无任何添加剂香酥鸭但家贵阳香酥鸭现榨香酥鸭无任何添加剂香酥鸭',
|
introduction: '但家贵阳香酥鸭现榨香酥鸭无任何添加剂香酥鸭但家贵阳香酥鸭现榨香酥鸭无任何添加剂香酥鸭',
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -362,7 +374,8 @@ function getProduct(id) {
|
||||||
GoodsApi.getProduct({ id }).then((res) => {
|
GoodsApi.getProduct({ id }).then((res) => {
|
||||||
formData.value = res.data
|
formData.value = res.data
|
||||||
|
|
||||||
richValues.value = res.data.description
|
// 内容为图片时,需要在末尾插入空行
|
||||||
|
richValues.value = res.data.description ? res.data.description + '<p><br/></p>' : ''
|
||||||
|
|
||||||
// 循环遍历 categoryList,从二级分类找出和 formData.value.categoryId 相等的
|
// 循环遍历 categoryList,从二级分类找出和 formData.value.categoryId 相等的
|
||||||
let tempCategory = categoryList.value.find((item) => {
|
let tempCategory = categoryList.value.find((item) => {
|
||||||
|
@ -390,18 +403,28 @@ function getProduct(id) {
|
||||||
return item.value === formData.value.deliveryTypes[0]
|
return item.value === formData.value.deliveryTypes[0]
|
||||||
}).label
|
}).label
|
||||||
|
|
||||||
|
formData.value.skus.forEach((item) => {
|
||||||
|
item.price = floatToFixed2(item.price)
|
||||||
|
item.marketPrice = floatToFixed2(item.marketPrice)
|
||||||
|
item.costPrice = floatToFixed2(item.costPrice)
|
||||||
|
})
|
||||||
|
|
||||||
peach.$store('trade').$patch({
|
peach.$store('trade').$patch({
|
||||||
goodsInfo: formData.value,
|
goodsInfo: formData.value,
|
||||||
skus: formData.value.skus,
|
skus: formData.value.skus,
|
||||||
|
specType: formData.value.specType,
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function saveContens(e) {
|
||||||
|
formData.value.description = e.html
|
||||||
|
}
|
||||||
|
|
||||||
function onSubmit() {
|
function onSubmit() {
|
||||||
console.log('res', formData.value)
|
console.log('res', formData.value)
|
||||||
console.log('richtext', richValues.value)
|
console.log('richtext', richValues.value)
|
||||||
|
|
||||||
formData.value.description = richValues.value
|
|
||||||
formData.value.skus = peach.$store('trade').skus
|
formData.value.skus = peach.$store('trade').skus
|
||||||
|
|
||||||
formRef.value
|
formRef.value
|
||||||
|
@ -414,22 +437,42 @@ function onSubmit() {
|
||||||
|
|
||||||
tempObj.skus.forEach((item) => {
|
tempObj.skus.forEach((item) => {
|
||||||
item.name = formData.value.name
|
item.name = formData.value.name
|
||||||
|
item.price = convertToInteger(item.price)
|
||||||
|
item.marketPrice = convertToInteger(item.marketPrice)
|
||||||
|
item.costPrice = convertToInteger(item.costPrice)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
tempObj.specType = peach.$store('trade').specType
|
||||||
|
|
||||||
|
let msg = ''
|
||||||
if (formData.value.id) {
|
if (formData.value.id) {
|
||||||
tempObj.id = formData.value.id
|
tempObj.id = formData.value.id
|
||||||
await GoodsApi.editProduct(tempObj)
|
await GoodsApi.editProduct(tempObj)
|
||||||
|
msg = '修改成功'
|
||||||
} else {
|
} else {
|
||||||
await GoodsApi.addProduct(tempObj)
|
await GoodsApi.addProduct(tempObj)
|
||||||
|
msg = '添加成功'
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: err[0].errorMessage,
|
title: msg,
|
||||||
icon: 'none',
|
icon: 'none',
|
||||||
duration: 4000,
|
duration: 4000,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
peach.$router.redirect('/pages/index/product')
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
console.log('err', err)
|
console.log('err', err)
|
||||||
|
if (err) {
|
||||||
|
uni.showToast({
|
||||||
|
title: err[0]?.errorMessage,
|
||||||
|
icon: 'none',
|
||||||
|
duration: 4000,
|
||||||
|
})
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,7 +495,7 @@ onLoad(async (options) => {
|
||||||
goodsTitle.value = options.title
|
goodsTitle.value = options.title
|
||||||
|
|
||||||
// 避免页面自动滚动到富文本框,先设置为只读
|
// 避免页面自动滚动到富文本框,先设置为只读
|
||||||
richReadOnly.value = true
|
// richReadOnly.value = true
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* todo 滚动一定距离后,修改富文本状态和 canEdit 一致
|
* todo 滚动一定距离后,修改富文本状态和 canEdit 一致
|
||||||
|
|
|
@ -33,6 +33,14 @@ const GoodsApi = {
|
||||||
data,
|
data,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
// 删除商品
|
||||||
|
delProduct: (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/product/spu/delete',
|
||||||
|
method: 'DELETE',
|
||||||
|
params: data,
|
||||||
|
})
|
||||||
|
},
|
||||||
// 商品分类
|
// 商品分类
|
||||||
getGoodsCategory: (data) => {
|
getGoodsCategory: (data) => {
|
||||||
return request({
|
return request({
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { isArray } from 'lodash'
|
import { isArray } from 'lodash'
|
||||||
import peach from '@/peach'
|
import peach from '@/peach'
|
||||||
|
import GoodsApi from '@/peach/api/trade/goods'
|
||||||
import { fen2yuan, formatSales, formatStock } from '@/peach/hooks/useGoods'
|
import { fen2yuan, formatSales, formatStock } from '@/peach/hooks/useGoods'
|
||||||
import { unix } from 'dayjs'
|
import { unix } from 'dayjs'
|
||||||
|
|
||||||
|
@ -114,7 +115,7 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const emits = defineEmits(['click'])
|
const emits = defineEmits(['click', 'refresh'])
|
||||||
|
|
||||||
function onClick() {
|
function onClick() {
|
||||||
emits('click')
|
emits('click')
|
||||||
|
@ -155,6 +156,7 @@ function clickGoods(mark) {
|
||||||
selectedProperty: null,
|
selectedProperty: null,
|
||||||
goodsInfo: null,
|
goodsInfo: null,
|
||||||
skus: null,
|
skus: null,
|
||||||
|
specType: false,
|
||||||
})
|
})
|
||||||
peach.$router.go('/pages/product/manageGoods', {
|
peach.$router.go('/pages/product/manageGoods', {
|
||||||
id: props.data.id,
|
id: props.data.id,
|
||||||
|
@ -165,8 +167,16 @@ function clickGoods(mark) {
|
||||||
uni.showModal({
|
uni.showModal({
|
||||||
title: '提示',
|
title: '提示',
|
||||||
content: '是否删除该商品?',
|
content: '是否删除该商品?',
|
||||||
success: (res) => {
|
success: async (res) => {
|
||||||
if (res.confirm) {
|
if (res.confirm) {
|
||||||
|
await GoodsApi.delProduct({ id: props.data.id })
|
||||||
|
|
||||||
|
uni.showToast({
|
||||||
|
title: '删除成功',
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
|
|
||||||
|
emits('refresh')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,29 +1,33 @@
|
||||||
import { ref, computed } from "vue";
|
import { ref, computed } from 'vue'
|
||||||
import { defineStore } from "pinia";
|
import { defineStore } from 'pinia'
|
||||||
|
|
||||||
const useTradeStore = defineStore("trade", () => {
|
const useTradeStore = defineStore('trade', () => {
|
||||||
// 已选择规格类型
|
// 已选择规格类型
|
||||||
const selectedProperty = ref(null);
|
const selectedProperty = ref(null)
|
||||||
|
|
||||||
// 商品信息
|
// 商品信息
|
||||||
const goodsInfo = ref(null);
|
const goodsInfo = ref(null)
|
||||||
|
|
||||||
// 详情标记
|
// 详情标记
|
||||||
const detailTag = ref("edit");
|
const detailTag = ref('edit')
|
||||||
|
|
||||||
// 商品属性
|
// 规格类型,默认单规格
|
||||||
const skus = ref(null);
|
const specType = ref(false)
|
||||||
|
|
||||||
// 商品是否可编辑
|
// 商品属性
|
||||||
const canEdit = computed(() => (detailTag.value === "detail" ? false : true));
|
const skus = ref(null)
|
||||||
|
|
||||||
return {
|
// 商品是否可编辑
|
||||||
selectedProperty,
|
const canEdit = computed(() => (detailTag.value === 'detail' ? false : true))
|
||||||
goodsInfo,
|
|
||||||
skus,
|
|
||||||
canEdit,
|
|
||||||
detailTag,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
export default useTradeStore;
|
return {
|
||||||
|
selectedProperty,
|
||||||
|
goodsInfo,
|
||||||
|
skus,
|
||||||
|
canEdit,
|
||||||
|
detailTag,
|
||||||
|
specType,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default useTradeStore
|
||||||
|
|
|
@ -56,6 +56,45 @@ export const handleTree = (data, id, parentId, children) => {
|
||||||
return tree
|
return tree
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const convertToInteger = (num) => {
|
||||||
|
if (typeof num === 'undefined') return 0
|
||||||
|
const parsedNumber = typeof num === 'string' ? parseFloat(num) : num
|
||||||
|
// TODO 分转元后还有小数则四舍五入
|
||||||
|
return Math.round(parsedNumber * 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将一个整数转换为分数保留两位小数
|
||||||
|
* @param num
|
||||||
|
*/
|
||||||
|
export const formatToFraction = (num) => {
|
||||||
|
if (typeof num === 'undefined') return '0.00'
|
||||||
|
const parsedNumber = typeof num === 'string' ? parseFloat(num) : num
|
||||||
|
return (parsedNumber / 100.0).toFixed(2)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const floatToFixed2 = (num) => {
|
||||||
|
let str = '0.00'
|
||||||
|
if (typeof num === 'undefined') {
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
const f = formatToFraction(num)
|
||||||
|
const decimalPart = f.toString().split('.')[1]
|
||||||
|
const len = decimalPart ? decimalPart.length : 0
|
||||||
|
switch (len) {
|
||||||
|
case 0:
|
||||||
|
str = f.toString() + '.00'
|
||||||
|
break
|
||||||
|
case 1:
|
||||||
|
str = f.toString() + '0'
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
str = f.toString()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
export function resetPagination(pagination) {
|
export function resetPagination(pagination) {
|
||||||
pagination.list = []
|
pagination.list = []
|
||||||
pagination.total = 0
|
pagination.total = 0
|
||||||
|
|
|
@ -263,7 +263,7 @@ export default {
|
||||||
},
|
},
|
||||||
clear() {
|
clear() {
|
||||||
this.editorCtx.clear()
|
this.editorCtx.clear()
|
||||||
this.$emit()
|
this.$emit('update:modelValue', '')
|
||||||
},
|
},
|
||||||
insertDate() {
|
insertDate() {
|
||||||
const date = new Date()
|
const date = new Date()
|
||||||
|
|
Loading…
Reference in New Issue