清空代码-初始化yudao

This commit is contained in:
落日晚风
2023-12-18 14:02:47 +08:00
parent aad925ed51
commit 4cb256af6c
102 changed files with 4959 additions and 7836 deletions
-95
View File
@@ -1,19 +1,6 @@
import request from '@/sheep/request';
import { baseUrl } from '@/sheep/config';
export default {
// TODO 芋艿:测试
test: () =>
request({
url: '/app-api/promotion/decorate/list',
params: {
page: 1
},
custom: {
showError: false,
showLoading: false,
},
}),
// 系统初始化
init: (templateId) =>
request({
@@ -39,50 +26,12 @@ export default {
showLoading: false,
},
}),
// 发送短信
sendSms: (data) =>
request({
url: 'sendSms',
method: 'POST',
data,
custom: {
showSuccess: true,
loadingMsg: '发送中',
},
}),
//意见反馈
feedback: (data) =>
request({
url: 'feedback',
method: 'POST',
data,
}),
// 自定义页面
page: (id) =>
request({
url: 'page/' + id,
method: 'GET',
}),
//积分商城
scoreShop: {
list: (params) =>
request({
url: 'app/scoreShop',
method: 'GET',
params,
}),
ids: (params = {}) =>
request({
url: 'app/scoreShop/ids',
method: 'GET',
params,
}),
detail: (id) =>
request({
url: 'app/scoreShop/' + id,
method: 'GET',
}),
},
//小程序直播
mplive: {
getRoomList: (ids) =>
@@ -99,48 +48,4 @@ export default {
method: 'GET'
}),
},
//上传
upload: (file, group = 'ugc', callback) => {
const token = uni.getStorageSync('token');
uni.showLoading({
title: '上传中',
});
return new Promise((resolve, reject) => {
// 此处先换成yudao
uni.uploadFile({
url: 'http://api-dashboard.yudao.iocoder.cn' + '/app-api/infra/file/upload',
filePath: file,
name: 'file',
formData: {
group,
},
header: {
// Accept: 'text/json',
// Authorization: token,
Accept : '*/*',
'tenant-id' :'1',
Authorization: 'Bearer test247',
},
success: (uploadFileRes) => {
let result = JSON.parse(uploadFileRes.data);
if (result.error === 1) {
uni.showToast({
icon: 'none',
title: result.msg,
});
} else {
return resolve(result.data);
}
},
fail: (error) => {
console.log('上传失败:', error);
return resolve(false);
},
complete: () => {
uni.hideLoading();
},
});
});
},
};
+1 -17
View File
@@ -12,18 +12,7 @@ export default {
showLoading: false,
},
}),
userCoupon: (params) =>
request2({
url: 'promotion/coupon/page',
method: 'GET',
params,
}),
// userCoupon: (params) =>
// request({
// url: 'user/coupon',
// method: 'GET',
// params,
// }),
detail: (id, user_coupon_id) =>
request({
url: 'coupon/' + id,
@@ -37,9 +26,4 @@ export default {
url: 'coupon/get/' + id,
method: 'POST',
}),
listByGoods: (id) =>
request({
url: 'coupon/listByGoods/' + id,
method: 'GET',
}),
};
+4 -1
View File
@@ -7,4 +7,7 @@ Object.keys(files).forEach((key) => {
};
});
export default api;
// TODO 芋艿:直接在 useModal 引入 AuthUtil 会报错,所以采用这用这方式先
api.AuthUtil = import.meta.globEager('./member/auth.js')['./member/auth.js'].default;
export default api;
+49
View File
@@ -0,0 +1,49 @@
import request2 from '@/sheep/request2';
const FileApi = {
// 上传文件
uploadFile: (file) => {
const token = uni.getStorageSync('token');
uni.showLoading({
title: '上传中',
});
return new Promise((resolve, reject) => {
// 此处先换成yudao
// TODO 芋艿:后续搞下
uni.uploadFile({
// url: 'http://api-dashboard.yudao.iocoder.cn' + '/app-api/infra/file/upload',
url: 'http://127.0.0.1:48080' + '/app-api/infra/file/upload',
filePath: file,
name: 'file',
header: {
// Accept: 'text/json',
// Authorization: token,
Accept : '*/*',
'tenant-id' :'1',
Authorization: 'Bearer test247',
},
success: (uploadFileRes) => {
debugger
let result = JSON.parse(uploadFileRes.data);
if (result.error === 1) {
uni.showToast({
icon: 'none',
title: result.msg,
});
} else {
return resolve(result);
}
},
fail: (error) => {
console.log('上传失败:', error);
return resolve(false);
},
complete: () => {
uni.hideLoading();
},
});
});
},
};
export default FileApi;
+45
View File
@@ -0,0 +1,45 @@
import request2 from '@/sheep/request2';
const AddressApi = {
// 获得用户收件地址列表
getAddressList: () => {
return request2({
url: '/app-api/member/address/list',
method: 'GET'
});
},
// 创建用户收件地址
createAddress: (data) => {
return request2({
url: '/app-api/member/address/create',
method: 'POST',
data
});
},
// 更新用户收件地址
updateAddress: (data) => {
return request2({
url: '/app-api/member/address/update',
method: 'PUT',
data
});
},
// 获得用户收件地址
getAddress: (id) => {
return request2({
url: '/app-api/member/address/get',
method: 'GET',
params: { id }
});
},
// 删除用户收件地址
deleteAddress: (id) => {
return request2({
url: '/app-api/member/address/delete',
method: 'DELETE',
params: { id }
});
},
};
export default AddressApi;
+42
View File
@@ -0,0 +1,42 @@
import request from '@/sheep/request';
const AuthUtil = {
// 使用手机 + 验证码登录
smsLogin: (data) => {
return request({
url: '/app-api/member/auth/sms-login',
method: 'POST',
data,
custom: {
showSuccess: true,
loadingMsg: '登录中',
successMsg: '登录成功',
},
});
},
// 发送手机验证码
sendSmsCode: (mobile, scene) => {
return request({
url: '/app-api/member/auth/send-sms-code',
method: 'POST',
data: {
mobile,
scene,
},
custom: {
loadingMsg: '发送中',
showSuccess: true,
successMsg: '发送成功',
},
});
},
// 登出系统
logout: () => {
return request({
url: '/app-api/member/auth/logout',
method: 'POST',
});
},
};
export default AuthUtil;
+32
View File
@@ -0,0 +1,32 @@
import request from '@/sheep/request2';
const UserApi = {
// 修改密码
updateUserPassword: (data) => {
return request({
url: '/app-api/member/user/update-password',
method: 'PUT',
data,
custom: {
loadingMsg: '验证中',
showSuccess: true,
successMsg: '修改成功'
},
});
},
// 重置密码
resetUserPassword: (data) => {
return request({
url: '/app-api/member/user/reset-password',
method: 'PUT',
data,
custom: {
loadingMsg: '验证中',
showSuccess: true,
successMsg: '修改成功'
}
});
},
};
export default UserApi;
-6
View File
@@ -15,12 +15,6 @@ export default {
// method: 'GET',
// params,
// }),
// 发票详情
invoice: (id) =>
request({
url: 'order/invoice/' + id,
method: 'GET',
}),
// 获取支付结果
payResult: (id) =>
request({
+14
View File
@@ -0,0 +1,14 @@
import request from '@/sheep/request';
const PayChannelApi = {
// 获得指定应用的开启的支付渠道编码列表
getEnableChannelCodeList: (appId) => {
return request({
url: '/app-api/pay/channel/get-enable-code-list',
method: 'GET',
params: { appId }
});
},
};
export default PayChannelApi;
+22
View File
@@ -0,0 +1,22 @@
import request from '@/sheep/request';
const PayOrderApi = {
// 获得支付订单
getOrder: (id) => {
return request({
url: '/app-api/pay/order/get',
method: 'GET',
params: { id }
});
},
// 提交支付订单
submitOrder: (data) => {
return request({
url: '/app-api/pay/order/submit',
method: 'POST',
data
});
}
};
export default PayOrderApi;
+26
View File
@@ -0,0 +1,26 @@
import request from '@/sheep/request';
const PayWalletApi = {
// 获得钱包流水分页
getWalletTransactionPage: (params) => {
const queryString = Object.keys(params)
.map((key) => encodeURIComponent(key) + '=' + params[key])
.join('&');
return request({
url: `/app-api/pay/wallet-transaction/page?${queryString}`,
method: 'GET'
});
},
// 获得钱包流水统计
getWalletTransactionSummary: (params) => {
const queryString = `createTime=${params.createTime[0]}&createTime=${params.createTime[1]}`
return request({
url: `/app-api/pay/wallet-transaction/get-summary?${queryString}`,
// url: `/app-api/pay/wallet-transaction/get-summary`,
method: 'GET',
// params: params
});
},
};
export default PayWalletApi;
+16 -7
View File
@@ -1,12 +1,21 @@
import request from '@/sheep/request';
const CategoryApi = {
// 查询分类列表
getCategoryList: () => {
return request({
url: '/app-api/product/category/list',
method: 'GET'
});
}
// 查询分类列表
getCategoryList: () => {
return request({
url: '/app-api/product/category/list',
method: 'GET',
});
},
// 查询分类列表,指定编号
getCategoryListByIds: (ids) => {
return request({
url: '/app-api/product/category/list-by-ids',
method: 'GET',
params: { ids },
});
},
};
export default CategoryApi;
+44
View File
@@ -0,0 +1,44 @@
import request from '@/sheep/request';
const FavoriteApi = {
// 获得商品收藏分页
getFavoritePage: (data) => {
return request({
url: '/app-api/product/favorite/page',
method: 'GET',
params: data
});
},
// 检查是否收藏过商品
isFavoriteExists: (spuId) => {
return request({
url: '/app-api/product/favorite/exits',
method: 'GET',
params: {
spuId
}
});
},
// 添加商品收藏
createFavorite: (spuId) => {
return request({
url: '/app-api/product/favorite/create',
method: 'POST',
data: {
spuId
}
});
},
// 取消商品收藏
deleteFavorite: (spuId) => {
return request({
url: '/app-api/product/favorite/delete',
method: 'DELETE',
data: {
spuId
}
});
}
};
export default FavoriteApi;
+43 -1
View File
@@ -1,6 +1,6 @@
import request from '@/sheep/request';
export default {
const CouponApi = {
// 获得优惠劵模板列表
getCouponTemplateListByIds: (ids) => {
return request({
@@ -17,4 +17,46 @@ export default {
params: { spuId, productScope, count },
});
},
// 获得优惠劵模版分页
getCouponTemplatePage: (params) => {
return request({
url: '/app-api/promotion/coupon-template/page',
method: 'GET',
params,
});
},
// 获得优惠劵模版
getCouponTemplate: (id) => {
return request({
url: '/app-api/promotion/coupon-template/get',
method: 'GET',
params: { id },
});
},
// 我的优惠劵列表
getCouponPage: (params) => {
return request({
url: '/app-api/promotion/coupon/page',
method: 'GET',
params,
});
},
// 领取优惠券
takeCoupon: (templateId) => {
return request({
url: '/app-api/promotion/coupon/take',
method: 'POST',
data: { templateId },
});
},
// 获得优惠劵
getCoupon: (id) => {
return request({
url: '/app-api/promotion/coupon/get',
method: 'GET',
params: { id },
});
},
};
export default CouponApi;
+13
View File
@@ -0,0 +1,13 @@
import request2 from '@/sheep/request2';
const AreaApi = {
// 获得地区树
getAreaTree: () => {
return request2({
url: '/app-api/system/area/tree',
method: 'GET'
});
},
};
export default AreaApi;
+45
View File
@@ -0,0 +1,45 @@
import request2 from '@/sheep/request2';
import request from '@/sheep/request';
const AfterSaleApi = {
// 创建售后
createAfterSale: (data) => {
return request2({
url: `/app-api/trade/after-sale/create`,
method: 'POST',
data,
});
},
// 获得售后
getAfterSale: (id) => {
return request2({
url: `/app-api/trade/after-sale/get`,
method: 'GET',
params: {
id,
},
});
},
// 取消售后
cancelAfterSale: (id) => {
return request2({
url: `/app-api/trade/after-sale/cancel`,
method: 'DELETE',
params: {
id,
},
});
},
// 获得售后日志列表
getAfterSaleLogList: (afterSaleId) => {
return request2({
url: `/app-api/trade/after-sale-log/list`,
method: 'GET',
params: {
afterSaleId,
},
});
}
};
export default AfterSaleApi;
+47
View File
@@ -0,0 +1,47 @@
import request2 from '@/sheep/request2';
const CartApi = {
addCart: (data) => {
return request2({
url: '/app-api/trade/cart/add',
method: 'POST',
data: data,
// TODO 芋艿:这里没提示
custom: {
showSuccess: true,
successMsg: '已添加到购物车~',
}
});
},
updateCartCount: (data) => {
return request2({
url: '/app-api/trade/cart/update-count',
method: 'PUT',
data: data
});
},
updateCartSelected: (data) => {
return request2({
url: '/app-api/trade/cart/update-selected',
method: 'PUT',
data: data
});
},
deleteCart: (ids) => {
return request2({
url: '/app-api/trade/cart/delete',
method: 'DELETE',
params: {
ids
}
});
},
getCartList: () => {
return request2({
url: '/app-api/trade/cart/list',
method: 'GET',
});
},
};
export default CartApi;
+14
View File
@@ -0,0 +1,14 @@
import request2 from '@/sheep/request2';
import request from '@/sheep/request';
const TradeConfigApi = {
// 获得交易配置
getTradeConfig: () => {
return request2({
url: `/app-api/trade/config/get`,
method: 'GET',
});
},
};
export default TradeConfigApi;
+103
View File
@@ -0,0 +1,103 @@
import request2 from '@/sheep/request2';
import request from '@/sheep/request';
const OrderApi = {
// 计算订单信息
settlementOrder: (data) => {
const data2 = {
...data,
};
// 移除多余字段
if (!(data.couponId > 0)) {
delete data2.couponId;
}
if (!(data.addressId > 0)) {
delete data2.addressId;
}
// 解决 SpringMVC 接受 List<Item> 参数的问题
delete data2.items;
for (let i = 0; i < data.items.length; i++) {
data2[encodeURIComponent('items[' + i + '' + '].skuId')] = data.items[i].skuId + '';
data2[encodeURIComponent('items[' + i + '' + '].count')] = data.items[i].count + '';
if (data.items[i].cartId) {
data2[encodeURIComponent('items[' + i + '' + '].cartId')] = data.items[i].cartId + '';
}
}
const queryString = Object.keys(data2)
.map((key) => key + '=' + data2[key])
.join('&');
return request2({
url: `trade/order/settlement?${queryString}`,
method: 'GET',
});
},
// 创建订单
createOrder: (data) => {
return request2({
url: `trade/order/create`,
method: 'POST',
data,
});
},
// 获得订单
getOrder: (id) => {
return request2({
url: `trade/order/get-detail`,
method: 'GET',
params: {
id,
},
});
},
// 订单列表
getOrderPage: (params) => {
return request({
url: '/app-api/trade/order/page',
method: 'GET',
params,
custom: {
showLoading: false,
},
});
},
// 确认收货
receiveOrder: (id) => {
return request2({
url: `/app-api/trade/order/receive`,
method: 'PUT',
params: {
id,
},
});
},
// 取消订单
cancelOrder: (id) => {
return request2({
url: `/app-api/trade/order/cancel`,
method: 'DELETE',
params: {
id,
},
});
},
// 删除订单
deleteOrder: (id) => {
return request2({
url: `/app-api/trade/order/delete`,
method: 'DELETE',
params: {
id,
},
});
},
// 创建单个评论
createOrderItemComment: (data) => {
return request2({
url: `/app-api/trade/order/item/create-comment`,
method: 'POST',
data,
});
},
};
export default OrderApi;
-112
View File
@@ -92,29 +92,6 @@ export default {
loadingMsg: '正在注册',
},
}),
// 重置密码
resetPassword: (data) =>
request({
url: '/user/api/user/resetPassword',
method: 'POST',
data,
custom: {
showSuccess: true,
loadingMsg: '验证中',
},
}),
// 修改密码
changePassword: (data) =>
request({
url: '/user/api/user/changePassword',
method: 'POST',
data,
custom: {
showSuccess: true,
loadingMsg: '验证中',
},
}),
// 绑定、更换手机号
changeMobile: (data) =>
@@ -128,18 +105,6 @@ export default {
},
}),
// 修改用户名
changeUsername: (data) =>
request({
url: '/user/api/user/changeUsername',
method: 'POST',
data,
custom: {
showSuccess: true,
loadingMsg: '验证中',
},
}),
// 更新小程序信息
updateMpUserInfo: (data) =>
request({
@@ -218,12 +183,6 @@ export default {
method: 'GET',
custom: {},
}),
// list: () =>
// request({
// url: 'user/address',
// method: 'GET',
// custom: {},
// }),
create: (data) =>
request2({
url: 'member/address/create',
@@ -233,15 +192,6 @@ export default {
showSuccess: true,
},
}),
// create: (data) =>
// request({
// url: 'user/address',
// method: 'POST',
// data,
// custom: {
// showSuccess: true,
// },
// }),
update: (data) =>
request2({
url: 'member/address/update',
@@ -251,71 +201,16 @@ export default {
showSuccess: true,
},
}),
// update: (id, data) =>
// request({
// url: 'user/address/' + id,
// method: 'PUT',
// data,
// custom: {
// showSuccess: true,
// },
// }),
detail: (id) =>
request2({
url: 'member/address/get?id=' + id,
method: 'GET',
}),
// detail: (id) =>
// request({
// url: 'user/address/' + id,
// method: 'GET',
// }),
delete: (id) =>
request2({
url: 'member/address/delete?id=' + id,
method: 'DELETE',
}),
// delete: (id) =>
// request({
// url: 'user/address/' + id,
// method: 'DELETE',
// }),
},
invoice: {
list: () =>
request({
url: 'user/invoice',
method: 'GET',
custom: {},
}),
create: (data) =>
request({
url: 'user/invoice',
method: 'POST',
data,
custom: {
showSuccess: true,
},
}),
update: (id, data) =>
request({
url: 'user/invoice/' + id,
method: 'PUT',
data,
custom: {
showSuccess: true,
},
}),
detail: (id) =>
request({
url: 'user/invoice/' + id,
method: 'GET',
}),
delete: (id) =>
request({
url: 'user/invoice/' + id,
method: 'DELETE',
}),
},
favorite: {
list: (params) =>
@@ -398,13 +293,6 @@ export default {
params,
custom: {},
}),
// log: (params) =>
// request({
// url: '/user/api/walletLog',
// method: 'GET',
// params,
// custom: {},
// }),
},
account: {
info: (params) =>
@@ -1,3 +1,4 @@
<!-- 地址卡片 -->
<template>
<view
class="address-item ss-flex ss-row-between ss-col-center"
@@ -11,18 +12,23 @@
custom-style="background-color: var(--ui-BG-Main); border-color: var(--ui-BG-Main); color: #fff;"
v-if="props.item.defaultStatus"
text="默认"
></uni-tag>
/>
{{ props.item.areaName }}
<!-- {{ props.item.city_name }} {{ props.item.district_name }} -->
</view>
<view class="address-text">{{ props.item.detailAddress }}</view>
<view class="person-text">{{ props.item.name }} {{ props.item.mobile }}</view>
<view class="address-text">
{{ props.item.detailAddress }}
</view>
<view class="person-text">
{{ props.item.name }} {{ props.item.mobile }}
</view>
</view>
<view v-else>
<view class="address-text ss-m-b-10">请选择收货地址</view>
</view>
<view v-else><view class="address-text ss-m-b-10">请选择收货地址</view></view>
<slot>
<button class="ss-reset-button edit-btn" @tap.stop="onEdit">
<view class="edit-icon ss-flex ss-row-center ss-col-center">
<image :src="sheep.$url.static('/static/img/shop/user/address/edit.png')"></image>
<image :src="sheep.$url.static('/static/img/shop/user/address/edit.png')" />
</view>
</button>
</slot>
@@ -4,10 +4,10 @@
<!-- 标题栏 -->
<view class="head-box ss-m-b-60 ss-flex-col">
<view class="ss-flex ss-m-b-20">
<view class="head-title ss-m-r-40 head-title-animation">账号登录</view>
<view class="head-title-active head-title-line" @tap="showAuthModal('smsLogin')">
短信登录
</view>
<view class="head-title ss-m-r-40 head-title-animation">账号登录</view>
</view>
<view class="head-subtitle">如果未设置过密码请点击忘记密码</view>
</view>
@@ -1,4 +1,4 @@
<!-- 修改密码 - changePassword -->
<!-- 修改密码登录时 -->
<template>
<view>
<!-- 标题栏 -->
@@ -16,29 +16,32 @@
labelWidth="140"
labelAlign="center"
>
<uni-forms-item name="oldPassword" label="旧密码">
<uni-forms-item name="code" label="验证码">
<uni-easyinput
placeholder="请输入旧密码"
v-model="state.model.oldPassword"
type="text"
placeholder="请输入验证码"
v-model="state.model.code"
type="number"
maxlength="4"
:inputBorder="false"
/>
>
<template v-slot:right>
<button
class="ss-reset-button code-btn code-btn-start"
:disabled="state.isMobileEnd"
:class="{ 'code-btn-end': state.isMobileEnd }"
@tap="getSmsCode('changePassword')"
>
{{ getSmsTimer('resetPassword') }}
</button>
</template>
</uni-easyinput>
</uni-forms-item>
<uni-forms-item name="newPassword" label="密码">
<uni-forms-item name="reNewPassword" label="密码">
<uni-easyinput
type="password"
placeholder="请输入密码"
v-model="state.model.newPassword"
:inputBorder="false"
/>
</uni-forms-item>
<uni-forms-item name="reNewPassword" label="确认密码">
<uni-easyinput
type="password"
placeholder="请重新输入您的新密码"
v-model="state.model.reNewPassword"
placeholder="请输入密码"
v-model="state.model.password"
:inputBorder="false"
>
<template v-slot:right>
@@ -50,69 +53,51 @@
</uni-forms-item>
</uni-forms>
<view class="editPwd-btn-box ss-m-t-80">
<button class="ss-reset-button forgot-btn" @tap="showAuthModal('resetPassword')">
忘记密码
</button>
</view>
<button class="ss-reset-button type-btn" @tap="closeAuthModal">
取消修改
</button>
</view>
</template>
<script setup>
import { computed, watch, ref, reactive, unref } from 'vue';
import sheep from '@/sheep';
import { password } from '@/sheep/validate/form';
import { showAuthModal, closeAuthModal } from '@/sheep/hooks/useModal';
import { ref, reactive, unref } from 'vue';
import { code, password } from '@/sheep/validate/form';
import { closeAuthModal, getSmsCode, getSmsTimer } from '@/sheep/hooks/useModal';
import UserApi from '@/sheep/api/member/user';
const changePasswordRef = ref(null);
// 数据
const state = reactive({
isMobileEnd: false, // 手机号输入完毕
model: {
oldPassword: '', //旧密码
newPassword: '', //新密
reNewPassword: '', //确认密码
mobile: '', // 手机号
code: '', // 验证
password: '', // 密码
},
rules: {
oldPassword: password,
newPassword: password,
reNewPassword: {
rules: [
{
required: true,
errorMessage: '请确认密码',
},
{
validateFunction: function (rule, value, data, callback) {
if (value !== state.model.newPassword) {
callback('两次输入的密码不一致');
}
if (value === state.model.oldPassword) {
callback('新密码不能与旧密码相同');
}
return true;
},
},
],
},
code,
password,
},
});
// 6.更改密码
// 更改密码
async function changePasswordSubmit() {
// 参数校验
const validate = await unref(changePasswordRef)
.validate()
.catch((error) => {
console.log('error: ', error);
});
if (!validate) return;
sheep.$api.user.changePassword(state.model).then((res) => {
if (res.error === 0) {
sheep.$store('user').getInfo();
closeAuthModal();
}
});
if (!validate) {
return;
}
// 发起请求
const { code } = await UserApi.updateUserPassword(state.model);
if (code !== 0) {
return;
}
// 成功后,只需要关闭弹窗
closeAuthModal();
}
</script>
@@ -1,72 +0,0 @@
<!-- 修改用户名 changeUsername -->
<template>
<view>
<!-- 标题栏 -->
<view class="head-box ss-m-b-60">
<view class="head-title ss-m-b-20">修改用户名</view>
<view class="head-subtitle">用户名仅限修改一次</view>
</view>
<!-- 表单项 -->
<uni-forms
ref="formRef"
v-model="state.model"
:rules="state.rules"
validateTrigger="bind"
labelWidth="140"
labelAlign="center"
>
<uni-forms-item name="username" label="用户名">
<uni-easyinput
placeholder="请输入用户名"
v-model="state.model.username"
:inputBorder="false"
></uni-easyinput>
</uni-forms-item>
<view class="editPwd-btn-box ss-m-t-80">
<button class="ss-reset-button save-btn ui-Shadow-Main" @tap="changeUsernameSubmit">
保存
</button>
</view>
</uni-forms>
</view>
</template>
<script setup>
import { computed, watch, ref, reactive, unref } from 'vue';
import sheep from '@/sheep';
import { username } from '@/sheep/validate/form';
import { showAuthModal, closeAuthModal } from '@/sheep/hooks/useModal';
const formRef = ref(null);
// 数据
const state = reactive({
model: {
username: '',
},
rules: {
username,
},
});
// 7.修改用户名
async function changeUsernameSubmit() {
const validate = await unref(formRef)
.validate()
.catch((error) => {
console.log('error: ', error);
});
if (!validate) return;
sheep.$api.user.changeUsername(state.model).then((res) => {
if (res.error === 0) {
sheep.$store('user').getInfo();
closeAuthModal();
}
});
}
</script>
<style lang="scss" scoped>
@import '../index.scss';
</style>
@@ -1,4 +1,4 @@
<!-- 重置密码 - resetPassword-- -->
<!-- 重置密码未登录时 -->
<template>
<view>
<!-- 标题栏 -->
@@ -43,7 +43,7 @@
type="number"
maxlength="4"
:inputBorder="false"
></uni-easyinput>
/>
</uni-forms-item>
<uni-forms-item name="password" label="密码">
@@ -69,10 +69,11 @@
</template>
<script setup>
import { computed, watch, ref, reactive, unref } from 'vue';
import { computed, ref, reactive, unref } from 'vue';
import sheep from '@/sheep';
import { code, mobile, password } from '@/sheep/validate/form';
import { showAuthModal, closeAuthModal, getSmsCode, getSmsTimer } from '@/sheep/hooks/useModal';
import UserApi from '@/sheep/api/member/user';
const resetPasswordRef = ref(null);
const isLogin = computed(() => sheep.$store('user').isLogin);
@@ -81,9 +82,9 @@
const state = reactive({
isMobileEnd: false, // 手机号输入完毕
model: {
mobile: '', //手机号
code: '', //验证码
password: '', //密码
mobile: '', // 手机号
code: '', // 验证码
password: '', // 密码
},
rules: {
code,
@@ -92,20 +93,24 @@
},
});
// 4.重置密码
// 重置密码
const resetPasswordSubmit = async () => {
// 参数校验
const validate = await unref(resetPasswordRef)
.validate()
.catch((error) => {
console.log('error: ', error);
});
if (!validate) return;
sheep.$api.user.resetPassword(state.model).then((res) => {
if (res.error === 0) {
sheep.$store('user').getInfo();
closeAuthModal();
}
});
if (!validate) {
return;
}
// 发起请求
const { code } = await UserApi.resetUserPassword(state.model);
if (code !== 0) {
return;
}
// 成功后,用户重新登录
showAuthModal('accountLogin')
};
</script>
@@ -4,12 +4,12 @@
<!-- 标题栏 -->
<view class="head-box ss-m-b-60">
<view class="ss-flex ss-m-b-20">
<view class="head-title-active ss-m-r-40" @tap="showAuthModal('accountLogin')"
>账号登录</view
>
<view class="head-title head-title-line head-title-animation">短信登录</view>
<view class="head-title-active ss-m-r-40" @tap="showAuthModal('accountLogin')">
账号登录
</view>
</view>
<view class="head-subtitle">未注册手机号请先点击下方立即注册</view>
<view class="head-subtitle">未注册手机号验证后自动注册账号</view>
</view>
<!-- 表单项 -->
@@ -59,10 +59,11 @@
</template>
<script setup>
import { computed, watch, ref, reactive, unref } from 'vue';
import { ref, reactive, unref } from 'vue';
import sheep from '@/sheep';
import { code, mobile } from '@/sheep/validate/form';
import { showAuthModal, closeAuthModal, getSmsCode, getSmsTimer } from '@/sheep/hooks/useModal';
import AuthUtil from '@/sheep/api/member/auth';
const smsLoginRef = ref(null);
@@ -89,22 +90,25 @@
},
});
// 2.短信登录
// 短信登录
async function smsLoginSubmit() {
// 参数校验
const validate = await unref(smsLoginRef)
.validate()
.catch((error) => {
console.log('error: ', error);
});
if (!validate) return;
if (!validate) {
return;
}
if (!props.agreeStatus) {
emits('onConfirm', true)
sheep.$helper.toast('请勾选同意');
return;
}
const { error } = await sheep.$api.user.smsLogin(state.model);
if (error === 0) {
// 提交数据
const { code } = await AuthUtil.smsLogin(state.model);
if (code === 0) {
closeAuthModal();
}
}
@@ -1,130 +0,0 @@
<!-- 短信注册 - smsRegister -->
<template>
<view>
<!-- 标题栏 -->
<view class="head-box ss-m-b-60">
<view class="head-title ss-m-b-20">注册</view>
<view class="head-subtitle">请使用本人手机号完成注册</view>
</view>
<!-- 表单项 -->
<uni-forms
ref="smsRegisterRef"
v-model="state.model"
:rules="state.rules"
validateTrigger="bind"
labelWidth="140"
labelAlign="center"
>
<uni-forms-item name="mobile" label="手机号">
<uni-easyinput
placeholder="请输入手机号"
v-model="state.model.mobile"
type="number"
:inputBorder="false"
>
<template v-slot:right>
<button
class="ss-reset-button code-btn code-btn-start"
:disabled="state.isMobileEnd"
:class="{ 'code-btn-end': state.isMobileEnd }"
@tap="getSmsCode('smsRegister', state.model.mobile)"
>
{{ getSmsTimer('smsRegister') }}
</button>
</template>
</uni-easyinput>
</uni-forms-item>
<uni-forms-item name="code" label="验证码">
<uni-easyinput
placeholder="请输入验证码"
v-model="state.model.code"
:inputBorder="false"
type="number"
maxlength="4"
></uni-easyinput>
</uni-forms-item>
<uni-forms-item name="password" label="密码">
<uni-easyinput
type="password"
placeholder="请输入密码"
v-model="state.model.password"
:inputBorder="false"
>
<template v-slot:right>
<button class="ss-reset-button login-btn-start" @tap="smsRegisterSubmit"> 注册 </button>
</template>
</uni-easyinput>
</uni-forms-item>
</uni-forms>
<button class="ss-reset-button type-btn" @tap="showAuthModal('accountLogin')">
返回登录
</button>
</view>
</template>
<script setup>
import { computed, ref, reactive, unref } from 'vue';
import sheep from '@/sheep';
import { code, mobile, password } from '@/sheep/validate/form';
import { showAuthModal, closeAuthModal, getSmsCode, getSmsTimer } from '@/sheep/hooks/useModal';
const props = defineProps({
agreeStatus: {
type: Boolean,
default: false,
},
});
const smsRegisterRef = ref(null);
const isLogin = computed(() => sheep.$store('user').isLogin);
const emits = defineEmits(['onConfirm']);
// 数据
const state = reactive({
isMobileEnd: false, // 手机号输入完毕
model: {
mobile: '', // 手机号
code: '', // 验证码
password: '', // 密码
},
rules: {
code,
mobile,
password,
},
});
// 3.短信注册
async function smsRegisterSubmit() {
const validate = await unref(smsRegisterRef)
.validate()
.catch((error) => {
console.log('error: ', error);
});
if (!validate) return;
if (!props.agreeStatus) {
emits('onConfirm',true);
sheep.$helper.toast('请勾选同意');
return;
}
const { error } = await sheep.$api.user.smsRegister({
...state.model,
shareInfo: uni.getStorageSync('shareLog') || {},
});
if (error === 0) {
closeAuthModal();
}
}
</script>
<style lang="scss" scoped>
@import '../index.scss';
</style>
+3 -24
View File
@@ -12,13 +12,6 @@
<!-- 2.短信登录 smsLogin -->
<sms-login v-if="authType === 'smsLogin'" :agreeStatus="state.protocol" @onConfirm="onConfirm" />
<!-- 3.短信注册 smsRegister-->
<sms-register
v-if="authType === 'smsRegister'"
:agreeStatus="state.protocol"
@onConfirm="onConfirm"
/>
<!-- 4.忘记密码 resetPassword-->
<reset-password v-if="authType === 'resetPassword'" />
@@ -26,10 +19,7 @@
<change-mobile v-if="authType === 'changeMobile'" />
<!-- 6.修改密码 changePassword-->
<change-passwrod v-if="authType === 'changePassword'" />
<!-- 7.修改用户名 changeUsername-->
<change-username v-if="authType === 'changeUsername'" />
<changePassword v-if="authType === 'changePassword'" />
<!-- 8.微信小程序授权 changeUsername-->
<mp-authorization v-if="authType === 'mpAuthorization'" />
@@ -42,22 +32,13 @@
<!-- 立即注册&快捷登录 TextButton -->
<view v-if="sheep.$platform.name === 'WechatMiniProgram'" class="ss-flex register-box">
<view class="register-title">还没有账号?</view>
<button class="ss-reset-button register-btn" @tap="showAuthModal('smsRegister')"
>立即注册</button
<button class="ss-reset-button register-btn" @tap="showAuthModal('smsRegister')">立即注册</button
>
<view class="or-title"></view>
<button class="ss-reset-button login-btn" @tap="thirdLogin('wechat')">快捷登录</button>
<view class="circle"></view>
</view>
<button
v-if="sheep.$platform.name !== 'WechatMiniProgram'"
class="ss-reset-button type-btn"
@tap="showAuthModal('smsRegister')"
>
立即注册
</button>
<!-- 公众号|App微信登录 -->
<button
v-if="
@@ -126,11 +107,9 @@
import sheep from '@/sheep';
import accountLogin from './components/account-login.vue';
import smsLogin from './components/sms-login.vue';
import smsRegister from './components/sms-register.vue';
import resetPassword from './components/reset-password.vue';
import changeMobile from './components/change-mobile.vue';
import changePasswrod from './components/change-password.vue';
import changeUsername from './components/change-username.vue';
import changePassword from './components/change-password.vue';
import mpAuthorization from './components/mp-authorization.vue';
import { closeAuthModal, showAuthModal } from '@/sheep/hooks/useModal';
@@ -20,7 +20,7 @@
<!-- 图文组件图片轮播 -->
<s-image-banner v-if="type === 'Carousel'" :data="data" :styles="styles" />
<!-- 基础组件标题栏 -->
<s-title-block v-if="type === 'titleBlock'" :data="data" :styles="styles" />
<s-title-block v-if="type === 'TitleBar'" :data="data" :styles="styles" />
<!-- 图文组件广告魔方 -->
<s-image-cube v-if="type === 'MagicCube'" :data="data" :styles="styles" />
<!-- 图文组件视频播放 -->
@@ -28,7 +28,7 @@
<!-- 基础组件分割线 -->
<s-line-block v-if="type === 'Divider'" :data="data" />
<!-- 图文组件热区 -->
<s-hotzone-block v-if="type === 'hotzone'" :data="data" :styles="styles" />
<s-hotzone-block v-if="type === 'HotZone'" :data="data" :styles="styles" />
<!-- 商品组件商品卡片 -->
<s-goods-card v-if="type === 'ProductCard'" :data="data" :styles="styles" />
@@ -39,8 +39,6 @@
<s-groupon-block v-if="type === 'PromotionCombination'" :data="data" :styles="styles" />
<!-- 营销组件秒杀 -->
<s-seckill-block v-if="type === 'PromotionSeckill'" :data="data" :styles="styles" />
<!-- 营销组件积分商城模式不一样无法适配 -->
<s-score-block v-if="type === 'PromotionPoint'" :data="data" :styles="styles" />
<!-- 营销组件小程序直播暂时没有这个功能 -->
<s-live-block v-if="type === 'MpLive'" :data="data" :styles="styles" />
<!-- 营销组件优惠券 -->
+10 -9
View File
@@ -1,3 +1,4 @@
<!-- 商品详情 - 优惠劵领取 -->
<template>
<su-popup
:show="show"
@@ -21,13 +22,11 @@
<template #default>
<button
class="ss-reset-button card-btn ss-flex ss-row-center ss-col-center"
:class="
item.get_status != 'can_get' && item.get_status != 'can_use' ? 'boder-btn' : ''
"
:class="!item.canTake ? 'boder-btn' : ''"
@click.stop="getBuy(item.id)"
:disabled="item.get_status != 'can_get' && item.get_status != 'can_use'"
:disabled="!item.canTake"
>
{{ item.get_status_text }}
{{ item.canTake ? '立即领取' : '已领取' }}
</button>
</template>
</s-coupon-list>
@@ -38,6 +37,7 @@
</template>
<script setup>
import { computed, reactive } from 'vue';
const props = defineProps({
modelValue: {
type: Object,
@@ -48,16 +48,17 @@
default: false,
},
});
const emits = defineEmits(['get', 'close']);
const state = reactive({
couponInfo: computed(() => props.modelValue),
currentValue: -1,
couponId: '',
couponInfo: computed(() => props.modelValue)
});
// 领取优惠劵
const getBuy = (id) => {
emits('get', id);
};
//立即领取
</script>
<style lang="scss" scoped>
.model-box {
+178 -168
View File
@@ -1,195 +1,205 @@
<template>
<view class="ss-m-20" :style="{ opacity: disabled ? '0.5' : '1' }">
<view class="content">
<!-- <view
<view class="ss-m-20" :style="{ opacity: disabled ? '0.5' : '1' }">
<view class="content">
<view
class="tag ss-flex ss-row-center"
:class="
data.status == 'expired' || data.status == 'used' ? 'disabled-bg-color' : 'info-bg-color'
"
>{{ data.type_text }}</view
> -->
<view class="title ss-m-x-30 ss-p-t-18">
<view class="ss-flex ss-row-between">
<view class="value-text ss-flex-1 ss-m-r-10" :class="
data.status == 'expired' || data.status == 'used' ? 'disabled-color' : 'info-color'
">{{ data.name }}</view>
<view>
<view class="ss-flex ss-col-bottom" :class="
data.status != 'expired' && data.status != 'used' ? 'price-text' : 'disabled-color'
">
<view class="value-reduce ss-m-b-10" v-if="data.type === 'reduce'"></view>
<view class="value-price">{{ data.amount }}</view>
<view class="value-discount ss-m-b-10 ss-m-l-4" v-if="data.type === 'discount'"></view>
</view>
</view>
</view>
<view class="ss-flex ss-row-between ss-m-t-16">
<view class="sellby-text" :class="
data.status == 'expired' || data.status == 'used'
? 'disabled-color'
: 'subtitle-color'
">
{{'有效期:' + data.use_start_time.substring(0, 11) }}
{{ data.use_end_time.substring(0, 11) }}
<!-- {{
type === 'user'
? '有效期:' + data.use_start_time.substring(0, 11)
: '领取时间:' + data.get_start_time.substring(0, 11)
}}
{{
type === 'user'
? data.use_end_time.substring(0, 11)
: data.get_end_time.substring(0, 11)
}} -->
</view>
<view class="value-enough" :class="
data.status == 'expired' || data.status == 'used'
? 'disabled-color'
: 'subtitle-color'
">{{ data.enough }}可用</view>
</view>
</view>
</view>
:class="isDisable ? 'disabled-bg-color' : 'info-bg-color'"
>
{{ data.discountType === 1 ? '满减券' : '折扣券' }}
</view>
<view class="title ss-m-x-30 ss-p-t-18">
<view class="ss-flex ss-row-between">
<view
class="value-text ss-flex-1 ss-m-r-10"
:class="isDisable ? 'disabled-color' : 'info-color'"
>
{{ data.name }}
</view>
<view>
<view
class="ss-flex ss-col-bottom"
:class="isDisable ? 'disabled-color' : 'price-text'"
>
<view class="value-reduce ss-m-b-10" v-if="data.discountType === 1"></view>
<view class="value-price">
{{
data.discountType === 1
? fen2yuan(data.discountPrice)
: data.discountPercent / 10.0
}}
</view>
<view class="value-discount ss-m-b-10 ss-m-l-4" v-if="data.discountType === 2"
></view
>
</view>
</view>
</view>
<view class="ss-flex ss-row-between ss-m-t-16">
<view
class="sellby-text"
:class=" isDisable ? 'disabled-color' : 'subtitle-color'"
v-if="data.validityType === 2"
>
有效期领取后 {{ data.fixedEndTerm }} 天内可用
</view>
<view
class="sellby-text"
:class=" isDisable ? 'disabled-color' : 'subtitle-color'"
v-else
>
有效期: {{ sheep.$helper.timeFormat(data.validStartTime, 'yyyy-mm-dd') }}
{{ sheep.$helper.timeFormat(data.validEndTime, 'yyyy-mm-dd') }}
</view>
<view
class="value-enough"
:class="isDisable ? 'disabled-color' : 'subtitle-color'"
>
{{ fen2yuan(data.usePrice) }} 可用
</view>
</view>
</view>
</view>
<view class="desc ss-flex ss-row-between">
<view>
<view class="desc-title">
{{ data.description }}
</view>
<view>
<slot name="reason">
</slot>
</view>
</view>
<view>
<slot></slot>
</view>
</view>
</view>
<!-- TODO 芋艿可优化增加优惠劵的描述 -->
<view class="desc ss-flex ss-row-between">
<view>
<view class="desc-title">{{ data.description }}</view>
<view>
<slot name="reason" />
</view>
</view>
<view>
<slot />
</view>
</view>
</view>
</template>
<script setup>
import {
reactive
} from 'vue';
import sheep from '@/sheep';
const state = reactive({
stateMap: {
0: '立即领取',
1: '去使用',
},
});
// 接受参数
const props = defineProps({
data: {
type: Object,
default: {},
},
disabled: {
type: Boolean,
default: false,
},
type: {
type: String,
default: 'coupon',
},
});
import { computed, reactive } from 'vue';
import { fen2yuan } from '../../hooks/useGoods';
import sheep from '../../index';
const state = reactive({});
const isDisable = computed(() => {
if (props.type === 'coupon') {
return false;
}
return props.data.status !== 1;
});
// 接受参数
const props = defineProps({
data: {
type: Object,
default: {},
},
disabled: {
type: Boolean,
default: false,
},
type: {
type: String,
default: 'coupon', // coupon 优惠劵模版;user 用户优惠劵
},
});
</script>
<style lang="scss" scoped>
.info-bg-color {
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
}
.info-bg-color {
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
}
.disabled-bg-color {
background: #999;
}
.disabled-bg-color {
background: #999;
}
.info-color {
color: #333;
}
.info-color {
color: #333;
}
.subtitle-color {
color: #666;
}
.subtitle-color {
color: #666;
}
.disabled-color {
color: #999;
}
.disabled-color {
color: #999;
}
.content {
width: 100%;
background: #fff;
border-radius: 20rpx 20rpx 0 0;
-webkit-mask: radial-gradient(circle at 12rpx 100%, #0000 12rpx, red 0) -12rpx;
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.04);
.content {
width: 100%;
background: #fff;
border-radius: 20rpx 20rpx 0 0;
-webkit-mask: radial-gradient(circle at 12rpx 100%, #0000 12rpx, red 0) -12rpx;
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.04);
.tag {
width: 100rpx;
.tag {
width: 100rpx;
color: #fff;
height: 40rpx;
font-size: 24rpx;
border-radius: 20rpx 0 20rpx 0;
}
color: #fff;
height: 40rpx;
font-size: 24rpx;
border-radius: 20rpx 0 20rpx 0;
}
.title {
padding-bottom: 22rpx;
border-bottom: 2rpx dashed #d3d3d3;
.title {
padding-bottom: 22rpx;
border-bottom: 2rpx dashed #d3d3d3;
.value-text {
font-size: 32rpx;
font-weight: 600;
}
.value-text {
font-size: 32rpx;
font-weight: 600;
}
.sellby-text {
font-size: 24rpx;
font-weight: 400;
}
.sellby-text {
font-size: 24rpx;
font-weight: 400;
}
.value-price {
font-size: 64rpx;
font-weight: 500;
line-height: normal;
font-family: OPPOSANS;
}
.value-price {
font-size: 64rpx;
font-weight: 500;
line-height: normal;
font-family: OPPOSANS;
}
.value-reduce {
line-height: normal;
font-size: 32rpx;
}
.value-reduce {
line-height: normal;
font-size: 32rpx;
}
.value-discount {
line-height: normal;
font-size: 28rpx;
}
.value-discount {
line-height: normal;
font-size: 28rpx;
}
.value-enough {
font-size: 24rpx;
font-weight: 400;
font-family: OPPOSANS;
}
}
}
.value-enough {
font-size: 24rpx;
font-weight: 400;
font-family: OPPOSANS;
}
}
}
.desc {
width: 100%;
background: #fff;
-webkit-mask: radial-gradient(circle at 12rpx 0%, #0000 12rpx, red 0) -12rpx;
box-shadow: rgba(#000, 0.1);
box-sizing: border-box;
padding: 24rpx 30rpx;
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.04);
border-radius: 0 0 20rpx 20rpx;
.desc {
width: 100%;
background: #fff;
-webkit-mask: radial-gradient(circle at 12rpx 0%, #0000 12rpx, red 0) -12rpx;
box-shadow: rgba(#000, 0.1);
box-sizing: border-box;
padding: 24rpx 30rpx;
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.04);
border-radius: 0 0 20rpx 20rpx;
.desc-title {
font-size: 24rpx;
color: #999;
font-weight: 400;
}
}
.desc-title {
font-size: 24rpx;
color: #999;
font-weight: 400;
}
}
.price-text {
color: #ff0000;
}
.price-text {
color: #ff0000;
}
</style>
+1 -13
View File
@@ -25,19 +25,7 @@
const props = defineProps({
data: {
type: Object,
default() {
return {
// horizontal vertical
direction: 'vertical',
showText: true,
list: [{
imgUrl: 'http://localhost/logo.gif',
url: '',
text: '客服',
textColor: '',
}],
}
},
default() {},
}
})
@@ -29,7 +29,7 @@
:style="[{ color: goodsFields.price.color }]"
>
<text class="price-unit ss-font-24">{{ priceUnit }}</text>
{{ isArray(data.price) ? data.price[0] : data.price }}
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
</view>
</view>
</view>
@@ -55,7 +55,7 @@
:style="[{ color: goodsFields.price.color }]"
>
<text class="price-unit ss-font-24">{{ priceUnit }}</text>
{{ isArray(data.price) ? data.price[0] : data.price }}
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
</view>
</view>
</view>
@@ -102,7 +102,7 @@
:style="[{ color: goodsFields.price.color }]"
>
<text class="price-unit ss-font-24">{{ priceUnit }}</text>
{{ isArray(data.price) ? data.price[0] : data.price }}
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
</view>
<view
@@ -111,7 +111,7 @@
:style="[{ color: originPriceColor }]"
>
<text class="price-unit ss-font-20">{{ priceUnit }}</text>
<view class="ss-m-l-8">{{ data.original_price||data.marketPrice }}</view>
<view class="ss-m-l-8">{{ fen2yuan(data.marketPrice) }}</view>
</view>
</view>
@@ -122,7 +122,7 @@
<slot name="cart">
<view class="cart-box ss-flex ss-col-center ss-row-center">
<image class="cart-icon" src="/static/img/shop/tabbar/category2.png" mode=""></image>
<image class="cart-icon" src="/static/img/shop/tabbar/category2.png" mode="" />
</view>
</slot>
</view>
@@ -174,7 +174,7 @@
:style="[{ color: goodsFields.price.color }]"
>
<text class="ss-font-24">{{ priceUnit }}</text>
{{ isArray(data.price) ? data.price[0] : data.price }}
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
</view>
<view
v-if="(goodsFields.original_price?.show||goodsFields.marketPrice?.show) &&( data.original_price > 0|| data.marketPrice > 0)"
@@ -182,7 +182,7 @@
:style="[{ color: originPriceColor }]"
>
<text class="price-unit ss-font-20">{{ priceUnit }}</text>
<view class="ss-m-l-8">{{ data.original_price||data.marketPrice }}</view>
<view class="ss-m-l-8">{{ fen2yuan(data.marketPrice) }}</view>
</view>
</view>
<view class="ss-m-t-8 ss-flex ss-col-center ss-flex-wrap">
@@ -191,11 +191,11 @@
</view>
</view>
<slot name="cart"
><view class="buy-box ss-flex ss-col-center ss-row-center" v-if="buttonShow"
>去购买</view
></slot
>
<slot name="cart">
<view class="buy-box ss-flex ss-col-center ss-row-center" v-if="buttonShow">
去购买
</view>
</slot>
</view>
<!-- sl卡片竖向型一行放一个图片上内容下边 -->
@@ -238,7 +238,7 @@
<view v-if="goodsFields.price?.show" class="ss-flex ss-col-bottom font-OPPOSANS">
<view class="sl-goods-price ss-m-r-12" :style="[{ color: goodsFields.price.color }]">
<text class="price-unit ss-font-24">{{ priceUnit }}</text>
{{ isArray(data.price) ? data.price[0] : data.price }}
{{ isArray(data.price) ? fen2yuan(data.price[0]) : fen2yuan(data.price) }}
</view>
<view
v-if="(goodsFields.original_price?.show||goodsFields.marketPrice?.show) &&( data.original_price > 0|| data.marketPrice > 0)"
@@ -246,7 +246,7 @@
:style="[{ color: originPriceColor }]"
>
<text class="price-unit ss-font-20">{{ priceUnit }}</text>
<view class="ss-m-l-8">{{ data.original_price||data.marketPrice }}</view>
<view class="ss-m-l-8">{{ fen2yuan(data.marketPrice) }}</view>
</view>
</view>
<view class="ss-m-t-16 ss-flex ss-flex-wrap">
@@ -293,7 +293,7 @@
*/
import { computed, reactive, getCurrentInstance, onMounted, nextTick } from 'vue';
import sheep from '@/sheep';
import { formatSales } from '@/sheep/hooks/useGoods';
import { fen2yuan, formatSales } from '@/sheep/hooks/useGoods';
import { formatStock } from '@/sheep/hooks/useGoods';
import goodsCollectVue from '@/pages/user/goods-collect.vue';
import { isArray } from 'lodash';
@@ -307,6 +307,7 @@
type: [Array, Object],
default() {
return {
// TODO @疯狂:旧的要不剔除掉,后续都用新的
// 商品名称(旧)
title: { show: true },
// 商品介绍(旧)
@@ -26,15 +26,7 @@
:style="[{ color: priceColor }]"
v-if="price && Number(price) > 0"
>
{{ price }}
</view>
<view v-if="score && Number(price) > 0">+</view>
<view class="price-text ss-flex ss-col-center" v-if="score">
<image
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
class="score-img"
></image>
<view>{{ score }}</view>
{{ fen2yuan(price) }}
</view>
<view v-if="num" class="total-text ss-flex ss-col-center">x {{ num }}</view>
<slot name="priceSuffix"></slot>
@@ -54,6 +46,7 @@
<script setup>
import sheep from '@/sheep';
import { computed } from 'vue';
import { fen2yuan } from '@/sheep/hooks/useGoods';
/**
* 订单卡片
*
@@ -1,3 +1,4 @@
<!-- 商品组 - 横向滚动商品目前暂时没用到 -->
<template>
<view class="goods-scroll-box">
<scroll-view class="scroll-box" scroll-x scroll-anchoring>
@@ -8,7 +9,7 @@
size="sm"
:data="item"
:titleWidth="200 - marginLeft - marginRight"
></s-goods-column>
/>
</view>
</view>
</scroll-view>
@@ -1,16 +1,16 @@
<template>
<view class="hotzone-wrap">
<image :src="sheep.$url.cdn(data.src)" style="width: 100%" mode="widthFix"></image>
<image :src="sheep.$url.cdn(data.imgUrl)" style="width: 100%" mode="widthFix"></image>
<view
class="hotzone-box"
v-for="item in data.list"
:key="item.width"
v-for="(item, index) in data.list"
:key="index"
:style="[
{
top: item.top + 'rpx',
left: item.left + 'rpx',
width: item.width + 'rpx',
height: item.height + 'rpx',
top: `${item.top}px`,
left: `${item.left}px`,
width: `${item.width}px`,
height: `${item.height}px`,
},
]"
@tap.stop="sheep.$router.go(item.url)"
@@ -1,96 +0,0 @@
<template>
<view
class="address-item ss-flex ss-row-between ss-col-center"
:class="[{ 'border-bottom': props.hasBorderBottom }]"
>
<view class="item-left" v-if="!_.isEmpty(props.item)">
<view class="address-text">{{ props.item.name }}</view>
<view class="person-text">{{ props.item.mobile }}</view>
</view>
<view v-else>
<view class="address-text">请选择收货地址</view>
</view>
<slot>
<button class="ss-reset-button edit-btn" @tap.stop="onEdit">
<view class="edit-icon ss-flex ss-row-center ss-col-center">
<image :src="sheep.$url.static('/static/img/shop/user/address/edit.png')"></image>
</view>
</button>
</slot>
</view>
</template>
<script setup>
/**
* 基础组件 - 地址卡片
*
* @param {String} icon = _icon-edit - icon
*
* @event {Function()} click - 点击
* @event {Function()} actionClick - 点击工具栏
*
* @slot - 默认插槽
*/
import sheep from '@/sheep';
import _ from 'lodash';
const props = defineProps({
item: {
type: Object,
default() {},
},
hasBorderBottom: {
type: Boolean,
defult: true,
},
});
const onEdit = () => {
sheep.$router.go('/pages/user/invoice/edit', {
id: props.item.id,
});
};
</script>
<style lang="scss" scoped>
.address-item {
padding: 30rpx;
.item-left {
width: 600rpx;
}
.area-text {
font-size: 26rpx;
font-weight: 400;
color: $dark-9;
}
.address-text {
font-size: 32rpx;
font-weight: 600;
color: #333333;
line-height: 48rpx;
}
.person-text {
font-size: 28rpx;
font-weight: 400;
color: $dark-9;
}
}
.edit-btn {
width: 44rpx;
height: 44rpx;
background: $gray-f;
border-radius: 50%;
.edit-icon {
width: 24rpx;
height: 24rpx;
}
}
image {
width: 100%;
height: 100%;
}
</style>
@@ -197,7 +197,7 @@
},
iconSize: {
type: Number,
default: 96,
default: 80,
},
color: {
type: String,
@@ -264,13 +264,13 @@
.menu-icon {
transform: translate(0, 0);
width: 98rpx;
height: 98rpx;
width: 80rpx;
height: 80rpx;
padding-bottom: 10rpx;
}
.menu-title {
font-size: 30rpx;
font-size: 24rpx;
color: #333;
}
}
@@ -1,3 +1,4 @@
<!-- 全局 - 快捷入口 -->
<template>
<su-popup :show="show" type="top" round="20" backgroundColor="#F0F0F0" @close="closeMenuTools">
<su-status-bar />
@@ -10,7 +11,7 @@
class="ss-reset-button list-image ss-flex ss-row-center ss-col-center"
@tap="onClick(item)"
>
<image v-if="show" :src="sheep.$url.static(item.icon)" class="list-icon"></image>
<image v-if="show" :src="sheep.$url.static(item.icon)" class="list-icon" />
</button>
<view class="list-title ss-m-t-20">{{ item.title }}</view>
</view>
@@ -63,11 +64,6 @@
icon: '/static/img/shop/tools/collect.png',
title: '我的收藏',
},
{
url: '/pages/public/feedback',
icon: '/static/img/shop/tools/feedback.png',
title: '意见反馈',
},
{
url: '/pages/chat/index',
icon: '/static/img/shop/tools/service.png',
@@ -32,7 +32,7 @@
<style lang="scss" scoped>
.notice-wrap {
.icon-img {
height: 60rpx;
height: 56rpx;
}
}
</style>
@@ -1,202 +0,0 @@
<template>
<view>
<view
v-if="mode === 1 && state.scoreList.length"
class="goods-md-wrap ss-flex ss-flex-wrap ss-col-top"
>
<view class="goods-list-box">
<view
class="left-list"
:style="[{ paddingRight: data.space + 'rpx', marginBottom: data.space + 'px' }]"
v-for="item in state.leftScoreList"
:key="item.id"
>
<s-score-card
class="goods-md-box"
size="md"
:goodsFields="goodsFields"
:data="item"
:titleColor="goodsFields.title?.color"
:subTitleColor="goodsFields.subtitle.color"
:topRadius="data.borderRadiusTop"
:bottomRadius="data.borderRadiusBottom"
:titleWidth="330 - marginLeft - marginRight"
@click="sheep.$router.go('/pages/goods/score', { id: item.id })"
@getHeight="mountMasonry($event, 'left')"
>
<template v-slot:cart>
<button class="ss-reset-button cart-btn" :style="[buyStyle]">
{{ buyNowStyle.mode === 1 ? buyNowStyle.text : '' }}
</button>
</template>
</s-score-card>
</view>
</view>
<view class="goods-list-box">
<view
class="right-list"
:style="[{ paddingLeft: data.space + 'rpx', marginBottom: data.space + 'px' }]"
v-for="item in state.rightScoreList"
:key="item.id"
>
<s-score-card
class="goods-md-box"
size="md"
:goodsFields="goodsFields"
:data="item"
:titleColor="goodsFields.title?.color"
:subTitleColor="goodsFields.subtitle.color"
:topRadius="data.borderRadiusTop"
:bottomRadius="data.borderRadiusBottom"
:titleWidth="330 - marginLeft - marginRight"
@click="sheep.$router.go('/pages/goods/score', { id: item.id })"
@getHeight="mountMasonry($event, 'right')"
>
<template v-slot:cart>
<button class="ss-reset-button cart-btn" :style="[buyStyle]">
{{ buyNowStyle.mode === 1 ? buyNowStyle.text : '' }}
</button>
</template>
</s-score-card>
</view>
</view>
<!-- <view class="goods-hack" v-if="state.scoreList.length % 2 == 1" style="width: 345rpx"></view> -->
</view>
<view v-if="mode === 2 && state.scoreList.length" class="goods-lg-box">
<view
class="goods-box"
:style="[{ marginBottom: data.space + 'px' }]"
v-for="item in state.scoreList"
:key="item.id"
>
<s-score-card
class="goods-card"
size="lg"
:goodsFields="goodsFields"
:data="item"
:titleColor="goodsFields.title?.color"
:subTitleColor="goodsFields.subtitle.color"
:topRadius="data.borderRadiusTop"
:bottomRadius="data.borderRadiusBottom"
@tap="sheep.$router.go('/pages/goods/score', { id: item.id })"
>
<template v-slot:cart>
<button class="ss-reset-button cart-btn" :style="[buyStyle]">
{{ buyNowStyle.mode === 1 ? buyNowStyle.text : '' }}
</button>
</template>
</s-score-card>
</view>
</view>
</view>
</template>
<script setup>
import { computed, reactive, onMounted } from 'vue';
import sheep from '@/sheep';
const state = reactive({
scoreList: [],
leftScoreList: [],
rightScoreList: [],
});
const props = defineProps({
data: {
type: Object,
default() {},
},
styles: {
type: Object,
default() {},
},
});
const { mode, buyNowStyle, goodsFields, goodsIds } = props.data ?? {};
const { marginLeft, marginRight } = props.styles ?? {};
async function getScoreListByIds(ids) {
let { data } = await sheep.$api.app.scoreShop.ids({ ids });
return data;
}
onMounted(async () => {
state.scoreList = await getScoreListByIds(goodsIds.join(','));
if (mode === 1) {
mountMasonry();
}
});
// 加载瀑布流
let count = 0;
let leftHeight = 0;
let rightHeight = 0;
function mountMasonry(height = 0, where = 'left') {
if (!state.scoreList[count]) return;
if (where === 'left') leftHeight += height;
if (where === 'right') rightHeight += height;
if (leftHeight <= rightHeight) {
state.leftScoreList.push(state.scoreList[count]);
} else {
state.rightScoreList.push(state.scoreList[count]);
}
count++;
}
// 购买按钮样式
const buyStyle = computed(() => {
if (buyNowStyle.mode == 1) {
// button
return {
background: `linear-gradient(to right, ${buyNowStyle.color1}, ${buyNowStyle.color2})`,
};
}
if (buyNowStyle.mode == 2) {
// image
return {
width: '54rpx',
height: '54rpx',
background: `url(${sheep.$url.cdn(buyNowStyle.src)}) no-repeat`,
backgroundSize: '100% 100%',
};
}
});
</script>
<style lang="scss" scoped>
.goods-md-wrap {
width: 100%;
}
.goods-list-box {
width: 50%;
box-sizing: border-box;
.left-list {
&:nth-last-child(1) {
margin-bottom: 0 !important;
}
}
}
.goods-box {
&:nth-last-of-type(1) {
margin-bottom: 0 !important;
}
}
.goods-md-box,
.goods-sl-box,
.goods-lg-box {
position: relative;
.cart-btn {
position: absolute;
bottom: 10rpx;
right: 20rpx;
z-index: 11;
height: 50rpx;
line-height: 50rpx;
padding: 0 20rpx;
border-radius: 25rpx;
font-size: 24rpx;
color: #fff;
}
}
</style>
@@ -1,459 +0,0 @@
<template>
<view>
<!-- md卡片竖向一行放两个图上内容下 -->
<view v-if="size === 'md'" class="md-goods-card ss-flex-col" :style="[elStyles]" @tap="onClick">
<image
class="md-img-box"
:src="sheep.$url.cdn(data.image)"
mode="widthFix"
@load="calculatePanelHeight"
></image>
<view
class="md-goods-content ss-flex-col ss-row-around ss-p-b-20 ss-p-t-20 ss-p-x-16"
:id="elId"
>
<view
v-if="goodsFields.title?.show"
class="md-goods-title ss-line-1"
:style="[{ color: titleColor, width: titleWidth ? titleWidth + 'rpx' : '' }]"
>
{{ data.title }}
</view>
<view
v-if="goodsFields.subtitle?.show"
class="md-goods-subtitle ss-m-t-16 ss-line-1"
:style="[{ color: subTitleColor }]"
>
{{ data.subtitle }}
</view>
<view class="ss-col-bottom">
<view
v-if="goodsFields.score_price?.show"
class="md-goods-price ss-m-t-16 font-OPPOSANS ss-m-r-10 ss-flex"
:style="[{ color: goodsFields.score_price.color }]"
>
<view>{{ Number(data.price[0]) > 0 ? '¥' + data.price[0] + '+' : '' }}</view>
<image
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
class="score-img"
></image>
{{ data.score }}
</view>
<view
v-if="goodsFields.price?.show && data.original_price > 0"
class="goods-origin-price ss-m-t-16 font-OPPOSANS ss-flex"
:style="[{ color: goodsFields.price.color }]"
>
<text class="price-unit ss-font-20">{{ priceUnit }}</text>
<view class="ss-m-l-8">{{ data.original_price }}</view>
</view>
</view>
<view class="ss-m-t-16 ss-flex ss-col-center ss-flex-wrap">
<view class="sales-text">{{ salesAndStock }}</view>
</view>
</view>
<slot name="cart">
<view class="cart-box ss-flex ss-col-center ss-row-center">
<image class="cart-icon" src="/static/img/shop/tabbar/category2.png" mode=""></image>
</view>
</slot>
</view>
<!-- lg卡片横向型一行放一个图片左内容右边 -->
<view
v-if="size === 'lg'"
class="lg-goods-card ss-flex ss-col-stretch"
:style="[elStyles]"
@tap="onClick"
>
<image class="lg-img-box" :src="sheep.$url.cdn(data.image)" mode="aspectFill"></image>
<view class="lg-goods-content ss-flex-1 ss-flex-col ss-row-between ss-p-b-10 ss-p-t-20">
<view class="ss-m-r-20">
<view
v-if="goodsFields.title?.show"
class="lg-goods-title ss-line-2"
:style="[{ color: titleColor }]"
>
{{ data.title }}
</view>
<view
v-if="goodsFields.subtitle?.show"
class="lg-goods-subtitle ss-m-t-10 ss-line-1"
:style="[{ color: subTitleColor }]"
>
{{ data.subtitle }}
</view>
</view>
<view>
<view class="ss-m-t-10">
<view
v-if="goodsFields.score_price?.show"
class="lg-goods-price ss-m-r-12 ss-flex ss-col-bottom font-OPPOSANS"
:style="[{ color: goodsFields.score_price.color }]"
>
<view>{{ Number(data.price[0]) > 0 ? '¥' + data.price[0] + '+' : '' }}</view>
<image
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
class="score-img"
></image>
{{ data.score }}
</view>
<view
v-if="goodsFields.price?.show && data.original_price > 0"
class="goods-origin-price ss-flex ss-col-bottom font-OPPOSANS"
:style="[{ color: goodsFields.price.color }]"
>
<text class="price-unit ss-font-20">{{ priceUnit }}</text>
<view class="ss-m-l-8">{{ data.original_price }}</view>
</view>
</view>
<view class="ss-m-t-16 ss-flex ss-col-center ss-flex-wrap">
<view class="sales-text">{{ salesAndStock }}</view>
</view>
</view>
</view>
<slot name="cart"
><view class="buy-box ss-flex ss-col-center ss-row-center">去兑换</view></slot
>
</view>
<!-- sl卡片竖向型一行放一个图片上内容下边 -->
<view v-if="size === 'sl'" class="sl-goods-card ss-flex-col" @tap="onClick">
<image class="sl-img-box" :src="sheep.$url.cdn(data.image)" mode="aspectFill"></image>
<view class="sl-goods-content ss-flex-col ss-row-between ss-p-b-20 ss-p-t-20">
<view class="ss-m-b-20">
<view class="sl-goods-title ss-line-1 ss-p-l-16 ss-p-r-16">
{{ data.title }}
</view>
<view v-if="data.subtitle" class="sl-goods-subtitle ss-p-l-16 ss-p-r-16 ss-m-t-16">
{{ data.subtitle }}
</view>
</view>
<view>
<slot name="activity">
<view
v-if="data.promos?.length"
class="tag-box ss-flex ss-col-center ss-flex-wrap ss-p-l-16 ss-p-r-16"
>
<view
class="activity-tag ss-m-r-10 ss-m-t-16"
v-for="item in data.promos"
:key="item.id"
>
{{ item.title }}
</view>
</view>
</slot>
<view class="ss-flex ss-col-bottom ss-p-l-16 ss-p-r-16 font-OPPOSANS">
<view class="sl-goods-price ss-m-r-12 ss-flex">
<view>{{ Number(data.price[0]) > 0 ? '¥' + data.price[0] + '+' : '' }}</view>
<image
:src="sheep.$url.static('/static/img/shop/goods/score1.svg')"
class="score-img"
></image>
<view>{{ data.score ? data.score : '' }}</view>
</view>
<view
v-if="data.original_price > 0"
class="goods-origin-price ss-m-t-16 font-OPPOSANS ss-flex"
>
<text class="price-unit ss-font-20"></text>
<view class="ss-m-l-8">{{ data.original_price }}</view>
</view>
</view>
<view class="ss-p-l-16 ss-p-r-16 ss-m-t-16 ss-flex ss-flex-wrap">
<view class="sales-text">{{ salesAndStock }}</view>
</view>
</view>
</view>
<slot name="cart"
><view class="buy-box ss-flex ss-col-center ss-row-center">去兑换</view></slot
>
</view>
</view>
</template>
<script setup>
import { computed, getCurrentInstance } from 'vue';
import sheep from '@/sheep';
import { formatSales } from '@/sheep/hooks/useGoods';
import { formatStock } from '@/sheep/hooks/useGoods';
import goodsCollectVue from '@/pages/user/goods-collect.vue';
/**
* 订单卡片
*
* @property {String} img - 图片
* @property {String} title - 标题
* @property {Number} titleWidth = 0 - 标题宽度,默认0,单位rpx
* @property {String} skuText - 规格
* @property {String | Number} score - 积分
* @property {String | Number} price - 价格
* @property {String | Number} originalPrice - 单购价
* @property {String} priceColor - 价格颜色
* @property {Number | String} num - 数量
*
*/
const props = defineProps({
goodsFields: {
type: [Array, Object],
default() {
return {
title: { show: true },
subtitle: { show: true },
price: { show: true },
original_price: { show: true },
sales: { show: true },
stock: { show: true },
};
},
},
tagStyle: {
type: Object,
default: {},
},
data: {
type: Object,
default: {},
},
size: {
type: String,
default: 'sl',
},
background: {
type: String,
default: '',
},
topRadius: {
type: Number,
default: 0,
},
bottomRadius: {
type: Number,
default: 0,
},
titleWidth: {
type: Number,
default: 0,
},
titleColor: {
type: String,
default: '#333',
},
priceUnit: {
type: String,
default: '¥',
},
subTitleColor: {
type: String,
default: '#999999',
},
});
// 组件样式
const elStyles = computed(() => {
return {
background: props.background,
'border-top-left-radius': props.topRadius + 'px',
'border-top-right-radius': props.topRadius + 'px',
'border-bottom-left-radius': props.bottomRadius + 'px',
'border-bottom-right-radius': props.bottomRadius + 'px',
};
});
const emits = defineEmits(['click', 'getHeight']);
const onClick = () => {
emits('click');
};
// 格式化销量、库存信息
const salesAndStock = computed(() => {
let text = [];
text.push(formatSales(props.data.sales_show_type, props.data.sales));
text.push(formatStock(props.data.stock_show_type, props.data.stock));
return text.join(' | ');
});
// 获取实时卡片高度
const { proxy } = getCurrentInstance();
const elId = `sheep_${Math.ceil(Math.random() * 10e5).toString(36)}`;
function calculatePanelHeight(e) {
if (props.size === 'md') {
const view = uni.createSelectorQuery().in(proxy);
view.select(`#${elId}`).fields({ size: true, scrollOffset: true });
view.exec((data) => {
const goodsPriceCard = data[0];
const card = {
width: goodsPriceCard.width,
height: (goodsPriceCard.width / e.detail.width) * e.detail.height + goodsPriceCard.height,
};
emits('getHeight', card.height);
});
}
}
</script>
<style lang="scss" scoped>
.price-unit {
margin-right: -4px;
}
.sales-text {
display: table;
font-size: 24rpx;
transform: scale(0.8);
margin-left: -16rpx;
color: #c4c4c4;
}
// md
.md-goods-card {
overflow: hidden;
width: 100%;
position: relative;
z-index: 1;
background-color: $white;
position: relative;
.md-img-box {
width: 100%;
}
.md-goods-title {
font-size: 26rpx;
color: #333;
width: 100%;
}
.md-goods-subtitle {
font-size: 24rpx;
font-weight: 400;
color: #999999;
}
.md-goods-price {
font-size: 30rpx;
color: $red;
line-height: 36rpx;
}
.cart-box {
width: 54rpx;
height: 54rpx;
background: linear-gradient(90deg, #fe8900, #ff5e00);
border-radius: 50%;
position: absolute;
bottom: 50rpx;
right: 20rpx;
z-index: 2;
.cart-icon {
width: 30rpx;
height: 30rpx;
}
}
}
// lg
.lg-goods-card {
overflow: hidden;
position: relative;
z-index: 1;
background-color: $white;
height: 280rpx;
.lg-img-box {
width: 280rpx;
height: 280rpx;
margin-right: 20rpx;
}
.lg-goods-title {
font-size: 28rpx;
font-weight: 500;
color: #333333;
// line-height: 36rpx;
// width: 410rpx;
}
.lg-goods-subtitle {
font-size: 24rpx;
font-weight: 400;
color: #999999;
line-height: 30rpx;
// width: 410rpx;
}
.lg-goods-price {
font-size: 30rpx;
color: $red;
line-height: 36rpx;
}
.buy-box {
position: absolute;
bottom: 20rpx;
right: 20rpx;
z-index: 2;
width: 120rpx;
height: 50rpx;
background: linear-gradient(90deg, var(--ui-BG-Main), var(--ui-BG-Main-gradient));
border-radius: 25rpx;
font-size: 24rpx;
color: #ffffff;
}
.tag-box {
width: 100%;
}
}
.sl-goods-card {
overflow: hidden;
position: relative;
z-index: 1;
width: 100%;
background-color: $white;
.sl-img-box {
width: 100%;
height: 360rpx;
}
.sl-goods-title {
font-size: 26rpx;
color: #333;
width: 100%;
box-sizing: border-box;
}
.sl-goods-subtitle {
font-size: 24rpx;
font-weight: 400;
color: #999999;
line-height: 30rpx;
width: 100%;
box-sizing: border-box;
}
.sl-goods-price {
font-size: 30rpx;
color: $red;
}
.buy-box {
position: absolute;
bottom: 20rpx;
right: 20rpx;
z-index: 2;
width: 148rpx;
height: 50rpx;
background: linear-gradient(90deg, #fe8900, #ff5e00);
border-radius: 25rpx;
font-size: 24rpx;
color: #ffffff;
}
}
.goods-origin-price {
font-size: 20rpx;
color: #c4c4c4;
text-decoration: line-through;
}
.score-img {
width: 36rpx;
height: 36rpx;
margin: 0 4rpx;
}
</style>
+1 -1
View File
@@ -1,5 +1,5 @@
<template>
<view class="status_bar"></view>
<view class="status_bar" />
</template>
<style>
@@ -2,36 +2,29 @@
<template>
<view
class="ss-title-wrap ss-flex ss-col-center"
:class="[state.typeMap[data.location]]"
:class="[state.typeMap[data.textAlign]]"
:style="[elStyles]"
>
<view class="title-content">
<view v-if="data.title.text" class="title-text" :style="[titleStyles]">{{
data.title.text
}}</view>
<view v-if="data.subtitle.text" :style="[subtitleStyles]" class="sub-title-text">
{{ data.subtitle.text }}
</view>
<!-- 主标题 -->
<view v-if="data.title" class="title-text" :style="[titleStyles]">{{ data.title }}</view>
<!-- 副标题 -->
<view v-if="data.description" :style="[descStyles]" class="sub-title-text">{{ data.description }}</view>
</view>
<view v-if="data.more.show" class="more-box ss-flex ss-col-center" @tap="sheep.$router.go(data.more.url)">
<view class="more-text">查看更多</view>
<text class="_icon-forward"></text>
<!-- 查看更多 -->
<view v-if="data.more?.show" class="more-box ss-flex ss-col-center" @tap="sheep.$router.go(data.more.url)"
:style="{color: data.descriptionColor}">
<view class="more-text" v-if="data.more.type !== 'icon'">{{ data.more.text }} </view>
<text class="_icon-forward" v-if="data.more.type !== 'text'"></text>
</view>
</view>
</template>
<script setup>
/**
*
* 标题栏
*
* @property {String} title - 标题
* @property {String} subTitle - 副标题
* @property {Number} height - 高度
* @property {String} Type = [left | right | center | between] - 样式
*
*/
import { computed, reactive } from 'vue';
import { reactive } from 'vue';
import sheep from '@/sheep';
// 数据
@@ -52,35 +45,28 @@
type: Object,
default() {},
},
height: {
type: Number,
default: 100,
},
});
// 组件样式
const elStyles = {
background: `url(${sheep.$url.cdn(props.data.src)}) no-repeat top center / 100% auto`,
height: props.styles.height + 'px',
fontStyle: props.data.title.other.includes('italic') ? 'italic' : 'normal',
fontWeight: props.data.title.other.includes('bold') ? 'bold' : '',
background: `url(${sheep.$url.cdn(props.data.bgImgUrl)}) no-repeat top center / 100% auto`,
fontSize: `${props.data.titleSize}px`,
fontWeight: `${props.data.titleWeight}px`,
};
// 标题样式
const titleStyles = {
color: props.data.title.color,
fontSize: props.data.title.textFontSize + 'px',
textAlign: props.data.location,
marginLeft: props.data.skew + 'px',
color: props.data.titleColor,
fontSize: `${props.data.titleSize}px`,
textAlign: props.data.textAlign
};
// 副标题
const subtitleStyles = {
color: props.data.subtitle.color,
fontSize: props.data.subtitle.textFontSize + 'px',
textAlign: props.data.location,
fontStyle: props.data.subtitle.other.includes('italic') ? 'italic' : 'normal',
fontWeight: props.data.subtitle.other.includes('bold') ? 'bold' : '',
const descStyles = {
color: props.data.descriptionColor,
textAlign: props.data.textAlign,
fontSize: `${props.data.descriptionSize}px`,
fontWeight: `${props.data.descriptionWeight}px`,
};
</script>
+178 -20
View File
@@ -1,6 +1,7 @@
import { ref } from 'vue';
import dayjs from 'dayjs';
import $url from '@/sheep/url';
import { formatDate } from '@/sheep/util';
/**
* 格式化销量
@@ -9,7 +10,7 @@ import $url from '@/sheep/url';
* @return {string} 格式化后的销量字符串
*/
export function formatSales(type, num) {
let prefix = type!=='exact' && num<10 ? '销量': '已售';
let prefix = type !== 'exact' && num < 10 ? '销量' : '已售';
return formatNum(prefix, type, num)
}
@@ -65,6 +66,7 @@ export function formatPrice(e) {
// 视频格式后缀列表
const VIDEO_SUFFIX_LIST = ['.avi', '.mp4']
/**
* 转换商品轮播的链接列表:根据链接的后缀,判断是视频链接还是图片链接
*
@@ -74,7 +76,7 @@ const VIDEO_SUFFIX_LIST = ['.avi', '.mp4']
export function formatGoodsSwiper(urlList) {
return urlList.map((url, key) => {
const isVideo = VIDEO_SUFFIX_LIST.some(suffix => url.includes(suffix));
const type = isVideo ? 'video' :'image'
const type = isVideo ? 'video' : 'image'
const src = $url.cdn(url);
return { type, src }
});
@@ -82,26 +84,182 @@ export function formatGoodsSwiper(urlList) {
/**
* 格式化订单状态的颜色
* @param type 订单类型
*
* @param order 订单
* @return {string} 颜色的 class 名称
*/
export function formatOrderColor(type) {
switch (type) {
case 'apply_refund':
case 'groupon_ing':
case 'nocomment':
case 'noget':
case 'nosend':
return 'warning-color';
case 'closed':
case 'groupon_invalid':
case 'cancel':
case 'refund_agree':
return 'danger-color';
case 'completed':
return 'success-color';
case 'unpaid':
return 'info-color';
export function formatOrderColor(order) {
if (order.status === 0) {
return 'info-color';
}
if (order.status === 10
|| order.status === 20
|| (order.status === 30 && !order.commentStatus)) {
return 'warning-color';
}
if (order.status === 30 && order.commentStatus) {
return 'success-color';
}
return 'danger-color';
}
/**
* 格式化订单状态
*
* @param order 订单
*/
export function formatOrderStatus(order) {
if (order.status === 0) {
return '待付款';
}
if (order.status === 10 && order.deliveryType === 1) {
return '待发货';
}
if (order.status === 10 && order.deliveryType === 2) {
return '待核销';
}
if (order.status === 20) {
return '待收货';
}
if (order.status === 30 && !order.commentStatus) {
return '待评价';
}
if (order.status === 30 && order.commentStatus) {
return '已完成';
}
return '已关闭';
}
/**
* 格式化订单状态的描述
*
* @param order 订单
*/
export function formatOrderStatusDescription(order) {
if (order.status === 0) {
return `请在 ${ formatDate(orderInfo.payExpireTime) } 前完成支付`;
}
if (order.status === 10) {
return '商家未发货,请耐心等待';
}
if (order.status === 20) {
return '商家已发货,请耐心等待';
}
if (order.status === 30 && !order.commentStatus) {
return '已收货,快去评价一下吧';
}
if (order.status === 30 && order.commentStatus) {
return '交易完成,感谢您的支持';
}
return '交易关闭';
}
/**
* 处理订单的 button 操作按钮数组
*
* @param order 订单
*/
export function handleOrderButtons(order) {
order.buttons = []
if (order.type === 3) { // 查看拼团
order.buttons.push('combination');
}
if (order.status === 20) { // 确认收货
order.buttons.push('confirm');
}
if (order.logisticsId > 0) { // 查看物流
order.buttons.push('express');
}
if (order.status === 0) { // 取消订单 / 发起支付
order.buttons.push('cancel');
order.buttons.push('pay');
}
if (order.status === 30 && !order.commentStatus) { // 发起评价
order.buttons.push('comment');
}
if (order.status === 40) { // 删除订单
order.buttons.push('delete');
}
}
/**
* 格式化售后状态
*
* @param afterSale 售后
*/
export function formatAfterSaleStatus(afterSale) {
if (afterSale.status === 10) {
return '申请售后';
}
if (afterSale.status === 20) {
return '商品待退货';
}
if (afterSale.status === 30) {
return '商家待收货';
}
if (afterSale.status === 40) {
return '等待退款';
}
if (afterSale.status === 50) {
return '退款成功';
}
if (afterSale.status === 61) {
return '买家取消';
}
if (afterSale.status === 62) {
return '商家拒绝';
}
if (afterSale.status === 63) {
return '商家拒收货';
}
return '未知状态';
}
/**
* 格式化售后状态的描述
*
* @param afterSale 售后
*/
export function formatAfterSaleStatusDescription(afterSale) {
if (afterSale.status === 10) {
return '退款申请待商家处理';
}
if (afterSale.status === 20) {
return '请退货并填写物流信息';
}
if (afterSale.status === 30) {
return '退货退款申请待商家处理';
}
if (afterSale.status === 40) {
return '等待退款';
}
if (afterSale.status === 50) {
return '退款成功';
}
if (afterSale.status === 61) {
return '退款关闭';
}
if (afterSale.status === 62) {
return `商家不同意退款申请,拒绝原因:${afterSale.auditReason}`;
}
if (afterSale.status === 63) {
return `商家拒绝收货,不同意退款,拒绝原因:${afterSale.auditReason}`;
}
return '未知状态';
}
/**
* 处理售后的 button 操作按钮数组
*
* @param afterSale 售后
*/
export function handleAfterSaleButtons(afterSale) {
afterSale.buttons = [];
if ([10, 20, 30].includes(afterSale.status)) { // 取消订单
afterSale.buttons.push('cancel');
}
if (afterSale.status === 20) { // 退货信息
afterSale.buttons.push('delivery');
}
}
+18 -9
View File
@@ -6,7 +6,7 @@ import test from '@/sheep/helper/test.js';
import $api from '@/sheep/api';
// 打开授权弹框
export function showAuthModal(type = 'accountLogin') {
export function showAuthModal(type = 'smsLogin') {
const modal = $store('modal');
if (modal.auth !== '') {
closeAuthModal();
@@ -58,10 +58,9 @@ export function closeMenuTools() {
}
// 发送短信验证码 60秒
export function getSmsCode(event, mobile = '') {
export function getSmsCode(event, mobile) {
const modalStore = $store('modal');
const lastSendTimer = modalStore.lastTimer[event];
if (typeof lastSendTimer === 'undefined') {
$helper.toast('短信发送事件错误');
return;
@@ -69,26 +68,36 @@ export function getSmsCode(event, mobile = '') {
const duration = dayjs().unix() - lastSendTimer;
const canSend = duration >= 60;
if (!canSend) {
$helper.toast('请稍后再试');
return;
}
if (!test.mobile(mobile)) {
// 只有 mobile 非空时才校验。因为部分场景(修改密码),不需要输入手机
if (mobile && !test.mobile(mobile)) {
$helper.toast('手机号码格式不正确');
return;
}
// 发送验证码 + 更新上次发送验证码时间
$api.app.sendSms({ mobile, event }).then((res) => {
if (res.error === 0) {
let scene = -1;
switch (event) {
case 'resetPassword':
scene = 4;
break;
case 'changePassword':
scene = 3;
break;
case 'smsLogin':
scene = 1;
break;
}
$api.AuthUtil.sendSmsCode(mobile, scene).then((res) => {
if (res.code === 0) {
modalStore.$patch((state) => {
state.lastTimer[event] = dayjs().unix();
});
}
});
}
// 获取短信验证码倒计时 -- 60秒
+99 -33
View File
@@ -3,19 +3,20 @@ import sheep from '@/sheep';
import $wxsdk from '@/sheep/libs/sdk-h5-weixin';
// #endif
import { getRootUrl } from '@/sheep/helper';
import PayOrderApi from '@/sheep/api/pay/order';
/**
* 支付
*
* @param {String} payment = ['wechat','alipay','wallet','offline'] - 支付方式
* @param {String} orderType = ['goods','recharge','groupon'] - 订单类型
* @param {String} orderSN - 订单号
* @param {String} id - 订单号
*/
export default class SheepPay {
constructor(payment, orderType, orderSN) {
constructor(payment, orderType, id) {
this.payment = payment;
this.orderSN = orderSN;
this.id = id;
this.orderType = orderType;
this.payAction();
}
@@ -29,8 +30,8 @@ export default class SheepPay {
alipay: () => {
this.redirectPay(); // 现在公众号可以直接跳转支付宝页面
},
money: () => {
this.moneyPay();
wallet: () => {
this.walletPay();
},
offline: () => {
this.offlinePay();
@@ -43,8 +44,8 @@ export default class SheepPay {
alipay: () => {
this.copyPayLink();
},
money: () => {
this.moneyPay();
wallet: () => {
this.walletPay();
},
offline: () => {
this.offlinePay();
@@ -57,8 +58,8 @@ export default class SheepPay {
alipay: () => {
this.alipay();
},
money: () => {
this.moneyPay();
wallet: () => {
this.walletPay();
},
offline: () => {
this.offlinePay();
@@ -71,8 +72,8 @@ export default class SheepPay {
alipay: () => {
this.redirectPay();
},
money: () => {
this.moneyPay();
wallet: () => {
this.walletPay();
},
offline: () => {
this.offlinePay();
@@ -83,18 +84,21 @@ export default class SheepPay {
}
// 预支付
prepay() {
prepay(channel) {
return new Promise((resolve, reject) => {
let data = {
order_sn: this.orderSN,
payment: this.payment,
id: this.id,
channelCode: channel,
channelExtras: {}
};
if (uni.getStorageSync('openid')) {
data.openid = uni.getStorageSync('openid');
}
sheep.$api.pay.prepay(data).then((res) => {
res.error === 0 && resolve(res);
if (res.error === -1 && res.msg === 'miss_openid') {
PayOrderApi.submitOrder(data).then((res) => {
// 成功时
res.code === 0 && resolve(res);
// 失败时
if (res.code !== 0 && res.msg === 'miss_openid') {
uni.showModal({
title: '微信支付',
content: '请先绑定微信再使用微信支付',
@@ -109,7 +113,7 @@ export default class SheepPay {
});
}
// #ifdef H5
// 微信公众号JSSDK支付
// 微信公众号JSSDK支付 TODO 芋艿:待接入
async wechatOfficialAccountPay() {
let that = this;
let { error, data, msg } = await this.prepay();
@@ -130,21 +134,21 @@ export default class SheepPay {
});
}
//浏览器微信H5支付
//浏览器微信H5支付 TODO 芋艿:待接入
async wechatWapPay() {
const { error, data } = await this.prepay();
if (error === 0) {
const redirect_url = `${getRootUrl()}pages/pay/result?orderSN=${this.orderSN}&payment=${this.payment
const redirect_url = `${getRootUrl()}pages/pay/result?id=${this.id}&payment=${this.payment
}&orderType=${this.orderType}`;
location.href = `${data.pay_data.h5_url}&redirect_url=${encodeURIComponent(redirect_url)}`;
}
}
// 支付链接
// 支付链接 TODO 芋艿:待接入
async redirectPay() {
let { error, data } = await this.prepay();
if (error === 0) {
const redirect_url = `${getRootUrl()}pages/pay/result?orderSN=${this.orderSN}&payment=${this.payment
const redirect_url = `${getRootUrl()}pages/pay/result?id=${this.id}&payment=${this.payment
}&orderType=${this.orderType}`;
location.href = data.pay_data + encodeURIComponent(redirect_url);
}
@@ -152,7 +156,7 @@ export default class SheepPay {
// #endif
// 微信小程序支付
// 微信小程序支付 TODO 芋艿:待接入
async wechatMiniProgramPay() {
let that = this;
let result = await this.prepay();
@@ -173,18 +177,18 @@ export default class SheepPay {
}
// 余额支付
async moneyPay() {
const { error } = await this.prepay();
error === 0 && this.payResult('success');
async walletPay() {
const { code } = await this.prepay('wallet');
code === 0 && this.payResult('success');
}
// 货到付款
// 货到付款 TODO 芋艿:待接入
async offlinePay() {
const { error } = await this.prepay();
error === 0 && this.payResult('success');
}
// 支付宝复制链接支付
// 支付宝复制链接支付 TODO 芋艿:待接入
async copyPayLink() {
let that = this;
let { error, data } = await this.prepay();
@@ -203,7 +207,7 @@ export default class SheepPay {
}
}
// 支付宝支付
// 支付宝支付 TODO 芋艿:待接入
async alipay() {
let that = this;
const { error, data } = await this.prepay();
@@ -225,7 +229,7 @@ export default class SheepPay {
}
}
// 微信支付
// 微信支付 TODO 芋艿:待接入
async wechatAppPay() {
let that = this;
let { error, data } = await this.prepay();
@@ -246,10 +250,72 @@ export default class SheepPay {
// 支付结果跳转,success:成功,fail:失败
payResult(resultType) {
sheep.$router.redirect('/pages/pay/result', {
orderSN: this.orderSN,
payment: this.payment, //重新支付的时候使用
payState: resultType,
id: this.id,
orderType: this.orderType,
payState: resultType
});
}
}
export function getPayMethods(channels) {
const payMethods = [
{
icon: '/static/img/shop/pay/wechat.png',
title: '微信支付',
value: 'wechat',
disabled: true,
},
{
icon: '/static/img/shop/pay/alipay.png',
title: '支付宝支付',
value: 'alipay',
disabled: true,
},
{
icon: '/static/img/shop/pay/wallet.png',
title: '余额支付',
value: 'wallet',
disabled: true,
},
{
icon: '/static/img/shop/pay/apple.png',
title: 'Apple Pay',
value: 'apple',
disabled: true,
},
{
icon: '/static/img/shop/pay/wallet.png',
title: '模拟支付',
value: 'mock',
disabled: true,
}
];
const platform = sheep.$platform.name
// 1. 处理【微信支付】
const wechatMethod = payMethods[0];
if ((platform === 'WechatOfficialAccount' && channels.includes('wx_pub'))
|| platform === 'WechatMiniProgram' && channels.includes('wx_lite')
|| platform === 'App' && channels.includes('wx_app')) {
wechatMethod.disabled = false;
}
// 2. 处理【支付宝支付】
const alipayMethod = payMethods[1];
if ((platform === 'WechatOfficialAccount' && channels.includes('alipay_wap'))
|| platform === 'WechatMiniProgram' && channels.includes('alipay_wap')
|| platform === 'App' && channels.includes('alipay_app')) {
alipayMethod.disabled = false;
}
// 3. 处理【余额支付】
const walletMethod = payMethods[2];
if (channels.includes('wallet')) {
walletMethod.disabled = false;
}
// 4. 处理【苹果支付】TODO 芋艿:未来接入
// 5. 处理【模拟支付】
const mockMethod = payMethods[4];
if (channels.includes('mock')) {
mockMethod.disabled = false;
}
return payMethods;
}
+8 -5
View File
@@ -94,6 +94,7 @@ http.interceptors.request.use(
if (config.url.indexOf('/app-api/') !== -1) {
config.header['Accept'] = '*/*'
config.header['tenant-id'] = '1';
config.header['terminal'] = '20';
config.header['Authorization'] = 'Bearer test247';
}
return config;
@@ -112,9 +113,10 @@ http.interceptors.response.use(
if (response.header.authorization || response.header.Authorization) {
$store('user').setToken(response.header.authorization || response.header.Authorization);
}
// TODO 芋艿:如果是登录的 API,则自动设置 token
response.config.custom.showLoading && closeLoading();
if (response.data.error !== 0) {
if (response.data.error !== 0 && response.data.code !== 0) {
if (response.config.custom.showError)
uni.showToast({
title: response.data.msg || '服务器开小差啦,请稍后再试~',
@@ -123,9 +125,10 @@ http.interceptors.response.use(
});
return Promise.resolve(response.data);
}
// 成功时的提示
if (
response.data.error === 0 &&
response.data.msg !== '' &&
(response.data.error === 0 || response.data.code === 0) &&
( response.data.msg !== '' || response.config.custom.successMsg !== '' ) &&
response.config.custom.showSuccess
) {
uni.showToast({
@@ -212,8 +215,8 @@ const request = (config) => {
}
// TODO 芋艿:额外拼接
if (config.url.indexOf('/app-api/') >= 0) {
config.url = 'http://api-dashboard.yudao.iocoder.cn' + config.url; // 调用【云端】
// config.url = 'http://127.0.0.1:48080' + config.url; // 调用【本地】
// config.url = 'http://api-dashboard.yudao.iocoder.cn' + config.url; // 调用【云端】
config.url = 'http://127.0.0.1:48080' + config.url; // 调用【本地】
}
return http.middleware(config);
};
+4 -3
View File
@@ -95,7 +95,8 @@ http.interceptors.request.use(
if (config.url.indexOf('/app-api/') !== -1) {
config.header['Accept'] = '*/*'
config.header['tenant-id'] = '1';
config.header['Authorization'] = 'Bearer test247';
config.header['terminal'] = '20';
config.header['Authorization'] = 'Bearer test247';
}
return config;
},
@@ -214,9 +215,9 @@ const request = (config) => {
// TODO 芋艿:额外拼接
if (config.url.indexOf('/app-api/') >= 0) {
// 设置接口地址
config.url = 'http://api-dashboard.yudao.iocoder.cn' + config.url; // 调用【云端】
// config.url = 'http://api-dashboard.yudao.iocoder.cn' + config.url; // 调用【云端】
// config.url = 'https://app.test.huizhizao.vip/prod-api' + config.url; // 调用【云端】
// config.url = 'http://127.0.0.1:48080' + config.url; // 调用【本地】
config.url = 'http://127.0.0.1:48080' + config.url; // 调用【本地】
}
return http.middleware(config);
};
+48 -53
View File
@@ -1,98 +1,93 @@
import { defineStore } from 'pinia';
import cartApi from '@/sheep/api/cart';
import CartApi from '@/sheep/api/trade/cart';
const cart = defineStore({
id: 'cart',
state: () => ({
list: [], // 购物车列表
selectedIds: [], // 已选列表
isAllSelected: false, //是否全选
cartSelectedTotalPrice: '0.00', // 选中项总金额
isAllSelected: false, // 是否全选
totalPriceSelected: 0, // 选中项总金额
}),
getters: {
totalPriceSelected: (state) => {
let price = 0;
if (!state.selectedIds.length) return price.toFixed(2);
state.list.forEach((item) => {
price += state.selectedIds.includes(item.id)
? Number(item.sku.price/100) * item.count
: 0;
});
return price.toFixed(2);
},
},
actions: {
// 获取购物车列表
async getList() {
const { data, code } = await cartApi.list();
const { data, code } = await CartApi.getCartList();
if (code === 0) {
this.list = data.validList;
// 计算各种关联属性
this.selectedIds = [];
this.isAllSelected = true;
this.totalPriceSelected = 0;
this.list.forEach((item) => {
if (item.selected) {
this.selectedIds.push(item.id);
this.totalPriceSelected += item.count * item.sku.price;
} else {
this.isAllSelected = false;
}
});
}
},
// 添加购物车
async add(goodsInfo) {
const { error } = await cartApi.append({
goods_id: goodsInfo.goods_id,
goods_num: goodsInfo.goods_num,
goods_sku_price_id: goodsInfo.id,
// 添加购物项
const { code } = await CartApi.addCart({
skuId: goodsInfo.id,
count: goodsInfo.goods_num,
});
if (error === 0) {
this.getList();
// 刷新购物车列表
if (code === 0) {
await this.getList();
}
},
// 更新购物车
async update(goodsInfo) {
const { error } = await cartApi.update({
const { code } = await CartApi.updateCartCount({
id: goodsInfo.goods_id,
count: goodsInfo.goods_num,
goods_sku_price_id: goodsInfo.goods_sku_price_id,
});
if (error === 0) {
// this.getList();
if (code === 0) {
await this.getList();
}
},
// 移除购物车
async delete(ids) {
if (typeof ids === 'array') {
ids = ids.join(',');
}
const { code } = await cartApi.delete(ids);
const { code } = await CartApi.deleteCart(ids.join(','));
if (code === 0) {
this.selectAll(false);
this.getList();
await this.getList();
}
},
// 选购物车商品
selectSingle(goodsId) {
if (!this.selectedIds.includes(goodsId)) {
this.selectedIds.push(goodsId);
} else {
this.selectedIds.splice(this.selectedIds.indexOf(goodsId), 1);
// 选购物车商品
async selectSingle(goodsId) {
const { code } = await CartApi.updateCartSelected({
ids: [goodsId],
selected: !this.selectedIds.includes(goodsId), // 取反
});
if (code === 0) {
await this.getList();
}
this.isAllSelected = this.selectedIds.length === this.list.length;
},
// 全选
selectAll(flag) {
this.isAllSelected = flag;
if (!flag) {
this.selectedIds = [];
} else {
this.list.forEach((item) => {
this.selectedIds.push(item.id);
});
// 全选购物车商品
async selectAll(flag) {
const { code } = await CartApi.updateCartSelected({
ids: this.list.map((item) => item.id),
selected: flag
});
if (code === 0) {
await this.getList();
}
},
// 清空购物车
emptyList() {
this.list = [];
this.selectedIds = [];
this.isAllSelected = false;
this.cartSelectedTotalPrice = '0.00';
async emptyList() {
await this.delete(this.list.map((item) => item.id));
},
},
persist: {
+2 -1
View File
@@ -13,10 +13,11 @@ const modal = defineStore({
smsRegister: 0,
changeMobile: 0,
resetPassword: 0,
changePassword: 0,
}
}),
persist: {
enabled: true,
enabled: true,
strategies: [
{
key: 'modal-store',
+24 -15
View File
@@ -14,6 +14,7 @@ import app from './app';
import {
showAuthModal
} from '@/sheep/hooks/useModal';
import AuthUtil from '@/sheep/api/member/auth';
// 默认用户信息
const defaultUserInfo = {
@@ -51,6 +52,7 @@ const user = defineStore({
actions: {
// 获取个人信息
// TODO 芋艿:整理下;
async getInfo() {
const {
code,
@@ -58,20 +60,21 @@ const user = defineStore({
} = await userApi.profile();
// 为了兼容 获取用户余额 可能还会用到其他参数
// 优惠券数量,积分数量 应该在这里
// 优惠券数量,积分数量 应该在这里
const {
code: code2,
data: data2
} = await userApi.balance();
if (code !== 0 || code2 != 0) return;
data.money = data2.balance / 100;
data.money = data2.balance;
this.userInfo = data;
console.log(data2, '信息')
return Promise.resolve(data);
},
// 获取分销商信息
async getAgentInfo() {
// TODO 芋艿:整理下;
async getAgentInfo() {
const res = await commissionApi.agent();
if (res.error === 0) {
this.agentInfo = res.data;
@@ -80,7 +83,8 @@ const user = defineStore({
},
// 获取订单、优惠券等其他资产信息
async getNumData() {
// TODO 芋艿:整理下;
async getNumData() {
const {
code,
data
@@ -103,7 +107,8 @@ const user = defineStore({
},
// 添加分享记录
async addShareLog(params) {
// TODO 芋艿:整理下;
async addShareLog(params) {
const {
error
} = await userApi.addShareLog(params);
@@ -111,7 +116,8 @@ const user = defineStore({
},
// 设置token
setToken(token = '') {
// TODO 芋艿:整理下;
setToken(token = '') {
if (token === '') {
this.isLogin = false;
uni.removeStorageSync('token');
@@ -124,7 +130,8 @@ const user = defineStore({
},
// 更新用户相关信息 (手动限流 5秒之内不刷新)
async updateUserData() {
// TODO 芋艿:整理下;
async updateUserData() {
if (!this.isLogin) {
this.resetUserData();
return;
@@ -138,7 +145,8 @@ const user = defineStore({
},
// 重置用户默认数据
resetUserData() {
// TODO 芋艿:整理下;
resetUserData() {
this.setToken();
this.userInfo = clone(defaultUserInfo);
this.numData = cloneDeep(defaultNumData);
@@ -147,7 +155,8 @@ const user = defineStore({
},
// 登录后
async loginAfter() {
// TODO 芋艿:整理下;
async loginAfter() {
await this.updateUserData();
cart().getList();
// 登录后设置全局分享参数
@@ -158,7 +167,8 @@ const user = defineStore({
// }
// 添加分享记录
const shareLog = uni.getStorageSync('shareLog');
// TODO 芋艿:整理下;
const shareLog = uni.getStorageSync('shareLog');
if (!isEmpty(shareLog)) {
this.addShareLog({
...shareLog,
@@ -167,12 +177,11 @@ const user = defineStore({
},
// 登出
async logout(force = false) {
// TODO 芋艿:整理下;
async logout(force = false) {
if (!force) {
const {
error
} = await userApi.logout();
if (error === 0) {
const { code } = AuthUtil.logout();
if (code === 0) {
this.resetUserData();
}
}
@@ -1,3 +1,4 @@
<!-- 省市区选择弹窗 -->
<template>
<su-popup :show="show" @close="onCancel" round="20">
<view class="ui-region-picker">
@@ -9,7 +10,7 @@
title="选择区域"
@cancel="onCancel"
@confirm="onConfirm('confirm')"
></su-toolbar>
/>
<view class="ui-picker-body">
<picker-view
:value="state.currentIndex"
+13
View File
@@ -99,4 +99,17 @@ export function handleTree(data, id = 'id', parentId = 'parentId', children = 'c
return father[parentId] === rootId;
});
return treeData !== '' ? treeData : data;
}
/**
* 重置分页对象
*
* TODO 芋艿:需要处理其它页面
*
* @param pagination 分页对象
*/
export function resetPagination(pagination) {
pagination.list = [];
pagination.total = 0;
pagination.pageNo = 1;
}
-29
View File
@@ -187,32 +187,6 @@ export const alipayAccount = {
],
};
export const consignee = {
rules: [
{
required: true,
errorMessage: '请输入收货人姓名',
},
],
};
export const region = {
rules: [
{
required: true,
errorMessage: '请选择您的位置',
},
],
};
export const address = {
rules: [
{
required: true,
errorMessage: '请输入详细地址',
},
],
};
export default {
mobile,
alipayAccount,
@@ -222,9 +196,6 @@ export default {
password,
code,
account,
consignee,
address,
region,
taxNo,
taxName,
};