feat(产品类别)

This commit is contained in:
Ankkaya 2024-08-28 18:36:22 +08:00
parent 8f339a1ecc
commit b577f0730c
23 changed files with 3123 additions and 2795 deletions

3
androidPrivacy.json Normal file
View File

@ -0,0 +1,3 @@
{
"prompt": "template"
}

BIN
mall-app-t.rar Normal file

Binary file not shown.

View File

@ -1,31 +1,34 @@
{ {
"name": "mall-app-t", "name" : "豫京牛商家端",
"appid": "__UNI__B201544", "appid" : "__UNI__B201544",
"description": "", "description" : "",
"versionName": "1.0.0", "versionName" : "1.0.0",
"versionCode": "100", "versionCode" : "100",
"transformPx": false, "transformPx" : false,
/* 5+App */ /* 5+App */
"app-plus": { "app-plus" : {
"usingComponents": true, "usingComponents" : true,
"nvueStyleCompiler": "uni-app", "nvueStyleCompiler" : "uni-app",
"compilerVersion": 3, "compilerVersion" : 3,
"splashscreen": { "splashscreen" : {
"alwaysShowBeforeRender": true, "alwaysShowBeforeRender" : true,
"waiting": true, "waiting" : true,
"autoclose": true, "autoclose" : true,
"delay": 0 "delay" : 0
}, },
"compatible": { "compatible" : {
"ignoreVersion": true "ignoreVersion" : true
}, },
/* */ /* */
"modules": {}, "modules" : {
"Barcode" : {},
"Camera" : {}
},
/* */ /* */
"distribute": { "distribute" : {
/* android */ /* android */
"android": { "android" : {
"permissions": [ "permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>", "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>", "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>", "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
@ -44,32 +47,71 @@
] ]
}, },
/* ios */ /* ios */
"ios": {}, "ios" : {
"dSYMs" : false
},
/* SDK */ /* SDK */
"sdkConfigs": {} "sdkConfigs" : {
"ad" : {}
},
"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" : {
"useOriginalMsgbox" : true
}
} }
}, },
/* */ /* */
"quickapp": {}, "quickapp" : {},
/* */ /* */
"mp-weixin": { "mp-weixin" : {
"appid": "wx64387dc8bba916ec", "appid" : "wx64387dc8bba916ec",
"setting": { "setting" : {
"urlCheck": false "urlCheck" : false
}, },
"usingComponents": true "usingComponents" : true
}, },
"mp-alipay": { "mp-alipay" : {
"usingComponents": true "usingComponents" : true
}, },
"mp-baidu": { "mp-baidu" : {
"usingComponents": true "usingComponents" : true
}, },
"mp-toutiao": { "mp-toutiao" : {
"usingComponents": true "usingComponents" : true
}, },
"uniStatistics": { "uniStatistics" : {
"enable": false "enable" : false
}, },
"vueVersion": "3" "vueVersion" : "3"
} }

View File

@ -1,225 +1,222 @@
{ {
"easycom": { "easycom": {
"autoscan": true, "autoscan": true,
"custom": { "custom": {
"^p-(.*)": "@/peach/components/p-$1/p-$1.vue", "^p-(.*)": "@/peach/components/p-$1/p-$1.vue",
"^pb-(.*)": "@/peach/ui/pb-$1/pb-$1.vue" "^pb-(.*)": "@/peach/ui/pb-$1/pb-$1.vue"
} }
},
"pages": [
//pageshttps://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/redirect"
}, },
"pages": [ {
//pageshttps://uniapp.dcloud.io/collocation/pages "path": "pages/index/index",
{ "style": {
"path": "pages/index/redirect" "navigationBarTitleText": "首页"
}, },
{ "meta": {
"path": "pages/index/index", "auth": true
"style": { }
"navigationBarTitleText": "首页" },
}, {
"meta": { "path": "pages/index/order",
"auth": true "style": {
} "navigationBarTitleText": "订单",
}, "enablePullDownRefresh": true
{ },
"path": "pages/index/order", "meta": {
"style": { "auth": true
"navigationBarTitleText": "订单", }
"enablePullDownRefresh": true },
}, {
"meta": { "path": "pages/index/product",
"auth": true "style": {
} "navigationBarTitleText": "产品",
}, "enablePullDownRefresh": true
{ },
"path": "pages/index/product",
"style": {
"navigationBarTitleText": "产品",
"enablePullDownRefresh": true
},
"meta": { "meta": {
"auth": false "auth": false
} }
},
{
"path": "pages/index/my",
"style": {
"navigationBarTitleText": "我的"
},
"meta": {
"auth": false
}
},
{
"path": "pages/index/icons",
"style": {
"navigationBarTitleText": "ICONS"
},
"meta": {
"auth": false
}
},
{
"path": "pages/index/login",
"style": {
"navigationBarTitleText": "登录"
},
"meta": {
"auth": false
}
}
],
"subPackages": [
{
"root": "pages/public",
"pages": [
{
"path": "error",
"style": {
"navigationBarTitleText": "错误页面"
}
},
{
"path": "setting",
"style": {
"navigationBarTitleText": "系统设置"
}
},
{
"path": "richtext",
"style": {
"navigationBarTitleText": "富文本"
}
},
{
"path": "faq",
"style": {
"navigationBarTitleText": "常见问题"
}
},
{
"path": "webview",
"style": {
"navigationBarTitleText": ""
}
}
]
},
{
"root": "pages/user",
"pages": [
{
"path": "wallet/money",
"style": {
"navigationBarTitleText": "余额"
},
"meta": {
"auth": false
}
},
{
"path": "wallet/withdraw",
"style": {
"navigationBarTitleText": "提现"
},
"meta": {
"auth": true
}
},
{
"path": "point/buy",
"style": {
"navigationBarTitleText": "购买积分"
},
"meta": {
"auth": true
}
},
{
"path": "point/share",
"style": {
"navigationBarTitleText": "分发积分"
},
"meta": {
"auth": true
}
},
{
"path": "point/loglist",
"style": {
"navigationBarTitleText": "历史积分",
"enablePullDownRefresh": true
},
"meta": {
"auth": true
}
}
]
},
{
"root": "pages/product",
"pages": [
{
"path": "manageGoods",
"style": {
"navigationBarTitleText": "商品管理"
},
"meta": {
"auth": false
}
},
{
"path": "sku",
"style": {
"navigationBarTitleText": "商品属性"
},
"meta": {
"auth": false
}
}
]
},
{
"root": "pages/order",
"pages": [
{
"path": "detail",
"style": {
"navigationBarTitleText": "订单详情"
},
"meta": {
"auth": true
}
}
]
}
],
"tabBar": {
"list": [
{
"pagePath": "pages/index/index"
},
{
"pagePath": "pages/index/product"
},
{
"pagePath": "pages/index/order"
},
{
"pagePath": "pages/index/my"
},
{
"pagePath": "pages/index/icons"
}
]
}, },
{
"path": "pages/index/my",
"style": {
"navigationBarTitleText": "我的"
},
"meta": {
"auth": false
}
},
{
"path": "pages/index/icons",
"style": {
"navigationBarTitleText": "ICONS"
},
"meta": {
"auth": false
}
},
{
"path": "pages/index/login",
"style": {
"navigationBarTitleText": "登录"
},
"meta": {
"auth": false
}
}
],
"subPackages": [
{
"root": "pages/public",
"pages": [
{
"path": "error",
"style": {
"navigationBarTitleText": "错误页面"
}
},
{
"path": "setting",
"style": {
"navigationBarTitleText": "系统设置"
}
},
{
"path": "richtext",
"style": {
"navigationBarTitleText": "富文本"
}
},
{
"path": "faq",
"style": {
"navigationBarTitleText": "常见问题"
}
},
{
"path": "webview",
"style": {
"navigationBarTitleText": ""
}
}
]
},
{
"root": "pages/user",
"pages": [
{
"path": "wallet/money",
"style": {
"navigationBarTitleText": "余额"
},
"meta": {
"auth": false
}
},
{
"path": "wallet/withdraw",
"style": {
"navigationBarTitleText": "提现"
},
"meta": {
"auth": true
}
},
{
"path": "point/buy",
"style": {
"navigationBarTitleText": "购买积分"
},
"meta": {
"auth": true
}
},
{
"path": "point/share",
"style": {
"navigationBarTitleText": "分发积分"
},
"meta": {
"auth": true
}
},
{
"path": "point/loglist",
"style": {
"navigationBarTitleText": "历史积分",
"enablePullDownRefresh": true
},
"meta": {
"auth": true
}
}
]
},
{
"root": "pages/product",
"pages": [
{
"path": "manageGoods",
"style": {
"navigationBarTitleText": "商品管理"
},
"meta": {
"auth": false
}
},
{
"path": "sku",
"style": {
"navigationBarTitleText": "商品属性"
},
"meta": {
"auth": false
}
}
]
},
{
"root": "pages/order",
"pages": [
{
"path": "detail",
"style": {
"navigationBarTitleText": "订单详情"
},
"meta": {
"auth": true
}
}
]
}
],
"tabBar": {
"list": [
{
"pagePath": "pages/index/index"
},
{
"pagePath": "pages/index/product"
},
{
"pagePath": "pages/index/order"
},
{
"pagePath": "pages/index/my"
}
]
},
"globalStyle": { "globalStyle": {
"navigationBarTextStyle": "black", "navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app", "navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8", "navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8", "backgroundColor": "#F8F8F8",
"navigationStyle": "custom" "navigationStyle": "custom"
}, },
"uniIdRouter": {} "uniIdRouter": {}
} }

View File

@ -1,49 +1,49 @@
<template> <template>
<pb-layout navbar="inner" tabbar="/pages/index/index" :bgStyle="bgStyle"> <pb-layout navbar="inner" tabbar="/pages/index/index" :bgStyle="bgStyle" :leftIcon="''">
<view class="dashboard-module ss-p-x-30"> <view class="dashboard-module ss-p-x-30">
<view class="merchant-info flex align-center justify-between"> <view class="merchant-info flex align-center justify-between">
<view class="flex align-center ss-gap-10"> <view class="flex align-center ss-gap-10">
<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>
<view class="description ss-font-26">{{ merchantInfo?.contactPhone }}</view> <view class="description ss-font-26">{{ merchantInfo?.contactPhone }}</view>
</view> </view>
</view>
<view @tap="checkVerifi">
<text style="color: #fff; font-size: 32px" class="cicon-scan"></text>
</view>
</view>
<view class="statistic ss-m-t-24">
<view class="title ss-font-24 ss-m-b-20">
{{ `今日收款金额(成功收款${state.statistic.todayPaymentCount}笔)` }}
</view>
<view class="income flex justify-between align-center">
<view class="left flex align-center">
<view class="unit self-start"></view>
<view class="sincome ss-font-60">{{ fen2yuan(state.statistic.todayPaymentAmount || 0) }}</view>
</view>
<!-- <button class="right-btn ss-reset-button">查看详情</button> -->
</view>
<view class="des ss-m-t-20">
总销售额 {{ fen2yuan(state.statistic.totalSalesAmount) }} | 成功退款
{{ state.statistic.refundCount }} | 退款金额 {{ fen2yuan(state.statistic.refundAmount) }}
</view>
</view>
<view class="more ss-m-t-70">
<view class="title ss-m-b-30">基础数据</view>
<view class="items">
<view class="item" v-for="(item, index) in state.more" :key="item.name">
<view class="label">{{ item.name }}</view>
<view class="value">{{ index !== 0 ? item.value : fen2yuan(item.value) }}</view>
<view class="last"> 昨日 {{ index === 0 ? fen2yuan(item.last) : item.last }} </view>
</view>
</view>
</view>
</view> </view>
</pb-layout> <view @tap="checkVerifi">
<text style="color: #fff; font-size: 32px" class="cicon-scan"></text>
</view>
</view>
<view class="statistic ss-m-t-24">
<view class="title ss-font-24 ss-m-b-20">
{{ `今日收款金额(成功收款${state.statistic?.todayPaymentCount || 0}笔)` }}
</view>
<view class="income flex justify-between align-center">
<view class="left flex align-center">
<view class="unit self-start"></view>
<view class="sincome ss-font-60">{{ fen2yuan(state.statistic.todayPaymentAmount || 0) }}</view>
</view>
<!-- <button class="right-btn ss-reset-button">查看详情</button> -->
</view>
<view class="des ss-m-t-20">
总销售额 {{ fen2yuan(state.statistic.totalSalesAmount) }} | 成功退款 {{ state.statistic.refundCount }} |
退款金额 {{ fen2yuan(state.statistic.refundAmount) }}
</view>
</view>
<view class="more ss-m-t-70">
<view class="title ss-m-b-30">基础数据</view>
<view class="items">
<view class="item" v-for="(item, index) in state.more" :key="item.name">
<view class="label">{{ item.name }}</view>
<view class="value">{{ index !== 0 ? item.value : fen2yuan(item.value) }}</view>
<view class="last"> 昨日 {{ index === 0 ? fen2yuan(item.last) : item.last ? item.last : 0 }} </view>
</view>
</view>
</view>
</view>
</pb-layout>
</template> </template>
<script setup> <script setup>
@ -57,64 +57,64 @@ import OrderUtil from '@/peach/api/trade/order'
import bg from '@/static/bg-page.png' import bg from '@/static/bg-page.png'
const bgStyle = { const bgStyle = {
backgroundImage: bg, backgroundImage: bg,
imageType: 'local', imageType: 'local',
backgroundColor: '#fff', backgroundColor: '#fff',
description: '', description: '',
} }
const state = ref({ const state = ref({
statistic: { statistic: {
todayPaymentCount: 0, todayPaymentCount: 0,
todayPaymentAmount: 0, todayPaymentAmount: 0,
totalSalesAmount: 0, totalSalesAmount: 0,
refundCount: 0, refundCount: 0,
refundAmount: 0, refundAmount: 0,
},
more: [
{
name: '销售金额',
key: 'Amount',
value: 0,
last: 0,
}, },
more: [ {
{ name: '订单数',
name: '销售金额', key: 'orderCount',
key: 'Amount', value: 0,
value: 0, last: 0,
last: 0, },
}, {
{ name: '待核销',
name: '订单数', key: 'verificationOrderCount',
key: 'orderCount', value: 0,
value: 0, },
last: 0, {
}, name: '待配送',
{ key: 'deliveryOrderCount',
name: '待核销', value: 0,
key: 'verificationOrderCount', },
value: 0, ],
},
{
name: '待配送',
key: 'deliveryOrderCount',
value: 0,
},
],
}) })
const userStore = $store('user') const userStore = $store('user')
const merchantInfo = computed(() => { const merchantInfo = computed(() => {
return userStore.userInfo?.particulars return userStore.userInfo?.particulars
}) })
async function getStatistic() { async function getStatistic() {
let res = await UserUtil.getHomeStatistics() let res = await UserUtil.getHomeStatistics()
for (let key of Object.keys(state.value.statistic)) { for (let key of Object.keys(state.value.statistic)) {
state.value.statistic[key] = res.data[key] state.value.statistic[key] = res.data[key]
} }
state.value.more[0].value = res.data.todayPaymentAmount ?? 0 state.value.more[0].value = res.data.todayPaymentAmount ?? 0
state.value.more[0].last = res.data.yesterdaySalesAmount ?? 0 state.value.more[0].last = res.data.yesterdaySalesAmount ?? 0
state.value.more[1].value = res.data.orderCount state.value.more[1].value = res.data.orderCount
state.value.more[1].last = res.data.yesterdayOrderCount state.value.more[1].last = res.data.yesterdayOrderCount
state.value.more[2].value = res.data.verificationOrderCount state.value.more[2].value = res.data.verificationOrderCount
state.value.more[3].value = res.data.deliveryOrderCount state.value.more[3].value = res.data.deliveryOrderCount
} }
/** /**
@ -124,126 +124,126 @@ async function getStatistic() {
* @returns {Type} * @returns {Type}
*/ */
function checkVerifi() { function checkVerifi() {
// //
uni.scanCode({ uni.scanCode({
success: (res) => { success: (res) => {
uni.showModal({ uni.showModal({
title: '提示', title: '提示',
content: '是否核销该订单', content: '是否核销该订单',
success: function (sres) { success: function (sres) {
if (sres.confirm) { if (sres.confirm) {
OrderUtil.orderVerification({ OrderUtil.orderVerification({
verifyCode: res.result, verifyCode: res.result,
}).then((res) => { }).then((res) => {
uni.showToast({ uni.showToast({
title: '订单核销成功', title: '订单核销成功',
icon: 'success', icon: 'success',
}) })
setTimeout(() => { setTimeout(() => {
peach.$router.go('/pages/order/detail', { peach.$router.go('/pages/order/detail', {
id: res.data, id: res.data,
}) })
}, 500) }, 500)
})
}
},
}) })
}
}, },
fail: (err) => { })
console.log(err) },
}, fail: (err) => {
}) console.log(err)
},
})
} }
onShow(() => { onShow(() => {
getStatistic() getStatistic()
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.dashboard-module { .dashboard-module {
.merchant-info { .merchant-info {
.logo { .logo {
width: 80rpx; width: 80rpx;
height: 80rpx; height: 80rpx;
margin-right: 20rpx; margin-right: 20rpx;
} }
.detail { .detail {
.name { .name {
color: #fff; color: #fff;
} }
.description { .description {
color: #fff; color: #fff;
opacity: 0.4; 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);
}
.income {
.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;
}
} }
.statistic { .des {
height: 200rpx; color: var(--ui-TC-2);
background-color: #fffefe; font-size: 24rpx;
opacity: 0.9;
border-radius: 26rpx;
padding: 31rpx 40rpx;
.title {
font-weight: 500;
color: var(--ui-TC);
}
.income {
.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;
}
}
.des {
color: var(--ui-TC-2);
font-size: 24rpx;
}
} }
}
.more { .more {
.title { .title {
font-weight: 600; font-weight: 600;
}
.items {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 30rpx 30rpx;
.item {
background: linear-gradient(90deg, #ffebeb 0%, #ffffff 100%);
border-radius: 18rpx;
padding: 19rpx 32rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 170rpx;
.name {
font-weight: 600;
color: var(--ui-TC);
}
.value {
font-weight: 600;
font-size: 31rpx;
color: var(--ui-TC);
}
.last {
font-weight: 400;
color: var(--ui-TC-2);
}
}
}
} }
.items {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 30rpx 30rpx;
.item {
background: linear-gradient(90deg, #ffebeb 0%, #ffffff 100%);
border-radius: 18rpx;
padding: 19rpx 32rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
height: 170rpx;
.name {
font-weight: 600;
color: var(--ui-TC);
}
.value {
font-weight: 600;
font-size: 31rpx;
color: var(--ui-TC);
}
.last {
font-weight: 400;
color: var(--ui-TC-2);
}
}
}
}
} }
</style> </style>

View File

@ -6,15 +6,32 @@
</view> </view>
<uni-forms ref="smsLoginRef" v-model="state.model" :rules="state.rules" validateTrigger="bind"> <uni-forms ref="smsLoginRef" v-model="state.model" :rules="state.rules" validateTrigger="bind">
<uni-forms-item name="mobile"> <uni-forms-item name="mobile">
<uni-easyinput :styles="state.inputStyle" trim="all" placeholder="请输入手机号" v-model="state.model.mobile" <uni-easyinput
:inputBorder="false" type="number" /> :styles="state.inputStyle"
trim="all"
placeholder="请输入手机号"
v-model="state.model.mobile"
:inputBorder="false"
type="number"
/>
</uni-forms-item> </uni-forms-item>
<uni-forms-item name="code"> <uni-forms-item name="code">
<uni-easyinput :styles="state.inputStyle" trim="all" placeholder="验证码" v-model="state.model.code" <uni-easyinput
:inputBorder="false" type="number" maxlength="4"> :styles="state.inputStyle"
trim="all"
placeholder="验证码"
v-model="state.model.code"
:inputBorder="false"
type="number"
maxlength="4"
>
<template #right> <template #right>
<button :disabled="state.isMobileEnd" :class="{ 'code-btn-end': state.isMobileEnd }" <button
class="ss-reset-button code-btn code-btn-start" @tap="getSmsCode('smsLogin', state.model.mobile)"> :disabled="state.isMobileEnd"
:class="{ 'code-btn-end': state.isMobileEnd }"
class="ss-reset-button code-btn code-btn-start"
@tap="getSmsCode('smsLogin', state.model.mobile)"
>
{{ getSmsTimer('smsLogin') }} {{ getSmsTimer('smsLogin') }}
</button> </button>
</template> </template>
@ -24,8 +41,12 @@
<button class="ss-reset-button login-btn-start" @tap="smsLoginSubmit">登录</button> <button class="ss-reset-button login-btn-start" @tap="smsLoginSubmit">登录</button>
<view class="agreement-box ss-flex ss-row-center" :class="{ shake: state.isShaking }"> <view class="agreement-box ss-flex ss-row-center" :class="{ shake: state.isShaking }">
<label class="radio ss-flex" @tap="onChange"> <label class="radio ss-flex" @tap="onChange">
<radio :checked="state.agreeStatus" color="var(--ui-BG-Main)" style="transform: scale(0.8)" <radio
@tap.stop="onChange" /> :checked="state.agreeStatus"
color="var(--ui-BG-Main)"
style="transform: scale(0.8)"
@tap.stop="onChange"
/>
<view class="agreement-text ss-flex ss-m-l-8"> <view class="agreement-text ss-flex ss-m-l-8">
我已阅读并遵守 我已阅读并遵守
<view class="tcp-text" @tap.stop="onProtocol('商家入驻协议')"> 商家入驻协议 </view> <view class="tcp-text" @tap.stop="onProtocol('商家入驻协议')"> 商家入驻协议 </view>
@ -51,8 +72,8 @@ const state = ref({
agreeStatus: false, agreeStatus: false,
isShaking: false, isShaking: false,
model: { model: {
mobile: '15036370128', mobile: '',
code: '9999', code: '',
}, },
rules: { rules: {
mobile, mobile,

View File

@ -1,52 +1,48 @@
<template> <template>
<pb-layout navbar="inner" tabbar="/pages/index/my" :bgStyle="bgStyle"> <pb-layout navbar="inner" tabbar="/pages/index/my" :bgStyle="bgStyle" :leftIcon="''">
<view class="my-module ss-p-x-30"> <view class="my-module ss-p-x-30">
<view class="user-info flex align-center justify-between"> <view class="user-info flex align-center justify-between">
<view class="flex align-center ss-gap-10"> <view class="flex align-center ss-gap-10">
<image <image class="avatar" :src="userInfo.avatar || '/static/default_avatar.png'" mode="aspectFill"></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> <!-- <view>
<text style="color: #fff; font-size: 20px" class="cicon-settings-o"></text> <text style="color: #fff; font-size: 20px" class="cicon-settings-o"></text>
</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 class="ss-p-x-30 bottom"> </view>
<button class="ss-reset-button login-btn-start" @tap="logOut">退出登录</button> </view>
</view> <view class="ss-p-x-30 bottom">
</pb-layout> <button class="ss-reset-button login-btn-start" @tap="logOut">退出登录</button>
</view>
</pb-layout>
</template> </template>
<script setup> <script setup>
@ -56,173 +52,173 @@ 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: '/pages/public/richtext?title=提现规则',
}, },
], ],
}) })
const userStore = peach.$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()
userStore.logOut() userStore.logOut()
peach.$router.go('/pages/index/login') peach.$router.go('/pages/index/login')
}, },
}) })
} }
onShow(() => { onShow(() => {
peach.$store('user').updateUserData() peach.$store('user').updateUserData()
}) })
</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 { .detail {
height: 200rpx; .name {
background-color: #fffefe; color: #fff;
opacity: 0.9; }
border-radius: 26rpx;
padding: 31rpx 40rpx;
.title { .description {
font-weight: 500; color: #fff;
color: var(--ui-TC); opacity: 0.4;
font-size: 24rpx; }
} }
}
.remain { .statistic {
.left { height: 200rpx;
font-weight: 600; background-color: #fffefe;
flex: 1; opacity: 0.9;
color: var(--ui-BG-Main); border-radius: 26rpx;
padding: 31rpx 40rpx;
.unit { .title {
position: relative; font-weight: 500;
top: 4px; color: var(--ui-TC);
} font-size: 24rpx;
}
.right-btn {
width: 161rpx;
height: 63rpx;
background-color: var(--ui-BG-Main);
color: #fff;
}
}
.cent {
color: var(--ui-TC-2);
font-size: 24rpx;
}
} }
.menu { .remain {
.title { .left {
font-weight: 600; font-weight: 600;
flex: 1;
color: var(--ui-BG-Main);
.unit {
position: relative;
top: 4px;
} }
}
.items { .right-btn {
display: grid; width: 161rpx;
grid-template-columns: repeat(4, 1fr); height: 63rpx;
gap: 30rpx 30rpx; background-color: var(--ui-BG-Main);
color: #fff;
.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;
}
}
}
} }
.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>

View File

@ -1,124 +1,118 @@
<template> <template>
<pb-layout <pb-layout
title="订单" title="订单"
navbar="normal" navbar="normal"
tabbar="/pages/index/order" tabbar="/pages/index/order"
:bgStyle="bgStyle" :bgStyle="bgStyle"
opacityBgUi="bg-white" opacityBgUi="bg-white"
color="black" color="black"
> :leftIcon="''"
<pb-sticky bgColor="#fff"> >
<pb-tabs :list="tabMaps" :scrollable="false" @change="onTabsChange" :current="state.currentTab" /> <pb-sticky bgColor="#fff">
</pb-sticky> <pb-tabs :list="tabMaps" :scrollable="false" @change="onTabsChange" :current="state.currentTab" />
<p-empty </pb-sticky>
v-if="state.pagination.total === 0" <p-empty v-if="state.pagination.total === 0" icon="/static/order-empty.png" text="暂无订单" bgColor="transparent" />
icon="/static/order-empty.png" <view v-if="state.pagination.total > 0">
text="暂无订单" <view
bgColor="transparent" class="bg-white order-list-card-box ss-r-10 ss-m-t-14 ss-m-20"
/> v-for="order in state.pagination.list"
<view v-if="state.pagination.total > 0"> :key="order.id"
<view >
class="bg-white order-list-card-box ss-r-10 ss-m-t-14 ss-m-20" <view @tap="onOrderDetail(order.id, state.currentTab)">
v-for="order in state.pagination.list" <view class="order-card-header ss-flex ss-col-center ss-row-between ss-p-x-20">
:key="order.id" <view class="order-no">订单号{{ order.no }}</view>
> <view class="order-state ss-font-26" :class="formatOrderColor(order)">
<view @tap="onOrderDetail(order.id, state.currentTab)"> {{ formatOrderStatus(order) }}
<view class="order-card-header ss-flex ss-col-center ss-row-between ss-p-x-20">
<view class="order-no">订单号{{ order.no }}</view>
<view class="order-state ss-font-26" :class="formatOrderColor(order)">
{{ formatOrderStatus(order) }}
</view>
</view>
<view class="border-bottom" v-for="item in order.items" :key="item.id">
<p-goods-item
:img="item.picUrl"
:title="item.spuName"
:skuText="item.properties.map((property) => property.valueName).join(' ')"
:price="item.price"
:num="item.count"
/>
</view>
<view
class="order-card-footer ss-flex ss-col-center ss-p-x-20"
:class="order.buttons.length > 3 ? 'ss-row-between' : 'ss-row-right'"
>
<view class="ss-flex ss-col-center">
<button
v-if="order.buttons.length === 0"
class="tool-btn ss-reset-button"
@tap.stop="onOrderDetail(order.id)"
>
查看详情
</button>
<button
v-if="order.buttons.includes('confirm')"
class="tool-btn ss-reset-button"
@tap.stop="onConfirm(order)"
>
确认收货
</button>
<button
v-if="order.buttons.includes('express')"
class="tool-btn ss-reset-button"
@tap.stop="onExpress(order.id)"
>
查看物流
</button>
<button
v-if="order.buttons.includes('cancel')"
class="tool-btn ss-reset-button"
@tap.stop="onCancel(order.id, sindex)"
>
取消订单
</button>
<button
v-if="order.buttons.includes('comment')"
class="tool-btn ss-reset-button"
@tap.stop="onComment(order.id)"
>
评价
</button>
<button
v-if="order.buttons.includes('delete')"
class="delete-btn ss-reset-button"
@tap.stop="onDelete(order.id)"
>
删除订单
</button>
<button
v-if="order.buttons.includes('verification')"
class="tool-btn ss-reset-button ui-BG-Main-Gradient"
@tap.stop="onVerification(order.id)"
>
核销订单
</button>
<button
v-if="order.buttons.includes('delivery')"
class="tool-btn ss-reset-button ui-BG-Main-Gradient"
@tap.stop="onDelivery(order.id)"
>
配送完成
</button>
</view>
</view>
<view class="pay-box ss-m-t-30 ss-flex ss-gap-40 ss-p-b-40 ss-row-right ss-p-r-20">
<view class="ss-flex ss-col-center">
<view class="discounts-title pay-color"
> {{ totalNumsPerOrder(order) }} 件商品,总金额:</view
>
<view class="discounts-money pay-color"> {{ fen2yuan(totalPricePerOrder(order)) }} </view>
</view>
</view>
</view>
</view> </view>
</view>
<view class="border-bottom" v-for="item in order.items" :key="item.id">
<p-goods-item
:img="item.picUrl"
:title="item.spuName"
:skuText="item.properties.map((property) => property.valueName).join(' ')"
:price="item.price"
:num="item.count"
/>
</view>
<view
class="order-card-footer ss-flex ss-col-center ss-p-x-20"
:class="order.buttons.length > 3 ? 'ss-row-between' : 'ss-row-right'"
>
<view class="ss-flex ss-col-center">
<button
v-if="order.buttons.length === 0"
class="tool-btn ss-reset-button"
@tap.stop="onOrderDetail(order.id)"
>
查看详情
</button>
<button
v-if="order.buttons.includes('confirm')"
class="tool-btn ss-reset-button"
@tap.stop="onConfirm(order)"
>
确认收货
</button>
<button
v-if="order.buttons.includes('express')"
class="tool-btn ss-reset-button"
@tap.stop="onExpress(order.id)"
>
查看物流
</button>
<button
v-if="order.buttons.includes('cancel')"
class="tool-btn ss-reset-button"
@tap.stop="onCancel(order.id, sindex)"
>
取消订单
</button>
<button
v-if="order.buttons.includes('comment')"
class="tool-btn ss-reset-button"
@tap.stop="onComment(order.id)"
>
评价
</button>
<button
v-if="order.buttons.includes('delete')"
class="delete-btn ss-reset-button"
@tap.stop="onDelete(order.id)"
>
删除订单
</button>
<button
v-if="order.buttons.includes('verification')"
class="tool-btn ss-reset-button ui-BG-Main-Gradient"
@tap.stop="onVerification(order.id)"
>
核销订单
</button>
<button
v-if="order.buttons.includes('delivery')"
class="tool-btn ss-reset-button ui-BG-Main-Gradient"
@tap.stop="onDelivery(order.id)"
>
配送完成
</button>
</view>
</view>
<view class="pay-box ss-m-t-30 ss-flex ss-gap-40 ss-p-b-40 ss-row-right ss-p-r-20">
<view class="ss-flex ss-col-center">
<view class="discounts-title pay-color"> {{ totalNumsPerOrder(order) }} 件商品,总金额:</view>
<view class="discounts-money pay-color"> {{ fen2yuan(totalPricePerOrder(order)) }} </view>
</view>
</view>
</view> </view>
<uni-load-more </view>
v-if="state.pagination.total > 0" </view>
:status="state.loadStatus" <uni-load-more
:content-text="{ contentdown: '上拉加载更多' }" v-if="state.pagination.total > 0"
/> :status="state.loadStatus"
</pb-layout> :content-text="{ contentdown: '上拉加载更多' }"
/>
</pb-layout>
</template> </template>
<script setup> <script setup>
@ -131,268 +125,268 @@ import _, { isEmpty } from 'lodash'
import { resetPagination } from '@/peach/utils' import { resetPagination } from '@/peach/utils'
const bgStyle = { const bgStyle = {
backgroundColor: 'var(--ui-BG-1)', backgroundColor: 'var(--ui-BG-1)',
description: '', description: '',
} }
const state = ref({ const state = ref({
currentTab: 0, currentTab: 0,
pagination: { pagination: {
list: [], list: [],
total: 0, total: 0,
pageNo: 1, pageNo: 1,
pageSize: 6, pageSize: 6,
}, },
loadStatus: '', loadStatus: '',
}) })
const tabMaps = [ const tabMaps = [
{ {
name: '全部', name: '全部',
}, },
{ {
name: '已付款', name: '已付款',
value: '50,60', value: '50,60',
commentStatus: 2, commentStatus: 2,
}, },
{ {
name: '已评价', name: '已评价',
value: '30', value: '30',
commentStatus: 1, commentStatus: 1,
}, },
{ {
name: '已退款', name: '已退款',
value: '10,20', value: '10,20',
}, },
] ]
function onDelivery(id) { function onDelivery(id) {
OrderApi.orderComplete({ orderId: id }).then(() => { OrderApi.orderComplete({ orderId: id }).then(() => {
uni.showToast({ uni.showToast({
title: '配送成功', title: '配送成功',
icon: 'success', icon: 'success',
})
setTimeout(() => {
peach.$router.go('/pages/order/detail', {
id: id,
})
}, 500)
}) })
setTimeout(() => {
peach.$router.go('/pages/order/detail', {
id: id,
})
}, 500)
})
} }
// //
function totalNumsPerOrder(order) { function totalNumsPerOrder(order) {
if (order.items.length) { if (order.items.length) {
return order.items.reduce((per, cur) => { return order.items.reduce((per, cur) => {
return per + cur.count return per + cur.count
}, 0) }, 0)
} }
} }
// //
function totalPricePerOrder(order) { function totalPricePerOrder(order) {
if (order.items.length) { if (order.items.length) {
return order.items.reduce((per, cur) => { return order.items.reduce((per, cur) => {
return per + cur.payPrice return per + cur.payPrice
}, 0) }, 0)
} }
} }
// //
function onTabsChange(e) { function onTabsChange(e) {
if (state.value.currentTab === e.index) { if (state.value.currentTab === e.index) {
return return
} }
// //
resetPagination(state.value.pagination) resetPagination(state.value.pagination)
state.value.currentTab = e.index state.value.currentTab = e.index
getOrderList() getOrderList()
} }
// //
function onOrderDetail(id) { function onOrderDetail(id) {
peach.$router.go('/pages/order/detail', { peach.$router.go('/pages/order/detail', {
id, id,
currentTabIndex: state.value.currentTab, currentTabIndex: state.value.currentTab,
}) })
} }
// //
async function getOrderList() { async function getOrderList() {
state.value.loadStatus = 'loading' state.value.loadStatus = 'loading'
let { data } = await OrderApi.getOrderPage({ let { data } = await OrderApi.getOrderPage({
pageNo: state.value.pagination.pageNo, pageNo: state.value.pagination.pageNo,
pageSize: state.value.pagination.pageSize, pageSize: state.value.pagination.pageSize,
status: state.value.currentTab !== 3 ? tabMaps[state.value.currentTab].value : undefined, status: state.value.currentTab !== 3 ? tabMaps[state.value.currentTab].value : undefined,
refundStatus: state.value.currentTab === 3 ? tabMaps[state.value.currentTab].value : undefined, refundStatus: state.value.currentTab === 3 ? tabMaps[state.value.currentTab].value : undefined,
commentStatus: tabMaps[state.value.currentTab].commentStatus commentStatus: tabMaps[state.value.currentTab].commentStatus
? state.value.currentTab === 1 ? state.value.currentTab === 1
? false ? false
: true : true
: undefined, : undefined,
}) })
data.list.forEach((item) => { data.list.forEach((item) => {
handleOrderButtons(item) handleOrderButtons(item)
}) })
state.value.pagination.list = _.concat(state.value.pagination.list, data.list) state.value.pagination.list = _.concat(state.value.pagination.list, data.list)
state.value.pagination.total = data.total state.value.pagination.total = data.total
let currentPageTotal = state.value.pagination.length let currentPageTotal = state.value.pagination.length
state.value.loadStatus = currentPageTotal < state.value.pagination.total ? 'more' : 'noMore' state.value.loadStatus = currentPageTotal < state.value.pagination.total ? 'more' : 'noMore'
} }
onLoad(async (options) => { onLoad(async (options) => {
if (options.type) { if (options.type) {
state.value.currentTab = options.type state.value.currentTab = options.type
} }
}) })
onShow(async () => { onShow(async () => {
resetPagination(state.value.pagination) resetPagination(state.value.pagination)
await getOrderList() await getOrderList()
}) })
// //
function loadMore() { function loadMore() {
if (state.value.loadStatus === 'noMore') { if (state.value.loadStatus === 'noMore') {
return return
} }
state.value.pagination.pageNo++ state.value.pagination.pageNo++
getOrderList() getOrderList()
} }
// //
onReachBottom(() => { onReachBottom(() => {
loadMore() loadMore()
}) })
// //
onPullDownRefresh(() => { onPullDownRefresh(() => {
resetPagination(state.value.pagination) resetPagination(state.value.pagination)
getOrderList() getOrderList()
setTimeout(function () { setTimeout(function () {
uni.stopPullDownRefresh() uni.stopPullDownRefresh()
}, 800) }, 800)
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.tool-btn { .tool-btn {
width: 160rpx; width: 160rpx;
height: 60rpx; height: 60rpx;
background: #f6f6f6; background: #f6f6f6;
font-size: 26rpx; font-size: 26rpx;
border-radius: 30rpx; border-radius: 30rpx;
margin-right: 10rpx; margin-right: 10rpx;
&:last-of-type { &:last-of-type {
margin-right: 0; margin-right: 0;
} }
} }
.delete-btn { .delete-btn {
width: 160rpx; width: 160rpx;
height: 56rpx; height: 56rpx;
color: #ff3000; color: #ff3000;
background: #fee; background: #fee;
border-radius: 28rpx; border-radius: 28rpx;
font-size: 26rpx; font-size: 26rpx;
margin-right: 10rpx; margin-right: 10rpx;
line-height: normal; line-height: normal;
&:last-of-type { &:last-of-type {
margin-right: 0; margin-right: 0;
} }
} }
.apply-btn { .apply-btn {
width: 140rpx; width: 140rpx;
height: 50rpx; height: 50rpx;
border-radius: 25rpx; border-radius: 25rpx;
font-size: 24rpx; font-size: 24rpx;
border: 2rpx solid #dcdcdc; border: 2rpx solid #dcdcdc;
line-height: normal; line-height: normal;
margin-left: 16rpx; margin-left: 16rpx;
} }
.order-list-card-box { .order-list-card-box {
.order-card-header { .order-card-header {
height: 80rpx; height: 80rpx;
.order-no { .order-no {
font-size: 26rpx; font-size: 26rpx;
font-weight: 500; font-weight: 500;
}
.order-state {
}
} }
.pay-box { .order-state {
.discounts-title { }
font-size: 24rpx; }
line-height: normal;
color: #999999;
}
.discounts-money { .pay-box {
font-size: 24rpx; .discounts-title {
line-height: normal; font-size: 24rpx;
color: #999; line-height: normal;
font-family: OPPOSANS; color: #999999;
}
.pay-color {
color: #333;
}
} }
.order-card-footer { .discounts-money {
height: 100rpx; font-size: 24rpx;
line-height: normal;
.more-item-box { color: #999;
padding: 20rpx; font-family: OPPOSANS;
.more-item {
height: 60rpx;
.title {
font-size: 26rpx;
}
}
}
.more-btn {
color: $dark-9;
font-size: 24rpx;
}
.content {
width: 154rpx;
color: #333333;
font-size: 26rpx;
font-weight: 500;
}
} }
.pay-color {
color: #333;
}
}
.order-card-footer {
height: 100rpx;
.more-item-box {
padding: 20rpx;
.more-item {
height: 60rpx;
.title {
font-size: 26rpx;
}
}
}
.more-btn {
color: $dark-9;
font-size: 24rpx;
}
.content {
width: 154rpx;
color: #333333;
font-size: 26rpx;
font-weight: 500;
}
}
} }
:deep(.uni-tooltip-popup) { :deep(.uni-tooltip-popup) {
background: var(--ui-BG); background: var(--ui-BG);
} }
.warning-color { .warning-color {
color: #faad14; color: #faad14;
} }
.danger-color { .danger-color {
color: #ff3000; color: #ff3000;
} }
.success-color { .success-color {
color: #52c41a; color: #52c41a;
} }
.info-color { .info-color {
color: #999999; color: #999999;
} }
</style> </style>

View File

@ -1,44 +1,45 @@
<template> <template>
<pb-layout <pb-layout
class="product-list" class="product-list"
title="产品" title="产品"
navbar="normal" navbar="normal"
tabbar="/pages/index/product" tabbar="/pages/index/product"
:bgStyle="bgStyle" :bgStyle="bgStyle"
opacityBgUi="bg-white" opacityBgUi="bg-white"
color="black" color="black"
> :leftIcon="''"
<view v-if="state.pagination.total > 0" class="goods-list ss-m-t-20"> >
<view class="ss-p-l-20 ss-p-r-20 ss-m-b-20" v-for="item in state.pagination.list" :key="item.id"> <view v-if="state.pagination.total > 0" class="goods-list ss-m-t-20">
<p-goods-column <view class="ss-p-l-20 ss-p-r-20 ss-m-b-20" v-for="item in state.pagination.list" :key="item.id">
size="lg" <p-goods-column
:data="item" size="lg"
:topRadius="10" :data="item"
:bottomRadius="10" :topRadius="10"
@refresh="refresh" :bottomRadius="10"
@click="peach.$router.go('/pages/product/manageGoods', { id: item.id, mark: 'detail' })" @refresh="refresh"
/> @click="peach.$router.go('/pages/product/manageGoods', { id: item.id, mark: 'detail' })"
</view>
</view>
<uni-load-more
v-if="state.pagination.total > 0"
:status="state.loadStatus"
:content-text="{
contentdown: '上拉加载更多',
}"
@click="loadMore"
/> />
</view>
</view>
<view class="_icon-add-round add-product" @click="addGoods"></view> <uni-load-more
v-if="state.pagination.total > 0"
:status="state.loadStatus"
:content-text="{
contentdown: '上拉加载更多',
}"
@click="loadMore"
/>
<p-empty <view class="_icon-add-round add-product" @click="addGoods"></view>
v-if="state.pagination.total === 0"
icon="/static/soldout-empty.png" <p-empty
text="暂无产品" v-if="state.pagination.total === 0"
bgColor="transparent" icon="/static/soldout-empty.png"
/> text="暂无产品"
</pb-layout> bgColor="transparent"
/>
</pb-layout>
</template> </template>
<script setup> <script setup>
@ -50,189 +51,189 @@ import _ from 'lodash'
import { resetPagination } from '@/peach/utils' import { resetPagination } from '@/peach/utils'
const bgStyle = { const bgStyle = {
backgroundImage: '', backgroundImage: '',
backgroundColor: 'var(--ui-BG-1)', backgroundColor: 'var(--ui-BG-1)',
description: '', description: '',
} }
const state = ref({ const state = ref({
pagination: { pagination: {
list: [], list: [],
total: 0, total: 0,
pageNo: 1, pageNo: 1,
pageSize: 6, pageSize: 6,
name: '', name: '',
createTime: [], createTime: [],
}, },
loadStatus: '', loadStatus: '',
}) })
function emptyList() { function emptyList() {
resetPagination(state.value.pagination) resetPagination(state.value.pagination)
} }
function onSearch() { function onSearch() {
emptyList() emptyList()
getList() getList()
} }
async function getList() { async function getList() {
let { data } = await GoodApi.getProductList({ let { data } = await GoodApi.getProductList({
pageNo: state.value.pagination.pageNo, pageNo: state.value.pagination.pageNo,
pageSize: state.value.pagination.pageSize, pageSize: state.value.pagination.pageSize,
}) })
state.value.pagination.list = _.concat(state.value.pagination.list, data.list) state.value.pagination.list = _.concat(state.value.pagination.list, data.list)
state.value.pagination.total = data.total state.value.pagination.total = data.total
let currentPageTotal = state.value.pagination.length let currentPageTotal = state.value.pagination.length
state.value.loadStatus = currentPageTotal < state.value.pagination.total ? 'more' : 'noMore' state.value.loadStatus = currentPageTotal < state.value.pagination.total ? 'more' : 'noMore'
} }
function addGoods() { function addGoods() {
peach.$store('trade').$patch({ peach.$store('trade').$patch({
selectedProperty: null, selectedProperty: null,
goodsInfo: null, goodsInfo: null,
skus: null, skus: null,
specType: false, specType: false,
}) })
peach.$router.go('/pages/product/manageGoods', { peach.$router.go('/pages/product/manageGoods', {
title: '添加商品', title: '添加商品',
}) })
} }
function loadMore() { function loadMore() {
if (state.value.loadStatus === 'noMore') { if (state.value.loadStatus === 'noMore') {
return return
} }
state.value.pagination.pageNo++ state.value.pagination.pageNo++
getList() getList()
} }
function refresh() { function refresh() {
resetPagination(state.value.pagination) resetPagination(state.value.pagination)
getList() getList()
} }
onShow(async () => { onShow(async () => {
resetPagination(state.value.pagination) resetPagination(state.value.pagination)
await getList() await getList()
}) })
onReachBottom(() => { onReachBottom(() => {
loadMore() loadMore()
}) })
// //
onPullDownRefresh(() => { onPullDownRefresh(() => {
resetPagination(state.value.pagination) resetPagination(state.value.pagination)
getList() getList()
setTimeout(function () { setTimeout(function () {
uni.stopPullDownRefresh() uni.stopPullDownRefresh()
}, 800) }, 800)
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.product-list { .product-list {
.add-product { .add-product {
position: fixed; position: fixed;
color: var(--ui-BG-Main); color: var(--ui-BG-Main);
bottom: 70px; bottom: 70px;
right: 20px; right: 20px;
font-size: 80rpx; font-size: 80rpx;
z-index: 999; z-index: 999;
}
.goods-list-box {
width: 50%;
box-sizing: border-box;
.left-list {
margin-right: 10rpx;
margin-bottom: 20rpx;
} }
.goods-list-box { .right-list {
width: 50%; margin-left: 10rpx;
box-sizing: border-box; margin-bottom: 20rpx;
}
}
.left-list { .goods-box {
margin-right: 10rpx; &:nth-last-of-type(1) {
margin-bottom: 20rpx; margin-bottom: 0 !important;
}
.right-list {
margin-left: 10rpx;
margin-bottom: 20rpx;
}
} }
.goods-box { &:nth-child(2n) {
&:nth-last-of-type(1) { margin-right: 0;
margin-bottom: 0 !important; }
} }
&:nth-child(2n) { .list-icon {
margin-right: 0; width: 80rpx;
}
.sicon-goods-card {
font-size: 40rpx;
} }
.list-icon { .sicon-goods-list {
width: 80rpx; font-size: 40rpx;
}
}
.sicon-goods-card { .goods-card {
font-size: 40rpx; margin-left: 20rpx;
} }
.sicon-goods-list { .list-filter-tabs {
font-size: 40rpx; background-color: #fff;
} }
.filter-list-box {
padding: 28rpx 52rpx;
.filter-item {
font-size: 28rpx;
font-weight: 500;
color: #333333;
line-height: normal;
margin-bottom: 24rpx;
&:nth-last-child(1) {
margin-bottom: 0;
}
} }
.goods-card { .filter-item-active {
margin-left: 20rpx; color: var(--ui-BG-Main);
}
}
.tab-item {
height: 50px;
position: relative;
z-index: 11;
.tab-title {
font-size: 30rpx;
} }
.list-filter-tabs { .cur-tab-title {
background-color: #fff; font-weight: $font-weight-bold;
} }
.filter-list-box { .tab-line {
padding: 28rpx 52rpx; width: 60rpx;
height: 6rpx;
.filter-item { border-radius: 6rpx;
font-size: 28rpx; position: absolute;
font-weight: 500; left: 50%;
color: #333333; transform: translateX(-50%);
line-height: normal; bottom: 10rpx;
margin-bottom: 24rpx; background-color: var(--ui-BG-Main);
z-index: 12;
&:nth-last-child(1) {
margin-bottom: 0;
}
}
.filter-item-active {
color: var(--ui-BG-Main);
}
}
.tab-item {
height: 50px;
position: relative;
z-index: 11;
.tab-title {
font-size: 30rpx;
}
.cur-tab-title {
font-weight: $font-weight-bold;
}
.tab-line {
width: 60rpx;
height: 6rpx;
border-radius: 6rpx;
position: absolute;
left: 50%;
transform: translateX(-50%);
bottom: 10rpx;
background-color: var(--ui-BG-Main);
z-index: 12;
}
} }
}
} }
</style> </style>

View File

@ -9,18 +9,46 @@
<view class="property-value ss-flex ss-gap-40"> <view class="property-value ss-flex ss-gap-40">
<view class="property-value-text">规格值</view> <view class="property-value-text">规格值</view>
<view class="property-value-value ss-flex ss-gap-10"> <view class="property-value-value ss-flex ss-gap-10">
<view v-for="sitem in item.propertyValues" @tap="chooseProperty(sitem)" <view
:class="['item', sitem.checked ? 'active' : '']">{{ sitem.name }}</view> v-for="sitem in item.propertyValues"
@tap="chooseProperty(sitem)"
@longpress="longPropertyValuePress(sitem)"
:class="['item', sitem.checked ? 'active' : '']"
>{{ sitem.name }}</view
>
</view>
<view v-if="canEdit" style="height: 60rpx" @click="addPropertyValueClick(item)">
<text style="color: #ff3300; font-size: 30px" class="cicon-add-round-o"></text>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<uni-popup ref="inputPropertyValueDialogRef" type="dialog">
<uni-popup-dialog
mode="input"
:title="propertyValueTitle"
v-model="inputPropertyValueFormdata.name"
placeholder="请输入商品规格"
:before-close="true"
@confirm="dialogInputPropertyValueConfirm"
@close="inputPropertyValueDialogRef.close()"
></uni-popup-dialog>
</uni-popup>
</view> </view>
</template> </template>
<script setup> <script setup>
import { defineProps, defineEmits, ref, computed } from 'vue' import { defineProps, defineEmits, ref, computed } from 'vue'
import { goodsPropertyList, canEdit } from '../js/sku' import {
goodsPropertyList,
canEdit,
addPropertyValueClick,
inputPropertyValueDialogRef,
inputPropertyValueFormdata,
propertyValueTitle,
dialogInputPropertyValueConfirm,
longPropertyValuePress,
} from '../js/sku'
const props = defineProps({ const props = defineProps({
modelValue: { modelValue: {

View File

@ -3,22 +3,44 @@
<uni-popup type="bottom" ref="propertyListPopupRef" background-color="#fff"> <uni-popup type="bottom" ref="propertyListPopupRef" background-color="#fff">
<view class="popup-header"> <view class="popup-header">
<view class="button-cancel" @click="onClosePopup">取消</view> <view class="button-cancel" @click="onClosePopup">取消</view>
<view style="color: #c0c0c0; font-size: 12px">长按规格修改/删除</view>
<view class="button-link" @click="onConfirmPopup">确定</view> <view class="button-link" @click="onConfirmPopup">确定</view>
</view> </view>
<view class="popup-content"> <view class="popup-content">
<view v-for="item in nowGoodsPropertyList" :key="item.id" <view
:class="['property-item', item.checked ? 'active' : '']" @tap="chooseProperty(item)"> v-for="item in nowGoodsPropertyList"
:key="item.id"
:class="['property-item', item.checked ? 'active' : '']"
@tap="chooseProperty(item)"
@longpress="longPress(item)"
>
{{ item.name }} {{ item.name }}
</view> </view>
<view v-if="canEdit" style="height: 60rpx" @click="addPropertyClick">
<text style="color: #ff3300; font-size: 30px" class="cicon-add-round-o"></text>
</view>
</view> </view>
</uni-popup> </uni-popup>
<uni-popup ref="inputDialogRef" type="dialog">
<uni-popup-dialog
mode="input"
:title="propertyTitle"
v-model="inputFormdata.name"
placeholder="请输入商品规格"
:before-close="true"
@confirm="dialogInputConfirm"
@close="inputDialogRef.close()"
></uni-popup-dialog>
</uni-popup>
</view> </view>
</template> </template>
<script setup> <script setup>
import { ref, computed, defineEmits, defineProps, defineExpose } from 'vue' import { ref, computed, defineEmits, defineProps, defineExpose } from 'vue'
import peach from '@/peach' import peach from '@/peach'
import { cloneDeep } from 'lodash'; import GoodsApi from '@/peach/api/trade/goods'
import { getGoodsProperty, canEdit } from '../js/sku'
import { cloneDeep } from 'lodash'
/** /**
* todo 底部高度配置 * todo 底部高度配置
@ -51,8 +73,30 @@ function chooseProperty(item) {
item.checked = !item.checked item.checked = !item.checked
} }
function onConfirmPopup() { function longPress(item) {
if (canEdit) {
//
uni.vibrateShort()
uni.showActionSheet({
itemList: ['编辑', '删除'],
success: async (res) => {
if (res.tapIndex === 0) {
propertyTitle.value = '编辑'
inputFormdata.value.id = item.id
inputFormdata.value.name = item.name
inputDialogRef.value.open()
}
if (res.tapIndex === 1) {
await GoodsApi.delProperty({ id: item.id })
await getGoodsProperty()
nowGoodsPropertyList.value = cloneDeep(props.goodsPropertyList)
}
},
})
}
}
function onConfirmPopup() {
let result = nowGoodsPropertyList.value let result = nowGoodsPropertyList.value
.filter((item) => { .filter((item) => {
if (item.checked) { if (item.checked) {
@ -67,13 +111,40 @@ function onConfirmPopup() {
} }
}) })
peach.$store('trade').selectedProperty = result peach.$store('trade').selectedProperty = result
emit('confirm') emit('confirm')
emit('update:modelValue', result) emit('update:modelValue', result)
onClosePopup() onClosePopup()
} }
const propertyTitle = ref('新增')
const inputDialogRef = ref()
const inputFormdata = ref({
id: '',
name: '',
remark: '',
})
function addPropertyClick() {
propertyTitle.value = '新增'
inputFormdata.value.name = ''
inputDialogRef.value.open()
}
async function dialogInputConfirm(value) {
if (!value) {
peach.$helper.toast('请输入商品属性')
return
}
if (inputFormdata.value.id) {
await GoodsApi.editProperty(inputFormdata.value)
} else {
await GoodsApi.createProperty(inputFormdata.value)
}
await getGoodsProperty()
inputDialogRef.value.close()
nowGoodsPropertyList.value = cloneDeep(props.goodsPropertyList)
}
function onOpen() { function onOpen() {
nowGoodsPropertyList.value = cloneDeep(props.goodsPropertyList) nowGoodsPropertyList.value = cloneDeep(props.goodsPropertyList)
propertyListPopupRef.value.open('bottom') propertyListPopupRef.value.open('bottom')

View File

@ -19,104 +19,103 @@ 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()
} }
function pickerProperty() { function pickerProperty() {
if (canEdit.value) { if (canEdit.value) {
let index = formData.value.specType ? 1 : 0 let index = formData.value.specType ? 1 : 0
pickerRef.value.onOpen([index]) pickerRef.value.onOpen([index])
} }
} }
async function onPropertyConfirm(e) { async function onPropertyConfirm(e) {
await getGoodsProperty() await getGoodsProperty()
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 中 id 相同的属性合并,并去重
propertyList.value = peach.$store('trade').selectedProperty || [] propertyList.value = peach.$store('trade').selectedProperty || []
// 根据已经选择数据,设置默认选中 // 根据已经选择数据,设置默认选中
data.forEach((item) => { data.forEach((item) => {
// 判断属性是否已经选中 // 判断属性是否已经选中
let propertyParent = propertyList.value.find((sitem) => sitem?.id === item.id) let propertyParent = propertyList.value.find((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((schild) => schild === child.id) let childResult = propertyParent?.children.some((schild) => schild === child.id)
child.checked = childResult ? true : false child.checked = childResult ? true : false
}) })
} }
}) })
goodsPropertyList.value = data goodsPropertyList.value = data
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(JSON.stringify(goodsPropertyList.value.filter((item) => item.checked))) let temp = JSON.parse(JSON.stringify(goodsPropertyList.value.filter((item) => item.checked)))
temp.forEach((item) => { temp.forEach((item) => {
item.propertyValues = item.propertyValues.filter((child) => child.checked) 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
} }
/** /**
@ -126,35 +125,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]
} else {
// 初始化已选中规格,属性和格式化后的结果
propertyList.value = []
goodsPropertyList.value = []
// 多规格
skus.value = []
} }
skus.value = [obj]
} else {
// 初始化已选中规格,属性和格式化后的结果
propertyList.value = []
goodsPropertyList.value = []
// 多规格
skus.value = []
}
} }
/** /**
@ -164,127 +163,188 @@ function initSku() {
* @returns {Type} * @returns {Type}
*/ */
function submitProperty() { function submitProperty() {
try { try {
validateSku(skus.value) validateSku(skus.value)
peach.$store('trade').$patch({ peach.$store('trade').$patch({
skus: skus.value, skus: skus.value,
specType: formData.value.specType, specType: formData.value.specType,
}) })
peach.$router.back() peach.$router.back()
} catch (e) { } catch (e) {
console.log(skus.value) console.log(skus.value)
console.log(e, '校验失败') 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
}
} }
for (const sku of skusValue) { if (!validateStatue) {
for (const rule of SKU_RULE_CONFIG) { uni.showToast({
const arg = getValue(sku, rule.name) title: warningInfo,
if (!rule.rule(arg)) { icon: 'none',
validateStatue = false duration: 4000,
warningInfo += rule.message })
break throw new Error(warningInfo)
}
}
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 {
acc.forEach((item, index) => { tempAcc[index] = [item]
cur.forEach((sitem, sindex) => {
tempAcc.push([...item, sitem])
})
})
if (cur.length < 1) {
tempAcc = acc
}
} }
return tempAcc })
}, []) } else {
acc.forEach((item, index) => {
cur.forEach((sitem, sindex) => {
tempAcc.push([...item, sitem])
})
})
if (cur.length < 1) {
tempAcc = acc
}
}
return tempAcc
}, [])
} }
const specType = computed(() => peach.$store('trade').specType) const specType = computed(() => peach.$store('trade').specType)
function initial() { function initial() {
onLoad(() => { onLoad(() => {
formData.value.specType = specType.value 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) {
getGoodsProperty()
}
})
}
const propertyValueTitle = ref('新增')
const inputPropertyValueDialogRef = ref()
const inputPropertyValueFormdata = ref({
id: '',
propertyId: '',
name: '',
remark: '',
})
function addPropertyValueClick(item) {
console.log(item)
propertyValueTitle.value = '新增'
inputPropertyValueFormdata.value.name = ''
inputPropertyValueFormdata.value.propertyId = item.id
inputPropertyValueDialogRef.value.open()
}
async function dialogInputPropertyValueConfirm(value) {
if (!value) {
peach.$helper.toast('请输入商品属性')
return
}
if (inputPropertyValueFormdata.value.id) {
await GoodsApi.editPropertyValue(inputPropertyValueFormdata.value)
} else {
await GoodsApi.createPropertyValue(inputPropertyValueFormdata.value)
}
await getGoodsProperty()
inputPropertyValueDialogRef.value.close()
}
function longPropertyValuePress(item) {
console.log(item)
if (canEdit.value) {
// 震动提示
uni.vibrateShort()
uni.showActionSheet({
itemList: ['编辑', '删除'],
success: async (res) => {
if (res.tapIndex === 0) {
propertyValueTitle.value = '编辑'
inputPropertyValueFormdata.value.id = item.id
inputPropertyValueFormdata.value.propertyId = item.propertyId
inputPropertyValueFormdata.value.name = item.name
inputPropertyValueDialogRef.value.open()
} }
if (specType.value) { if (res.tapIndex === 1) {
getGoodsProperty() await GoodsApi.delPropertyValue({ id: item.id })
await 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,
getGoodsProperty,
addPropertyValueClick,
dialogInputPropertyValueConfirm,
longPropertyValuePress,
inputPropertyValueDialogRef,
inputPropertyValueFormdata,
propertyValueTitle,
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,68 +1,68 @@
<template> <template>
<pb-layout <pb-layout
class="goods-property" class="goods-property"
title="商品属性" title="商品属性"
leftIcon="leftIcon" leftIcon="leftIcon"
navbar="normal" navbar="normal"
:bgStyle="bgStyle" :bgStyle="bgStyle"
opacityBgUi="bg-white" opacityBgUi="bg-white"
color="black" color="black"
> >
<view class="property"> <view class="property">
<uni-forms ref="formRef" v-model="formData" :rules="rules" label-position="top" label-width="160"> <uni-forms ref="formRef" v-model="formData" :rules="rules" label-position="top" label-width="160">
<uni-forms-item label="商品规格" @tap="pickerProperty" name="specType" label-position="left" required> <uni-forms-item label="商品规格" @tap="pickerProperty" name="specType" label-position="left" required>
<uni-easyinput <uni-easyinput
type="text" type="text"
:clearable="false" :clearable="false"
:styles="selfStyles" :styles="selfStyles"
placeholderStyle="color:#8a8a8a" placeholderStyle="color:#8a8a8a"
:inputBorder="false" :inputBorder="false"
v-model="formData.specText" v-model="formData.specText"
placeholder="请选择商品规格" placeholder="请选择商品规格"
disabled disabled
> >
<template v-slot:right> <template v-slot:right>
<uni-icons type="right" /> <uni-icons type="right" />
</template> </template>
</uni-easyinput> </uni-easyinput>
</uni-forms-item> </uni-forms-item>
</uni-forms> </uni-forms>
</view> </view>
<template v-if="formData.specType"> <template v-if="formData.specType">
<!-- 添加商品 --> <!-- 添加商品 -->
<button v-if="canEdit" class="ss-reset-button add-property" @tap="showPropertyList">+添加规格</button> <button v-if="canEdit" class="ss-reset-button add-property" @tap="showPropertyList">选择规格</button>
<!-- 商品属性展示 --> <!-- 商品属性展示 -->
<property-detail <property-detail
v-if="propertyList.length > 0" v-if="propertyList.length > 0"
v-model="propertyList" v-model="propertyList"
:goodsPropertyList="goodsPropertyList" :goodsPropertyList="goodsPropertyList"
@changeSubProperty="changeSubProperty" @changeSubProperty="changeSubProperty"
></property-detail> ></property-detail>
<!-- 多规格商品 --> <!-- 多规格商品 -->
<mutiple-sku :skus="skus"></mutiple-sku> <mutiple-sku :skus="skus"></mutiple-sku>
</template> </template>
<template v-else> <template v-else>
<!-- 单规格商品 --> <!-- 单规格商品 -->
<SkuItem :skus="skus" /> <SkuItem :skus="skus" />
</template> </template>
<!-- 确认选择 --> <!-- 确认选择 -->
<view style="padding: 0 40rpx 40rpx" @tap="submitProperty" v-if="canEdit"> <view style="padding: 0 40rpx 40rpx" @tap="submitProperty" v-if="canEdit">
<button class="ss-reset-button submit-button ui-Shadow-Main">保存</button> <button class="ss-reset-button submit-button ui-Shadow-Main">保存</button>
</view> </view>
<!-- 商品规格 --> <!-- 商品规格 -->
<p-picker ref="pickerRef" mode="single" :options-cols="SPEC_TYPE" @confirm="onRDPickerConfirm"></p-picker> <p-picker ref="pickerRef" mode="single" :options-cols="SPEC_TYPE" @confirm="onRDPickerConfirm"></p-picker>
<!-- 商品属性列表 --> <!-- 商品属性列表 -->
<PropertyList <PropertyList
ref="propertyListRef" ref="propertyListRef"
v-model="propertyList" v-model="propertyList"
:goodsPropertyList="goodsPropertyList" :goodsPropertyList="goodsPropertyList"
@confirm="onPropertyConfirm" @confirm="onPropertyConfirm"
/> />
</pb-layout> </pb-layout>
</template> </template>
<script setup> <script setup>
@ -72,26 +72,26 @@ import PropertyList from './components/propertyList'
import PropertyDetail from './components/propertyDetail' import PropertyDetail from './components/propertyDetail'
import { SPEC_TYPE } from './js/config' import { SPEC_TYPE } from './js/config'
import { import {
initial, initial,
canEdit, canEdit,
pickerRef, pickerRef,
propertyListRef, propertyListRef,
onRDPickerConfirm, onRDPickerConfirm,
formData, formData,
propertyList, propertyList,
onPropertyConfirm, onPropertyConfirm,
showPropertyList, showPropertyList,
goodsPropertyList, goodsPropertyList,
pickerProperty, pickerProperty,
skus, skus,
changeSubProperty, changeSubProperty,
submitProperty, submitProperty,
} from './js/sku' } from './js/sku'
const bgStyle = { const bgStyle = {
backgroundImage: '', backgroundImage: '',
backgroundColor: '#fff', backgroundColor: '#fff',
description: '', description: '',
} }
initial() initial()
@ -99,57 +99,57 @@ initial()
<style lang="scss" scoped> <style lang="scss" scoped>
.goods-property { .goods-property {
.property { .property {
margin: 40rpx; margin: 40rpx;
:deep() { :deep() {
.uni-easyinput__content-input { .uni-easyinput__content-input {
font-size: 28rpx !important; font-size: 28rpx !important;
color: #333333 !important; color: #333333 !important;
line-height: normal !important; line-height: normal !important;
} }
.uni-easyinput__placeholder-class { .uni-easyinput__placeholder-class {
font-size: 14px; font-size: 14px;
} }
.is-direction-left { .is-direction-left {
.uni-forms-item__label { .uni-forms-item__label {
padding-left: 10px; padding-left: 10px;
background-color: #f9f9f9; background-color: #f9f9f9;
border-radius: 10px 0 0 10px; border-radius: 10px 0 0 10px;
}
uni-icons {
margin-right: 10px;
}
.uni-easyinput__content {
border-radius: 0 10px 10px 0;
}
}
.is-disabled {
color: #333333;
text-align: right;
}
} }
}
.add-property { uni-icons {
margin: 40rpx; margin-right: 10px;
border: 1px dotted var(--ui-BG-Main); }
color: var(--ui-BG-Main);
border-radius: 10px;
text-align: center;
}
.submit-button { .uni-easyinput__content {
width: 100%; border-radius: 0 10px 10px 0;
height: 80rpx; }
border-radius: 40rpx; }
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
color: $white; .is-disabled {
color: #333333;
text-align: right;
}
} }
}
.add-property {
margin: 40rpx;
border: 1px dotted var(--ui-BG-Main);
color: var(--ui-BG-Main);
border-radius: 10px;
text-align: center;
}
.submit-button {
width: 100%;
height: 80rpx;
border-radius: 40rpx;
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
color: $white;
}
} }
</style> </style>

View File

@ -1,47 +1,51 @@
<!-- 文章展示 --> <!-- 文章展示 -->
<template> <template>
<pb-layout class="set-wrap" :title="state.title" :bgStyle="{ color: '#FFF' }"> <pb-layout class="set-wrap" :title="state.title" :bgStyle="{ color: '#FFF' }">
<view class="ss-p-30"> <view class="ss-p-30">
<mp-html class="richtext" :content="state.content" /> <mp-html class="richtext" :content="state.content" />
</view> </view>
</pb-layout> </pb-layout>
</template> </template>
<script setup> <script setup>
import { onLoad } from '@dcloudio/uni-app' import { onLoad } from '@dcloudio/uni-app'
import ArticleApi from '@/peach/api/promotion/article'
import { reactive } from 'vue' import { reactive } from 'vue'
const state = reactive({ const state = reactive({
title: '', title: '',
content: '', content: '',
}) })
async function getRichTextContent(id, title) { async function getRichTextContent(id, title) {
// const { code, data } = await ArticleApi.getArticle(id, title)
// state.content = data.content; if (code !== 0) {
// return
// if (state.title !== data.title) { }
// state.title = data.title; state.content = data.content
// uni.setNavigationBarTitle({ //
// title: state.title, if (state.title !== data.title) {
// }); state.title = data.title
// } uni.setNavigationBarTitle({
title: state.title,
})
}
} }
onLoad((options) => { onLoad((options) => {
if (options.title) { if (options.title) {
state.title = options.title state.title = options.title
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title: state.title, title: state.title,
}) })
} }
// getRichTextContent(options.id, options.title); getRichTextContent(options.id, options.title)
}) })
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.set-title { .set-title {
margin: 0 30rpx; margin: 0 30rpx;
} }
.richtext { .richtext {

View File

@ -1,176 +1,224 @@
<template> <template>
<pb-layout <pb-layout
navbar="inner" navbar="inner"
iconColor="#fff" iconColor="#fff"
class="buy-point-wrap" class="buy-point-wrap"
leftIcon="leftIcon" leftIcon="leftIcon"
color="#fff" color="#fff"
title="购买积分" title="购买积分"
:bgStyle="bgStyle" :bgStyle="bgStyle"
> >
<view class="title ss-m-t-80"> <view class="title ss-m-t-80">
<view class="main">购买商城积分</view> <view class="main">购买商城积分</view>
<view class="sub ss-flex ss-row-center ss-m-t-55" <view class="sub ss-flex ss-row-center ss-m-t-55"
><text style="color: #f3d3bf" class="cicon-safe"></text>订单多多·出单多多<text ><text style="color: #f3d3bf" class="cicon-safe"></text>订单多多·出单多多<text
style="color: #f3d3bf" style="color: #f3d3bf"
class="cicon-safe" class="cicon-safe"
></text ></text
></view> ></view>
</view> </view>
<view class="middle ss-m-t-150 ss-flex-col ss-row-center ss-col-center ss-gap-40"> <view class="middle ss-m-t-150 ss-flex-col ss-row-center ss-col-center ss-gap-40">
<view class="title">积分额度选择</view> <view class="title">积分额度选择</view>
<view class="sub">专属您的积分</view> <view class="sub">专属您的积分</view>
</view> </view>
<view class="combo ss-m-t-90 ss-m-b-50 ss-p-x-40"> <view class="combo ss-m-t-90 ss-m-b-50 ss-p-x-40">
<button class="ss-reset-button draw-btn ui-Shadow-Main">购买5000积分/50</button> <template v-for="(item, index) in state.pointList">
<button class="ss-reset-button draw-btn-raw ui-Shadow-Main">购买5000积分/50</button> <button
</view> :class="['ss-reset-button', state.currentIndex === index ? 'draw-btn' : 'draw-btn-raw', 'ui-Shadow-Main']"
@click="chooseItemClick(index)"
>
{{ `购买${item.point}积分/${item.price}` }}
</button>
</template>
</view>
<view class="agreement-box ss-flex ss-row-center" :class="{ shake: state.isShaking }"> <view class="agreement-box ss-flex ss-row-center" :class="{ shake: state.isShaking }">
<label class="radio ss-flex" @tap="onChange"> <label class="radio ss-flex" @tap="onChange">
<radio <radio
:checked="state.agreeStatus" :checked="state.agreeStatus"
color="rgba(243, 192, 156, 1)" color="rgba(243, 192, 156, 1)"
style="transform: scale(0.8)" style="transform: scale(0.8)"
@tap.stop="onChange" @tap.stop="onChange"
/> />
<view class="agreement-text ss-flex ss-m-l-8"> <view class="agreement-text ss-flex ss-m-l-8">
我已阅读并遵守 我已阅读并遵守
<view class="tcp-text" @tap.stop="onProtocol('积分须知')"> 积分须知 </view> <view class="tcp-text" @tap.stop="onProtocol('积分须知')"> 积分须知 </view>
</view>
</label>
</view> </view>
</pb-layout> </label>
</view>
</pb-layout>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import PointApi from '@/peach/api/pay/point'
import peach from '@/peach'
const state = ref({ const state = ref({
isShaking: false, isShaking: false,
agreeStatus: false, agreeStatus: false,
pointList: [],
currentIndex: -1,
}) })
const bgStyle = { const bgStyle = {
backgroundImage: '/static/point.png', backgroundImage: '/static/point.png',
imageType: 'local', imageType: 'local',
backgroundColor: '#fff', backgroundColor: '#fff',
description: '', description: '',
height: '100%', height: '100%',
} }
function onProtocol(title) {} function onProtocol() {
peach.$router.go('/pages/public/richtext?title=积分须知')
}
function getPointConfig() {
PointApi.getPointConfig().then((res) => {
if (res.data.packagePoint) state.value.pointList = JSON.parse(res.data.packagePoint)
})
}
function onChange() {
state.value.agreeStatus = !state.value.agreeStatus
}
function chooseItemClick(index) {
if (!state.value.agreeStatus) {
state.value.isShaking = true
setTimeout(() => {
state.value.isShaking = false
}, 1000)
peach.$helper.toast('请勾选同意积分须知')
return
}
state.value.currentIndex = index
uni.showModal({
title: '提示',
content: '确认购买该积分额度?',
success: function (res) {
if (res.confirm) {
}
},
})
}
onShow(() => {
getPointConfig()
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.buy-point-wrap { .buy-point-wrap {
.title {
.main {
font-size: 80rpx;
color: rgba(232, 181, 150, 1);
letter-spacing: 20px;
position: relative;
left: 20px;
}
.sub {
font-size: 32rpx;
color: #f3d3bf;
letter-spacing: 4px;
}
}
.middle {
.title { .title {
.main { font-size: 39rpx;
font-size: 80rpx; color: #fccdb1;
color: rgba(232, 181, 150, 1);
letter-spacing: 20px;
position: relative;
left: 20px;
}
.sub {
font-size: 32rpx;
color: #f3d3bf;
letter-spacing: 4px;
}
} }
.middle { .title::before {
.title { content: '';
font-size: 39rpx; display: block;
color: #fccdb1; width: 80px;
} position: relative;
left: -100px;
.title::before { top: 14px;
content: ''; border-bottom: 1px dotted #e7b493;
display: block;
width: 80px;
position: relative;
left: -100px;
top: 14px;
border-bottom: 1px dotted #e7b493;
}
.title::after {
content: '';
display: block;
width: 80px;
position: relative;
left: 130px;
top: -12px;
border-bottom: 1px dotted #e7b493;
}
.sub {
background-color: #e7b493;
border-radius: 18rpx;
border: 1px solid #979797;
letter-spacing: 5px;
padding: 0 10rpx 0 18rpx;
font-size: 24rpx;
}
} }
.combo { .title::after {
.draw-btn { content: '';
height: 82rpx; display: block;
line-height: normal; width: 80px;
background: linear-gradient(-90deg, rgba(230, 179, 147, 1), rgba(250, 232, 218, 1)); position: relative;
border-radius: 28rpx; left: 130px;
font-size: 32rpx; top: -12px;
font-weight: 500; border-bottom: 1px dotted #e7b493;
}
.draw-btn-raw {
height: 82rpx;
line-height: normal;
background: transparent;
border-radius: 28rpx;
font-size: 32rpx;
font-weight: 500;
color: #e7b493;
border: 1px solid #e7b493;
margin-top: 20px;
}
} }
.agreement-box { .sub {
width: 100%; background-color: #e7b493;
border-radius: 18rpx;
border: 1px solid #979797;
letter-spacing: 5px;
padding: 0 10rpx 0 18rpx;
font-size: 24rpx;
}
}
.protocol-check { .combo {
transform: scale(0.7); .draw-btn {
} height: 82rpx;
line-height: normal;
.agreement-text { background: linear-gradient(-90deg, rgba(230, 179, 147, 1), rgba(250, 232, 218, 1));
font-size: 26rpx; border-radius: 28rpx;
font-weight: 500; font-size: 32rpx;
color: #999999; font-weight: 500;
.tcp-text {
color: rgba(243, 192, 156, 1);
}
}
} }
.shake { .draw-btn-raw {
animation: shake 0.05s linear 4 alternate; height: 82rpx;
line-height: normal;
background: transparent;
border-radius: 28rpx;
font-size: 32rpx;
font-weight: 500;
color: #e7b493;
border: 1px solid #e7b493;
margin-top: 20px;
}
}
.agreement-box {
width: 100%;
.protocol-check {
transform: scale(0.7);
} }
@keyframes shake { .agreement-text {
from { font-size: 26rpx;
transform: translateX(-5rpx); font-weight: 500;
} color: #999999;
to { .tcp-text {
transform: translateX(5rpx); color: rgba(243, 192, 156, 1);
} }
} }
}
.shake {
animation: shake 0.05s linear 4 alternate;
}
@keyframes shake {
from {
transform: translateX(-5rpx);
}
to {
transform: translateX(5rpx);
}
}
} }
</style> </style>

View File

@ -1,68 +1,68 @@
<template> <template>
<pb-layout <pb-layout
navbar="inner" navbar="inner"
iconColor="#fff" iconColor="#fff"
class="share-point-wrap" class="share-point-wrap"
leftIcon="leftIcon" leftIcon="leftIcon"
color="#fff" color="#fff"
title="分发积分" title="分发积分"
right="历史积分" right="历史积分"
:bgStyle="bgStyle" :bgStyle="bgStyle"
> >
<view class="title ss-m-t-80"> <view class="title ss-m-t-80">
<view class="main">分发积分</view> <view class="main">分发积分</view>
<view class="sub ss-flex ss-row-center ss-m-t-55" <view class="sub ss-flex ss-row-center ss-m-t-55"
><text style="color: #f3d3bf" class="cicon-safe"></text>订单多多·出单多多<text ><text style="color: #f3d3bf" class="cicon-safe"></text>订单多多·出单多多<text
style="color: #f3d3bf" style="color: #f3d3bf"
class="cicon-safe" class="cicon-safe"
></text ></text
></view> ></view>
</view> </view>
<view class="user-search"> <view class="user-search">
<view class="search"> <view class="search">
<uni-easyinput <uni-easyinput
v-model="state.inputData" v-model="state.inputData"
:styles="{ backgroundColor: 'transparent', color: '#E7B493' }" :styles="{ backgroundColor: 'transparent', color: '#E7B493' }"
placeholderStyle="color: #E7B493;" placeholderStyle="color: #E7B493;"
@input="inputUserFunc" @input="inputUserFunc"
:clearable="false" :clearable="false"
:inputBorder="false" :inputBorder="false"
trim="all" trim="all"
suffixIcon="search" suffixIcon="search"
placeholder="请输入用户名/手机号" placeholder="请输入用户名/手机号"
/> />
</view> </view>
<view class="result" :style="{ height: resultHeight, overflow: 'auto' }"> <view class="result" :style="{ height: resultHeight, overflow: 'auto' }">
<view v-for="item in state.userList" class="user ss-flex ss-row-between ss-col-center"> <view v-for="item in state.userList" class="user ss-flex ss-row-between ss-col-center">
<view class="user-info ss-flex ss-col-center ss-gap-20"> <view class="user-info ss-flex ss-col-center ss-gap-20">
<image <image
style="width: 48rpx; height: 48rpx; border-radius: 50%" style="width: 48rpx; height: 48rpx; border-radius: 50%"
:src="item.avatar ? item.avatar : '/static/default_avatar.png'" :src="item.avatar ? item.avatar : '/static/default_avatar.png'"
/> />
<view class="nickname">{{ item.nickname }}</view> <view class="nickname">{{ item.nickname }}</view>
</view> </view>
<view class="input-point"> <view class="input-point">
<uni-easyinput <uni-easyinput
:styles="{ backgroundColor: 'transparent', color: '#E7B493' }" :styles="{ backgroundColor: 'transparent', color: '#E7B493' }"
:placeholderStyle="placeholderStyle" :placeholderStyle="placeholderStyle"
v-model="item.point" v-model="item.point"
:clearable="false" :clearable="false"
:inputBorder="false" :inputBorder="false"
@input="inputPointFunc(item)" @input="inputPointFunc(item)"
type="number" type="number"
trim="all" trim="all"
placeholder="请输入积分额度" placeholder="请输入积分额度"
/> />
</view> </view>
</view>
</view>
</view> </view>
</view>
</view>
<view class="ss-p-x-30 bottom"> <view class="ss-p-x-30 bottom">
<button class="ss-reset-button share-btn" @tap="confirmShare">确定</button> <button class="ss-reset-button share-btn" @tap="confirmShare">确定</button>
</view> </view>
</pb-layout> </pb-layout>
</template> </template>
<script setup> <script setup>
@ -74,171 +74,171 @@ import peach from '@/peach'
const placeholderStyle = ref('color: #E7B493') const placeholderStyle = ref('color: #E7B493')
const resultHeight = computed(() => { const resultHeight = computed(() => {
return `calc(100vh - 728rpx)` return `calc(100vh - 728rpx)`
}) })
const state = ref({ const state = ref({
inputData: '', inputData: '',
userList: [], userList: [],
isShaking: false, isShaking: false,
agreeStatus: false, agreeStatus: false,
userParams: { userParams: {
mobile: '', mobile: '',
nickname: '', nickname: '',
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
}, },
pointParams: { pointParams: {
memberId: '', memberId: '',
point: '', point: '',
}, },
}) })
const bgStyle = { const bgStyle = {
backgroundImage: '/static/point.png', backgroundImage: '/static/point.png',
imageType: 'local', imageType: 'local',
backgroundColor: '#fff', backgroundColor: '#fff',
description: '', description: '',
height: '100%', height: '100%',
} }
let timer let timer
function inputUserFunc() { function inputUserFunc() {
clearTimeout(timer) clearTimeout(timer)
timer = setTimeout(() => { timer = setTimeout(() => {
getUserList() getUserList()
}, 1000) }, 1000)
} }
async function confirmShare() { async function confirmShare() {
let user = state.value.userList.find((item) => item.point) let user = state.value.userList.find((item) => item.point)
if (!user) { if (!user) {
peach.$helper.toast('请输入要赠送的积分') peach.$helper.toast('请选择需要赠送积分的用户')
return return
} }
state.value.pointParams.memberId = user.id state.value.pointParams.memberId = user.id
state.value.pointParams.point = user.point state.value.pointParams.point = user.point
await PointApi.sendPoint(state.value.pointParams) await PointApi.sendPoint(state.value.pointParams)
state.value.inputData = '' state.value.inputData = ''
state.value.userList = [] state.value.userList = []
state.value.pointParams = { state.value.pointParams = {
memberId: '', memberId: '',
point: '', point: '',
} }
} }
function inputPointFunc(data) { function inputPointFunc(data) {
state.value.userList.forEach((item) => { state.value.userList.forEach((item) => {
console.log(data.id !== item.id) console.log(data.id !== item.id)
if (data.id !== item.id) { if (data.id !== item.id) {
item.point = '' item.point = ''
} }
}) })
// state.value.pointParams.memberId = data.id // state.value.pointParams.memberId = data.id
// state.value.pointParams.point = data.point // state.value.pointParams.point = data.point
} }
async function getUserList() { async function getUserList() {
// userParams // userParams
state.value.userParams = { state.value.userParams = {
mobile: '', mobile: '',
nickname: '', nickname: '',
pageNo: 1, pageNo: 1,
pageSize: 10, pageSize: 10,
} }
// inputData // inputData
// string // string
if (/^\d+$/.test(state.value.inputData)) { if (/^\d+$/.test(state.value.inputData)) {
state.value.userParams.mobile = state.value.inputData state.value.userParams.mobile = state.value.inputData
} else { } else {
state.value.userParams.nickname = state.value.inputData state.value.userParams.nickname = state.value.inputData
} }
let { data } = await UserUtil.getUserList(state.value.userParams) let { data } = await UserUtil.getUserList(state.value.userParams)
data.list.forEach((item) => { data.list.forEach((item) => {
item.point = '' item.point = ''
}) })
state.value.userList = data.list state.value.userList = data.list
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.share-point-wrap { .share-point-wrap {
.title { .title {
.main { .main {
font-size: 80rpx; font-size: 80rpx;
color: rgba(232, 181, 150, 1); color: rgba(232, 181, 150, 1);
letter-spacing: 20px; letter-spacing: 20px;
position: relative; position: relative;
left: 10px; left: 10px;
text-align: center; text-align: center;
}
.sub {
font-size: 32rpx;
color: #f3d3bf;
letter-spacing: 4px;
}
} }
.user-search { .sub {
margin: 50rpx 40rpx 0; font-size: 32rpx;
color: #f3d3bf;
letter-spacing: 4px;
}
}
.search { .user-search {
border: 1px solid #e7b493; margin: 50rpx 40rpx 0;
border-radius: 30px;
}
:deep(.uniui-search) { .search {
color: #e7b493 !important; border: 1px solid #e7b493;
padding-right: 10px; border-radius: 30px;
}
:deep(.uni-easyinput__content-input) {
padding-left: 15px !important;
}
.result {
.user {
margin-top: 20px;
border: 1px solid #e7b493;
border-radius: 30px;
padding: 0 40rpx;
.user-info {
.nickname {
font-size: 26rpx;
color: #e7b493;
}
}
.input-point {
:deep(.uni-easyinput__content-input) {
text-align: right;
}
}
}
}
} }
.bottom { :deep(.uniui-search) {
position: absolute; color: #e7b493 !important;
bottom: 20px; padding-right: 10px;
width: calc(100% - 60rpx); }
.share-btn { :deep(.uni-easyinput__content-input) {
height: 82rpx; padding-left: 15px !important;
line-height: normal; }
background: linear-gradient(-90deg, rgba(230, 179, 147, 1), rgba(250, 232, 218, 1));
border-radius: 28rpx; .result {
.user {
margin-top: 20px;
border: 1px solid #e7b493;
border-radius: 30px;
padding: 0 40rpx;
.user-info {
.nickname {
font-size: 26rpx; font-size: 26rpx;
font-weight: 500; color: #e7b493;
}
} }
.input-point {
:deep(.uni-easyinput__content-input) {
text-align: right;
}
}
}
} }
}
.bottom {
position: absolute;
bottom: 20px;
width: calc(100% - 60rpx);
.share-btn {
height: 82rpx;
line-height: normal;
background: linear-gradient(-90deg, rgba(230, 179, 147, 1), rgba(250, 232, 218, 1));
border-radius: 28rpx;
font-size: 26rpx;
font-weight: 500;
}
}
} }
</style> </style>

View File

@ -1,32 +1,32 @@
import request from '@/peach/request' import request from '@/peach/request'
const PointApi = { const PointApi = {
/** /**
* @author Ankkaya * @author Ankkaya
* @description 分发积分 * @description 分发积分
* @param {String} memberId - 用户 id * @param {String} memberId - 用户 id
* @param {Number} point - 积分 * @param {Number} point - 积分
* @returns {Type} * @returns {Type}
*/ */
sendPoint: (data) => { sendPoint: (data) => {
return request({ return request({
url: '/particulars/point/send-member', url: '/particulars/point/send-member',
method: 'post', method: 'post',
data, data,
custom: { custom: {
showSuccess: true, showSuccess: true,
successMsg: '赠送成功', successMsg: '赠送成功',
}, },
}) })
}, },
getPointList: (data) => { // 获取积分配置信息
return request({ getPointConfig: () => {
url: '/particulars/point/page-record', return request({
method: 'get', url: '/particulars/point/get-config',
params: data, method: 'get',
}) })
}, },
} }
export default PointApi export default PointApi

View File

@ -0,0 +1,15 @@
import request from '@/peach/request'
export default {
// 获得文章详情
getArticle: (id, title) => {
return request({
url: '/promotion/article/get',
method: 'GET',
params: { id, title },
custom: {
auth: false,
},
})
},
}

View File

@ -1,76 +1,142 @@
import request from '@/peach/request' import request from '@/peach/request'
const GoodsApi = { const GoodsApi = {
// 商品列表 // 商品列表
getProductList: (data) => { getProductList: (data) => {
return request({ return request({
url: '/product/spu/page', url: '/product/spu/page',
method: 'GET', method: 'GET',
params: data, params: data,
}) })
}, },
// 商品详情 spuIds // 商品详情 spuIds
getProduct: (data) => { getProduct: (data) => {
return request({ return request({
url: '/product/spu/get-detail', url: '/product/spu/get-detail',
method: 'GET', method: 'GET',
params: data, params: data,
}) })
}, },
// 添加商品 // 添加商品
addProduct: (data) => { addProduct: (data) => {
return request({ return request({
url: '/product/spu/create', url: '/product/spu/create',
method: 'POST', method: 'POST',
data, data,
}) })
}, },
// 修改商品 // 修改商品
editProduct: (data) => { editProduct: (data) => {
return request({ return request({
url: '/product/spu/update', url: '/product/spu/update',
method: 'PUT', method: 'PUT',
data, data,
}) })
}, },
// 删除商品 // 删除商品
delProduct: (data) => { delProduct: (data) => {
return request({ return request({
url: '/product/spu/delete', url: '/product/spu/delete',
method: 'DELETE', method: 'DELETE',
params: data, params: data,
}) })
}, },
// 商品分类 // 商品分类
getGoodsCategory: (data) => { getGoodsCategory: (data) => {
return request({ return request({
url: '/product/category/list', url: '/product/category/list',
method: 'GET', method: 'GET',
params: data, params: data,
}) })
}, },
// 商品品牌 // 商品品牌
getBrand: (data) => { getBrand: (data) => {
return request({ return request({
url: '/product/brand/list', url: '/product/brand/list',
method: 'GET', method: 'GET',
params: data, params: data,
}) })
}, },
// 历史属性 // 历史属性
getHistoryProperty: () => { getHistoryProperty: () => {
return request({ return request({
url: '/product/property/history-list', url: '/product/property/history-list',
method: 'GET', method: 'GET',
}) })
}, },
getPropertyList: (data) => { getPropertyList: (data) => {
return request({ return request({
url: '/product/property/get', url: '/product/property/get',
method: 'GET', method: 'GET',
params: data, params: data,
}) })
}, },
// 创建商品属性项
createProperty: (data) => {
return request({
url: '/product/property/create',
method: 'POST',
data,
custom: {
successMsg: '新增成功',
},
})
},
// 修改商品属性项
editProperty: (data) => {
return request({
url: '/product/property/update',
method: 'PUT',
data,
custom: {
successMsg: '修改成功',
},
})
},
// 删除商品属性项
delProperty: (data) => {
return request({
url: '/product/property/delete',
method: 'DELETE',
params: data,
custom: {
successMsg: '删除成功',
},
})
},
// 创建商品属性值
createPropertyValue: (data) => {
return request({
url: '/property/value/create',
method: 'POST',
data,
custom: {
successMsg: '新增成功',
},
})
},
// 删除商品属性值
delPropertyValue: (data) => {
return request({
url: '/property/value/delete',
method: 'DELETE',
params: data,
custom: {
successMsg: '删除成功',
},
})
},
// 修改商品属性值
editPropertyValue: (data) => {
return request({
url: '/property/value/update',
method: 'PUT',
data,
custom: {
successMsg: '修改成功',
},
})
},
} }
export default GoodsApi export default GoodsApi

View File

@ -120,9 +120,9 @@ export function getSmsCode(event, mobile) {
} }
AuthUtil.sendSmsCode(mobile, scene).then((res) => { AuthUtil.sendSmsCode(mobile, scene).then((res) => {
// if (res.code === 0) { if (res.code === 0) {
// modalStore.lastTimer[event] = dayjs().unix() modalStore.lastTimer[event] = dayjs().unix()
// } }
}) })
} }

View File

@ -5,177 +5,171 @@ import $router from '@/peach/router'
import useSysStore from './sys' import useSysStore from './sys'
const useAppStore = defineStore( const useAppStore = defineStore(
'app', 'app',
() => { () => {
/** /**
* @description 应用信息 * @description 应用信息
* @param string name 应用名称 * @param string name 应用名称
* @param string logo 应用logo * @param string logo 应用logo
* @param string version 应用版本 * @param string version 应用版本
* @param string copyright 版权信息 * @param string copyright 版权信息
* @param string copyrightTime 版权时间 * @param string copyrightTime 版权时间
* @param string cdnurl 静态资源域名 * @param string cdnurl 静态资源域名
* @param string filesystem 文件系统 * @param string filesystem 文件系统
*/ */
const info = ref({ const info = ref({
name: '', name: '',
logo: '', logo: '',
version: '', version: '',
copyright: '', copyright: '',
copytime: '', copytime: '',
cdnurl: '', cdnurl: '',
filesystem: '', filesystem: '',
}) })
/** /**
* @description 平台信息 * @description 平台信息
* @param Array share.methods 分享方式 * @param Array share.methods 分享方式
* @param Object share.forwardInfo 转发信息 * @param Object share.forwardInfo 转发信息
* @param Object share.posterInfo 海报信息 * @param Object share.posterInfo 海报信息
* @param string share.linkAddress 分享链接地址 * @param string share.linkAddress 分享链接地址
* @param number bindMobile 绑定手机号提醒 0: 提醒 1: 不提醒 * @param number bindMobile 绑定手机号提醒 0: 提醒 1: 不提醒
*/ */
const platform = ref({ const platform = ref({
share: { share: {
methods: [], methods: [],
forwardInfo: {}, forwardInfo: {},
posterInfo: {}, posterInfo: {},
linkAddress: '', linkAddress: '',
},
bindMobile: 0,
})
const chat = ref({})
/**
* @description 模板信息
* @param Object basic 基础模板
* @param Object tabbar 底部导航模板
*/
const template = ref({
basic: {
tabbar: {
items: [
{
activeIconUrl: '/static/a-index.png',
iconUrl: '/static/index.png',
text: '首页',
url: '/pages/index/index',
}, },
bindMobile: 0, {
}) activeIconUrl: '/static/a-product.png',
iconUrl: '/static/product.png',
const chat = ref({}) text: '产品',
url: '/pages/index/product',
/**
* @description 模板信息
* @param Object basic 基础模板
* @param Object tabbar 底部导航模板
*/
const template = ref({
basic: {
tabbar: {
items: [
{
activeIconUrl: '/static/a-index.png',
iconUrl: '/static/index.png',
text: '首页',
url: '/pages/index/index',
},
{
activeIconUrl: '/static/a-product.png',
iconUrl: '/static/product.png',
text: '产品',
url: '/pages/index/product',
},
{
activeIconUrl: '/static/a-order.png',
iconUrl: '/static/order.png',
text: '订单',
url: '/pages/index/order',
},
{
activeIconUrl: '/static/a-my.png',
iconUrl: '/static/my.png',
text: '我的',
url: '/pages/index/my',
},
{
activeIconUrl: 'http://mall.yudao.iocoder.cn/static/images/4-002.png',
iconUrl: 'http://mall.yudao.iocoder.cn/static/images/4-001.png',
text: 'icons',
url: '/pages/index/icons',
},
],
style: {
activeColor: '#fc4141',
bgColor: '#fff',
bgType: 'color',
color: '#282828',
},
theme: 'red',
},
}, },
}) {
activeIconUrl: '/static/a-order.png',
// 全局分享信息 iconUrl: '/static/order.png',
const shareInfo = ref({}) text: '订单',
url: '/pages/index/order',
// 小程序发货信息管理 0: 没有 1 },
const hasWechatTradeManaged = ref(0) {
activeIconUrl: '/static/a-my.png',
/** iconUrl: '/static/my.png',
* @author Ankkaya text: '我的',
* @description 小程序初始化 url: '/pages/index/my',
* @param {Type} - },
* @returns {Type} ],
*/ style: {
async function init() { activeColor: '#fc4141',
// 检查网络 bgColor: '#fff',
const networkStatus = await $platform.checkNetwork() bgType: 'color',
if (!networkStatus) { color: '#282828',
$router.error('NetworkError') },
} theme: 'red',
if (true) {
this.info = {
name: '🍑商城',
logo: 'https://static.iocoder.cn/ruoyi-vue-pro-logo.png',
version: '1.0.0',
copyright: '全部开源,个人与企业可 100% 免费使用',
copytime: 'Copyright© 2018-2024',
cdnurl: 'https://file.sheepjs.com', // 云存储域名
filesystem: 'qcloud', // 云存储平台
}
this.platform = {
share: {
methods: ['poster', 'link'],
linkAddress: 'https://shopro.sheepjs.com/#/',
posterInfo: {
user_bg: '/static/img/shop/config/user-poster-bg.png',
goods_bg: '/static/img/shop/config/goods-poster-bg.png',
groupon_bg: '/static/img/shop/config/groupon-poster-bg.png',
},
},
bind_mobile: 0,
}
this.chat = {
chat_domain: 'https://api.shopro.sheepjs.com/chat',
room_id: 'admin',
}
this.has_wechat_trade_managed = 0
// 加载主题
const sysStore = useSysStore()
sysStore.setTheme()
return Promise.resolve(true)
} else {
$router.error('InitError', res.msg || '加载失败')
}
}
return {
info,
platform,
chat,
template,
shareInfo,
hasWechatTradeManaged,
init,
}
},
{
persist: {
enabled: true,
strategies: [
{
key: 'app-store',
},
],
}, },
},
})
// 全局分享信息
const shareInfo = ref({})
// 小程序发货信息管理 0: 没有 1
const hasWechatTradeManaged = ref(0)
/**
* @author Ankkaya
* @description 小程序初始化
* @param {Type} -
* @returns {Type}
*/
async function init() {
// 检查网络
const networkStatus = await $platform.checkNetwork()
if (!networkStatus) {
$router.error('NetworkError')
}
if (true) {
this.info = {
name: '🍑商城',
logo: 'https://static.iocoder.cn/ruoyi-vue-pro-logo.png',
version: '1.0.0',
copyright: '全部开源,个人与企业可 100% 免费使用',
copytime: 'Copyright© 2018-2024',
cdnurl: 'https://file.sheepjs.com', // 云存储域名
filesystem: 'qcloud', // 云存储平台
}
this.platform = {
share: {
methods: ['poster', 'link'],
linkAddress: 'https://shopro.sheepjs.com/#/',
posterInfo: {
user_bg: '/static/img/shop/config/user-poster-bg.png',
goods_bg: '/static/img/shop/config/goods-poster-bg.png',
groupon_bg: '/static/img/shop/config/groupon-poster-bg.png',
},
},
bind_mobile: 0,
}
this.chat = {
chat_domain: 'https://api.shopro.sheepjs.com/chat',
room_id: 'admin',
}
this.has_wechat_trade_managed = 0
// 加载主题
const sysStore = useSysStore()
sysStore.setTheme()
return Promise.resolve(true)
} else {
$router.error('InitError', res.msg || '加载失败')
}
} }
return {
info,
platform,
chat,
template,
shareInfo,
hasWechatTradeManaged,
init,
}
},
{
persist: {
enabled: true,
strategies: [
{
key: 'app-store',
},
],
},
}
) )
export default useAppStore export default useAppStore

View File

@ -1,316 +1,319 @@
<template> <template>
<view class="uni-popup-dialog"> <view class="uni-popup-dialog">
<view class="uni-dialog-title"> <view class="uni-dialog-title">
<text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{titleText}}</text> <text class="uni-dialog-title-text" :class="['uni-popup__' + dialogType]">{{ titleText }}</text>
</view> </view>
<view v-if="mode === 'base'" class="uni-dialog-content"> <view v-if="mode === 'base'" class="uni-dialog-content">
<slot> <slot>
<text class="uni-dialog-content-text">{{content}}</text> <text class="uni-dialog-content-text">{{ content }}</text>
</slot> </slot>
</view> </view>
<view v-else class="uni-dialog-content"> <view v-else class="uni-dialog-content">
<slot> <slot>
<input class="uni-dialog-input" :maxlength="maxlength" v-model="val" :type="inputType" <input
:placeholder="placeholderText" :focus="focus"> class="uni-dialog-input"
</slot> :maxlength="maxlength"
</view> v-model="val"
<view class="uni-dialog-button-group"> :type="inputType"
<view class="uni-dialog-button" v-if="showClose" @click="closeDialog"> :placeholder="placeholderText"
<text class="uni-dialog-button-text">{{closeText}}</text> :focus="focus"
</view> />
<view class="uni-dialog-button" :class="showClose?'uni-border-left':''" @click="onOk"> </slot>
<text class="uni-dialog-button-text uni-button-color">{{okText}}</text> </view>
</view> <view class="uni-dialog-button-group">
</view> <view class="uni-dialog-button" v-if="showClose" @click="closeDialog">
<text class="uni-dialog-button-text">{{ closeText }}</text>
</view> </view>
<view class="uni-dialog-button" :class="showClose ? 'uni-border-left' : ''" @click="onOk">
<text class="uni-dialog-button-text uni-button-color">{{ okText }}</text>
</view>
</view>
</view>
</template> </template>
<script> <script>
import popup from '../uni-popup/popup.js' import popup from '../uni-popup/popup.js'
import { import { initVueI18n } from '@dcloudio/uni-i18n'
initVueI18n import messages from '../uni-popup/i18n/index.js'
} from '@dcloudio/uni-i18n' const { t } = initVueI18n(messages)
import messages from '../uni-popup/i18n/index.js' /**
const { * PopUp 弹出层-对话框样式
t * @description 弹出层-对话框样式
} = initVueI18n(messages) * @tutorial https://ext.dcloud.net.cn/plugin?id=329
/** * @property {String} value input 模式下的默认值
* PopUp 弹出层-对话框样式 * @property {String} placeholder input 模式下输入提示
* @description 弹出层-对话框样式 * @property {Boolean} focus input模式下是否自动聚焦默认为true
* @tutorial https://ext.dcloud.net.cn/plugin?id=329 * @property {String} type = [success|warning|info|error] 主题样式
* @property {String} value input 模式下的默认值 * @value success 成功
* @property {String} placeholder input 模式下输入提示 * @value warning 提示
* @property {Boolean} focus input模式下是否自动聚焦默认为true * @value info 消息
* @property {String} type = [success|warning|info|error] 主题样式 * @value error 错误
* @value success 成功 * @property {String} mode = [base|input] 模式
* @value warning 提示 * @value base 基础对话框
* @value info 消息 * @value input 可输入对话框
* @value error 错误 * @showClose {Boolean} 是否显示关闭按钮
* @property {String} mode = [base|input] 模式 * @property {String} content 对话框内容
* @value base 基础对话框 * @property {Boolean} beforeClose 是否拦截取消事件
* @value input 可输入对话框 * @property {Number} maxlength 输入
* @showClose {Boolean} 是否显示关闭按钮 * @event {Function} confirm 点击确认按钮触发
* @property {String} content 对话框内容 * @event {Function} close 点击取消按钮触发
* @property {Boolean} beforeClose 是否拦截取消事件 */
* @property {Number} maxlength 输入
* @event {Function} confirm 点击确认按钮触发
* @event {Function} close 点击取消按钮触发
*/
export default { export default {
name: "uniPopupDialog", name: 'uniPopupDialog',
mixins: [popup], mixins: [popup],
emits: ['confirm', 'close', 'update:modelValue', 'input'], emits: ['confirm', 'close', 'update:modelValue', 'input'],
props: { props: {
inputType: { inputType: {
type: String, type: String,
default: 'text' default: 'text',
}, },
showClose: { showClose: {
type: Boolean, type: Boolean,
default: true default: true,
}, },
// #ifdef VUE2 // #ifdef VUE2
value: { value: {
type: [String, Number], type: [String, Number],
default: '' default: '',
}, },
// #endif // #endif
// #ifdef VUE3 // #ifdef VUE3
modelValue: { modelValue: {
type: [Number, String], type: [Number, String],
default: '' default: '',
}, },
// #endif // #endif
placeholder: {
placeholder: { type: [String, Number],
type: [String, Number], default: '',
default: '' },
}, type: {
type: { type: String,
type: String, default: 'error',
default: 'error' },
}, mode: {
mode: { type: String,
type: String, default: 'base',
default: 'base' },
}, title: {
title: { type: String,
type: String, default: '',
default: '' },
}, content: {
content: { type: String,
type: String, default: '',
default: '' },
}, beforeClose: {
beforeClose: { type: Boolean,
type: Boolean, default: false,
default: false },
}, cancelText: {
cancelText: { type: String,
type: String, default: '',
default: '' },
}, confirmText: {
confirmText: { type: String,
type: String, default: '',
default: '' },
}, maxlength: {
maxlength: { type: Number,
type: Number, default: -1,
default: -1, },
}, focus: {
focus: { type: Boolean,
type: Boolean, default: true,
default: true, },
} },
}, data() {
data() { return {
return { dialogType: 'error',
dialogType: 'error', val: '',
val: "" }
} },
}, computed: {
computed: { okText() {
okText() { return this.confirmText || t('uni-popup.ok')
return this.confirmText || t("uni-popup.ok") },
}, closeText() {
closeText() { return this.cancelText || t('uni-popup.cancel')
return this.cancelText || t("uni-popup.cancel") },
}, placeholderText() {
placeholderText() { return this.placeholder || t('uni-popup.placeholder')
return this.placeholder || t("uni-popup.placeholder") },
}, titleText() {
titleText() { return this.title || t('uni-popup.title')
return this.title || t("uni-popup.title") },
} },
}, watch: {
watch: { type(val) {
type(val) { this.dialogType = val
this.dialogType = val },
}, mode(val) {
mode(val) { if (val === 'input') {
if (val === 'input') { this.dialogType = 'info'
this.dialogType = 'info' }
} },
}, value(val) {
value(val) { if (this.maxlength != -1 && this.mode === 'input') {
if (this.maxlength != -1 && this.mode === 'input') { this.val = val.slice(0, this.maxlength)
this.val = val.slice(0, this.maxlength); } else {
} else { this.val = val
this.val = val }
} },
}, val(val) {
val(val) { // #ifdef VUE2
// #ifdef VUE2 // TODO vue2
// TODO vue2 this.$emit('input', val)
this.$emit('input', val); // #endif
// #endif // #ifdef VUE3
// #ifdef VUE3 // TODO  vue3
// TODO  vue3 this.$emit('update:modelValue', val)
this.$emit('update:modelValue', val); // #endif
// #endif },
} modelValue(newVal, oldVal) {
}, this.val = newVal
created() { },
// },
this.popup.disableMask() created() {
// this.popup.closeMask() //
if (this.mode === 'input') { this.popup.disableMask()
this.dialogType = 'info' // this.popup.closeMask()
this.val = this.value; if (this.mode === 'input') {
// #ifdef VUE3 this.dialogType = 'info'
this.val = this.modelValue; this.val = this.value
// #endif // #ifdef VUE3
} else { this.val = this.modelValue
this.dialogType = this.type // #endif
} } else {
}, this.dialogType = this.type
methods: { }
/** },
* 点击确认按钮 methods: {
*/ /**
onOk() { * 点击确认按钮
if (this.mode === 'input') { */
this.$emit('confirm', this.val) onOk() {
} else { if (this.mode === 'input') {
this.$emit('confirm') this.$emit('confirm', this.val)
} } else {
if (this.beforeClose) return this.$emit('confirm')
this.popup.close() }
}, if (this.beforeClose) return
/** this.popup.close()
* 点击取消按钮 },
*/ /**
closeDialog() { * 点击取消按钮
this.$emit('close') */
if (this.beforeClose) return closeDialog() {
this.popup.close() this.$emit('close')
}, if (this.beforeClose) return
close() { this.popup.close()
this.popup.close() },
} close() {
} this.popup.close()
} },
},
}
</script> </script>
<style lang="scss"> <style lang="scss">
.uni-popup-dialog { .uni-popup-dialog {
width: 300px; width: 300px;
border-radius: 11px; border-radius: 11px;
background-color: #fff; background-color: #fff;
} }
.uni-dialog-title { .uni-dialog-title {
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
display: flex; display: flex;
/* #endif */ /* #endif */
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
padding-top: 25px; padding-top: 25px;
} }
.uni-dialog-title-text { .uni-dialog-title-text {
font-size: 16px; font-size: 16px;
font-weight: 500; font-weight: 500;
} }
.uni-dialog-content { .uni-dialog-content {
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
display: flex; display: flex;
/* #endif */ /* #endif */
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 20px; padding: 20px;
} }
.uni-dialog-content-text { .uni-dialog-content-text {
font-size: 14px; font-size: 14px;
color: #6C6C6C; color: #6c6c6c;
} }
.uni-dialog-button-group { .uni-dialog-button-group {
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
display: flex; display: flex;
/* #endif */ /* #endif */
flex-direction: row; flex-direction: row;
border-top-color: #f5f5f5; border-top-color: #f5f5f5;
border-top-style: solid; border-top-style: solid;
border-top-width: 1px; border-top-width: 1px;
} }
.uni-dialog-button { .uni-dialog-button {
/* #ifndef APP-NVUE */ /* #ifndef APP-NVUE */
display: flex; display: flex;
/* #endif */ /* #endif */
flex: 1; flex: 1;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
height: 45px; height: 45px;
} }
.uni-border-left { .uni-border-left {
border-left-color: #f0f0f0; border-left-color: #f0f0f0;
border-left-style: solid; border-left-style: solid;
border-left-width: 1px; border-left-width: 1px;
} }
.uni-dialog-button-text { .uni-dialog-button-text {
font-size: 16px; font-size: 16px;
color: #333; color: #333;
} }
.uni-button-color { .uni-button-color {
color: #007aff; color: #007aff;
} }
.uni-dialog-input { .uni-dialog-input {
flex: 1; flex: 1;
font-size: 14px; font-size: 14px;
border: 1px #eee solid; border: 1px #eee solid;
height: 40px; height: 40px;
padding: 0 10px; padding: 0 10px;
border-radius: 5px; border-radius: 5px;
color: #555; color: #555;
} }
.uni-popup__success { .uni-popup__success {
color: #4cd964; color: #4cd964;
} }
.uni-popup__warn { .uni-popup__warn {
color: #f0ad4e; color: #f0ad4e;
} }
.uni-popup__error { .uni-popup__error {
color: #dd524d; color: #dd524d;
} }
.uni-popup__info { .uni-popup__info {
color: #909399; color: #909399;
} }
</style> </style>