first commit

This commit is contained in:
李志强 2025-08-06 17:17:48 +08:00
commit dc5fba137c
453 changed files with 85995 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
unpackage
node_modules/

26
.hbuilderx/launch.json Normal file
View File

@ -0,0 +1,26 @@
{
// launch.json configurations app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtypelocalremote, localremote
"version" : "0.0",
"configurations" : [
{
"app-plus" : {
"launchtype" : "remote"
},
"default" : {
"launchtype" : "remote"
},
"h5" : {
"launchtype" : "remote"
},
"mp-weixin" : {
"launchtype" : "remote"
},
"type" : "uniCloud"
},
{
"playground" : "standard",
"type" : "uni-app:app-android"
}
]
}

93
App.vue Normal file
View File

@ -0,0 +1,93 @@
<script>
import { mapMutations, mapActions } from "vuex";
import { inputInviteCode } from "@/api/user";
import { userShare, getConfig } from "@/api/app";
import Cache from "@/utils/cache";
import { strToParams, showModal, setTabbar } from "@/utils/tools";
import { wxMnpLogin } from "@/utils/login";
export default {
globalData: {
navHeight: "",
},
onLaunch: async function (options) {
uni.hideTabBar({
animation: false,
});
//
this.getConfigFun();
this.getUser();
//
this.getShareInfo();
//
this.getSystemInfo();
},
onShow: function (options) {
//
this.bindCode(options);
},
onHide: function () {
console.log("App Hide");
},
methods: {
...mapMutations(["SETCONFIG"]),
...mapActions(["getUser"]),
getSystemInfo() {
uni.getSystemInfo({
success: (res) => {
let { statusBarHeight, platform } = res;
let navHeight;
if (platform == "ios" || platform == "devtools") {
navHeight = statusBarHeight + 44;
} else {
navHeight = statusBarHeight + 48;
}
this.globalData.navHeight = navHeight;
},
fail(err) {
console.log(err);
},
});
},
async getShareInfo() {
const { code, data } = await userShare();
if (code == 1) {
Cache.set("shareInfo", data);
}
},
async getConfigFun() {
try {
const { code, data } = await getConfig();
if (code == 1) {
this.SETCONFIG(data);
setTabbar();
}
} catch (e) {
uni.showTabBar();
}
},
bindCode(options) {
if (!options.query) return;
let invite_code =
options.query.invite_code ||
strToParams(decodeURIComponent(options.query.scene)).invite_code;
if (invite_code) {
inputInviteCode({
code: invite_code,
}).then((res) => {
if (res.code == -1) {
Cache.set("INVITE_CODE", invite_code);
}
});
}
},
},
};
</script>
<style lang="scss">
@import "styles/base.scss";
/*每个页面公共css */
@import "components/uview-ui/index.scss";
</style>

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Xaber
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

28
androidPrivacy.json Normal file
View File

@ -0,0 +1,28 @@
{
"version" : "1",
"prompt" : "template",
"title" : "用户协议和隐私政策",
"message" : "  请你务必审慎阅读、充分理解“用户协议”和“隐私政策”各条款,包括但不限于:为了更好的向你提供服务,我们需要收集你的设备标识、操作日志等信息用于分析、优化应用性能。<br/>  你可阅读<a href=\"https://b2c.likeshop.cn/mobile/bundle/pages/server_explan/server_explan?type=0\">《用户协议》</a>和<a href=\"https://b2c.likeshop.cn/mobile/bundle/pages/server_explan/server_explan?type=1\">《隐私政策》</a>了解详细信息。如果你同意,请点击下面按钮开始接受我们的服务。",
"buttonAccept" : "同意并接受",
"buttonRefuse" : "暂不同意",
"hrefLoader" : "system|default",
"second" : {
"title" : "确认提示",
"message" : "  进入应用前,你需先同意<a href=\"https://b2c.likeshop.cn/mobile/bundle/pages/server_explan/server_explan?type=0\" >《用户协议》</a>和<a href=\"https://b2c.likeshop.cn/mobile/bundle/pages/server_explan/server_explan?type=1\">《隐私政策》</a>,否则将退出应用。",
"buttonAccept" : "同意并继续",
"buttonRefuse" : "退出应用"
},
"styles" : {
"backgroundColor" : "#ffffff",
"borderRadius" : "5px",
"title" : {
"color" : "#FF2C3C"
},
"buttonAccept" : {
"color" : "#FF2C3C"
},
"buttonRefuse" : {
"color" : "#545454"
}
}
}

98
api/activity.js Normal file
View File

@ -0,0 +1,98 @@
import request from '@/utils/request'
import {client} from '@/utils/tools'
//获取商品的优惠券
export function getGoodsCoupon(data) {
return request.get("coupon/getGoodsCoupon", {params: data});
}
//领券中心
export function getCouponList(data) {
return request.get("coupon/couponList", {params: data});
}
// 获取活动专区商品列表
export function getActivityGoodsLists(data) {
return request.get("activity_area/activityGoodsList", {params: data})
}
// 获取秒杀时间段
export function getSeckillTime() {
return request.get("seckill/seckillTime");
}
// 获取秒杀商品
export function getSeckillGoods(params) {
return request.get("seckill/seckillGoods", {params})
}
export function getGroupList(params) {
return request.get('team/teamGoodsList', {params});
}
//我的拼团
export function getUserGroup(params) {
return request.get('user/myTeam', {params});
}
//拼团详情
export function getTeamInfo(params) {
return request.get('team/teamInfo', {params});
}
//参与拼团验证
export function teamCheck(data) {
return request.post('team/check', data);
}
//拼团下单
export function teamBuy(data) {
return request.post("team/buy",data);
}
// 获取砍价列表
export function getBargainList(data) {
return request.get('bargain/lists', {params: data})
}
// 获取砍价详情
export function getBargainDetail(data) {
return request.get('bargain/detail', {params: data})
}
// 获取砍价成功人数
export function getBargainNumber() {
return request.get("bargain/barginNumber")
}
// 发起砍价
export function launchBargain(data) {
return request.post('bargain/sponsor', data)
}
// 获取砍价活动商品列表
export function getBargainActivityList(data) {
return request.get('bargain/orderList', {params: data})
}
// 砍价详情
export function getBargainActivityDetail(data) {
return request.get("bargain/bargainDetail", {params: data})
}
// 砍价海报
export function getBargainPost(data) {
return request.get("share/shareBargain", {params: data})
}
// 好友助力
export function helpBargain(data) {
return request.post('bargain/knife', data)
}
// 关闭结算订单
export function closeBargainOrder(data) {
return request.get("bargain/closeBargain", {params: data})
}

140
api/app.js Normal file
View File

@ -0,0 +1,140 @@
import request from "@/utils/request";
import wechath5 from "@/utils/wechath5";
import { client } from "@/utils/tools";
//小程序授权登录
export function authLogin(data) {
return request.post("account/authLogin", data);
}
//小程序静默登录
export function silentLogin(data) {
return request.post("account/silentLogin", data);
}
//更新小程序头像昵称
export function updateUser(data, token) {
return request.post("account/updateUser", data, { header: { token } });
}
// app登录
export function opLogin(data) {
return request.post("account/uinAppLogin", { ...data, client });
}
//预支付接口
export function prepay(data) {
return request.post("payment/prepay", { ...data, order_source: client });
}
//小程序订阅
export function getMnpNotice(data) {
return request.get("subscribe/lists", {
params: data,
});
}
//账号登录
export function accountLogin(data) {
return request.post("account/login", { ...data, client });
}
export function getWechatConfig() {
return request.get("wechat/config", {
url: encodeURIComponent(wechat.signLink()),
});
}
// 登录
export function wechatLogin(data) {
return request.post("account/oalogin", data);
}
// 获取获取向微信请求code的链接
export function getCodeUrl() {
return request.get("account/codeurl", {
params: {
url: encodeURIComponent(location.href),
},
});
}
//微信sdk配置
export function getJsconfig() {
return request.get("we_chat/jsconfig", {
params: {
url: encodeURIComponent(wechath5.signLink()),
},
});
}
// 忘记密码
export function forgetPwd(data) {
return request.post("login_password/forget", { ...data, client });
}
// 发送短信
export function sendSms(data) {
return request.post("sms/send", { ...data, client });
}
// Html5 注册账号
export function register(data) {
return request.post("account/register", { ...data, client });
}
// 获取服务协议
export function getServerProto() {
return request.get("policy/service");
}
// 获取隐私政策
export function getPrivatePolicy() {
return request.get("policy/privacy");
}
// 售后保障
export function getAfterSaleGuar() {
return request.get("policy/afterSale");
}
//客服
export function getService() {
return request.get("service/lists");
}
// 足迹气泡
export function getBubbleLists() {
return request.get("footprint/lists");
}
// 用户自定义分享
export function userShare(params) {
return request.get("index/share", {
params: {
...params,
client,
},
});
}
// 验证码登录
export function smsCodeLogin(data) {
return request.post("account/smsLogin", { ...data, client });
}
export function getConfig() {
return request.get("index/config");
}
// 注册赠送优惠券
export function getRegisterCoupon() {
return request.get("coupon/registerSendCoupon");
}
// 获取支付配置
export function getPayway(params) {
return request.get("payment/payway", { params });
}
// 获取微信小程序码-生成海报需使用
export function getShareMnQrcode(params) {
return request.get("share/getMnQrcode", { params });
}

29
api/new.js Normal file
View File

@ -0,0 +1,29 @@
import request from '@/utils/request'
import {client} from '@/utils/tools'
//文章分类
export function getCategoryList(data) {
let {type} = data
let url = type ? 'help/category' : 'article/category'
delete data.type
return request.get(url)
}
//文章列表
export function getArticleList(data) {
let {type} = data
let url = type ? 'help/lists' : 'article/lists'
delete data.type
return request.get(url, {
params: data
})
}
// 文章详情
export function getArticleDetail(data) {
let {type} = data
let url = type ? 'help/detail' : 'article/detail'
delete data.type
return request.get(url, {
params: { id: data.id }
})
}

85
api/order.js Normal file
View File

@ -0,0 +1,85 @@
import request from "@/utils/request";
import { client } from "@/utils/tools";
//下单
export function orderBuy(data) {
return request.post("order/buy", data);
}
//删除订单
export function delOrder(id) {
return request.post("order/del", {
id,
});
}
// 获取配送方式
export function getDelivery() {
return request.get("order/getDeliveryType");
}
//订单列表
export function getOrderList(data) {
return request.get("order/lists", {
params: data,
});
}
//订单详情
export function getOrderDetail(id) {
return request.get("order/detail", {
params: {
id,
},
});
}
//取消订单
export function cancelOrder(id) {
return request.post("order/cancel", {
id,
});
}
//物流
export function orderTraces(id) {
return request.get("order/orderTraces", {
params: {
id,
},
});
}
//确认收货
export function confirmOrder(id) {
return request.post("order/confirm", {
id,
});
}
//下单获取优惠券
export function getOrderCoupon(data) {
return request.post("coupon/orderCoupon", data);
}
// 核销订单
export function getVerifyLists(data) {
return request.get("order/verificationLists", {
params: data,
});
}
// 核销详情
export function verification(data) {
return request.post("order/verification", data);
}
// 确认核销
export function verificationConfirm(data) {
return request.post("order/verificationConfirm", data);
}
//确认收货组件
export function getwxReceiveDetail(params) {
return request.get("order/wxReceiveDetail", { params });
}
//查询确认收货
export function getwechatSyncCheck(params) {
return request.get("order/wechatSyncCheck", { params });
}

171
api/store.js Normal file
View File

@ -0,0 +1,171 @@
import request from '@/utils/request'
import {client} from '@/utils/tools'
//获取首页数据接口
export function getHome() {
return request.get('index/lists')
}
//获取菜单
export function getMenu(data) {
return request.get('menu/lists', {
params: data,
});
}
//广告位
export function getAdList(data) {
return request.get('ad_content/lists', {
params: data
});
}
// 购物车列表
export function getCartList() {
return request.get('cart/lists')
}
//获取好物优选商品列表
export function getBestList(data) {
return request.get('goods/getBestList', {
params: data
});
}
// 商品分类
export function getCatrgory() {
return request.get('goods_category/lists');
}
//商品详情
export function getGoodsDetail(data) {
return request.get('goods/getGoodsDetail', {
params: data
});
}
// 商品搜索
export function getGoodsSearch(data) {
return request.get('goods/getGoodsList', {
params: data
});
}
//搜索页,热门搜索列表,和历史搜索列表
export function getSearchpage(data) {
return request.get('goods/getSearchPage', {
params: data
});
}
// 清空历史搜索
export function clearSearch() {
return request.get('goods/clearSearch');
}
//评价列表
export function getCommentList(data) {
return request.get("goods_comment/lists", {
params: data
})
}
// 获取评价列表
export function getOrderCommentList(data) {
return request.get("goods_comment/getOrderGoods", {
params: data
})
}
// 购物车数量更改
export function changeGoodsCount(data) {
return request.post("cart/change", data)
}
// 单选/全选/店铺选择
export function selectedOpt(data) {
return request.post("cart/selected", data)
}
// 删除商品
export function deleteGoods(data) {
return request.post("cart/del", data);
}
//购物车选中状态
export function changeCartSelect(data) {
return request.post('cart/selected', data)
}
//评价分类
export function getCommentCategory(id) {
return request.get("/goods_comment/category", {
params: {
goods_id: id
}
})
}
//加入购物车
export function addCart(data) {
return request.post('cart/add', data);
}
//购物车数量
export function getCartNum(params) {
return request.get("cart/num", {params});
}
//获取商品热搜榜单
export function getHotGoods(data) {
return request.get("goods/getHostList", {params: data});
}
// 获取秒杀时间段
export function getSeckillTime() {
return request.get("/seckill/seckillTime");
}
// 获取秒杀商品
export function getSeckillGoods(params) {
return request.get("/seckill/seckillGoods", {params})
}
// 消息中心首页
export function getMessageLists() {
return request.get("notice/index")
}
// 消息通知
export function getNoticeLists(params) {
return request.get("notice/lists", {params})
}
//商品海报
export function getPoster(data) {
return request.get("share/sharegoods", {
params: data
});
}
// 门店自提列表
export function getStoreList(data) {
return request.get("selffetch_shop/lists", {
params: data
});
}
// 直播列表
export function getLiveRoom(data) {
return request.get("live_room/lists", {
params: data
});
}

394
api/user.js Normal file
View File

@ -0,0 +1,394 @@
// +----------------------------------------------------------------------
// | likeshop开源商城系统
// +----------------------------------------------------------------------
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
// | gitee下载https://gitee.com/likeshop_gitee
// | github下载https://github.com/likeshop-github
// | 访问官网https://www.likeshop.cn
// | 访问社区https://home.likeshop.cn
// | 访问手册http://doc.likeshop.cn
// | 微信公众号likeshop技术社区
// | likeshop系列产品在gitee、github等公开渠道开源版本可免费商用未经许可不能去除前后端官方版权标识
// | likeshop系列产品收费版本务必购买商业授权购买去版权授权后方可去除前后端官方版权标识
// | 禁止对系统程序代码以任何目的,任何形式的再发布
// | likeshop团队版权所有并拥有最终解释权
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import request from '../utils/request'
import { client } from '@/utils/tools'
//个人中心
export function getUser() {
return request.get('user/center')
}
//用户领取优惠券
export function getCoupon(id) {
return request.post('coupon/getCoupon', { id })
}
// 地址列表
export function getAddressLists() {
return request.get('user_address/lists')
}
// 添加编辑地址
export function editAddress(data) {
return request.post('user_address/update', data)
}
export function addAddress(data) {
return request.post('user_address/add', data)
}
// 删除地址
export function delAddress(id) {
return request.post('user_address/del', { id })
}
// 获取单个地址
export function getOneAddress(id) {
return request.get('user_address/detail', { params: { id } })
}
// 获取默认地址
export function getDefaultAddress(id) {
return request.get('user_address/getDefault', { params: { id } })
}
// 设置默认地址
export function setDefaultAddress(id) {
return request.post('user_address/setDefault', { id })
}
//传省市区字符串判读是否有code
export function hasRegionCode(data) {
return request.post('user_address/handleRegion', data)
}
//我的优惠券
export function getMyCoupon(data) {
return request.get('coupon/myCoupon', {
params: data
})
}
// 获取商品的收藏列表
export function getCollectGoods(data) {
return request.get('collect/getCollectGoods', {
params: data
})
}
// 商品的增添取消收藏
export function collectGoods(data) {
return request.post('collect/handleCollectGoods', data)
}
//删除订单
export function delOrder(id) {
return request.post('order/del', { id })
}
//订单列表
export function getOrderList(data) {
return request.get('order/lists', { params: data })
}
//订单详情
export function getOrderDetail(id) {
return request.get('order/detail', { id })
}
//取消订单
export function cancelOrder(id) {
return request.post('order/cancel', { id })
}
//物流
export function orderTraces(id) {
return request.get('order/orderTraces', { params: { id } })
}
//确认收货
export function confirmOrder(id) {
return request.post('order/confirm', { id })
}
// 充值模板
export function rechargeTemplate() {
return request.get('recharge/rechargeTemplate')
}
// 获取售后列表
export function getAfterSaleList(params) {
return request.get('after_sale/lists', { params })
}
// 申请售后
export function applyAfterSale(data) {
return request.post('after_sale/add', data)
}
// 获取商品信息
export function getGoodsInfo(params) {
return request.get('after_sale/goodsInfo', { params })
}
// 填写快递信息
export function inputExpressInfo(data) {
return request.post('after_sale/express', data)
}
// 撤销申请
export function cancelApply(data) {
return request.post('after_sale/cancel', data)
}
// 售后详情
export function afterSaleDetail(params) {
return request.get('after_sale/detail', { params })
}
// 重新申请
export function applyAgain(data) {
return request.post('after_sale/again', data)
}
// 账户明细 积分明细
export function getAccountLog(params) {
return request.get('user/accountLog', { params })
}
//充值
export function recharge(data) {
return request.post('recharge/recharge', data)
}
export function getRechargeRecord(params) {
return request.get('recharge/rechargeRecord', { params })
}
// 填写邀请码
export function inputInviteCode(data) {
return request.post('distribution/code', data)
}
// 分销会员申请
export function applyVip(data) {
return request.post('distribution/apple', data)
}
// 分销入口验证
export function veryfiyDistribute() {
return request.post('distribution/check')
}
// 最新分销会员申请详情
export function applyVipDetail() {
return request.post('distribution/appledetail')
}
// 邀请人信息
export function getInviteInfo() {
return request.get('distribution/myleader')
}
// 获取评价信息
export function getCommentInfo(data) {
return request.get('goods_comment/getGoods', { params: data })
}
// 分销主页
export function getPromoteHome() {
return request.get('distribution/index')
}
// 分销订单列表
export function getPromoteOrder(data) {
return request.get('distribution/order', { params: data })
}
//商品评价
export function goodsComment(data) {
return request.post('goods_comment/addGoodsComment', data)
}
// 获取个人详情
export function getUserInfo() {
return request.get('user/info')
}
// 设置个人信息
export function setUserInfo(data) {
return request.post('user/setInfo', data)
}
// 更换手机号
export function changeUserMobile(data) {
// #ifdef MP-WEIXIN
return request.post('user/getMobile', data)
// #endif
// #ifdef H5 || APP-PLUS
return request.post('user/changeMobile', { ...data, client })
// #endif
}
//会员中心
export function getLevelList() {
return request.get('user_level/lists')
}
// 我的粉丝
export function getUserFans(data) {
return request.get('user/fans', { params: data })
}
// 佣金提现
export function applyWithdraw(data) {
return request.post('withdraw/apply', data)
}
// 提现记录列表
export function getWithdrawRecords(params) {
return request.get('withdraw/records', { params })
}
// 提现详情
export function getWithdrawDetail(params) {
return request.get('withdraw/info', { params })
}
// 提现页信息
export function getWithdrawConfig() {
return request.get('withdraw/config')
}
// 月度账单
export function getMonthBill(params) {
return request.get('distribution/monthbill', { params })
}
// 月度账单明细
export function getMonthOrderDetail(params) {
return request.get('distribution/monthDetail', { params })
}
// 邀请海报
export function getInviteBanner(data) {
return request.get('share/userPoster', { params: data })
}
// 用户钱包
export function getWallet() {
return request.get('user/myWallet')
}
// 获取签到列表
export function getSignList() {
return request.get('sign/lists')
}
// 签到
export function userSign() {
return request.get('sign/sign')
}
// 获取签到规则
export function getSignRule() {
return request.get('sign/rule')
}
// 退出登录
export function userLogout(data) {
return request.post('account/logout', data)
}
// 获取抽奖配置
export function getPrize(data) {
return request.get('Luckdraw/prize', {
params: data
})
}
// 抽奖记录
export function getUserRecord(data) {
return request.get('Luckdraw/record', {
params: data
})
}
// 抽奖
export function userLottery(data) {
return request.get('Luckdraw/draw', {
params: data
})
}
// 中奖名单
export function luckyDrawWinningList(data) {
return request.get('Luckdraw/winList', {
params: data
})
}
//更新微信信息
export function setWechatInfo(data) {
return request.post('user/setWechatInfo', data)
}
//设置交易密码
export function setPassword(data) {
return request.post('user/setPayPassword', data)
}
//修改支付密码
export function changePayPassword(data) {
return request.post('user/changePayPassword', data)
}
//判断是否设置交易密码
export function hasPayPassword() {
return request.get('user/hasPayPassword')
}
//会员转账
export function transfer(data) {
return request.post('user/transfer', data)
}
//最近转账会员
export function getTransferRecent() {
return request.get('user/transferRecent')
}
//会员转账记录
export function transferRecord(params) {
return request.get('user/transferRecord', { params })
}
//发送验证码
export function send(data) {
return request.post('user/send', data)
}
// 找回密码
export function retrievePayPassword(data) {
return request.post('user/retrievePayPassword', data)
}
//获取会员信息
export function transferToInfo(params) {
return request.get('user/transferToInfo', { params })
}
// 获取微信小程序码-生成海报需使用
export function apiDistributionPoster() {
return request.get('distribution/getPoster')
}
// 资质信息
export function getCopyright() {
return request.get('index/copyright')
}
// 绑定微信
export function bindOawechat(data) {
return request.post('account/oaAuthLogin', data)
}

View File

@ -0,0 +1,11 @@
{
"applinks": {
"apps": [],
"details": [
{
"appID": "8656MXP6VT.com.gzyx.likeshop",
"paths": [ "/ulink/*"]
}
]
}
}

17
autoRelease.sh Normal file
View File

@ -0,0 +1,17 @@
#!/bin/bash
# 文件原路径
srcPath="./unpackage/dist/build/web"
# 发布路径文件夹
releasePath="../server/public/mobile"
#删除发布目录下的mobile文件
rm -r $releasePath
echo "已删除 ==> $releasePath 下的目录文件"
mkdir $releasePath
echo "已新建 ==> $releasePath 目录"
# 复制打包目录内的文件到发布目录
cp -r $srcPath/* $releasePath
echo "已复制 $srcPath/* ==> $releasePath"
cp $releasePath/../favicon.ico $releasePath

View File

@ -0,0 +1,161 @@
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
<template>
<view class="activity-detail-contain">
<view class="header row-start" v-if="goodsList.length">
<text class="white header-title"> {{title}} <text class="white xxs ml20">{{name}}</text></text>
</view>
<view class="content">
<view class="goods-container">
<navigator v-for="(item, index) in goodsList" :key="index" :url="'/pages/goods_details/goods_details?id=' + item.id" class="goods-item bg-white row mb10" hover-class="none">
<view class="goods-img">
<custom-image width="100%" height="100%" radius="6rpx" lazy-load :src="item.image"></custom-image>
</view>
<view class="goods-info ml20">
<view class="goods-name line2 normal nr mb10">{{item.name}}</view>
<view class="count-buy br60 xxs">累计{{item.sales_sum}}人购买</view>
<view class="row-between mt10">
<view class="row">
<price-format :price="item.price" :subscript-size="26" :first-size="34" :second-size="26" color="#FF2C3C"></price-format >
<price-format class="ml20" :price="item.market_price" :subscript-size="24" :first-size="24" :second-size="24" color="#999999"></price-format>
</view>
<view class="buy-btn row-center br60">
马上抢
</view>
</view>
</view>
</navigator>
</view>
<loading-footer slot-empty :status="status">
<view slot="empty" class="data-null column-center" style="padding-top: 500rpx">
<image class="img-null" src="/static/images/goods_null.png"></image>
<view class="lighter">暂无活动商品</view>
</view>
</loading-footer>
</view>
</view>
</template>
<script>
import { loadingType } from '@/utils/type';
import { getActivityGoodsLists } from "@/api/activity";
import { loadingFun } from "@/utils/tools";
export default {
data() {
return {
status: loadingType.LOADING,
goodsList: [],
page: 1,
name: '',
title: ''
};
},
components: {
},
props: {},
onLoad: function (options) {
this.id = options.id;
this.title = options.title,
this.name = options.name
uni.setNavigationBarTitle({
title: options.title
});
this.getActivityGoodsListsFun();
},
onReachBottom: function () {
this.getActivityGoodsListsFun();
},
methods: {
async getActivityGoodsListsFun() {
let {
page,
status,
goodsList
} = this;
const data = await loadingFun(getActivityGoodsLists,page, goodsList,status, {id : this.id})
if (!data) return
this.page = data.page
this.goodsList = data.dataList
this.status = data.status
}
}
};
</script>
<style>
.activity-detail-contain .header {
background-image: url(../../static/images/activity_detail_bg.png);
background-size: 100% 100%;
height: 340rpx;
width: 100%;
padding-left: 24rpx;
box-sizing: border-box;
padding-top: 20rpx;
}
.activity-detail-contain .header .header-title {
font-size: 47rpx;
}
.activity-detail-contain .content {
margin-top: -240rpx;
padding: 0 20rpx;
}
.activity-detail-contain .content .goods-container .goods-item {
padding: 30rpx 20rpx;
border-radius: 10rpx;
}
.activity-detail-contain .content .goods-container .goods-item .goods-img {
width: 180rpx;
height: 180rpx;
flex: none;
}
.activity-detail-contain .content .goods-container .goods-item .goods-info {
flex: 1;
}
.activity-detail-contain .content .goods-container .goods-item .goods-info .goods-name {
line-height: 40rpx;
}
.activity-detail-contain .content .goods-container .goods-item .goods-info .count-buy {
background-color: #FEF0DA;
color: #F77A0C;
padding: 4rpx 18rpx;
display: inline-flex;
}
.activity-detail-contain .content .goods-container .goods-item .goods-info .buy-btn {
padding: 0rpx 34rpx;
height: 60rpx;
color: white;
background: linear-gradient(90deg, #F95F2F 0%, #FF2C3C 100%);
}
.goods-container .data-null {
padding-top: 225rpx;
}
</style>

View File

@ -0,0 +1,341 @@
<template>
<view>
<!--pages/after_sales_detail/after_sales_detail.wxml-->
<view class="after-sales-detail">
<view class="after-sales-header">
<view class="after-sales-status white lg">
{{lists.status_text}}
</view>
<!-- <view class="after-sales-explain bg-white" hidden="{{lists.status == 2 || lists.status == 5 || lists == 6}}">
<text class="xs muted" style="line-height: 40rpx" wx:if="{{lists.status == 0 || lists.status == 1 || lists == 4}}">如果商家拒绝您可重新发起申请
如果商家同意将通过申请原路退款至您的账户中
如果商家逾期未处理平台将自动通过申请并退款给您
</text>
<text class="xs muted" style="line-height: 40rpx" wx:if="{{lists.status == 3}}">如果商家确认收到货后将会退款给您
如果商家拒绝收货该次退款将会关闭您可以重新发起退款
</text>
</view> -->
</view>
<!-- <view class="negotiation-record row-between bg-white mt20">
<view class="nr">协商记录</view>
<view class="arrow">
<image src="/images/arrow_right.png" />
</view>
</view> -->
<view class="return-address-contain row bg-white mt20" v-show="!(lists.refund_type == 0)">
<view class="nr normal address-title">退货地址</view>
<view class="sm normal address">{{lists.shop && lists.shop.address}}
{{lists.shop && lists.shop.contact}} {{lists.shop && lists.shop.mobile}}</view>
<view class="xs copy-btn row-center flex-none" @tap="onCopy">复制</view>
</view>
<view class="goods-container bg-white mt20">
<!-- <view class="goods-header row">
<view class="store-img mr10">
<image src="/images/icon_shop.png" />
</view>
<view class="store-name nr bold">
{{lists.shop.name}}
</view>
</view> -->
<view class="goods-item row">
<view class="goods-img">
<custom-image width="100%" height="100%" radius="10rpx" lazy-load
:src="lists.order_goods && lists.order_goods.image" />
</view>
<view class="goods-info">
<view class="two-txt-cut nr">{{lists.order_goods && lists.order_goods.goods_name}}</view>
<view class="row-between mt20">
<!-- <view class="md">999.00</view> -->
<price-format :price="lists.order_goods && lists.order_goods.goods_price" :firstSize="30"
:secondSize="30" :showSubscript="true" :subscriptSize="30" color="#101010" />
<view class="nr">x{{lists.order_goods && lists.order_goods.goods_num}}</view>
</view>
</view>
</view>
</view>
<view class="return-goods-container bg-white mt20">
<view class="return-goods-row row sm">
<view class="return-title">退款方式</view>
<view class="return-explain">{{lists.refund_type == 0 ? '仅退款' : '退款退货'}}</view>
</view>
<view class="return-goods-row row sm mt20">
<view class="return-title">退款原因</view>
<view class="return-explain">{{lists.refund_reason}}</view>
</view>
<view class="return-goods-row row sm mt20">
<view class="return-title">退款金额</view>
<view class="return-explain primary">¥{{lists.refund_price}}</view>
</view>
<view class="return-goods-row row sm mt20">
<view class="return-title">退款编号</view>
<view class="return-explain">{{lists.sn}}</view>
</view>
<view class="return-goods-row row sm mt20">
<view class="return-title">申请时间</view>
<view class="return-explain">{{lists.create_time}}</view>
</view>
<view class="return-goods-row row sm mt20" v-if="lists.refund_remark">
<view class="return-title">备注说明</view>
<view class="return-explain">{{lists.refund_remark}}</view>
</view>
<view class="return-goods-row row sm mt20" v-if="lists.refund_image">
<view class="return-title">图片凭证</view>
<view class="return-explain">
<custom-image mode="aspectFit" class="img-preview" radius="10rpx" :src="lists.refund_image" width="160rpx" height="160rpx" />
</view>
</view>
</view>
<view class="btn-group fixed bg-white row-end" v-show="lists.status != 6">
<view class="mr20 btn br60" @tap="showDialog">撤销申请</view>
<view class="mr20 btn br60" @tap="goRefund" v-show="lists.status == 4 || lists.status == 1">重新申请</view>
<navigator hover-class="none"
:url="'/bundle/pages/input_express_info/input_express_info?id=' + lists.id" class="mr20 btn br60"
v-show="lists.status == 2">填写快递单号</navigator>
<view class="btn br60" v-show="false">平台退款</view>
</view>
</view>
<u-modal v-model="confirmDialog" confirm-text="确定" :showCancelButton="true" :show-title="false"
confirm-color="#FF2C3C" @confirm="cancelApplyFun" @cancel="hideDialog">
<view class="column-center tips-dialog" style="padding: 20rpx 0;">
<image class="icon-lg" src="/static/images/icon_warning.png"></image>
<view style="margin-top:30rpx">是否要撤销申请</view>
</view>
</u-modal>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | LikeShop100%
// +----------------------------------------------------------------------
// |
// |
// |
// |
// | Giteehttps://gitee.com/likeshop_gitee/likeshop
// | 访https://www.likemarket.net
// | 访https://home.likemarket.net
// | 访http://doc.likemarket.net
// |
// |
// +----------------------------------------------------------------------
// | Author: LikeShopTeam
// +----------------------------------------------------------------------
import {
afterSaleDetail,
cancelApply
} from "@/api/user";
import {
trottle,
copy
} from "@/utils/tools.js";
export default {
data() {
return {
goods: {},
reason: [],
lists: {},
copyContent: "",
confirmDialog: false
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
let {
afterSaleId,
order_id
} = options;
this.afterSaleId = afterSaleId;
this.orderId = order_id;
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function() {
this.afterSaleDetailFun();
},
methods: {
onCopy() {
let {
lists,
copyContent
} = this;
let {
address,
contact,
mobile
} = lists.shop;
copyContent = address + " " + contact + " " + mobile;
copy(copyContent)
},
goRefund(e) {
let {
lists
} = this;
uni.navigateTo({
url: '/bundle/pages/apply_refund/apply_refund?order_id=' + this.orderId + '&afterSaleId=' +
this.afterSaleId + '&item_id=' + lists.order_goods.item_id
});
},
showDialog() {
this.confirmDialog = true
},
hideDialog() {
this.confirmDialog = false;
},
confirmCancel() {},
cancelApplyFun() {
cancelApply({
id: this.afterSaleId
}).then(res => {
if (res.code == 1) {
this.$toast({
title: res.msg
}, {
tab: 3
});
uni.$emit("refreshsale")
}
});
},
afterSaleDetailFun() {
afterSaleDetail({
id: this.afterSaleId
}).then(res => {
if (res.code == 1) {
this.lists = res.data
}
});
}
}
};
</script>
<style lang="scss">
/* pages/after_sales_detail/after_sales_detail.wxss */
.after-sales-detail {
padding-bottom: calc(120rpx + env(safe-area-inset-bottom));
.after-sales-header {
.after-sales-status {
padding: 48rpx 30rpx;
background-color: #555555;
}
.after-sales-explain {
padding: 20rpx 30rpx 24rpx;
}
}
.negotiation-record {
padding: 24rpx 30rpx;
.arrow {
width: 28rpx;
height: 28rpx;
}
}
.return-goods-container {
padding: 20rpx 24rpx 55rpx;
.return-goods-row {
line-height: 40rpx;
font-weight: 400;
}
}
.btn-group {
padding: 0rpx 24rpx;
position: fixed;
left: 0;
right: 0;
bottom: 0;
height: 100rpx;
.btn {
padding: 10rpx 34rpx;
border: 1px solid #999999;
}
}
.goods-container {
.goods-header {
padding: 20rpx 24rpx;
.store-img {
width: 40rpx;
height: 40rpx;
}
.store-name {
line-height: 40rpx;
align-self: flex-end;
font-family: PingFang SC;
}
}
.goods-item {
padding: 25rpx 24rpx;
.goods-img {
width: 180rpx;
height: 180rpx;
flex: none;
}
.goods-info {
margin-left: 24rpx;
flex: 1;
}
}
}
}
.return-address-contain {
padding: 20rpx 24rpx 28rpx 30rpx;
.address {
flex: 1;
line-height: 38rpx;
}
.address-title {
width: 150rpx;
align-self: flex-start;
line-height: 40rpx;
}
.copy-btn {
flex: 0 0 13%;
background-color: #F4F4F4;
color: #555555;
align-self: flex-start;
padding: 3rpx 16rpx;
margin-left: 12rpx;
border-radius: 4rpx;
}
}
.tips-dialog {
height: 230rpx;
width: 100%;
}
</style>

View File

@ -0,0 +1,394 @@
<template>
<view>
<!-- pages/apply_refund/apply_refund.wxml -->
<view class="apply-refund">
<view class="goods">
<view class="row">
<custom-image
width="160rpx"
height="160rpx"
radius="6rpx"
lazy-load
:src="goods.image"
/>
<view class="goods-info">
<view class="nr line2">{{ goods.goods_name }}</view>
<view class="xs muted mt10">{{ goods.spec_value }}</view>
</view>
</view>
</view>
<view class="opt-box mt20" :hidden="hiddenOpt">
<view class="opt-item row-between border-line" @tap="onlyRefund">
<view>
<view class="lg normal">仅退款</view>
<view class="muted xs mt10"
>未收到货与卖家协商同意无需退货只需退款</view
>
</view>
<image
style="width: 28rpx; height: 28rpx"
src="/static/images/arrow_right.png"
></image>
</view>
<view class="opt-item row-between" @tap="allRefunds">
<view>
<view class="lg normal">退货退款</view>
<view class="muted xs mt10">已收到货需退还收到的实物</view>
</view>
<image
style="width: 28rpx; height: 28rpx"
src="/static/images/arrow_right.png"
></image>
</view>
</view>
<view :hidden="!hiddenOpt">
<view class="refund-info row-between mt20">
<view class="lable">数量</view>
<view>{{ goods.goods_num }}</view>
</view>
<view class="refund-info row-between">
<view class="lable">退款金额</view>
<price-format
color="#FF2C3C"
:price="
parseFloat(goods.total_pay_price) +
parseFloat(goods.refund_express_money)
"
showSubscript="true"
:subscriptSize="28"
:firstSize="28"
:secondSize="28"
/>
</view>
<view class="refund-info row-between" @tap="showPopup">
<view class="lable">退款原因</view>
<view class="row">
<text :class="'nr ' + (reasonIndex == -1 ? 'muted' : 'normal')">{{
reasonIndex == -1 ? "请选择" : reason[reasonIndex]
}}</text>
<image
class="icon-sm ml20"
src="/static/images/arrow_right.png"
></image>
</view>
</view>
<view class="refund-info row">
<view class="label">备注说明</view>
<textarea
v-show="!showPop"
class="bg-body"
placeholder="请描述申请售后的具体原因100字以内"
v-model="remark"
name="textarea"
></textarea>
</view>
<view class="upload bg-white">
<view class="title row-between">
<view>上传凭证</view>
<view class="muted">选填最多可上传1张</view>
</view>
<uploader
:deletable="true"
preview-size="160rpx"
:file-list="fileList"
@after-read="afterRead"
@delete="deleteImage"
image-fit="aspectFill"
/>
</view>
<button class="btn br60" type="primary" size="lg" @tap="onSubmit">
申请退款
</button>
</view>
</view>
<u-popup id="popup" v-model="showPop" mode="bottom">
<view class="pop-container bg-white">
<view class="pop-header row-center md normal"> 退款原因 </view>
<scroll-view style="height: 800rpx" :scroll-y="true">
<view class="reason-box mt20">
<radio-group @change="radioChange">
<label
v-for="(item, index) in reason"
:key="index"
class="reason-item row-between"
@tap="hidePopup"
>
<view class="reason-desc nr">
{{ item }}
</view>
<radio :value="index"></radio>
</label>
</radio-group>
</view>
</scroll-view>
</view>
</u-popup>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { refundOptType } from "@/utils/type";
import { baseURL } from "@/config/app";
import { getGoodsInfo, applyAfterSale, applyAgain } from "@/api/user";
import { uploadFile, trottle } from "@/utils/tools.js";
export default {
data() {
return {
hiddenOpt: false,
optTyle: refundOptType.ONLY_REFUND,
goods: {},
reason: [],
showPop: false,
reasonIndex: -1,
fileList: [],
remark: "",
};
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let { order_id, item_id, afterSaleId } = options;
this.orderId = order_id;
this.itemId = item_id;
this.afterSaleId = afterSaleId;
this.getGoodsInfoFun();
this.onSubmit = trottle(this.onSubmit, 1000, this);
},
methods: {
showPopup() {
this.showPop = true;
},
radioChange(e) {
this.reasonIndex = e.detail.value;
},
hidePopup() {
this.showPop = false;
},
onlyRefund: function () {
this.optTyle = refundOptType.ONLY_REFUND;
this.hiddenOpt = true;
},
allRefunds() {
this.optTyle = refundOptType.REFUNDS;
this.hiddenOpt = true;
},
onSubmit() {
console.log(this.afterSaleId);
if (this.afterSaleId) {
this.applyAgainFun();
} else {
this.applyAfterSaleFun();
}
},
//
applyAgainFun() {
let { reason, reasonIndex, optTyle, remark, fileList } = this;
if (!reason[reasonIndex]) {
return this.$toast({
title: "请选择退款原因",
});
}
const data = {
id: this.afterSaleId,
reason: reason[reasonIndex],
refund_type: optTyle,
remark: remark,
img: fileList.length <= 0 ? "" : fileList[0].base_url,
};
applyAgain(data).then((res) => {
if (res.code == 1) {
uni.$emit("refreshsale");
this.$toast(
{
title: res.msg,
},
{
tab: 5,
url:
"/bundle/pages/after_sales_detail/after_sales_detail?afterSaleId=" +
res.data.after_sale_id,
}
);
}
});
},
onInput(e) {
this.setData({
remark: e.detail.value,
});
this.remark = e.detail.value;
},
applyAfterSaleFun() {
let { reason, reasonIndex, optTyle, remark, fileList } = this;
if (!reason[reasonIndex]) {
return this.$toast({
title: "请选择退款原因",
});
}
const data = {
item_id: this.itemId,
order_id: this.orderId,
reason: reason[reasonIndex],
refund_type: optTyle,
remark: remark,
img: fileList.length <= 0 ? "" : fileList[0].url,
};
applyAfterSale(data).then((res) => {
if (res.code == 1) {
uni.$emit("refreshsale");
this.$toast({
title: "提交成功",
});
setTimeout(() => {
uni.redirectTo({
url:
"/bundle/pages/after_sales_detail/after_sales_detail?afterSaleId=" +
res.data.after_sale_id,
});
}, 500);
}
});
},
afterRead(e) {
const file = e;
uni.showLoading({
title: "正在上传中...",
mask: true,
});
file.map((item) => {
uploadFile(item.path).then((res) => {
uni.hideLoading();
this.fileList.push(res);
});
});
},
deleteImage(index) {
this.fileList.splice(index, 1);
},
getGoodsInfoFun() {
let { orderId, itemId } = this;
getGoodsInfo({
order_id: orderId,
item_id: itemId,
}).then((res) => {
if (res.code == 1) {
this.goods = res.data.goods;
this.reason = res.data.reason;
}
});
},
},
};
</script>
<style lang="scss">
/* pages/apply_refund/apply_refund.wxss */
.apply-refund {
padding-bottom: 50rpx;
.goods {
padding: 20rpx 0;
background-color: white;
padding: 20rpx 24rpx;
.goods-info {
margin-left: 24rpx;
flex: 1;
}
}
}
.opt-box {
.opt-item {
padding: 20rpx 20rpx 20rpx 30rpx;
background-color: white;
}
}
.border-line {
border: 1px solid #f2f2f2;
}
.apply-refund {
.refund-info {
background-color: #fff;
padding: 24rpx 20rpx;
border-bottom: var(--border);
.label {
align-self: start;
width: 140rpx;
line-height: 36rpx;
margin-top: 19rpx;
}
textarea {
flex: 1;
height: 172rpx;
border-radius: 10rpx;
padding: 20rpx;
box-sizing: border-box;
}
}
.upload {
padding: 0 20rpx 20rpx;
.title {
padding: 24rpx 0;
}
}
.btn {
width: 680rpx;
margin-top: 30rpx;
margin-left: 26rpx;
margin-right: 26rpx;
}
}
.pop-header {
line-height: 42rpx;
padding: 30rpx;
}
.reason-box {
.reason-item {
padding: 24rpx 20rpx;
.reason-desc {
line-height: 46rpx;
}
}
}
</style>

View File

@ -0,0 +1,244 @@
<template>
<view class="balance-transfer">
<view class="contain bg-white">
<input
style="height: 100rpx"
v-model="userSn"
type="text"
placeholder="请输入对方会员ID/手机号码进行转账"
/>
</view>
<view class="contain transfer-money bg-white mt20">
<view class="muted xs">转账金额</view>
<view class="input row-center">
<view style="font-size: 23px; align-self: flex-end; margin-bottom: 5px">¥</view>
<input v-model="money" type="digit" placeholder="0.00" />
<view class="column" style="flex: none">
<view
class="xs primary"
style="text-align: right"
@tap="money = wallet.user_money"
>全部</view
>
<view class="xs mt10" style="color: #bbbbbb"
>钱包余额{{ wallet.user_money }}</view
>
</view>
</view>
<view class="btn lg white row-center br60" @tap="transferBtn">转账</view>
<navigator
url="/bundle/pages/transfer_record/transfer_record"
hover-class="none"
class="mt20 nr lighter row-center"
>
转账记录</navigator
>
</view>
<view class="user contain bg-white mt20" v-if="transferList.length">
<view class="lg bold">最近转账</view>
<view class="list">
<view
class="item row"
v-for="(item, index) in transferList"
:key="index"
@tap="userSn = item.sn"
>
<image class="avatar mr30" :src="item.avatar"></image>
<view>
<view class="md">{{ item.nickname }}</view>
<view class="xs muted">会员ID:{{ item.sn }}</view>
</view>
</view>
</view>
</view>
<u-modal
:value="showTransferInfo"
show-cancel-button
title="确认转账给"
:confirm-color="primaryColor"
async-close
confirm-text="确认转账"
@confirm="showInputPwd"
@cancel="showTransferInfo = false"
>
<view class="slot-content row-center" style="padding: 40rpx 80rpx">
<view class="transfer-user row">
<image class="avatar mr30" :src="transferInfo.avatar"></image>
<view>
<view class="md">{{ transferInfo.nickname }}</view>
<view class="xs muted mt10">会员ID:{{ transferInfo.sn }}</view>
</view>
</view>
</view>
</u-modal>
<set-pay-pwd ref="setPayPwd" @confirm="transferFun"></set-pay-pwd>
</view>
</template>
<script>
import {
hasPayPassword,
transfer,
getTransferRecent,
setPassword,
transferToInfo,
getWallet
} from '@/api/user'
import { trottle } from '@/utils/tools'
export default {
data() {
return {
showTransferInfo: false,
pwd: '',
comfirmPwd: '',
userSn: '',
money: '',
transferInfo: {},
transferList: [],
wallet: {}
}
},
onLoad() {
this.getTransferRecentFun()
this.getWalletFun()
this.transferFun = trottle(this.transferFun, 1000, this)
},
onShow() {
setTimeout(() => {
this.$refs.setPayPwd && this.$refs.setPayPwd.hasPayWord()
})
},
methods: {
getWalletFun() {
getWallet().then((res) => {
if (res.code == 1) {
this.wallet = res.data
}
})
},
showInputPwd() {
this.showTransferInfo = false
this.$refs.setPayPwd.showInputPwd()
},
getTransferRecentFun() {
getTransferRecent().then((res) => {
if (res.code == 1) {
this.transferList = res.data
}
})
},
async transferBtn() {
let { userSn, money } = this
if (!userSn)
return this.$toast({
title: '请输入对方会员ID/手机号码'
})
if (!money)
return this.$toast({
title: '请输入转账金额'
})
let data = {
transferTo: userSn
}
//
const { code: vipCode, data: transferInfo } = await transferToInfo(data)
if (vipCode != 1) return
this.transferInfo = transferInfo
this.showTransferInfo = true
},
transferFun(payPwd) {
const { userSn, money } = this
let data = {
transferTo: userSn,
money: money,
pay_password: payPwd
}
transfer(data).then((res) => {
if (res.code == 1) {
this.$toast(
{
title: res.msg
}
// {
// tab: 2,
// url: '/bundle/pages/transfer_record/transfer_record'
// }
)
this.money = ''
this.showInputPwd()
this.getWalletFun()
this.getTransferRecentFun()
}
})
}
}
}
</script>
<style lang="scss">
.balance-transfer {
padding: 20rpx 30rpx;
.contain {
border-radius: 20rpx;
padding: 0 24rpx;
}
.transfer-money {
padding: 30rpx 45rpx;
.input {
border-bottom: $-solid-border;
margin-top: 30rpx;
input {
width: 100%;
height: 94rpx;
text-align: left;
font-size: 66rpx;
margin-left: 30rpx;
}
}
.btn {
background: linear-gradient(79deg, #f95f2f 0%, #ff2c3c 100%);
line-height: 84rpx;
margin-top: 80rpx;
}
}
.user {
padding: 22rpx 25rpx;
.list .item {
padding: 26rpx 0;
&:not(:last-of-type) {
border-bottom: $-solid-border;
}
}
}
.avatar {
width: 68rpx;
height: 68rpx;
border-radius: 50%;
flex: none;
}
}
/* 弹窗 */
.balance-transfer .set-word input {
border: var(--border);
padding: 16rpx 20rpx;
font-size: 28rpx;
border-radius: 6rpx;
margin-bottom: 20rpx;
}
.balance-transfer .phone {
padding: 20rpx 0;
font-size: 42rpx;
}
</style>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,84 @@
<template>
<view class="bargain-code-container">
<tabs :active="active" @change="onChange">
<tab v-for="(item, index) in bargain" :key="item.type" :title="item.name" >
<bargain-list :ref="item.ref_name" :bargainType="item.type" v-if="item.isShow" />
</tab>
</tabs>
</view>
</template>
<script>
import {bargainType} from "@/utils/type"
export default {
data() {
return {
active: 0,
bargainCodeType: bargainType.ALL,
bargain: [{
name: '全部',
type: bargainType.ALL,
ref_name: 'all',
isShow: true
}, {
name: '砍价中',
type: bargainType.BARGINNING,
ref_name: 'barginning',
isShow: false
}, {
name: "砍价成功",
type: bargainType.SUCCESS,
ref_name: 'success',
isShow: false
}, {
name: '砍价失败',
type: bargainType.FAIL,
ref_name: 'fail',
isShow: false
}]
}
},
onLoad(options) {
},
onReachBottom: function () {
const {
active, bargain
} = this;
let type = bargain[active].ref_name;
let myComponent = this.$refs[type][0];
if (myComponent.$getBargainActivityList) {
myComponent.$getBargainActivityList();
}
},
methods: {
onChange(active) {
const {bargain} = this;
console.log(active)
let type = bargain[active].ref_name
let index = bargain.findIndex(item => {
return item.ref_name == type;
});
if (index != -1) {
this.bargain[index].isShow = true;
console.log(this.bargain)
this.active = index;
}
this.$nextTick(() => {
console.log(this.$refs, "refs", type)
console.log('this.$refs[all]', this.$refs['all'])
if(this.$refs[type] && this.$refs[type][0].$getBargainActivityList) {
this.$refs[type][0].$getBargainActivityList();
}
})
}
}
}
</script>
<style lang="scss">
.bargain-code-container {
}
</style>

View File

@ -0,0 +1,717 @@
<template>
<view class="bargain-process-container">
<navbar title="砍价进度"></navbar>
<!-- #ifdef H5 -->
<download-nav v-if="showDownload" :top="44"></download-nav>
<!-- #endif -->
<view v-show="status == -1">
<view class="bargain-process-header">
<view class="mt20 column status-container">
<view class="white xxl">
{{activityObj.bargain_tips}}
</view>
<view class="mt10 white xxs">
{{activityObj.simple_tips}}
</view>
</view>
</view>
<view class="main">
<navigator class="goods-planel row" :url="'/pages/goods_details/goods_details?id=' + activityObj.goods_id" hover-class="none">
<custom-image width="180rpx" height="180rpx" :src="activityObj.image" radius="10rpx" />
<view class="goods-info">
<view class="goods-name line2 nr">
{{activityObj.name}}
</view>
<view class="xs" style="color: #F95F2F;">
最低可砍至<text class="sm" style="line-height: 48rpx;">¥<text class="xl">{{activityObj.activity_price}}</text></text>
</view>
<view class="xs muted">
原价 <text style="text-decoration:line-through;">¥{{activityObj.price}}</text>
</view>
</view>
</navigator>
<view class="choose-container">
<view class="title xl normal">
请选择商品规格
</view>
<view class="choose-content row-between" @click="showSpecPop">
<view class="row">
<view class="muted sm">已选</view>
<view class="md normal">
{{userSpecText}}
</view>
</view>
<u-icon name="arrow-right" size="28" color="#999" />
</view>
</view>
<view class="lunch-btn white br60 row-center" @click="$launchBargain">发起砍价</view>
</view>
</view>
<view v-show="status != -1">
<view class="bargain-process-header">
<view class="mt20 status-container row">
<custom-image
v-if="bargainObj.share_avatar"
width="80rpx"
height="80rpx"
:src="bargainObj.share_avatar"
round
:customStyle="{'border': '2rpx solid #fff'}"
/>
<view class="column ml20">
<view class="white xxl">
{{bargainObj.bargain_tips}}
</view>
<view class="mt10 white xxs">
{{bargainObj.simple_tips || '邀请好友帮忙砍价 —— 砍至'+ bargainObj.current_price +'元即可发货'}}
</view>
</view>
</view>
</view>
<view class="main">
<navigator class="goods-planel row" :url="'/pages/goods_details/goods_details?id=' + bargainObj.goods_id" hover-class="none">
<custom-image width="180rpx" height="180rpx" :src="bargainObj.image" radius="10rpx" />
<view class="goods-info">
<view class="goods-name line2 nr">
{{bargainObj.name}}
</view>
<view class="xs muted">
{{bargainObj.spec_value_str}}
</view>
<view class="row-between mt10">
<view class="xs muted">
原价 ¥{{bargainObj.price || 0}}
</view>
<view class="row" v-show="showCountDown" v-if="timestamp > 0">
<u-count-down
:timestamp="timestamp"
:bg-color="primaryColor"
color="#fff"
:separator-color="primaryColor"
height="36"
:show-days="true"
@end="closeBargainOrderFun"
/>
<text class="muted xs ml10">内可砍</text>
</view>
</view>
</view>
</navigator>
<!-- 非被邀请状态 -->
<view class="bargain-panel" v-if="status != 5">
<view class="bargain-panel-header nr">
已砍{{bargainObj.knife_price || 0}}还差{{bargainObj.diff_price || 0}}
</view>
<view class="progress-container row">
<view class="progress">
<view class="progress-bar" :style="{'width': precent + '%'}">
</view>
</view>
<view class="primary xs ml20">
<text class="xxs">¥</text>{{bargainObj.activity_price}}
</view>
</view>
<view class="nr lighter row-center" style="margin-top: 35rpx;" v-if="bargainObj.status != 0 && bargainObj != -1">
{{bargainObj.status_tips}}
</view>
<view class="invite-btn1 br60 white row-center lg" @click="shareToBargain" v-if="bargainObj.direct_buy_btn != 1 && bargainObj.invite_btn">
邀请好友帮砍价
</view>
<view class="invite-btn1 br60 white row-center lg" v-if="bargainObj.buy_btn" @tap="handleClickBuy" >
立即购买
</view>
<view class="fail-btn br60 white row-center lg" v-if="bargainObj.status == 2">
砍价失败
</view>
<view class="invite-btn-group row-between" v-if="bargainObj.direct_buy_btn">
<view class="buy-now-btn br60 md row-center" @click="handleClickBuy">
¥{{bargainObj.current_price}} 直接购买
</view>
<view class="invite-friend-btn white br60 md row-center" @click="shareToBargain">
邀请好友帮砍价
</view>
</view>
<view class="invite-btn1 br60 white row-center lg" v-if="bargainObj.order_btn" @click="toOrderDetail">
查看订单
</view>
<view class="bargain-code-content">
<view class="bargain-code-title row-between">
<view class="md normal bold">
砍价记录
</view>
<view class="muted xs">
已有{{bargainObj.knife_list && bargainObj.knife_list.length}}人帮砍
</view>
</view>
<view class="code-content">
<view class="user-item row-between" v-for="(item, index) in bargainObj.knife_list" :key="item.id">
<view class="user-content row">
<custom-image width="80rpx" height="80rpx" radius="60rpx" :src="item.avatar" />
<view class="ml20">
<view class="sm normal">
{{item.nickname}}
</view>
<view class="muted xxs">
小刀一砍惊喜满满
</view>
</view>
</view>
<view class="bargain-price xs primary">
¥{{item.help_price || 0}}
</view>
</view>
</view>
</view>
</view>
<!-- end -->
<!-- 被邀请状态 -->
<view class="shared-panel" v-if="status == 5" >
<view class="btn-container">
<view class="nr muted row-center">
{{bargainObj.status_tips}}
</view>
<view class="help-knife-btn row-center white lg br60" v-if="bargainObj.knife_btn" @click="$helpBargain">
帮忙砍一刀
</view>
<navigator hover-class="none" url="/bundle/pages/bargain/bargain" class="knife-btn row-center lg normal br60" v-if="bargainObj.sponsor_btn">
我也要砍价
</navigator>
</view>
<view class="code-content">
<view class="bargain-code-title row-between">
<view class="md normal bold">
砍价记录
</view>
<view class="muted xs">
已有{{bargainObj.knife_list.length}}人帮砍
</view>
</view>
<view class="user-item row-between" v-for="(item, index) in bargainObj.knife_list" :key="item.id">
<view class="user-content row">
<custom-image width="80rpx" height="80rpx" radius="60rpx" :src="item.avatar" />
<view class="ml20">
<view class="sm normal">
{{item.nickname}}
</view>
<view class="muted xxs">
小刀一砍惊喜满满
</view>
</view>
</view>
<view class="bargain-price xs primary">
¥{{item.help_price || 0}}
</view>
</view>
</view>
</view>
<!-- end -->
</view>
</view>
<loading-view v-if="showLoadingView" />
<goods-bargain v-if="status != -1" ref="goodsBargain" />
<u-popup v-model="showBargainPop" mode="center">
<view class="bargain-pop-container">
<view class="md normal bold row-center" style="padding-top: 64rpx;">
恭喜您成功砍下<text class="primary lg">{{knifePrice || 0}}</text>
</view>
<view class="bold md row-center" style="margin-top: 38rpx;" v-if="!isHelpKnife">
还差<text class="ml20 differ-price primary">{{diffPrice || 0}}<text style="font-size: 40rpx;"></text></text>
</view>
<view class="bold primary xxl row-center" style="margin-top: 38rpx;" v-else>
已为好友砍价成功
</view>
<view class="progress-container row-center">
<view class="progress">
<view class="progress-bar" :style="{'width': precent + '%'}" />
</view>
</view>
<view class="row-center">
<view class="invite-btn row-center md" @click="shareToBargain">
{{isHelpKnife ? '确定' : '邀请好友帮砍'}}
</view>
</view>
</view>
<view class="close-icon row-center" @click="closeBargainPop" mode="bottom">
<u-icon name="close-circle" size="68rpx" color="#fff"></u-icon>
</view>
</u-popup>
<spec-popup
:show="showPop"
:goods="activityObj"
:isBargain="true"
:show-add="false"
:show-buy="false"
:showConfirm="true"
:disabledNumberBox="true"
:showStock="false"
@confirm="chooseSpec"
@close="showPop=false"
/>
<!-- <share-popup
:show="showSharePop"
@close="showSharePop = false"
:goodsId="bargainId"
:isBargain="true"
:shareTitle="bargainObj.share_titles || bargainObj.name"
:summary="bargainObj.share_intros || bargainObj.simple_tips"
:img-url="bargainObj.image"
/> -->
<share-popup
v-model="showSharePop"
:share-id="bargainId"
pagePath="bundle/pages/bargain_process/bargain_process"
:config="{
avatar: userInfo.avatar,
nickname: userInfo.nickname,
image: bargainObj.image,
name: bargainObj.name ||bargainObj.share_titles,
}"
:type="2"
/>
</view>
</template>
<script>
import {getBargainDetail, launchBargain, getBargainActivityDetail, helpBargain, closeBargainOrder} from '@/api/activity'
import {strToParams} from '@/utils/tools'
import config from '@/config/app'
import { mapGetters } from 'vuex'
export default {
data() {
return {
showPop: false,
showBargainPop: false,
showSharePop: false,
activityObj: {},
bargainObj: {},
status: 1,
precent: 0,
timestamp: 0,
userSpecText: '请选择商品规格',
userSpec: {},
bargainId: -1,
activityId: -1,
//
knifePrice: 0,
diffPrice: 0,
isHelpKnife: false,
showCountDown: true,
showLoadingView: true,
showDownload: false
}
},
onLoad(options) {
if (options && options.scene) {
let scene = strToParams(decodeURIComponent(options.scene));
console.log('scenescene',scene)
options.bargainId = scene.id;
}
if(options && options.id) {
options.bargainId = options.id
}
// #ifdef H5
if(options && options.isapp == 1) {
this.showDownload = true
}
// #endif
// ID
this.bargainId = options.bargainId;
// ID
this.activityId = options.activityId;
console.log(this.bargainId, this.activityId, "option")
if(this.activityId && this.activityId != -1) {
this.$getBargainDetail(this.activityId);
}
else if(this.bargainId && this.bargainId != -1) {
this.$getBargainActivityDetail(this.bargainId)
}
},
onReachBottom() {
if(this.$refs.goodsBargain) {
this.$refs.goodsBargain.$getBargainList();
}
},
// #ifdef MP-WEIXIN
onShareAppMessage() {
return {
path: "bundle/pages/bargain_process/bargain_process?bargainId=" + this.bargainId,
title: this.bargainObj.share_titles || this.bargainObj.name,
imageUrl: this.bargainObj.image,
}
},
// #endif
computed: {
...mapGetters(['userInfo']),
},
methods: {
showSpecPop() {
this.showPop = true;
},
closeBargainPop() {
this.showBargainPop = false
},
$getBargainDetail(id) {
getBargainDetail({bargain_id: id}).then(res => {
if(res.code == 1) {
this.activityObj = res.data;
this.status = res.data.status;
this.showLoadingView = false;
this.userSpecText = res.data.goods_item[0].spec_value_str
this.userSpec = {
id: res.data.goods_item[0].id
}
// let url = config.baseURL.replace(/\/api\//g, "/mobile/");
let options = {
shareTitle: this.activityObj.name,
shareLink: location.href + "&invite_code=" + this.$store.getters.inviteCode,
shareImage: this.activityObj.image,
shareDesc: this.activityObj.simple_tips
}
this.wxShare(options)
console.log(options, "share-bargain-options1", location.href);
}
})
},
chooseSpec(e) {
this.userSpec = e.detail;
this.userSpecText = e.detail.spec_value_str;
this.showPop = false;
},
$launchBargain() {
let data = {
// id
bargain_id: this.activityId,
item_id: this.userSpec.id
}
launchBargain(data).then(res => {
if(res.code == 1) {
this.$toast({title: res.msg});
this.knifePrice = res.data.knife_price;
this.diffPrice = res.data.diff_price;
this.precent = res.data.progress * 100;
if(this.precent > 100) {
this.precent = 100
}
this.showBargainPop = true;
this.bargainId = res.data.id;
this.showLoadingView = true;
uni.showLoading()
this.$getBargainActivityDetail(res.data.id);
}
})
},
$getBargainActivityDetail(id) {
let timestamp = 0;
let now_time = (new Date().getTime()) / 1000
getBargainActivityDetail({
id: id
}).then(res => {
if(res.code == 1) {
uni.hideLoading()
this.status = res.data.status;
this.bargainObj = res.data;
timestamp = res.data.over_time;
this.precent = res.data.progress * 100;
if(this.precent > 100) {
this.precent = 100
}
this.showLoadingView = false;
this.timestamp = (timestamp - Math.floor(now_time));
console.log('calc: ', timestamp, '-', Math.floor(now_time), '=', this.timestamp )
let url = location.href.replace(/activityId=\d*/g, "bargainId=" + id);
let options = {
shareTitle: this.bargainObj.share_titles || this.bargainObj.name,
shareLink: url + "&invite_code=" + this.$store.getters.inviteCode,
shareImage: this.bargainObj.image,
shareDesc: this.bargainObj.share_intros || this.bargainObj.simple_tips
}
this.wxShare(options)
console.log(options, "share-bargain-options2", url);
if(this.timestamp <= 0 || this.status == 1) {
//
this.showCountDown = false;
}
else {
this.showCountDown = true;
}
}
})
},
shareToBargain() {
this.showBargainPop = false
if(this.isHelpKnife) {
return;
}
this.showSharePop = true
},
$helpBargain() {
//
helpBargain({
id: this.bargainId
}).then(res => {
if(res.code == 1) {
this.knifePrice = res.data.knife_price;
this.precent = res.data.progress * 100;
if(this.precent > 100) {
this.precent = 100
}
this.isHelpKnife = true;
this.showBargainPop = true;
this.$getBargainActivityDetail(this.bargainId)
}
})
},
toOrderDetail() {
uni.navigateTo({
url: "/pages/order_details/order_details?id=" + this.bargainObj.order_id
})
},
closeBargainOrderFun() {
//
closeBargainOrder({
id: this.bargainObj.id
}).then(res => {
if(res.code == 1) {
this.$toast({
title: res.msg
})
this.$getBargainActivityDetail(this.bargainObj.id)
}
})
},
handleClickBuy() {
let goods = [{
num: 1,
item_id: this.bargainObj.item_id
}]
let params = {
goods
}
console.log(goods, 'handleClickBuy')
uni.navigateTo({
url: '/pages/confirm_order/confirm_order?data=' + encodeURIComponent(JSON.stringify(params)) + "&bargain_launch_id=" + this.bargainObj.id
})
}
}
}
</script>
<style lang="scss">
.bargain-process-container {
.bargain-process-header {
background-image: url(../../../static/images/bg_hometop.png);
height: 420rpx;
background-size: 100% 100%;
padding-top: 30rpx;
.rule-contain {
background-color: rgba(255, 255, 255, 0.8);
border-radius: 100rpx;
padding: 6rpx 10rpx;
margin-right: 24rpx;
}
.status-container {
margin-left: 24rpx;
}
}
.main {
padding: 0 24rpx;
margin-top: -230rpx;
.goods-planel {
background-color: white;
padding: 30rpx 24rpx;
border-radius: 20rpx;
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.06);
.goods-info {
margin-left: 24rpx;
flex: 1;
.goods-name {
line-height: 40rpx;
}
}
}
// 2
.bargain-panel {
margin-top: 30rpx;
padding: 24rpx 24rpx 20rpx;
background-color: $-color-white;
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.06);
border-radius: 20rpx;
.bargain-panel-header {
font-weight: bold;
}
.progress-container {
margin-top: 33rpx;
.progress {
flex: 1;
background-color: #FFEBE5;
height: 20rpx;
border-radius: 50rpx;
.progress-bar {
background: linear-gradient(90deg, #F95F2F 0%, #FF2C3C 100%);
transition: width .5s ease;
height: 100%;
width: 0%;
border-radius: 50rpx;
}
}
}
.invite-btn1 {
background-color: $-color-primary;
height: 84rpx;
margin-top: 36rpx;
box-shadow: 0px 3px 10px rgba(235, 36, 51, 0.5);
}
.fail-btn {
background-color: #E5E5E5;
height: 84rpx;
margin-top: 30rpx;
}
.invite-btn-group {
margin-top: 60rpx;
.buy-now-btn {
width: 316rpx;
height: 84rpx;
color: #F95F2F;
font-size: 30rpx;
background-color: rgba($color: #F95F2F, $alpha: 0.2);
}
.invite-friend-btn {
width: 316rpx;
height: 84rpx;
background-color: $-color-primary;
}
}
.bargain-code-content {
margin-top: 62rpx;
.bargain-code-title {
}
.code-content {
margin-top: 30rpx;
.user-item {
padding: 15rpx 0;
margin-bottom: 30rpx;
}
}
}
}
// end
//
.shared-panel {
.btn-container {
margin-top: 40rpx;
.help-knife-btn {
background-color: $-color-primary;
height: 84rpx;
box-shadow: 0px 3px 10px rgba(235, 36, 51, 0.5);
}
.knife-btn {
height: 84rpx;
background-color: $-color-white;
border: 1px solid #BBBBBB;
margin-top: 30rpx;
}
}
.code-content {
margin-top: 30rpx;
padding: 27rpx 24rpx;
background-color: $-color-white;
.user-item {
padding: 15rpx 0;
margin-top: 10rpx;
}
}
}
// end
.choose-container {
margin: 40rpx 0;
.title {
font-weight: 500;
margin-bottom: 30rpx;
}
.choose-content {
padding: 30rpx 20rpx;
background-color: $-color-white;
border-radius: 10px;
}
}
.lunch-btn {
height: 84rpx;
background-color: $-color-primary;
box-shadow: 0px 3px 10px rgba(235, 36, 51, 0.5);
}
}
.pop-container {
height: 800rpx;
.goods-info {
padding: 20rpx 20rpx;
.goods-spec {
align-self: flex-end;
}
}
.spec-selector {
padding: 30rpx 20rpx;
.title {
line-height: 36rpx;
}
.spec-item {
padding: 8rpx 28rpx;
background-color: #F4F4F4;
}
.spec-active-item {
padding: 8rpx 28rpx;
color: white;
background-color: $-color-primary;
}
}
.pickup-number {
margin-top: 30rpx;
padding: 0 20rpx;
}
}
.bargain-pop-container {
width: 559rpx;
height: 580rpx;
background-image: url(../../static/images/bg_kanjia.png);
background-size: 100% 100%;
.differ-price {
font-size: 58rpx;
line-height: 38rpx;
}
.progress-container {
margin-top: 26rpx;
.progress {
width: 409rpx;
height: 20rpx;
background-color: #FD498F1A;
border-radius: 50rpx;
.progress-bar {
height: 100%;
width: 0%;
background: linear-gradient(90deg, #FA444D 0%, #FD498F 100%);
border-radius: 50rpx;
transition: width .5s ease;
}
}
}
.invite-btn {
background-image: url(../../static/images/coupon_button.png);
background-size: 100% 100%;
height: 106rpx;
color: #7B3200;
font-weight: 500;
margin-top: 180rpx;
width: 478rpx;
}
}
.close-icon {
margin-top: 26rpx;
}
.share-pop-container {
height: 500rpx;
background-color: $-color-white;
}
}
</style>

View File

@ -0,0 +1,157 @@
<template>
<view class="contact-offical">
<view class="header">
</view>
<view class="content column-center">
<view class="content-view column-center bg-white">
<img class="content-img" :src="server.image" />
<view class="primary wechat-num lg">客服微信</view>
<view class="row-center copy-btn xxl white" @click="onCopy(server.wechat)">
<image class="mr5" style="width: 32px;height: 25px;" src="../../static/images/wechat-btn-icon.png" />
微信扫码添加
</view>
<view class="mt20 normal xs" style="line-height: 35px">{{server.time}}</view>
<!-- #ifdef MP-WEIXIN -->
<button open-type="contact" class="sm row-center br60">
<text style="line-height: 50px;">在线客服</text>
</button>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<view class="sm row-center br60" @click="tipsShow()">
<text style="line-height: 50px;">在线客服</text>
</view>
<!-- #endif -->
</view>
<view class="xs white" style="margin-top: 40px;line-height: 49px;">
无法添加或疑难问题请联系工作人员
</view>
<view class="row white">
<view class="xs" style="line-height: 49px;">{{server.phone}}</view>
<!-- #ifdef H5 -->
<a class="ml10 phone-btn xs row-center white" :href="'tel:' + server.phone">拨打</a>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<a class="ml10 phone-btn xs row-center white" @click="showTelTips">拨打</a>
<!-- #endif -->
<view class="ml5 copy-phone-btn xs row-center" @click="onCopy(server.phone)">复制</view>
</view>
</view>
<u-modal
:content="content"
v-model="showPhoneCall"
show-cancel-button
confirm-text='呼叫'
:confirm-color="primaryColor"
@confirm="onCall"
>
</u-modal>
</view>
</template>
<script>
import {getService} from "@/api/app"
import {copy} from '@/utils/tools'
export default {
name: 'contactOffical',
data() {
return {
server: {},
showPhoneCall: false,
content: '即将打电话给'
}
},
onLoad() {
this.$getService()
},
methods: {
$getService() {
getService().then(res => {
if(res.code == 1) {
this.server = res.data
}
})
},
tipsShow() {
this.$toast({title: "该功能暂未开放"})
},
onCopy(str) {
copy(str);
},
showTelTips() {
this.showPhoneCall = true;
this.content = '即将打电话给' + this.server.phone
},
onCall() {
wx.makePhoneCall({
phoneNumber: this.server.phone.toString(),
success(e) {
console.log('成功', e)
},
fail(err) {
console.log('失败', err)
}
})
}
}
}
</script>
<style lang="scss">
.contact-offical {
min-height: 100vh;
background: linear-gradient(180deg, #F62318 0%, #F20407 100%);
.header {
height: 383px;
width: 100%;
}
.content {
.content-view {
border: 5px solid #FA7949;
width: 310px;
border-radius: 10px;
margin-top: -350px;
.content-img {
margin-top: 20px;
height: 192px;
width: 192px;
}
.wechat-num {
line-height: 45px;
}
.copy-btn {
background: linear-gradient(180deg, #FFA200 0%, #FF5E44 100%);
width: 230px;
height: 50px;
border-radius: 50px;
line-height: 49px;
margin-top: 30px;
}
.contact-btn {
width: 300rpx;
height: 60rpx;
margin-bottom: 20rpx;
}
}
.phone-btn {
background: linear-gradient(180deg, #FFA200 0%, #FF5E44 100%);
height: 24px;
width: 60px;
line-height: 33px;
border-radius: 50px;
}
.copy-phone-btn {
background-color: rgba($color: #fff, $alpha: 0.5);
height: 24px;
width: 60px;
line-height: 33px;
border-radius: 50px;
}
}
}
</style>

View File

@ -0,0 +1,184 @@
<template>
<view class="set-pwd">
<view class="input-container bg-white">
<view class="input-item row">
<view class="input-label md normal">手机号</view>
<u-input class="flex1" v-model="mobile" />
</view>
<view class="input-item row">
<view class="input-label md normal">验证码</view>
<u-input class="flex1" v-model="code" placeholder="请输入验证码" />
<view class="get-code xs br60 row-center primary" @tap="sendSms">
<view v-show="!showCount">获取验证码</view>
<u-count-down
v-show="showCount"
ref="countDown"
:show-days="false"
:timestamp="time"
separator="zh"
color="#FF2C3C"
separatorColor="#FF2C3C"
bg-color="rgba(0, 0, 0, 0)"
:show-hours="false"
:show-minutes="false"
:autoplay="false"
@end="showCount = false"
/>
</view>
</view>
<view class="input-item row">
<view class="input-label md normal">转账密码</view>
<u-input
class="flex1"
type="password"
v-model="setPwd"
placeholder="请输入新的转账密码"
/>
</view>
<view class="input-item row">
<view class="input-label md normal">确认密码</view>
<u-input
class="flex1"
type="password"
v-model="comfirmPwd"
placeholder="请再次确认密码"
/>
</view>
<button
size="lg"
type="primary"
class="btn bg-primary white br60 row-center"
@tap="retrievePayPasswordFun"
>
确认
</button>
</view>
</view>
</template>
<script>
import { retrievePayPassword, send } from '@/api/user'
import { mapGetters } from 'vuex'
export default {
data() {
return {
time: 59,
showCount: false,
setPwd: '',
comfirmPwd: '',
code: ''
}
},
onLoad() {},
methods: {
retrievePayPasswordFun() {
let { setPwd, comfirmPwd, code } = this
if (!code) {
this.$toast({
title: '请输入验证码'
})
return
}
if (!setPwd) {
this.$toast({
title: '请输入新的转账密码'
})
return
}
if (!comfirmPwd) {
this.$toast({
title: '请输入确认密码'
})
return
}
if (setPwd != comfirmPwd) {
this.$toast({
title: '两次密码输入不一致'
})
return
}
if (setPwd.length < 4 || setPwd.length > 8) {
this.$toast({
title: '请输入长度为4-8位的密码'
})
return
}
let data = {
new_pay_password: setPwd,
mobile: this.userInfo.mobile,
code: code
}
retrievePayPassword(data).then((res) => {
if (res.code == 1) {
this.$toast(
{
title: res.msg
},
{ tab: 3 }
)
}
})
},
sendSms() {
let data = {
mobile: this.userInfo.mobile
}
if (this.showCount) return
send(data).then((res) => {
if (res.code == 1) {
this.$toast({
title: res.msg
})
this.showCount = true
this.$refs.countDown.start()
}
})
}
},
computed: {
...mapGetters(['userInfo']),
mobile() {
if (this.userInfo.mobile) {
return this.userInfo.mobile.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2')
}
}
}
}
</script>
<style lang="scss">
.set-pwd {
padding-top: 20rpx;
.input-container {
padding: 20rpx 0 100rpx;
border-radius: 20rpx;
.input-item {
margin: 0 30rpx;
height: 88rpx;
margin-bottom: 30rpx;
border-bottom: 1px solid #d7d7d7;
.input-label {
width: 180rpx;
flex: none;
}
.get-code {
width: 176rpx;
height: 58rpx;
flex: none;
border: 1px solid $-color-primary;
}
}
.btn {
margin: 80rpx 30rpx 0;
}
}
}
</style>

View File

@ -0,0 +1,169 @@
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
<template>
<view class="goods-combination">
<navbar title="拼团活动"></navbar>
<view class="header">
<image class="img" src="../../static/images/group_bg.png"></image>
</view>
<view class="main bg-primary">
<view class="goods-list">
<navigator v-for="(item, index) in groupList" :key="index" class="goods-item row mt20 bg-white" hover-class="none"
:url="'/pages/goods_details/goods_details?id=' + item.goods_id">
<custom-image width="180rpx" height="180rpx" radius="6rpx" lazy-load :src="item.image"></custom-image>
<view class="goods-info ml20">
<view class="goods-name line2 mb10">{{item.name}}</view>
<view class="dec row">
<view class="group mr20 row">
<view class="group-img row-center">
<image class="icon-sm" src="../../static/images/icon_group_white.png"></image>
</view>
<view class="primary xxs mr10 ml10">{{item.people_num}}人团</view>
</view>
<view class="sale muted xs">已拼{{item.sales_sum}}</view>
</view>
<view class="info-footer row-between">
<view class="price row">
<price-format color="#FF2C3C" :subscript-size="26" :second-size="26" :first-size="34" :price="item.team_min_price"
:weight="500"></price-format>
<price-format class="ml10" color="#999" :line-through="true" :subscript-size="24" :first-size="24" :second-size="24"
:price="item.min_price"></price-format>
</view>
<button class="br60 btn white" size="sm" type="primary">去拼团</button>
</view>
</view>
</navigator>
</view>
<loading-footer :status="status" :slot-empty="true" color="#fff" @refresh="getGroupListFun">
<view slot="empty" class="column-center" style="padding-top: 200rpx">
<text class="lg" style="color: #FFD4D8">暂无拼团商品</text>
</view>
</loading-footer>
</view>
</view>
</template>
<script>
import {
loadingType
} from '@/utils/type';
import {
getGroupList
} from '@/api/activity';
import {
loadingFun
} from '@/utils/tools'
export default {
data() {
return {
page: 1,
groupList: [],
status: loadingType.LOADING
};
},
components: {},
onLoad: function(options) {
this.getGroupListFun();
},
onPullDownRefresh: function() {
this.page = 1;
this.groupList = [];
this.status = loadingType.LOADING;
this.getGroupListFun();
},
onReachBottom: function() {
this.getGroupListFun();
},
methods: {
async getGroupListFun() {
try {
let {
page,
groupList,
status
} = this;
const data = await loadingFun(getGroupList, page, groupList, status)
if (!data) return
this.page = data.page
this.groupList = data.dataList
this.status = data.status
} catch(err) {
this.status = loadingType.ERROR
}
}
}
};
</script>
<style lang="scss">
.goods-combination {
background-color: $-color-primary;
min-height: 100vh;
.header .img {
display: block;
width: 750rpx;
height: 380rpx;
}
.main {
padding: 0 20rpx;
margin-top: -30rpx;
position: relative;
z-index: 1;
.goods-list {
.goods-item {
border-radius: 20rpx;
padding: 30rpx 20rpx;
.goods-img {
width: 180rpx;
height: 180rpx;
flex: none;
}
.goods-info {
flex: 1;
width: 475rpx;
.group {
border: 1px solid $-color-primary;
border-radius: 4rpx;
.group-img {
padding: 2rpx 6rpx;
background: linear-gradient(90deg, rgba(249, 95, 47, 1) 0%, rgba(255, 44, 60, 1) 100%);
border-radius: 0 4rpx 4rpx 0;
}
}
.info-footer {.btn {
padding: 0 30rpx;
background-color: #F95F2F;
}}
}
}
}
}
}
</style>

View File

@ -0,0 +1,48 @@
<template>
<view class="goods-comment-list">
<tabs :active="active" line-width="40" @change="changeActive">
<tab title="待评价">
<comment-list type="1" v-if="active == 0"></comment-list>
</tab>
<tab title="已评价">
<comment-list type="2" v-if="active == 1"></comment-list>
</tab>
</tabs>
</view>
</template>
<script>
export default {
data() {
return {
active: 0
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.type = options.type;
if (this.type) {
this.active = parseInt(this.type)
}
},
methods: {
changeActive(e) {
this.active = e
}
}
};
</script>
<style>
</style>

View File

@ -0,0 +1,258 @@
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
<template>
<view>
<view class="goods-logistics mb20">
<view class="header row bg-white">
<view class="goods mr20">
<image class="goods-img" :src="order.image"></image>
<view class="count xs white br60">{{order.count}}件商品</view>
</view>
<view class="info sm">
<view class="bold lg">{{order.tips}}</view>
<view class="black mt10 mb10">物流公司{{order.shipping_name}}</view>
<view class="row">
<text class="black">快递单号{{order.invoice_no}}</text>
<text class="primary ml20" @tap="onCopy">复制</text>
</view>
</view>
</view>
<view class="main mt20 bg-white column">
<!-- 物流时间轴 -->
<view class="express">
<!-- 顶部收货地址 -->
<view class="express-address row" v-if="take.contacts">
<view class="express-left column-center">
<image class="express-icon" :src="finish.tips ? '../../static/images/logistics_address.png' : '../../static/images/logistics_address_gray.png'"></image>
<view class="express-line"></view>
</view>
<view class="express-right">
<view class="name bold mb10 sm">{{take.contacts}} {{take.mobile}}</view>
<view class="address sm lighter line2">{{take.address}}</view>
</view>
</view>
<view class="express-item row" v-if="finish.tips">
<view class="express-left column-center">
<image class="express-icon" src="../../static/images/logistics_success.png"></image>
<view class="express-line"></view>
</view>
<view class="express-right">
<view class="title bold sm">{{finish.title}}</view>
<view class="dec sm">{{finish.tips}}</view>
<view class="time xs muted">{{finish.time}}</view>
</view>
</view>
<view class="express-item row" v-if="delivery.traces && delivery.traces.length">
<view class="express-left column-center">
<image class="express-icon" src="../../static/images/logistics_transit.png"></image>
<view class="express-line"></view>
</view>
<view class="express-right muted">
<view class="title bold sm ">{{delivery.title}}</view>
<view class="xs" v-if="delivery.traces[0][0]">
{{delivery.traces[0][0]}}
</view>
<view class="xs" v-if="delivery.traces[0][1]">
{{delivery.traces[0][1]}}
</view>
<view class="xs" v-if="delivery.traces[0][2]">
{{delivery.traces[0][2]}}
</view>
</view>
</view>
<block v-for="(item, index) in delivery.traces" :key="index">
<view class="express-item row" v-if="index >= 1">
<view class="express-left column-center">
<view class="express-doted"></view>
<view class="express-line"></view>
</view>
<view class="express-right muted">
<view class="sm" v-if="item[0]">{{item[0]}}</view>
<view class="sm" v-if="item[1]">{{item[1]}}</view>
<view class="sm" v-if="item[2]">{{item[2]}}</view>
</view>
</view>
</block>
<view class="express-item row" v-if="shipment.tips">
<view class="express-left column-center">
<image class="express-icon" src="../../static/images/logistics_delivered.png"></image>
<view class="express-line"></view>
</view>
<view class="express-right muted">
<view class="title bold sm">{{shipment.title}}</view>
<view class="dec xs">{{shipment.tips}}</view>
<view class="time xs muted">{{shipment.time}}</view>
</view>
</view>
<view class="express-item row" v-if="buy.tips">
<view class="express-left column-center">
<image class="express-icon" src="../../static/images/logistics_pay.png"></image>
<view class="express-line"></view>
</view>
<view class="express-right muted">
<view class="title bold sm">{{buy.title}}</view>
<view class="dec xs">{{buy.tips}}</view>
<view class="time xs muted">{{buy.time}}</view>
</view>
</view>
</view>
</view>
</view>
<recommend></recommend>
<loading-view v-if="isFirstLoading"></loading-view>
</view>
</template>
<script>
import {
orderTraces
} from '@/api/order';
import {copy} from '@/utils/tools'
export default {
data() {
return {
shipment: {},
buy: {},
delivery: {},
finish: {},
order: {},
take: {},
isFirstLoading: true
};
},
components: {},
props: {},
onLoad: function(options) {
this.id = options.id;
this.orderTracesFun();
},
methods: {
async orderTracesFun() {
const {
code,
data: {
shipment,
buy,
delivery,
finish,
order,
take
}
} = await orderTraces(this.id)
if (code == 1) {
this.shipment = shipment
this.buy = buy
this.delivery = delivery
this.finish = finish
this.order = order
this.take = take
this.isFirstLoading = false
} else {
setTimeout(() => uni.navigateBack(), 1000);
}
},
onCopy() {
copy(this.order.invoice_no)
}
}
};
</script>
<style lang="scss">
.goods-logistics {
padding-top: 20rpx;
.header {
padding: 20rpx;
.goods-img {
width: 160rpx;
height: 160rpx;
flex: none;
border-radius: 10rpx;
}
}
.goods {
position: relative;
.count {
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
background-color: rgba(0, 0, 0, 0.6);
padding: 4rpx 0;
}
}
.express {
width: 700rpx;
padding-top: 30rpx;
padding-bottom: 100rpx;
margin: 0 auto;
border-radius: 10rpx;
}
.express-address,
.express-item {
align-items: flex-start;
position: relative;
padding: 20rpx 0;
}
.express-left {
margin-top: 10rpx;
margin-right: 24rpx;
height: 100%;
position: absolute;
width: 40rpx;
flex: none;
.express-icon {
width: 40rpx;
height: 40rpx;
}
.express-line {
flex: 1;
border-left: 1px dotted #E5E5E5;
}
.express-doted {
width: 16rpx;
height: 16rpx;
border-radius: 50%;
background-color: #E5E5E5;
}
}
.express-right {
padding-left: 60rpx;
& .title,
& .dec {
margin-bottom: 5rpx;
}
}
.express-item:last-of-type .express-left .express-line {
border: none;
}
}
</style>

View File

@ -0,0 +1,258 @@
<template>
<view class="goods-reviews">
<order-goods :list="goods"></order-goods>
<view class="goods-evaluate row">
<view class="lable">商品评价</view>
<u-rate
name="goodsRate"
:count="5"
:size="42"
active-color="#FF2C3C"
v-model="goodsRate"
@change="goodsRateChange"
/>
<view
:class="'desc ' + (goodsRate <= 2 ? 'muted' : 'primary') + ' '"
v-show="!(goodsRate == 0)"
>
{{ goodsRateDesc }}
</view>
</view>
<view class="rate bg-white">
<view class="item row mb20">
<view class="lable">描述相符</view>
<u-rate name="descRate" :size="42" active-color="#FF2C3C" v-model="descRate" />
</view>
<view class="item row mb20">
<view class="lable">服务态度</view>
<u-rate name="serverRate" :size="42" active-color="#FF2C3C" v-model="serverRate" />
</view>
<view class="item row">
<view class="lable">配送服务</view>
<u-rate
name="deliveryRate"
:size="42"
active-color="#FF2C3C"
v-model="deliveryRate"
/>
</view>
</view>
<view class="goods-dec bg-white mt20">
<view class="title mb20 md bold">商品描述</view>
<view class="textarea mb20" style="background-color: #f5f5f5">
<u-input
v-model="comment"
placeholder="宝贝收到还满意吗,说说你的使用心得。分享给想买的他们吧!!"
type="textarea"
:clearable="false"
:height="240"
>
</u-input>
</view>
<uploader
preview-size="180rpx"
:mutiple="true"
:maxUpload="5"
:file-list="fileList"
@after-read="afterRead"
:deletable="true"
@delete="onDelete"
/>
</view>
<button form-type="submit" class="btn br60" type="primary" size="lg" @tap="onSubmit">
立即评价
</button>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { baseURL } from '@/config/app.js'
import { goodsComment, getCommentInfo } from '@/api/user'
import { uploadFile } from '@/utils/tools.js'
export default {
data() {
return {
goodsRate: 0,
descRate: 0,
serverRate: 0,
deliveryRate: 0,
goodsRateDesc: '',
fileList: [],
goods: [],
comment: '',
type: ''
}
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.id = options.id
this.getCommentInfoFun()
},
methods: {
onChange(e) {
this.type = e.value
},
goodsRateChange: function (e) {
let goodsRateDesc = ''
if (e <= 2) {
goodsRateDesc = '差评'
} else if (e == 3) {
goodsRateDesc = '中评'
} else {
goodsRateDesc = '好评'
}
this.goodsRateDesc = goodsRateDesc
},
onSubmit() {
let { goodsRate, fileList, comment, deliveryRate, descRate, serverRate } = this
let image = fileList.map((item) => item.base_url)
if (!goodsRate)
return this.$toast({
title: '请对商品进行评分'
})
if (!descRate)
return this.$toast({
title: '请对描述相符进行评分'
})
if (!serverRate)
return this.$toast({
title: '请对服务态度进行评分'
})
if (!deliveryRate)
return this.$toast({
title: '请对配送服务进行评分'
})
goodsComment({
id: parseInt(this.id),
goods_comment: goodsRate,
service_comment: serverRate,
express_comment: deliveryRate,
description_comment: descRate,
comment,
image
}).then((res) => {
if (res.code == 1) {
this.$toast(
{
title: '评价成功'
},
{
tab: 5,
url: '/bundle/pages/goods_comment_list/goods_comment_list?type=1'
}
)
}
})
},
onInput(e) {
this.comment = e.detail.value
},
getCommentInfoFun() {
getCommentInfo({
id: this.id
}).then((res) => {
if (res.code == 1) {
this.goods.push(res.data)
}
})
},
afterRead(e) {
const file = e
uni.showLoading({
title: '正在上传中...',
mask: true
})
file.map((item) => {
uploadFile(item.path)
.then((res) => {
uni.hideLoading()
this.fileList.push(res)
})
.catch(() => {
uni.hideLoading()
this.$toast({
title: '上传失败'
})
})
})
},
onDelete(index) {
this.fileList.splice(index, 1)
}
}
}
</script>
<style>
.goods-reviews {
padding: 20rpx 0 40rpx;
}
.goods-reviews .rate {
padding: 20rpx 30rpx;
}
.goods-reviews .rate .lable {
width: 170rpx;
}
.goods-reviews .goods-dec {
padding: 30rpx;
}
.goods-reviews .goods-dec .textarea {
height: 240rpx;
border-radius: 10rpx;
}
.goods-reviews .goods-dec .textarea textarea {
width: 100%;
height: 100%;
padding: 20rpx;
box-sizing: border-box;
}
.goods-reviews .btn {
width: 698rpx;
margin: 30rpx 26rpx 0;
}
.rate .item .desc {
margin-left: 30rpx;
}
.goods-reviews .goods-evaluate {
padding: 20rpx 30rpx;
background-color: white;
border: 1rpx solid #f2f2f2;
}
.goods-reviews .goods-evaluate .desc {
margin-left: 30rpx;
}
.goods-reviews .goods-evaluate .lable {
width: 170rpx;
}
</style>

View File

@ -0,0 +1,288 @@
<template>
<!-- pages/active/goods_seckill/goods_seckill.wxml -->
<view class="goods-seckill">
<navbar title="限时秒杀"></navbar>
<view class="banner">
<swipers :pid="14" height="284rpx" radius="10rpx" padding="20rpx"></swipers>
</view>
<view class="time-list">
<scroll-view style="height: 120rpx; white-space: nowrap;" :scroll-into-view="'item-' + currentView" scroll-x="true" scroll-with-animation="true">
<view v-for="(item, index) in seckillTime" :key="index" :id="'item-' + index" class="time-item column-center" @tap="exchangeTime" :data-id="item.id" :data-index="index">
<view :class="'xl bold ' + (item.active==1 ? 'primary': '')">{{ item.start_time }}</view>
<view :class="'sm br60 state ' + ( item.active === 1 ? 'bg-primary white': '' ) + ' ' + ( item.status === 2 ? 'muted': '' )" :style="item.active==1 ? 'background-color: #FF2C3C;color: white': ''">
{{ item.tips }}
</view>
</view>
</scroll-view>
</view>
<view class="goods-list">
<view v-for="(item, index) in seckillGoods" :key="index" class="goods-item row bg-white" @tap="goGoodsDetail" :data-id="item.id" :data-shop_id="item.shop_id">
<custom-image width="180rpx" height="180rpx" radius="10rpx" lazy-load class="goods-img mr20" :src="item.image" />
<view class="goods-info">
<view style="width: 490rpx" class="goods-name line2 mb10">{{item.name}}</view>
<label class="sale-info xs primary br60">
已抢{{item.sales_sum}}
</label>
<view class="info-footer row-between" style="margin-top: 5rpx">
<view class="price">
<price-format class="mr10" :price="item.seckill_price" color="#FF2C3C" :firstSize="34" :secondSize="26" :showSubscript="true" :subscriptSize="26" />
<price-format class="line-through muted" :price="item.min_price" color="#999999" :firstSize="24" :secondSize="24" :showSubscript="true" :subscriptSize="24" />
</view>
<button :class="'br60 white ' + (currentStatus == 2? 'bg-gray' : currentStatus == 1 ? 'primary-btn' : 'border-btn')" size="sm" @tap.stop="goGoodsDetail" :data-id="item.id" :data-shop_id="item.shop_id">{{currentStatus == 2? '已结束': currentStatus == 1 ? '立即抢购' : '未开始'}}</button>
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/goods_null.png"></image>
<view class="muted nr">暂无商品</view>
</view>
</loading-footer>
</view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getSeckillTime, getSeckillGoods } from "@/api/activity";
import { loadingType } from "@/utils/type";
import {loadingFun} from "@/utils/tools";
export default {
data() {
return {
currentView: 0,
bannerList: [],
seckillTime: [],
seckillGoods: [],
page: 1,
loadingStatus: "loading",
currentId: 0,
//
currentStatus: 0,
isDataNull: false,
id: ""
};
},
components: {
},
props: {},
onLoad: function (options) {
this.getSeckillTimeFun();
},
onReachBottom: function () {
this.getSeckillGoodsFun(this.currentId);
},
methods: {
//
getSeckillTimeFun() {
let {
currentView,
currentStatus
} = this;
getSeckillTime().then(res => {
if (res.code == 1) {
if (!res.data.length && res.data.length <= 0) {
this.isDataNull = true
return;
}
let index = res.data.findIndex(item => item.status == 1);
if (index == -1) {
index = res.data.findIndex(item => item.status == 0);
}
if (index == -1) {
index = 0;
}
res.data[index].active = 1;
currentView = index - 2;
currentStatus = res.data[index].status;
if (currentView < 0) {
currentView = 0;
}
this.seckillTime = res.data;
this.id = res.data[index].id;
this.currentView = currentView;
this.currentStatus = currentStatus;
this.getSeckillGoodsFun(res.data[index].id);
}
});
},
//
getSeckillGoodsFun(id) {
let {
page,
seckillGoods
} = this;
loadingFun(getSeckillGoods, page, seckillGoods, this.loadingStatus, {id: id}).then(res => {
if(res) {
this.page = res.page;
this.seckillGoods = res.dataList
this.loadingStatus = res.status
}
})
},
//
exchangeTime(e) {
let {
id,
index
} = e.currentTarget.dataset;
let {
currentView,
seckillTime,
currentStatus
} = this;
seckillTime.forEach((item, idx) => {
if (index == idx) {
item.active = 1;
currentStatus = item.status;
} else {
item.active = 0;
}
});
if (index == -1) {
index = 0;
}
currentView = index - 2;
if (currentView < 0) {
currentView = 0;
}
this.page = 1;
this.currentView = currentView;
this.isDataNull = false;
this.currentId = id;
this.seckillGoods = []
this.loadingStatus = loadingType.LOADING;
this.seckillTime = seckillTime;
this.currentStatus = currentStatus;
this.getSeckillGoodsFun(id);
},
goGoodsDetail(e) {
let {
id,
shop_id
} = e.currentTarget.dataset;
uni.navigateTo({
url: '/pages/goods_details/goods_details?id=' + id
});
},
goToBuy(e) {
console.log("goToBuy");
console.log(e);
}
}
};
</script>
<style lang="scss">
/* pages/active/goods_seckill/goods_seckill.wxss */
.bg-gray {
background-color: #CCCCCC !important;
}
.goods-seckill .banner {
}
.goods-seckill {
.time-list {
.time-item {
display: inline-flex;
width: 160rpx;
height: 100%;
.state {
padding: 0 10rpx;
}
}
}
.goods-list {
.goods-item{
padding: 30rpx;
.goods-img {
width: 180rpx;
height: 180rpx;
flex: none;
}
.goods-info {
flex: 1;
width: 470rpx;
.sale-info {
padding: 4rpx 16rpx;
background-color: #FFE9EB;
}
.info-footer {
.btn {
padding: 0 30rpx;
}
}
.progress-wrap {
.progress {
width: 260rpx;
display: inline-block;
}
}
}
}
}
}
.primary-btn {
padding: 0 30rpx;
background: linear-gradient(
270deg,
rgba(255, 44, 60, 1) 0%,
rgba(249, 95, 47, 1) 100%
);
}
.border-btn {
padding: 0 30rpx;
border: 1px solid #FF2C3C !important;
color: #FF2C3C !important;
}
.data-null {
padding-top: 100rpx;
.img-null {
width: 300rpx;
height: 300rpx;
flex: none;
}
}
</style>

View File

@ -0,0 +1,108 @@
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
<template>
<view class="hot-list">
<view class="header">
<view class="title row mb20">
<image src="../../static/images/icon_paixu.png" class="icon mr20"></image>
<text class="xs white">实时更新热销火爆商品</text>
</view>
<swipers :pid="15" height="284rpx" radius="10rpx"></swipers>
</view>
<view class="main">
<view v-if="hasHot">
<goods-list type="hot" :list="goodsList"></goods-list>
<loading-footer :status="status">
</loading-footer>
</view>
<view v-else class="column-center" style="padding-top: 400rpx">
<image class="img-null" src="/static/images/goods_null.png"></image>
<text class="lighter">暂无商品~</text>
</view>
</view>
</view>
</template>
<script>
import {
loadingType
} from '@/utils/type';
import {
getHotGoods
} from '@/api/store';
import {loadingFun} from '@/utils/tools'
export default {
data() {
return {
goodsList: [],
page: 1,
status: loadingType.LOADING,
hasHot: true
};
},
components: {},
props: {},
onLoad(options) {
this.getHotGoodsFun();
},
onReachBottom() {
this.getHotGoodsFun();
},
methods: {
async getHotGoodsFun() {
let {
page,
status,
goodsList
} = this;
const data = await loadingFun(getHotGoods,page, goodsList,status)
if (!data) return
this.page = data.page
this.goodsList = data.dataList
this.status = data.status
}
}
};
</script>
<style lang="scss">
.hot-list {
background: url(../../static/images/hot_list_bg.png) no-repeat;
background-size: 100% 330rpx;
padding: 62rpx 30rpx 0;
min-height: 100vh;
box-sizing: border-box;
.main {
padding: 0 0 20rpx;
}
.data-null {
padding-top: 150rpx;
}
}
</style>

View File

@ -0,0 +1,208 @@
<template>
<!--pages/input_express_info/input_express_info.wxml-->
<view class="input-express-info">
<form @submit="formSubmit">
<view class="input-contain mt20">
<view class="input-item row">
<view class="nr label">物流公司</view>
<input class="input" placeholder="请输入物流公司名称" :value="formInfo.express" name="express"></input>
</view>
<view class="input-item row">
<view class="nr label">快递单号</view>
<input class="input" placeholder="请输入快递单号" :value="formInfo.number" name="number"></input>
</view>
<view class="input-item row">
<view class="nr label">备注说明</view>
<input class="input" placeholder="选填" :value="formInfo.remark" name="remark"></input>
</view>
</view>
<view class="upload-contain mt20">
<view class="header row">
<view class="nr normal">上传凭证</view>
<view class="sm muted ml20">(请上传快递单号凭证</view>
</view>
<view class="upload">
<uploader :deletable="true" @delete="handleImage" preview-size="160rpx" max-count="1" :file-list="fileList" @after-read="afterRead" />
</view>
</view>
<view class="submit-btn">
<button size="lg" class=" br60 bg-primary white lg" form-type="submit">提交</button>
</view>
</form>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { inputExpressInfo } from '@/api/user';
import { baseURL } from '@/config/app.js';
export default {
data() {
return {
fileList: [],
formInfo: {
express: '',
number: '',
remark: ''
}
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let {
id
} = options; // id
this.afterSalesId = id;
},
methods: {
afterRead(e) {
const file = e
uni.showLoading({
title: '正在上传中...',
mask: true
});
file.forEach(item => {
this.uploadFile(item.path).then(res => {
uni.hideLoading();
this.fileList.push(res);
});
})
},
formSubmit(e) {
let {
value
} = e.detail;
let {
fileList
} = this;
console.log(value);
if (!value.express) return this.$toast({
title: '请填写物流公司名称'
});
if (!value.number) return this.$toast({
title: '请填写快递单号'
});
let data = {
id: this.afterSalesId,
express_name: value.express,
invoice_no: value.number,
express_remark: value.remark,
express_image: fileList.length <= 0 ? '' : fileList[0].url
};
this.inputExpressInfoFun(data);
},
uploadFile(path) {
return new Promise(resolve => {
uni.uploadFile({
url: `${baseURL}/api/file/formimage`,
filePath: path,
name: 'file',
fileType: 'image',
cloudPath: '',
success: res => {
console.log('uploadFile res ==> ', res)
const {
fileList
} = this;
let data = JSON.parse(res.data);
if (data.code == 1) {
resolve(data.data);
}
},
fail: (err) => {
console.log(err)
}
});
});
},
inputExpressInfoFun(data) {
inputExpressInfo(data).then(res => {
if (res.code == 1) {
this.$toast({
title: '提交成功'
}, () => {
uni.navigateBack();
});
uni.$emit("refreshsale")
}
});
},
handleImage(index) {
this.fileList.splice(index)
}
}
};
</script>
<style>
/* pages/input_express_info/input_express_info.wxss */
.input-express-info {
}
.input-contain {
background-color: white;
}
.input-contain .input-item {
padding: 24rpx;
}
.input-item .label{
width: 152rpx;
}
.input-item .input {
flex: 1;
}
.upload-contain {
background-color: white;
padding: 24rpx 20rpx 44rpx;
}
.upload-contain .header {
margin-bottom: 30rpx;
}
.submit-btn {
margin-top: 50rpx;
margin-left: 26rpx;
margin-right: 26rpx;
}
</style>

View File

@ -0,0 +1,153 @@
<template>
<view class="pages">
<view class="invite-fans column column-center">
<image :src="path" mode="widthFix" class="poster"></image>
<invite-poster v-if="showPoster" :config="{
avatar: userInfo.avatar,
nickname: userInfo.nickname,
code:inviteCode,
link: link,
qrCode: qrCode,
poster: poster
}" @success="handleSuccess" />
<view class="bg-white footer flex1">
<view class="" style="margin-bottom: 40rpx;">
<view class="mb10 sm lighter">我的邀请码</view>
<view class="row row-between">
<view class="font-size-44">{{inviteCode}}</view>
<view class="sm mr30 copy-btn" @tap="$copy(inviteCode || '')">点击复制</view>
</view>
</view>
<!-- #ifndef H5 -->
<button class="save-btn br60" size="lg" @tap="saveImageToAlbum">保存到相册</button>
<!-- #endif -->
<!-- #ifdef H5 -->
<button class="save-btn br60" size="lg">长按保存到相册</button>
<!-- #endif -->
</view>
</view>
<loading-view v-show="loading"></loading-view>
</view>
</template>
<script>
import {
// apiMnpQrCode,
getShareMnQrcode
} from '@/api/app'
import {
baseURL,
basePath
} from '@/config/app'
import { apiDistributionPoster } from '@/api/user'
import { mapGetters } from 'vuex'
export default {
data() {
return {
path: '',
qrCode: '',
loading: true,
showPoster: false,
poster: ''
};
},
async onLoad() {
await this.getPoster()
// #ifdef MP-WEIXIN
this.getMnpQrCode()
// #endif
// #ifdef APP-PLUS || H5
this.showPoster = true
// #endif
},
methods: {
async getPoster() {
const res = await apiDistributionPoster()
this.poster = res.data.poster
},
getMnpQrCode() {
// apiMnpQrCode().then(res => {
// this.qrCode = res.qr_code
// this.showPoster = true
// })
getShareMnQrcode({
id: '', // idid
url: 'pages/index/index', //
type: 0, // 0- 1- 2-
})
.then((res) => {
console.log('shareRes', res)
this.qrCode = res.data.qr_code
this.showPoster = true
})
},
saveImageToAlbum() {
// #ifndef H5
uni.saveImageToPhotosAlbum({
filePath: this.path,
success: res => {
this.$toast({
title: "保存成功"
});
},
fail: err => {
this.$toast({
title: '保存失败'
});
}
});
// #endif
// #ifdef H5
this.$toast({
title: 请长按图片保存
})
// #endif
},
handleSuccess(val) {
this.path = val
this.loading = false
}
},
computed: {
...mapGetters(['inviteCode','userInfo']),
link() {
return `${baseURL}${basePath}?invite_code=${this.inviteCode}`
}
}
};
</script>
<style lang="scss">
page {
padding: 0
}
.invite-fans {
min-height: 100vh;
overflow: hidden;
.poster {
width: 600rpx;
margin: 40rpx 0;
}
.footer {
padding: 30rpx;
width: 100%;
}
.copy-btn {
color: $-color-primary;
}
.save-btn {
color: #fff;
background-color: $-color-primary;
}
}
</style>

View File

@ -0,0 +1,71 @@
<template>
<view class="license">
<view class="box bg-white">
<template v-if="images.length">
<view v-for="(item, index) in images" :key="index" class="m-b-25" @click="viewImage(index)">
<u-image :src="item" width="100%" height="348rpx">
</u-image>
</view>
</template>
<template v-else>
<view class="data-null xs muted">
<image src="../../../static/images/order_null.png" mode=""></image>
<view>
商家暂时还没有上传资质哦~
</view>
</view>
</template>
</view>
</view>
</template>
<script>
import {
getCopyright
} from "@/api/user";
export default {
data() {
return {
images: []
}
},
methods: {
getCopyrightFunc() {
getCopyright().then(res => {
this.images = res.data
})
},
viewImage(current) {
uni.previewImage({
current,
urls: this.images// http
});
}
},
onLoad() {
this.getCopyrightFunc()
}
}
</script>
<style lang="scss">
.license {
padding: 30rpx;
.box {
padding: 30rpx;
border-radius: 16rpx;
.data-null {
padding-top: 200rpx;
height: 700rpx;
text-align: center;
image {
width: 200rpx;
height: 200rpx;
}
}
}
}
</style>

View File

@ -0,0 +1,155 @@
<template>
<view class="live-broadcast">
<!-- #ifdef MP-WEIXIN -->
<view class="broadcast-list">
<view class="broadcast-item" @tap="navigateTo(item)" v-for="(item, index) in lists" :key="index">
<view class="img-wrap">
<u-image width="100%" height="100%" :src="item.cover_img"></u-image>
<view class="tag xxs" :class="{
active: item.status == 101
}">
<u-icon v-if="item.status == 101" name="play-right-fill" size="24"></u-icon>
<text v-else class="circel"></text>
<text class="ml10">{{ item.live_status }}</text>
</view>
<view class="tips line1">{{ item.name }}</view>
</view>
<view class="info">
<view class="md">
主播{{ item.anchor_name }}
<text class="xs">直播商品{{item.goods}}</text>
</view>
<view class="muted xs mt20">直播时间{{item.start_time}} {{item.end_time}}</view>
</view>
</view>
</view>
<loading-footer :status="status" slot-empty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png"></image>
<text class="nr muted">暂无直播~</text>
</view>
</loading-footer>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<view class="data-null column-center" style="padding-top: 400rpx;">
<image class="img-null" src="/static/images/order_null.png"></image>
<text class="nr muted">非小程序端暂不支持直播~</text>
</view>
<!-- #endif -->
</view>
</template>
<script>
import {
loadingType
} from "@/utils/type";
import {
loadingFun
} from "@/utils/tools"
import {
getLiveRoom
} from "@/api/store"
export default {
data() {
return {
lists: [],
page: 1,
status: loadingType.LOADING
};
},
methods: {
navigateTo(item) {
const roomId = [item.roomid];
wx.navigateTo({
url: `plugin-private://wx2b03c6e691cd7370/pages/live-player-plugin?room_id=${roomId}`
});
},
getLists() {
let {
lists,
status,
page
} = this;
loadingFun(getLiveRoom, page, lists, status).then(res => {
if (res) {
this.page = res.page;
this.lists = res.dataList
this.status = res.status
}
})
}
},
onLoad(options) {
this.getLists();
},
onReachBottom() {
this.getLists();
},
onPullDownRefresh() {
this.page = 1
this.status = loadingType.LOADING
this.getLists();
},
}
</script>
<style lang="scss">
.live-broadcast {
.broadcast-list {
padding: 20rpx 20rpx 0;
overflow: hidden;
.broadcast-item {
border-radius: 12rpx;
overflow: hidden;
background-color: #fff;
&:not(:last-of-type) {
margin-bottom: 20rpx;
}
.img-wrap {
height: 300rpx;
position: relative;
color: #fff;
.tag {
position: absolute;
top: 0;
border-radius: 0 60rpx 60rpx 0;
background: #ccc;
padding: 8rpx 20rpx;
&.active{
background: linear-gradient(#ff2c3c 0%, #f95f2f 100%);
}
.circel {
display: inline-block;
width: 14rpx;
height: 14rpx;
background: #fff;
border-radius: 50%;
}
}
.tips {
position: absolute;
background: linear-gradient(rgba(255, 255, 255, 0) 0%, #808080 100%);
bottom: 0;
width: 100%;
font-weight: 500;
font-size: 30rpx;
padding: 42rpx 20rpx 16rpx;
}
}
.info {
padding: 20rpx;
}
}
}
}
</style>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,88 @@
<template>
<!--pages/message_center/message_center.wxml-->
<view class="message-center-container">
<navigator v-for="(item, index) in list" :key="index" class="message-item row" hover-class="none" :url="'/bundle/pages/notice/notice?type=' + item.type">
<image style="width: 76rpx;height: 76rpx;flex: none" :src="item.img"></image>
<view class="item-info ml20 column">
<view class="item-title">{{item.title}}</view>
<view class="item-desc line1 muted">{{item.content}}</view>
</view>
</navigator>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getNoticeLists, getMessageLists } from '@/api/store';
export default {
data() {
return {
list: []
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getMessageListsFun();
},
methods: {
getMessageListsFun() {
getMessageLists().then(res => {
if (res.code == 1) {
this.list = res.data;
}
});
}
}
};
</script>
<style lang="scss">
/* pages/message_center/message_center.wxss */
.message-center-container {
margin-top: 10rpx;
padding: 0 20rpx;
background-color: white;
.message-item {
padding: 32rpx 0;
&:not(:last-of-type) {
border-bottom: $-solid-border;
}
.item-info {
font-size: 32rpx;
flex: 1;
overflow: hidden;
.item-title{
font-size: 32rpx;
}
.item-desc{
font-size: 26rpx;
}
}
}
}
</style>

View File

@ -0,0 +1,149 @@
<template>
<!--pages/notice/notice.wxml-->
<view class="notice-container">
<view v-for="(item, index) in lists" :key="index" class="notice-item mb20">
<view class="row-between item-header">
<view class="header-title md">{{item.title}}</view>
<view class="header-time muted xs">{{item.create_time}}</view>
</view>
<view class="item-main">
<view class="content sm lighter">{{item.content}}</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/news_null.png" />
<text class="nr muted">暂无消息通知</text>
</view>
</loading-footer>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getNoticeLists } from '@/api/store';
import { loadingType } from '@/utils/type';
export default {
data() {
return {
page: 1,
loadingStatus: loadingType.LOADING,
lists: []
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.type = options.type;
switch (this.type) {
case "system":
uni.setNavigationBarTitle({
title: '系统通知'
});
break;
case "earning":
uni.setNavigationBarTitle({
title: '收益通知'
});
break;
}
this.getNoticeListsFun();
},
onReachBottom: function () {
this.getNoticeListsFun();
},
methods: {
getNoticeListsFun() {
let {
page,
loadingStatus,
lists
} = this;
if (loadingStatus == loadingType.FINISHED) return;
getNoticeLists({
type: this.type,
page_no: page
}).then(res => {
if (res.code == 1) {
let {
list,
more
} = res.data;
lists.push(...list);
this.lists = lists;
this.page ++;
if (!more) {
this.loadingStatus = loadingType.FINISHED
}
if (lists.length <= 0) {
this.loadingStatus = loadingType.EMPTY
return;
}
} else {
this.loadingStatus = loadingType.ERROR
}
});
}
}
};
</script>
<style lang="scss">
/* pages/notice/notice.wxss */
.notice-container {
padding: 0 20rpx;
margin-top: 8rpx;
.notice-item {
background-color: white;
padding: 0rpx 20rpx 30rpx;
border-radius: 10rpx;
.item-header {
padding: 19rpx 0;
border-bottom: $-solid-border;
.header-title {
font-weight: bold;
}
}
.item-main {
.content {
margin-top: 15rpx;
}
}
}
.data-null {
padding-top: 100rpx;
}
}
</style>

View File

@ -0,0 +1,177 @@
<template>
<view class="post-sale">
<view class="contain">
<tabs :active="active" :line-width="40" @change="onChange" sticky>
<tab v-for="(item, index) in afterSale" :key="index" :title="item.name">
<after-sales-list :ref="item.type" :type="item.type" v-if="item.isShow"></after-sales-list>
</tab>
</tabs>
</view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getAfterSaleList, applyAfterSale, getGoodsInfo, inputExpressInfo, cancelApply, afterSaleDetail, applyAgain } from "@/api/user";
import { AfterSaleType } from "@/utils/type";
export default {
data() {
return {
active: 0,
afterSaleType: AfterSaleType.NORMAL,
afterSaleList: [],
afterSale: [{
name: '售后申请',
type: AfterSaleType.NORMAL,
isShow: true
}, {
name: '处理中',
type: AfterSaleType.HANDLING,
isShow: false
}, {
name: '已处理',
type: AfterSaleType.FINISH,
isShow: false
}]
};
},
components: {
},
props: {},
onReachBottom: function () {
const {
active
} = this;
let afterSaleType = AfterSaleType.NORMAL
switch(active) {
case 0:
afterSaleType = AfterSaleType.NORMAL;
break;
case 1:
break;
case 2:
afterSaleType = AfterSaleType.FINISH;
break;
default:
afterSaleType = AfterSaleType.NORMAL
break;
}
let myComponent = this.$refs[afterSaleType][0];
if (myComponent.getAfterSaleListFun) {
myComponent.getAfterSaleListFun();
}
},
methods: {
onChange(e) {
// const {
// name
// } = e.detail;
this.changeShow(e);
},
changeShow(active) {
const {
afterSale
} = this;
let type = active == 0 ? AfterSaleType.NORMAL : active == 1 ? AfterSaleType.HANDLING : AfterSaleType.FINISH
let index = afterSale.findIndex(item => {
return item.type == type;
});
if (index != -1) {
this.afterSale[index].isShow = true;
this.active = type == AfterSaleType.NORMAL ? 0 : type == AfterSaleType.HANDLING ? 1 : 2
}
if(this.$refs[type] && this.$refs[type][0].getAfterSaleListFun()) {
this.$refs[type][0].getAfterSaleListFun()
}
},
goPage(e) {
let {
url
} = e.currentTarget.dataset;
uni.navigateTo({
url: url
});
}
}
};
</script>
<style lang="scss">
image {
width: 100%;
height: 100%;
}
.post-sale {
.contain {
.sale-list {
padding: 20rpx 0;
.sale-item {
.sale-header {
padding: 20rpx 24rpx;
.store-name {
font-weight: bold;
font-family:PingFang SC;
line-height: 40rpx;
}
}
.sale-goods-show {
padding: 20rpx 24rpx;
.goods-img {
height: 160rpx;
width: 160rpx;
}
.goods-desc {
margin-left: 24rpx;
}
.sale-status {
padding: 20rpx 60rpx;
background-color: #F6F6F6;
}
}
.sale-footer {
padding: 0 24rpx 22rpx;
.btn {
padding: 9rpx 34rpx;
font-family: PingFang SC;
}
.grey-btn {
border: 1px solid #CCCCCC;
padding: 9rpx 34rpx;
font-family: PingFang SC;
}
}
}
}
}
}
</style>

View File

@ -0,0 +1,104 @@
<template>
<!--bundle/pages/prize_record/prize_record.wxml-->
<view class="prize-record-container">
<view v-for="(item, index) in lists" :key="index" class="prize-record-item row">
<custom-image :src="item.prize_image" style="width: 90rpx;height: 90rpx" radius="6rpx" />
<view class="prize-record-info">
<view class="lg">{{item.prize_name}}</view>
<view class="mt20 row-between">
<view class="xs lighter">{{item.create_time}}</view>
<view class="xs primary need-integral-tips" v-if="item.need_tips">{{item.need_tips}}</view>
</view>
<view class="xs primary mt10">
{{item.send_tips}}
</view>
<!-- <view class="xs lighter">领取时间{{item.create_time}}</view> -->
</view>
</view>
<loading-footer slotEmpty :status="loadingStatus">
<view class="data-null column-center" slot="empty">
<image src="../../static/images/null_gift.png" class="img-null"></image>
<text class="xs muted">暂无抽奖记录</text>
</view>
</loading-footer>
</view>
</template>
<script>
// bundle/pages/prize_record/prize_record.js
import {
loadingType
} from '@/utils/type';
import {
getUserRecord
} from '@/api/user';
import {
loadingFun
} from "@/utils/tools"
export default {
data() {
return {
loadingStatus: loadingType.LOADING,
page: 1,
lists: []
};
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.getUserRecordFun();
},
onReachBottom: function() {
this.getUserRecordFun();
},
methods: {
getUserRecordFun() {
let {
loadingStatus,
lists,
page
} = this;
loadingFun(getUserRecord, page, lists, loadingStatus).then(res => {
if (res) {
this.page = res.page;
this.lists = res.dataList
this.loadingStatus = res.status
}
})
}
}
};
</script>
<style lang="scss">
/* bundle/pages/prize_record/prize_record.wxss */
.prize-record-container {
padding: 0 20rpx;
.prize-record-item {
align-items: flex-start;
margin-top: 20rpx;
background-color: white;
padding: 26rpx 24rpx;
border-radius: 10rpx;
.prize-record-info {
margin-left: 24rpx;
flex: 1
}
}
}
.data-null {
padding-top: 200rpx;
}
</style>

View File

@ -0,0 +1,81 @@
<template>
<view class="recharge-code">
<view class="list">
<view v-for="(item, index) in lists" :key="index" class="item bg-white">
<view class="row-between">
<view class="black mb10">{{item.desc}}</view>
<view class="xl primary">+{{item.total}}</view>
</view>
<view class="xs muted">{{item.create_time}}</view>
</view>
</view>
<loading-footer :status="status" slotEmpty>
<view class="data-null column-center" slot="empty" style="padding-top: 200rpx">
<image class="img-null" src="/static/images/order_null.png" />
<text class="nr muted">暂无记录</text>
</view>
</loading-footer>
</view>
</template>
<script>
import {
getRechargeRecord
} from '@/api/user'
import {
loadingType
} from "@/utils/type";
import {
loadingFun
} from "@/utils/tools"
export default {
data() {
return {
lists: [],
page: 1,
status: loadingType.LOADING
}
},
onLoad: function(options) {
this.getRechargeRecordFun();
},
onReachBottom: function() {
this.getRechargeRecordFun();
},
methods: {
getRechargeRecordFun(type) {
let {
lists,
status,
page
} = this;
loadingFun(getRechargeRecord, page, lists, status).then(res => {
if (res) {
this.page = res.page;
this.lists = res.dataList
this.status = res.status
}
})
}
}
}
</script>
<style lang="scss">
.recharge-code {
padding-top: 20rpx;
.list {
.item {
padding: 20rpx 30rpx;
&:not(:last-of-type) {
border-bottom: $-solid-border;
}
}
}
}
</style>

View File

@ -0,0 +1,120 @@
<template>
<view>
<!--pages/server_explan/server_explan.wxml-->
<view class="main">
<u-parse :html="article_content" />
</view>
<!--<import src="/wxParse/wxParse.wxml"></import>-->
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getServerProto, getPrivatePolicy, getAfterSaleGuar } from '@/api/app';
export default {
data() {
return {
article_content: ""
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let {
type
} = options;
type = parseInt(type); // 0 ==> 1 ==> 2 ==>
uni.setNavigationBarTitle({
title: type == 0 ? '服务协议' : type == 1 ? '隐私政策' : '售后保障'
});
switch (type) {
case 0:
this.getServerProtoFun();
break;
case 1:
this.getPrivatePolicyFun();
break;
case 2:
this.getAfterSaleGuarFun();
break;
default:
this.getServerProtoFun();
break;
}
},
methods: {
//
getServerProtoFun() {
getServerProto().then(res => {
if (res.code == 1) {
//wxParse.wxParse('content', 'html', res.data, this, 15)
setTimeout(() => {
this.article_content = res.data;
}, 200);
}
});
},
//
getPrivatePolicyFun() {
getPrivatePolicy().then(res => {
if (res.code == 1) {
//wxParse.wxParse('content', 'html', res.data, this, 15)
setTimeout(() => {
this.article_content = res.data;
}, 200);
}
});
},
//
getAfterSaleGuarFun() {
getAfterSaleGuar().then(res => {
if (res.code == 1) {
//wxParse.wxParse('content', 'html', res.data, this, 15)
setTimeout(() => {
this.article_content = res.data;
}, 200);
}
});
}
}
};
</script>
<style lang="scss">
/* pages/server_explan/server_explan.wxss */
.main {
padding: 20rpx;
/* min-height: 100vh; */
}
</style>

View File

@ -0,0 +1,154 @@
<template>
<view class="set-pwd">
<view class="input-container bg-white">
<view class="input-item row" v-if="hasPayPwd">
<view class="input-label md normal">原密码</view>
<u-input
class="flex1"
type="password"
v-model="originPwd"
placeholder="请输入原来的转账密码"
/>
</view>
<view class="input-item row">
<view class="input-label md normal">转账密码</view>
<u-input
class="flex1"
type="password"
v-model="setPwd"
:placeholder="hasPayPwd ? '请输入新的转账密码' : '请输入转账密码'"
/>
</view>
<view class="input-item row">
<view class="input-label md normal">确认密码</view>
<u-input
class="flex1"
type="password"
v-model="comfirmPwd"
placeholder="请再次确认密码"
/>
</view>
<navigator
hover-class="none"
url="/bundle/pages/forget_pay_pwd/forget_pay_pwd"
class="row-end lighter xs mr20"
v-if="hasPayPwd"
>忘记原密码</navigator
>
<button
size="lg"
type="primary"
class="btn bg-primary white br60 row-center"
@tap="setPasswordFun"
>
确认
</button>
</view>
</view>
</template>
<script>
import { hasPayPassword, setPassword, changePayPassword } from '@/api/user'
export default {
data() {
return {
hasPayPwd: false,
setPwd: '',
comfirmPwd: '',
originPwd: ''
}
},
onLoad() {
this.hasPayWord()
},
methods: {
async setPasswordFun() {
let { setPwd, comfirmPwd, originPwd, hasPayPwd } = this
if (hasPayPwd) {
if (!originPwd) {
this.$toast({
title: '请输入原来的转账密码'
})
return
}
}
if (!setPwd) {
this.$toast({
title: '请输入新的转账密码'
})
return
}
if (!comfirmPwd) {
this.$toast({
title: '请填写确认密码'
})
return
}
if (setPwd != comfirmPwd) {
this.$toast({
title: '两次密码输入不一致'
})
return
}
if (setPwd.length < 4 || setPwd.length > 8) {
this.$toast({
title: '请输入长度为4-8位的密码'
})
return
}
let data = {
pay_password: setPwd
}
const { msg, code } = hasPayPwd
? await changePayPassword({
origin_pay_password: originPwd,
new_pay_password: setPwd
})
: await setPassword(data)
if (code == 1) {
this.$toast(
{
title: msg
},
{ tab: 3 }
)
}
},
hasPayWord() {
hasPayPassword().then((res) => {
if (res.code == 1) {
this.hasPayPwd = true
}
})
}
}
}
</script>
<style lang="scss">
.set-pwd {
padding-top: 20rpx;
.input-container {
padding: 20rpx 0 100rpx;
border-radius: 20rpx;
.input-item {
margin: 0 30rpx;
height: 88rpx;
margin-bottom: 30rpx;
border-bottom: 1px solid #d7d7d7;
.input-label {
width: 180rpx;
flex: none;
}
}
.btn {
margin: 80rpx 30rpx 0;
}
}
}
</style>

View File

@ -0,0 +1,116 @@
<template>
<!--pages/sign_detail/sign_detail.wxml-->
<view class="sign-detail-container">
<view v-for="(item, index) in detailList" :key="index">
<view class="sign-item row-between">
<view class="flexnone">
<view class="nr sign-type">{{item.source_type}}</view>
<view class="muted xs mt10" style="line-height: 33rpx">{{item.create_time}}</view>
</view>
<view class="column-end" style="align-items: flex-end;">
<text class="lg" :class="{
primary: item.change_type == 1,
normal: item.change_type == 2
}" style="line-height: 45rpx">{{item.change_amount}}</text>
<view v-if="item.remark" style="width: 300rpx" class="xxs primary">备注{{ item.remark }}</view>
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image src="/static/images/order_null.png" class="img-null"></image>
<view class="muted sm">暂无其他记录</view>
</view>
</loading-footer>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { loadingType } from '@/utils/type';
import { getAccountLog } from '@/api/user.js';
import {loadingFun} from "@/utils/tools"
export default {
data() {
return {
rule: '',
loadingStatus: loadingType.LOADING,
detailList: [],
page: 1
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getAccountLogFun();
},
onReachBottom: function () {
this.getAccountLogFun();
},
methods: {
getAccountLogFun() {
let {
detailList,
loadingStatus,
page
} = this;
loadingFun(getAccountLog, page, detailList, loadingStatus, {source: 2}).then(res => {
if(res) {
this.page = res.page;
this.detailList = res.dataList
this.loadingStatus = res.status
}
})
}
}
};
</script>
<style lang="scss">
/* pages/sign_detail/sign_detail.wxss */
.sign-detail-container {
margin-top: 20rpx;
}
.sign-detail-container .sign-item {
padding: 18rpx 30rpx;
background-color: #fff;
border-bottom: $-solid-border;
}
.sign-type {
line-height: 40rpx;
}
.data-null {
padding-top: 100rpx;
}
</style>

View File

@ -0,0 +1,60 @@
<template>
<!--pages/sign_rule/sign_rule.wxml-->
<view style="padding: 30rpx">
<text class="nr" style="line-height: 36rpx">{{rule}}</text>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getSignRule } from "@/api/user.js";
export default {
data() {
return {
rule: ""
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getSignRuleFun();
},
methods: {
getSignRuleFun() {
getSignRule().then(res => {
if (res.code == 1) {
this.rule = res.data
}
});
}
}
};
</script>
<style>
/* pages/sign_rule/sign_rule.wxss */
</style>

View File

@ -0,0 +1,263 @@
<template>
<view class="store-list">
<!-- #ifndef APP-PLUS -->
<map
v-if="location.latitude"
style="width: 750rpx; height: 400rpx"
show-location
:latitude="location.latitude"
:longitude="location.longitude"
:markers="markers"
/>
<!-- #endif -->
<view class="scroll">
<scroll-view style="height: 100%" :scroll-y="true">
<view class="lists">
<view
:class="[
'item',
'bg-white',
'row',
{ 'item-disabled': !(item.business_status * 1) },
]"
v-for="(item, index) in lists"
:key="index"
@tap="onSelect(item)"
>
<view class="flex1">
<view class="name mb20">
<text class="bold lg black">{{ item.name }}</text>
<text class="muted xs ml10">{{ item.distance }}</text>
</view>
<view class="address black xs mb20 row">
<image
class="icon1"
src="../../static/images/icon_shop.png"
></image>
{{ item.shop_address }}
</view>
<view class="time black xs row">
<image
class="icon1"
src="../../static/images/icon_time.png"
></image>
{{ item.business_start_time }} - {{ item.business_end_time }}
</view>
</view>
<view class="ml20 flexnone">
<image
class="icon2"
src="../../static/images/icon_call.png"
@tap.stop="onCall(item.mobile)"
></image>
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view slot="empty" class="data-null column-center">
<image
src="/static/images/address_null.png"
class="img-null"
></image>
<view class="muted xs">暂无门店</view>
</view>
</loading-footer>
</scroll-view>
</view>
</view>
</template>
<script>
import { getStoreList } from "@/api/store";
import { loadingType } from "@/utils/type";
import { loadingFun } from "@/utils/tools";
export default {
data() {
return {
loadingStatus: loadingType.LOADING,
page: 1,
lists: [],
location: {},
markers: [],
};
},
methods: {
onCall(phone) {
uni.makePhoneCall({
phoneNumber: String(phone),
});
},
async getLocation() {
const [error, res] = await uni.getLocation({
// #ifndef APP
type: 'gcj02',
// #endif
});
if (!res) {
// #ifdef MP-WEIXIN
this.getAuthorize();
// #endif
return;
}
if (error) {
return this.$toast({
title: error.msg,
});
}
return {
latitude: res.latitude,
longitude: res.longitude,
};
},
async getAuthorize() {
const [error, res] = await uni.showModal({
title: "您已拒绝地理位置权限",
content: "是否进入权限管理,调整授权?",
});
if (res.confirm) {
// #ifdef MP
const [error, res] = await uni.openSetting();
if (res) this.getLocation();
// #endif
// #ifdef APP-PLUS
// #ifdef APP-PLUS
// android
if (uni.getSystemInfoSync().platform == 'android') {
var Intent = plus.android.importClass('android.content.Intent');
var Settings = plus.android.importClass('android.provider.Settings');
var intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
var main = plus.android.runtimeMainActivity();
main.startActivity(intent); // GPS
}
// ios
if (uni.getSystemInfoSync().platform == 'ios') {
var UIApplication = plus.ios.import("UIApplication");
var application2 = UIApplication.sharedApplication();
var NSURL2 = plus.ios.import("NSURL");
var setting2 = NSURL2.URLWithString("App-Prefs:root=Privacy&path=LOCATION");
application2.openURL(setting2);
plus.ios.deleteObject(setting2);
plus.ios.deleteObject(NSURL2);
plus.ios.deleteObject(application2);
}
// #endif
// #endif
} else if (res.cancel) {
this.$Router.go(-1);
}
},
getLists() {
let { loadingStatus, page, lists } = this;
loadingFun(getStoreList, page, lists, loadingStatus, this.location).then(
(res) => {
if (res) {
this.page = res.page;
this.lists = res.dataList;
this.loadingStatus = res.status;
this.markers = this.lists.map((item) => {
return {
id: item.id,
latitude: item.latitude,
longitude: item.longitude,
iconPath: "../../static/images/icon_marker.png",
width: 34,
height: 34,
callout: {
content: item.name,
padding: 5,
borderRadius: 4,
fontSize: 13,
display: "ALWAYS",
},
};
});
}
}
);
},
onSelect(info) {
if (!(info.business_status * 1))
return this.$toast({
title: "不在营业中",
});
//
uni.$emit("store", info);
uni.navigateBack();
},
},
async onLoad() {
const res = await this.getLocation();
if (res) {
this.location = res;
this.getLists();
} else {
this.$toast({ title: "获取定位失败" });
}
},
onReachBottom: function () {
this.getLists();
},
};
</script>
<style lang="scss">
page {
padding: 0;
height: 100%;
}
.store-list {
height: 100%;
display: flex;
flex-direction: column;
.scroll {
flex: 1;
.lists {
padding: 20rpx;
.item {
padding: 30rpx;
border-radius: 14rpx;
&:not(:last-of-type) {
margin-bottom: 20rpx;
}
&-disabled {
position: relative;
&::before {
z-index: 9;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: block;
content: "";
width: 100%;
height: 100%;
background-color: rgba(255, 255, 255, 0.5);
}
}
.icon1 {
width: 36rpx;
height: 36rpx;
margin-right: 10rpx;
}
.icon2 {
width: 60rpx;
height: 60rpx;
margin-right: 10rpx;
}
}
}
}
}
</style>

View File

@ -0,0 +1,170 @@
<template>
<!--pages/user_bill/user_bill.wxml-->
<view class="transfer-record">
<tabs :active="active" line-width="40" @change="onChange">
<tab title="全部">
<view class="list mt20">
<view v-for="(item, index) in lists" :key="index" class="item bg-white row">
<view class="flexnone mr20">
<image class="avatar" :src="item.avatar"></image>
</view>
<view class="flex1 mr20">
<view class="black mb10">{{item.nickname}}</view>
<view class="xs muted">会员ID:{{item.sn}}</view>
<view class="xs muted">{{item.create_time}}</view>
</view>
<view :class="'lg flexnone ' + (item.type == 1 ? 'primary' : '')">
{{item.type == 1 ? '+' : '-'}}{{item.money}}
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png" />
<text class="nr muted">暂无记录</text>
</view>
</loading-footer>
</tab>
<tab title="转出">
<view class="list mt20">
<view v-for="(item, index) in lists" :key="index" class="item bg-white row">
<view class="flexnone mr20">
<image class="avatar" :src="item.avatar"></image>
</view>
<view class="flex1 mr20">
<view class="black mb10">{{item.nickname}}</view>
<view class="xs muted">会员ID:{{item.sn}}</view>
<view class="xs muted">{{item.create_time}}</view>
</view>
<view :class="'lg flexnone ' + (item.type == 1 ? 'primary' : '')">
{{item.type == 1 ? '+' : '-'}}{{item.money}}
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png" />
<text class="nr muted">暂无转出记录</text>
</view>
</loading-footer>
</tab>
<tab title="转入">
<view class="list mt20">
<view v-for="(item, index) in lists" :key="index" class="item bg-white row">
<view class="flexnone mr20">
<image class="avatar" :src="item.avatar"></image>
</view>
<view class="flex1 mr20">
<view class="black mb10">{{item.nickname}}</view>
<view class="xs muted">会员ID:{{item.sn}}</view>
<view class="xs muted">{{item.create_time}}</view>
</view>
<view :class="'lg flexnone ' + (item.type == 1 ? 'primary' : '')">
{{item.type == 1 ? '+' : '-'}}{{item.money}}
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png"></image>
<text class="nr muted">暂无转入记录</text>
</view>
</loading-footer>
</tab>
</tabs>
</view>
</template>
<script>
import {
transferRecord
} from "@/api/user";
import {
loadingType
} from "@/utils/type";
import {
loadingFun
} from "@/utils/tools"
export default {
data() {
return {
active: 0,
lists: [],
page: 1,
loadingStatus: loadingType.LOADING
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.active = parseInt(options.type || 0);
this.transferRecordFun(this.active);
},
onReachBottom: function() {
this.transferRecordFun(this.active);
},
methods: {
onChange(e) {
this.active = e;
this.cleanStatus();
this.transferRecordFun(e);
},
cleanStatus() {
//
this.page = 1;
this.lists = [];
this.loadingStatus = loadingType.LOADING
},
transferRecordFun(type) {
let changeType = 'all';
type == 0 ? changeType = 'all' : type == 1 ? changeType = 'out' : changeType = 'in';
let {
lists,
loadingStatus,
page
} = this;
loadingFun(transferRecord, page, lists, loadingStatus, {
type: changeType
}).then(res => {
if (res) {
this.page = res.page;
this.lists = res.dataList
this.loadingStatus = res.status
}
})
}
}
};
</script>
<style lang="scss">
.transfer-record {
.list {
.item {
padding: 20rpx 30rpx;
border-bottom: $-solid-border;
align-items: flex-start;
.avatar {
width: 68rpx;
height: 68rpx;
border-radius: 50%;
}
}
}
}
.data-null {
padding-top: 150rpx;
}
</style>

View File

@ -0,0 +1,185 @@
<template>
<!--pages/user_bill/user_bill.wxml-->
<view class="user-bill">
<tabs :active="active" line-width="40" @change="onChange">
<tab title="全部">
<view class="list mt20">
<view v-for="(item, index) in lists" :key="index" class="item">
<view class="bill-list bg-white">
<view class="bill-item row-between">
<view>
<view class="black mb10">{{item.source_type}}</view>
<view class="xs muted">{{item.create_time}}</view>
</view>
<view :class="'lg ' + (item.change_type == 1 ? 'income' : '')">{{item.change_amount}}</view>
</view>
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png" />
<text class="nr muted">暂无记录</text>
</view>
</loading-footer>
</tab>
<tab title="支出">
<view class="list mt20">
<view v-for="(item, index) in lists" :key="index" class="item">
<view class="bill-list bg-white">
<view class="bill-item row-between">
<view>
<view class="black mb10">{{item.source_type}}</view>
<view class="xs muted">{{item.create_time}}</view>
</view>
<view class="lg">{{item.change_amount}}</view>
</view>
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png" />
<text class="nr muted">暂无支出记录</text>
</view>
</loading-footer>
</tab>
<tab title="收入">
<view class="list mt20">
<view v-for="(item, index) in lists" :key="index" class="item">
<view class="bill-list bg-white">
<view class="bill-item row-between">
<view>
<view class="black mb10">{{item.source_type}}</view>
<view class="xs muted">{{item.create_time}}</view>
</view>
<view class="lg income">{{item.change_amount}}</view>
</view>
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png"></image>
<text class="nr muted">暂无收入记录</text>
</view>
</loading-footer>
</tab>
</tabs>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getAccountLog } from "@/api/user";
import { loadingType } from "@/utils/type";
import {loadingFun} from "@/utils/tools"
export default {
data() {
return {
active: 0,
lists: [],
page: 1,
loadingStatus: loadingType.LOADING
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
console.log(options.type, "option.type")
this.active = parseInt(options.type);
this.getAccountLogFun(this.active);
},
onReachBottom: function () {
this.getAccountLogFun(this.active);
},
methods: {
onChange(e) {
this.active = e;
this.cleanStatus();
this.getAccountLogFun(e);
},
cleanStatus() {
//
this.page = 1;
this.lists = [];
this.loadingStatus = loadingType.LOADING
},
getAccountLogFun(type) {
let changeType = 0;
changeType = type == 0 ? 0 : type == 1 ? 2 : 1;
let {
lists,
loadingStatus,
page
} = this;
loadingFun(getAccountLog, page, lists, loadingStatus, { source: 1, type: changeType}).then(res => {
if(res) {
this.page = res.page;
this.lists = res.dataList
this.loadingStatus = res.status
}
})
}
}
};
</script>
<style lang="scss">
/* pages/user_bill/user_bill.wxss */
.user-bill {
.list {
.item {
.time{
padding: 30rpx;
}
.bill-list {
.bill-item {
padding: 20rpx 30rpx;
border-bottom: $-solid-border;
.income {
color: $-color-primary;
}
}
}
}
}
}
.order-null {
padding-top: 200rpx;
}
.data-null {
padding-top: 150rpx;
}
</style>

View File

@ -0,0 +1,313 @@
<template>
<view class="user-fans-box">
<view class="header">
<view class="top-bar row bg-white md">
<view :class="'bar-item row-center ' + (active == 'all' ? 'item-active' : '')" @tap="changeTab" data-active="all">全部粉丝</view>
<view :class="'bar-item row-center ' + (active == 'first' ? 'item-active' : '')" @tap="changeTab" data-active="first">一级粉丝</view>
<view :class="'bar-item row-center ' + (active == 'second' ? 'item-active' : '')" @tap="changeTab" data-active="second">二级粉丝</view>
</view>
<u-search
v-model="keyword"
shape="round"
background="white"
:show-action="true"
action-text="确定"
placeholder="请输入搜索关键词"
@search="onSearch"
@custom="onSearch"
/>
<view class="sort-bar row">
<view class="sort-bar-item row-center nr" @tap="sortStatusChange" data-sort-type="0">
<view :class="sortType == 0 ? 'item-active' : ''">团队排序</view>
<view class="column">
<trigonometry direction="up" :color="fansSort == 'asc' ? '#FF2C3C' : '#585858'" size="small"></trigonometry>
<trigonometry :color="fansSort == 'desc' ? '#FF2C3C' : '#585858'" size="small"></trigonometry>
</view>
</view>
<view class="sort-bar-item row-center nr" @tap="sortStatusChange" data-sort-type="1">
<view :class="sortType == 1 ? 'item-active' : ''">金额排序</view>
<view class="column">
<trigonometry direction="up" :color="moneySort == 'asc' ? '#FF2C3C' : '#585858'" size="small"></trigonometry>
<trigonometry :color="moneySort == 'desc' ? '#FF2C3C' : '#585858'" size="small"></trigonometry>
</view>
</view>
<view class="sort-bar-item row-center nr" @tap="sortStatusChange" data-sort-type="2">
<view :class="sortType == 2 ? 'item-active' : ''">订单排序</view>
<view class="column">
<trigonometry direction="up" :color="orderSort == 'asc' ? '#FF2C3C' : '#585858'" size="small"></trigonometry>
<trigonometry :color="orderSort == 'desc' ? '#FF2C3C' : '#585858'" size="small"></trigonometry>
</view>
</view>
</view>
</view>
<view class="content">
<view class="data-null" v-if="false">
<view class="muted">暂无相关数据...</view>
</view>
<view v-else class="card-box">
<view v-for="(item, index) in fansObject" :key="index" class="card-item row-between">
<view class="row">
<view class="card-img">
<u-image :src="item.avatar" round width="100%" height="100%" />
</view>
<view class="fans-info ml10">
<view class="fans-name row">{{item.nickname}}</view>
<view class="row lighter mt5">
<view>{{item.mobile}}</view>
<view class="ml20">{{item.create_time}}</view>
</view>
</view>
</view>
<view class="column xs">
<view class="msg"><span class="primary">{{item.fans_team}} </span></view>
<view class="mt5 msg"><span>{{item.fans_order}} </span></view>
<view class="mt5 msg"><span>{{item.fans_money}} </span></view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png"></image>
<text>暂无相关数据...</text>
</view>
</loading-footer>
</view>
</view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { loadingType, SortType, FansType } from '@/utils/type';
import { getUserFans } from '@/api/user';
import {loadingFun} from '@/utils/tools'
export default {
data() {
return {
active: FansType.ALL,
loadingStatus: loadingType.LOADING,
sortType: 0,
keyword: "",
page: 1,
fansSort: SortType.ASC,
moneySort: SortType.NONE,
orderSort: SortType.NONE,
fansObject: []
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getUserFansFun();
},
onReachBottom() {
this.getUserFansFun();
},
methods: {
onSearch() {
console.log(this.keyword);
this.cleanStatus();
this.getUserFansFun();
},
changeTab(e) {
let {
active
} = e.currentTarget.dataset;
this.active = active
this.cleanStatus();
this.getUserFansFun();
},
//
getUserFansFun() {
const {
fansSort,
moneySort,
orderSort,
active,
loadingStatus,
keyword,
fansObject,
page,
} = this;
const inputData = {
type: active,
keyword,
fans: fansSort,
money: moneySort,
order: orderSort
};
loadingFun(getUserFans, page, fansObject, loadingStatus, inputData).then(res => {
if(res) {
this.page = res.page;
this.fansObject = res.dataList
this.loadingStatus = res.status
}
})
},
//
cleanStatus() {
this.loadingStatus = loadingType.LOADING;
this.fansObject = [];
this.page = 1
},
//
sortStatusChange(e) {
let {
sortType
} = e.currentTarget.dataset;
let {
fansSort,
moneySort,
orderSort
} = this;
this.sortType = parseInt(sortType)
switch (parseInt(sortType)) {
case 0:
//
if (fansSort == SortType.NONE || fansSort == SortType.DESC) {
this.fansSort = SortType.ASC;
this.moneySort = SortType.NONE
this.orderSort = SortType.NONE
}
else if (fansSort == SortType.ASC) {
this.fansSort = SortType.DESC;
this.moneySort = SortType.NONE;
this.orderSort = SortType.NONE;
}
break;
case 1:
//
if (moneySort == SortType.DESC || moneySort == SortType.NONE) {
this.moneySort = SortType.ASC;
this.fansSort = SortType.NONE;
this.orderSort = SortType.NONE
} else if (moneySort == SortType.ASC) {
this.moneySort = SortType.DESC;
this.fansSort = SortType.NONE;
this.orderSort = SortType.NONE;
}
break;
case 2:
//
if (orderSort == SortType.DESC || orderSort == SortType.NONE) {
this.orderSort = SortType.ASC;
this.moneySort = SortType.NONE;
this.fansSort = SortType.NONE;
} else if (orderSort == SortType.ASC) {
this.orderSort = SortType.DESC;
this.moneySort = SortType.NONE;
this.fansSort = SortType.NONE;
}
break;
}
this.cleanStatus();
this.getUserFansFun();
}
}
};
</script>
<style lang="scss">
/* pages/user_fans/user_fans.wxss */
.user-fans-box {
.header {
.top-bar {
padding: 18rpx 50rpx;
height: 100rpx;
.bar-item {
flex: 1;
line-height: 34rpx;
height: 100%;
&:not(:last-of-type) {
margin-right: 54rpx;
}
}
.item-active {
color: white;
background-color: $-color-primary;
border-radius: 100rpx;
height: 100%;
}
}
.sort-bar {
background-color: white;
height: 80rpx;
.sort-bar-item {
flex: 1;
line-height: 40rpx;
height: 100%;
.item-active {
color: $-color-primary;
}
}
}
}
}
.content {
.data-null {
padding-top: 200rpx;
line-height: 40rpx;
}
.card-box {
margin-top: 20rpx;
.card-item {
padding: 20rpx;
background-color: white;
.card-img {
width: 100rpx;
height: 100rpx;
flex: none;
}
.fans-info {
.fans-name {
line-height: 44rpx;
}
}
.msg {
line-height: 32rpx;
text-align: right;
}
&:not(:nth-last-of-type(3)) {
border-bottom: $-solid-border;
}
}
}
}
</style>

View File

@ -0,0 +1,71 @@
<template>
<view class="user-group">
<tabs :active="active" @change="changeShow">
<tab v-for="(item, index) in group" :key="index" :title="item.name">
<group-list v-if="item.isShow" :ref="'group' + item.type" :group-type="item.type"></group-list>
</tab>
</tabs>
</view>
</template>
<script>
import { groupType } from "@/utils/type";
export default {
data() {
return {
active: "",
typeStr: "",
group: [{
name: '全部',
type: groupType.ALL,
isShow: false
}, {
name: '拼团中',
type: groupType.PROGESS,
isShow: false
}, {
name: '拼团成功',
type: groupType.SUCCESS,
isShow: false
}, {
name: '拼团失败',
type: groupType.FAIL,
isShow: false
}]
};
},
onLoad: function (options) {
const{group} = this
let type = options.type || groupType.ALL;
let index = group.findIndex(item => item.type == type)
this.changeShow(index);
},
onPullDownRefresh: function () {
const {active, group} = this
console.log(this.$refs['group' + group[active].type])
this.$refs['group' + group[active].type][0].reflesh()
},
onReachBottom: function () {
const {active, group} = this
console.log(this.$refs['group' + group[active].type])
this.$refs['group' + group[active].type][0].getUserGroupFun()
},
methods: {
changeShow(index) {
if(index != -1) {
this.active = index
this.group[index].isShow = true
}
},
}
};
</script>
<style>
</style>

View File

@ -0,0 +1,330 @@
<template>
<view>
<!-- pages/user_payment/user_payment.wxml -->
<view class="user-payment">
<form report-submit="true">
<view class="payment bg-white">
<view class="md normal row" style="padding: 66rpx 66rpx 0">
充值金额
</view>
<view class="input row">
<text style="font-size: 46rpx"></text>
<input :placeholder="placeholder" type="digit" @focus="setPlaceholder"
@blur="setPlaceholderStatus" :value="number" @input="onInput"></input>
</view>
<view class="tip muted mt20 row">
提示当前余额为
<text class="primary">{{userInfo.user_money || 0}}</text>
</view>
</view>
<button size="lg" class="btn white br60" @tap="rechargeRights">
立即充值
</button>
</form>
<view class="fast-payment-container">
<view class="title bold normal row">推荐充值</view>
<view class="fast-pay row wrap">
<view v-for="(item, index) in rechargeObj" :key="index" class="fast-pay-item bg-white column-center"
@tap="temRecharge" :data-id="item.id">
<view class="hot-recharge white" v-if="item.is_recommend">热门充值</view>
<view class="price primary bold">
<price-format weight="500" :firstSize="42" :secondSize="42" :price="item.money">
</price-format>
<text class="xxl" style="font-weight: 500"></text>
</view>
<view class="preferential primary xs">{{item.tips}}</view>
</view>
</view>
</view>
</view>
<u-popup class="pay-popup" v-model="showPopup" closeable round mode="center">
<view class="content bg-white">
<image class="img-icon" src="../../static/images/recharge_success.png"></image>
<view class="xxl bold mt10">充值成功</view>
<view v-if="rechargeInfo.give_integral || rechargeInfo.give_growth" class="lg"
style="margin-top: 50rpx">恭喜您获得 <text><text class="primary"
v-if="rechargeInfo.give_integral">{{rechargeInfo.give_integral}}</text> 积分</text> <text
v-if="rechargeInfo.give_growth">+ <text
class="primary">{{rechargeInfo.give_growth}}</text>成长值</text></view>
<button class="br60 btn" type="primary" size="md" @tap="onShowPopup">好的谢谢</button>
</view>
</u-popup>
<loading-view id="van-toast" v-if="showLoading" backgroundColor="rgba(0, 0, 0, 0)"></loading-view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | LikeShop100%
// +----------------------------------------------------------------------
// |
// |
// |
// |
// | Giteehttps://gitee.com/likeshop_gitee/likeshop
// | 访https://www.likemarket.net
// | 访https://home.likemarket.net
// | 访http://doc.likemarket.net
// |
// |
// +----------------------------------------------------------------------
// | Author: LikeShopTeam
// +----------------------------------------------------------------------
import {
rechargeTemplate,
recharge,
getUser
} from '@/api/user';
import {
prepay
} from '@/api/app';
import {
wxpay
} from '@/utils/pay';
export default {
data() {
return {
navRecharge: ['账户充值', '佣金转入'],
active: 0,
number: '',
placeholder: "0.00",
rechargeObj: [],
showPopup: false,
rechargeInfo: {},
userInfo: {},
showLoading: false
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.rechargeTemplateFun();
this.getUserInfoFun();
uni.$on('payment', params => {
if (params.result) {
this.onShowPopup()
this.getUserInfoFun()
uni.navigateBack()
}
})
},
onUnload() {
uni.$off('payment')
},
methods: {
onShowPopup() {
this.showPopup = !this.showPopup
},
setPlaceholderStatus: function(event) {
if (event.detail.value.length == 0) {
this.placeholder = '0.00'
}
},
setPlaceholder: function() {
this.placeholder = ''
},
getUserInfoFun() {
getUser().then(res => {
if (res.code == 1) {
this.userInfo = res.data
}
});
},
rechargeTemplateFun() {
rechargeTemplate().then(res => {
if (res.code == 1) {
this.rechargeObj = res.data
}
});
},
rechargeRights() {
const {
number
} = this;
this.rechargeFun({
money: Number(number)
});
},
temRecharge(e) {
let {
id
} = e.currentTarget.dataset;
this.rechargeFun({
id
});
},
rechargeFun(obj) {
this.showLoading = true
recharge(obj).then(({ code, data, msg }) => {
if (code != 1) throw new Error(msg)
this.rechargeInfo = data
uni.navigateTo({
url: `/pages/payment/payment?from=${'recharge'}&order_id=${data.id}`
})
}).catch(err => {
console.log(err)
}).finally(() => {
this.showLoading = false
})
},
checkInputText: function(text) {
var reg = /^(\.*)(\d+)(\.?)(\d{0,2}).*$/g;
if (reg.test(text)) {
//
text = text.replace(reg, '$2$3$4');
} else {
//
text = '';
}
return text; //2
},
onInput(e) {
let number = e.detail.value;
number = this.checkInputText(number);
this.number = number
}
}
};
</script>
<style lang="scss">
/* pages/user_payment/user_payment.wxss */
.user-payment {
padding: 20rpx 30rpx;
.payment {
text-align: center;
border-radius: 20rpx;
overflow: hidden;
padding-bottom: 74rpx;
.nav {
margin: 20rpx 95rpx 80rpx;
.item {
flex: 1;
.line {
width: 110rpx;
height: 2px;
}
}
}
.line {
width: 110rpx;
height: 2px;
}
.input {
margin-left: 66rpx;
margin-top: 35rpx;
margin-right: 30rpx;
input {
height: 94rpx;
text-align: left;
font-size: 66rpx;
margin-left: 30rpx;
}
border-bottom: $-solid-border;
}
.tip {
margin: 25rpx 66rpx;
}
}
.btn {
background: linear-gradient(79deg, rgba(249, 95, 47, 1) 0%, rgba(255, 44, 60, 1) 100%);
margin: 70rpx 0 30rpx;
}
.fast-payment-container {
margin-top: 72rpx;
.title {
font-size: 38rpx;
line-height: 53rpx;
}
.fast-pay {
margin-top: 40rpx;
.fast-pay-item {
position: relative;
width: 214rpx;
height: 150rpx;
border-radius: 10rpx;
margin-bottom: 16rpx;
border: 1px solid $-color-primary;
&:not(:nth-of-type(3n)) {
margin-right: 24rpx;
}
.hot-recharge {
position: absolute;
padding: 2rpx 10rpx;
background: linear-gradient(180deg, #FF2C3C 0%, #F95F2F 100%);
border-radius: 0 10rpx 0 10rpx;
font-size: 20rpx;
top: 0;
right: 0;
}
.price {
font-size: 42rpx;
line-height: 50rpx;
}
.preferential {
line-height: 32rpx;
}
}
}
}
}
.pay-popup {
.content {
padding: 40rpx 0;
text-align: center;
width: 560rpx;
border-radius: 20rpx;
}
.img-icon {
width: 168rpx;
height: 118rpx;
display: inline-block;
}
.btn {
margin: 80rpx 60rpx 0;
}
}
</style>

View File

@ -0,0 +1,702 @@
<template>
<view class="user-profile-container mt10">
<view class="user-profile">
<view class="user-avatar-box row-start" @click="handleUser">
<!-- <button
class="column column-center"
hover-class="none"
open-type="chooseAvatar"
@chooseavatar="onChooseAvatar"
@click="onChooseAvatar"
>
</button> -->
<image
class="user-avatar"
:src="
userInfo.avatar != ''
? userInfo.avatar
: '../../static/images/default_avatar.png'
"
@click="handleUser"
>
</image>
<view class="row-between flex1">
<view class="ml30 text-name">
<view class="">
{{ userInfo.nickname }}
</view>
<view> ID:{{ userInfo.sn }} </view>
</view>
<u-icon name="arrow-right" />
</view>
<!-- <view class="muted xs" @click="handleUser">点击修改头像</view> -->
</view>
<!-- <view class="row-info row bdb-line" @click="changeName">
<view class="label md">昵称</view>
<view class="md row" style="flex: 1">{{ userInfo.nickname }}</view>
<u-icon name="arrow-right" />
</view> -->
<!-- <view class="row-info row bdb-line" @click="changeSex()">
<view class="label md">性别</view>
<view class="md row" :class="userInfo.sex == 0 ? 'muted' : ''" style="flex: 1">
{{ userInfo.sex == 0 ? '未设置' : userInfo.sex == 1 ? '男' : '女' }}
</view>
<u-icon name="arrow-right" />
</view> -->
<!-- <view class="row-info row bdb-line">
<view class="label md">手机号</view>
<view class="md row" :class="{ muted: !userInfo.mobile }" style="flex: 1">
{{ userInfo.mobile ? userInfo.mobile : '未绑定' }}
</view> -->
<!-- #ifdef H5 || APP-PLUS -->
<!-- <view class="bd-btn br60 row-center" @click="showModifyMobile">
{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}
</view> -->
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<!-- <button
class="bd-btn br60 row-center"
size="sm"
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
>
{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}
</button> -->
<!-- #endif -->
<!-- </view> -->
<view class="row-info row-between bdb-line mt10" @tap="toSetPayPwd">
<view class="label md">转账密码</view>
<u-icon name="arrow-right" />
</view>
<!-- #ifdef H5 -->
<view class="row-info row-between bdb-line" @tap="bindWechat" v-if="!userInfo.oa_auth">
<view class="label md">微信授权</view>
<u-icon name="arrow-right" />
</view>
<!-- #endif -->
<!-- #ifndef MP-WEIXIN -->
<view class="row-info row-between" @click="showPwdPop">
<view class="label md">登录密码</view>
<view class="row">
<view class="muted nr">点击设置</view>
<u-icon name="arrow-right" />
</view>
</view>
<!-- #endif -->
<view class="row-info row-between bdb-line mt10" @click="goToExplain(0)">
<view class="label md">服务协议</view>
<u-icon name="arrow-right" />
</view>
<view class="row-info row-between bdb-line" @click="goToExplain(1)">
<view class="label md">隐私政策</view>
<u-icon name="arrow-right" />
</view>
<view class="row-info row-between bdb-line" @click="goLicense()">
<view class="label md">版权信息</view>
<u-icon name="arrow-right" />
</view>
<view class="row-info row-between">
<view class="label md">关于我们</view>
<view>v{{ version }}</view>
</view>
<view class="bg-primary white save-btn row-center lg" @click="logout">退出登录</view>
<!-- 版权信息 -->
<view class="license xs" v-if="appConfig.copyright_info">
<view>{{ appConfig.copyright_info }}</view>
<view>{{ appConfig.icp_number }}</view>
</view>
</view>
<u-popup type="center" closeable v-model="showMobile" mode="center" border-radius="14">
<view class="modify-container column-center bg-white" v-show="showMobile">
<view class="title xl">{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}</view>
<view class="modify-row row" v-if="userInfo.mobile">
<view style="width: 56px; border-right: 1px solid #e5e5e5">+86</view>
<view style="margin-left: 15px">{{ userInfo.mobile }}</view>
</view>
<view class="modify-row row" v-else>
<view style="width: 71px">手机号</view>
<input v-model="new_mobile" placeholder="请输入绑定手机号" />
</view>
<view class="modify-row row">
<view style="width: 71px">验证码</view>
<input
v-model="smsCode"
style="padding-left: 5px; width: 130px"
placeholder="请输入验证码"
/>
<view class="send-code-btn nr row-center" @click="$sendSms">
<u-verification-code
:keep-running="true"
ref="uCode"
@change="codeChange"
unique-key="page-b"
>
</u-verification-code>
<view class="xs">{{ tips }}</view>
</view>
</view>
<view class="modify-row row" v-if="userInfo.mobile">
<view style="width: 71px">新手机号</view>
<input v-model="new_mobile" placeholder="请输入新的手机号码" />
</view>
<view class="primary mt10"
>{{
userInfo.mobile ? '更改' : '绑定'
}}手机号码成功后您的账号将会变更为该设置号码</view
>
<view class="btn bg-primary white row-center" @click="$changeUserMobile">确定</view>
</view>
</u-popup>
<!-- 昵称修改组件 -->
<u-popup
v-model="showNickName"
:closeable="true"
:maskCloseAble="false"
mode="center"
border-radius="14"
>
<view
class="modify-container column-center bg-white"
style="width: 70vw; padding: 24rpx"
>
<view class="title xl">修改用户名</view>
<form @submit="changeNameConfirm">
<u-form-item label="新昵称" :labelWidth="120">
<input
style="height: 60rpx"
class="nr"
:value="userInfo.nickname"
name="nickname"
type="nickname"
placeholder="请输入新的昵称"
/>
</u-form-item>
<button class="btn bg-primary white row-center" form-type="submit">确定</button>
</form>
</view>
</u-popup>
<u-popup v-model="showPwd" closeable mode="center" border-radius="14">
<view class="modify-container column-center bg-white" v-show="showPwd">
<view class="title xl">设置密码</view>
<view class="modify-row row">
<view style="width: 56px; border-right: 1px solid #e5e5e5">+86</view>
<view style="margin-left: 15px">{{ userInfo.mobile }}</view>
</view>
<view class="modify-row row">
<view style="width: 142rpx">验证码</view>
<input
v-model="smsCode"
style="padding-left: 10rpx; width: 260rpx"
placeholder="请输入验证码"
/>
<view class="send-code-btn nr row-center" @click="$sendSms">
<u-verification-code
:keep-running="true"
ref="uCode"
@change="codeChange"
unique-key="page-a"
>
</u-verification-code>
<view class="xs">{{ tips }}</view>
</view>
</view>
<view class="modify-row row">
<view style="width: 71px">设置密码</view>
<input type="password" v-model="pwd" placeholder="请输入新密码" />
</view>
<view class="modify-row row">
<view style="width: 71px">确认密码</view>
<input type="password" v-model="comfirmPwd" placeholder="再次输入新密码确认" />
</view>
<view class="btn bg-primary white row-center" @click="$forgetPwd">确定</view>
</view>
</u-popup>
<u-picker
mode="selector"
v-model="showPicker"
:default-selector="[0]"
:range="sexList"
@confirm="onConfirm"
/>
<view class="xs muted" style="margin: 50rpx 0;">
<view class="row-center">
likeshop 提供免费开源商城系统
</view>
<view class="row-center">
© likeshop.cn
</view>
</view>
</view>
</template>
<script>
import { userLogout, getUserInfo, changeUserMobile, setUserInfo, setWechatInfo } from '@/api/user'
import { version } from '@/config/app'
import { sendSms, forgetPwd } from '@/api/app'
import { bindOawechat } from '@/api/user'
import { SMSType } from '@/utils/type'
import { mapState, mapGetters } from 'vuex'
import { uploadFile, isWeixinClient, trottle } from '@/utils/tools'
import { getWxCode, getUserProfile } from '@/utils/login'
import wechath5 from '@/utils/wechath5'
const FieldType = {
NONE: '',
SEX: 'sex',
NICKNAME: 'nickname',
AVATAR: 'avatar',
MOBILE: 'mobile'
}
export default {
name: 'userProfile',
data() {
return {
version: version,
fileList: [],
userInfo: {},
new_mobile: '',
smsCode: '',
newNickname: '',
sexList: ['男', '女'],
fieldType: FieldType.NONE,
showPicker: false,
showMobile: false,
showPwd: false,
showNickName: false,
tips: '',
canSendSms: true,
pwd: '',
comfirmPwd: '',
smsType: SMSType.FINDPWD,
code: ''
}
},
methods: {
oaAuth() {
wechath5.getWxUrl()
},
bindWechat() {
this.oaAuth()
},
handleUser() {
console.log(123465)
uni.redirectTo({
url: '/bundle/pages/user_set/user_set'
})
},
codeChange(text) {
this.tips = text
},
onChooseAvatar(e) {
this.fieldType = FieldType.AVATAR
// #ifndef MP-WEIXIN
// uView"-JS"uniuni.navigateTo
uni.$u.route({
// ""
url: '/components/uview-ui/components/u-avatar-cropper/u-avatar-cropper',
//
params: {
// px
destWidth: 300,
// px
rectWidth: 200,
// 'png'"jpg"
fileType: 'jpg'
}
})
// #endif
// #ifdef MP-WEIXIN
if (e.detail.avatarUrl) {
console.log(e.detail.avatarUrl)
this.uploadImage(e.detail.avatarUrl)
}
// #endif
},
//
async changeNameConfirm(e) {
this.fieldType = FieldType.NICKNAME
this.newNickname = e.detail.value.nickname
if (!this.newNickname)
return this.$toast({
title: '请输入新的昵称'
})
await this.$setUserInfo(this.newNickname)
this.showNickName = false
},
// end
logout() {
// 退
userLogout({
token: this.token
}).then((res) => {
if (res.code == 1) {
this.$store.commit('LOGOUT')
this.$toast({
title: '退出成功'
})
setTimeout(() => {
uni.redirectTo({
url: '/pages/login/login'
})
}, 500)
}
})
},
goToExplain(value) {
uni.navigateTo({
url: '/bundle/pages/server_explan/server_explan?type=' + value
})
},
goLicense() {
uni.navigateTo({
url: '/bundle/pages/license/license'
})
},
toSetPayPwd() {
if (!this.userInfo.mobile)
return this.$toast({
title: '请先设置手机号'
})
uni.navigateTo({
url: '/bundle/pages/set_pay_pwd/set_pay_pwd'
})
},
//
$sendSms(type) {
if (!this.canSendSms) return
sendSms({
mobile: this.userInfo.mobile || this.new_mobile,
key: this.smsType
}).then((res) => {
if (res.code == 1) {
this.$toast({
title: res.msg
})
this.$refs.uCode.start()
}
})
},
$getUserInfo() {
getUserInfo().then((res) => {
if (res.code == 1) {
this.userInfo = res.data
}
})
},
//
showModifyMobile() {
this.smsCode = ''
this.new_mobile = ''
this.showMobile = true
this.smsType = this.userInfo.mobile ? SMSType.CHANGE_MOBILE : SMSType.BIND
},
$changeUserMobile() {
if (!this.smsCode) {
this.$toast({
title: '请输入验证码'
})
return
}
if (!this.new_mobile) {
this.$toast({
title: '请输入新的手机号码'
})
return
}
changeUserMobile({
mobile: this.userInfo.mobile,
new_mobile: this.new_mobile,
code: this.smsCode,
action: this.userInfo.mobile ? 'change' : ''
}).then((res) => {
if (res.code == 1) {
this.showMobile = false
this.$toast({
title: res.msg
})
this.$getUserInfo()
}
})
},
// end
//
async $setUserInfo(value) {
const res = await setUserInfo({
field: this.fieldType,
value: value
})
if (res.code == 1) {
this.$toast({
title: res.msg
})
this.$getUserInfo()
}
},
// end
timeChange(timestamp) {
console.log(timestamp, 'timestamp')
},
onConfirm(value) {
this.$setUserInfo(value[0] + 1)
this.showPicker = false
},
changeSex(e) {
this.showPicker = true
this.fieldType = FieldType.SEX
},
//
countDownFinish() {
this.canSendSms = true
},
//
showPwdPop() {
if (!this.userInfo.mobile) {
this.$toast({
title: '请绑定手机后再设置密码'
})
return
}
this.smsCode = ''
this.smsType = SMSType.FINDPWD
this.showPwd = true
},
$forgetPwd() {
let { smsCode, pwd, comfirmPwd } = this
if (!smsCode) {
this.$toast({
title: '请填写短信验证码'
})
return
}
if (!pwd) {
this.$toast({
title: '请输入新密码'
})
return
}
if (!comfirmPwd) {
this.$toast({
title: '再次输入新密码确认'
})
return
}
if (pwd != comfirmPwd) {
this.$toast({
title: '两次密码输入不一致'
})
return
}
let data = {
mobile: this.userInfo.mobile,
code: smsCode,
password: pwd,
repassword: comfirmPwd
}
forgetPwd(data).then((res) => {
if (res.code == 1) {
this.showPwd = false
this.$toast({
title: '设置密码成功'
})
this.$getUserInfo()
}
})
},
// end
//
changeName() {
this.fieldType = FieldType.NICKNAME
this.newNickname = ''
this.showNickName = true
},
// end
async getPhoneNumber(e) {
const { encryptedData, iv } = e.detail
let data = {
code: this.code,
encrypted_data: encryptedData,
iv
}
this.fieldType = FieldType.MOBILE
if (encryptedData) {
this.$changeUserMobileMP(data)
}
},
$changeUserMobileMP(data) {
changeUserMobile(data).then((res) => {
if (res.code == 1) {
this.$toast({
title: res.msg
})
this.$getUserInfo()
}
// #ifdef MP-WEIXIN
getWxCode().then((res) => {
this.code = res
})
// #endif
})
},
uploadImage(path) {
uni.showLoading({
title: '正在上传中...',
mask: true
})
uploadFile(path)
.then((res) => {
uni.hideLoading()
this.$setUserInfo(res.url)
})
.catch(() => {
uni.hideLoading()
this.$toast({
title: '上传失败'
})
})
}
},
async onLoad(options) {
// #ifdef H5
const bindCode = options.code
if (bindCode) {
if (Array.isArray(bindCode)) bindCode = bindCode.pop()
await bindOawechat({ code: bindCode })
}
// #endif
this.$getUserInfo()
// #ifdef MP-WEIXIN
getWxCode().then((res) => {
this.code = res
})
// #endif
//
uni.$on('uAvatarCropper', (path) => {
console.log(path)
this.uploadImage(path)
})
this.getUserProfile = trottle(this.getUserProfile, 500, this)
},
onUnload() {
uni.$off('uAvatarCropper')
},
computed: {
...mapState(['token']),
...mapGetters(['appConfig'])
}
}
</script>
<style lang="scss">
.user-profile-container {
.user-profile {
border-top-left-radius: 28rpx;
border-top-right-radius: 28rpx;
.user-avatar-box {
padding: 30rpx 20rpx;
background-color: white;
border-top-left-radius: 28rpx;
border-top-right-radius: 28rpx;
.user-avatar {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
}
}
.row-info {
padding: 30rpx 20rpx;
background-color: white;
.label {
width: 180rpx;
}
.bd-btn {
padding: 8rpx 24rpx;
border: 1px solid $-color-primary;
color: $-color-primary;
}
}
.license {
margin-top: 80rpx;
color: #a7a7a7;
text-align: center;
}
.bdb-line {
border-bottom: 1rpx solid #e5e5e5;
}
.save-btn {
margin-top: 40rpx;
height: 88rpx;
margin-left: 54rpx;
margin-right: 54rpx;
border-radius: 10rpx;
box-sizing: border-box;
}
.updata-btn {
margin: 0 30rpx;
margin-top: 40rpx;
background-color: #0cc267;
}
}
.modify-container {
padding-left: 30rpx;
padding-right: 30rpx;
padding-bottom: 30rpx;
width: 580rpx;
border-radius: 30rpx;
background-color: $-color-white;
.title {
padding: 26rpx 0rpx;
}
.modify-row {
padding: 32rpx 0rpx;
width: 100%;
border-bottom: 1rpx solid #e5e5e5;
.send-code-btn {
border: 1px solid $-color-primary;
width: 184rpx;
height: 62rpx;
color: $-color-primary;
}
}
.btn {
height: 80rpx;
padding: 0 180rpx;
border-radius: 20rpx;
margin-top: 60rpx;
}
}
}
.text-name {
display: flex;
flex-direction: column;
justify-content: space-around;
}
</style>

View File

@ -0,0 +1,615 @@
<template>
<view class="user-profile-container mt10">
<view class="user-profile">
<view class="user-avatar-box column-center">
<button
class="column column-center"
hover-class="none"
open-type="chooseAvatar"
@chooseavatar="onChooseAvatar"
@click="onChooseAvatar"
>
<image
class="user-avatar"
:src="
userInfo.avatar != ''
? userInfo.avatar
: '../../static/images/default_avatar.png'
"
>
</image>
<view class="muted xs">点击修改头像</view>
</button>
</view>
<view class="row-info row bdb-line">
<view class="label md">ID</view>
<view class="md row" style="flex: 1">{{ userInfo.sn }}</view>
</view>
<view class="row-info row bdb-line" @click="changeName">
<view class="label md">昵称</view>
<view class="md row" style="flex: 1">{{ userInfo.nickname }}</view>
<u-icon name="arrow-right" />
</view>
<view class="row-info row bdb-line" @click="changeSex()">
<view class="label md">性别</view>
<view class="md row" :class="userInfo.sex == 0 ? 'muted' : ''" style="flex: 1">
{{ userInfo.sex == 0 ? '未设置' : userInfo.sex == 1 ? '男' : '女' }}
</view>
<u-icon name="arrow-right" />
</view>
<view class="row-info row bdb-line">
<view class="label md">手机</view>
<view class="md row" :class="{ muted: !userInfo.mobile }" style="flex: 1">
{{ userInfo.mobile ? userInfo.mobile : '未绑定' }}
</view>
<!-- #ifdef H5 || APP-PLUS -->
<view class="bd-btn br60 row-center" @click="showModifyMobile">
{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}
</view>
<!-- #endif -->
<!-- #ifdef MP-WEIXIN -->
<button
class="bd-btn br60 row-center"
size="sm"
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
>
{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}
</button>
<!-- #endif -->
</view>
<view class="row-info row bdb-line">
<view class="label md">注册时间 </view>
<view class="md row" style="flex: 1">{{ userInfo.create_time }}</view>
</view>
</view>
<u-popup type="center" closeable v-model="showMobile" mode="center" border-radius="14">
<view class="modify-container column-center bg-white" v-show="showMobile">
<view class="title xl">{{ userInfo.mobile ? '更换手机号' : '绑定手机号' }}</view>
<view class="modify-row row" v-if="userInfo.mobile">
<view style="width: 56px; border-right: 1px solid #e5e5e5">+86</view>
<view style="margin-left: 15px">{{ userInfo.mobile }}</view>
</view>
<view class="modify-row row" v-else>
<view style="width: 71px">手机号</view>
<input v-model="new_mobile" placeholder="请输入绑定手机号" />
</view>
<view class="modify-row row">
<view style="width: 71px">验证码</view>
<input
v-model="smsCode"
style="padding-left: 5px; width: 130px"
placeholder="请输入验证码"
/>
<view class="send-code-btn nr row-center" @click="$sendSms">
<u-verification-code
:keep-running="true"
ref="uCode"
@change="codeChange"
unique-key="page-b"
>
</u-verification-code>
<view class="xs">{{ tips }}</view>
</view>
</view>
<view class="modify-row row" v-if="userInfo.mobile">
<view style="width: 71px">新手机号</view>
<input v-model="new_mobile" placeholder="请输入新的手机号码" />
</view>
<view class="primary mt10"
>{{
userInfo.mobile ? '更改' : '绑定'
}}手机号码成功后您的账号将会变更为该设置号码</view
>
<view class="btn bg-primary white row-center" @click="$changeUserMobile">确定</view>
</view>
</u-popup>
<!-- 昵称修改组件 -->
<u-popup
v-model="showNickName"
:closeable="true"
:maskCloseAble="false"
mode="center"
border-radius="14"
>
<view
class="modify-container column-center bg-white"
style="width: 70vw; padding: 24rpx"
>
<view class="title xl">修改用户名</view>
<form @submit="changeNameConfirm">
<u-form-item label="新昵称" :labelWidth="120">
<input
style="height: 60rpx"
class="nr"
:value="userInfo.nickname"
name="nickname"
type="nickname"
placeholder="请输入新的昵称"
/>
</u-form-item>
<button class="btn bg-primary white row-center" form-type="submit">确定</button>
</form>
</view>
</u-popup>
<u-popup v-model="showPwd" closeable mode="center" border-radius="14">
<view class="modify-container column-center bg-white" v-show="showPwd">
<view class="title xl">设置密码</view>
<view class="modify-row row">
<view style="width: 56px; border-right: 1px solid #e5e5e5">+86</view>
<view style="margin-left: 15px">{{ userInfo.mobile }}</view>
</view>
<view class="modify-row row">
<view style="width: 142rpx">验证码</view>
<input
v-model="smsCode"
style="padding-left: 10rpx; width: 260rpx"
placeholder="请输入验证码"
/>
<view class="send-code-btn nr row-center" @click="$sendSms">
<u-verification-code
:keep-running="true"
ref="uCode"
@change="codeChange"
unique-key="page-a"
>
</u-verification-code>
<view class="xs">{{ tips }}</view>
</view>
</view>
<view class="modify-row row">
<view style="width: 71px">设置密码</view>
<input type="password" v-model="pwd" placeholder="请输入新密码" />
</view>
<view class="modify-row row">
<view style="width: 71px">确认密码</view>
<input type="password" v-model="comfirmPwd" placeholder="再次输入新密码确认" />
</view>
<view class="btn bg-primary white row-center" @click="$forgetPwd">确定</view>
</view>
</u-popup>
<u-picker
mode="selector"
v-model="showPicker"
:default-selector="[0]"
:range="sexList"
@confirm="onConfirm"
/>
</view>
</template>
<script>
import { userLogout, getUserInfo, changeUserMobile, setUserInfo, setWechatInfo } from '@/api/user'
import { version } from '@/config/app'
import { sendSms, forgetPwd } from '@/api/app'
import { SMSType } from '@/utils/type'
import { mapState, mapGetters } from 'vuex'
import { uploadFile, isWeixinClient, trottle } from '@/utils/tools'
import { getWxCode, getUserProfile } from '@/utils/login'
const FieldType = {
NONE: '',
SEX: 'sex',
NICKNAME: 'nickname',
AVATAR: 'avatar',
MOBILE: 'mobile'
}
export default {
name: 'userProfile',
data() {
return {
version: version,
fileList: [],
userInfo: {},
new_mobile: '',
smsCode: '',
newNickname: '',
sexList: ['男', '女'],
fieldType: FieldType.NONE,
showPicker: false,
showMobile: false,
showPwd: false,
showNickName: false,
tips: '',
canSendSms: true,
pwd: '',
comfirmPwd: '',
smsType: SMSType.FINDPWD,
code: ''
}
},
methods: {
codeChange(text) {
this.tips = text
},
onChooseAvatar(e) {
this.fieldType = FieldType.AVATAR
// #ifndef MP-WEIXIN
// uView"-JS"uniuni.navigateTo
uni.$u.route({
// ""
url: '/components/uview-ui/components/u-avatar-cropper/u-avatar-cropper',
//
params: {
// px
destWidth: 300,
// px
rectWidth: 200,
// 'png'"jpg"
fileType: 'jpg'
}
})
// #endif
// #ifdef MP-WEIXIN
if (e.detail.avatarUrl) {
console.log(e.detail.avatarUrl)
this.uploadImage(e.detail.avatarUrl)
}
// #endif
},
//
async changeNameConfirm(e) {
this.fieldType = FieldType.NICKNAME
this.newNickname = e.detail.value.nickname
if (!this.newNickname)
return this.$toast({
title: '请输入新的昵称'
})
await this.$setUserInfo(this.newNickname)
this.showNickName = false
},
// end
logout() {
// 退
userLogout({
token: this.token
}).then((res) => {
if (res.code == 1) {
this.$store.commit('LOGOUT')
this.$toast({
title: '退出成功'
})
setTimeout(() => {
uni.redirectTo({
url: '/pages/login/login'
})
}, 500)
}
})
},
goToExplain(value) {
uni.navigateTo({
url: '/bundle/pages/server_explan/server_explan?type=' + value
})
},
goLicense() {
uni.navigateTo({
url: '/bundle/pages/license/license'
})
},
toSetPayPwd() {
if (!this.userInfo.mobile)
return this.$toast({
title: '请先设置手机号'
})
uni.navigateTo({
url: '/bundle/pages/set_pay_pwd/set_pay_pwd'
})
},
//
$sendSms(type) {
if (!this.canSendSms) return
sendSms({
mobile: this.userInfo.mobile || this.new_mobile,
key: this.smsType
}).then((res) => {
if (res.code == 1) {
this.$toast({
title: res.msg
})
this.$refs.uCode.start()
}
})
},
$getUserInfo() {
getUserInfo().then((res) => {
if (res.code == 1) {
this.userInfo = res.data
}
})
},
//
showModifyMobile() {
this.smsCode = ''
this.new_mobile = ''
this.showMobile = true
this.smsType = this.userInfo.mobile ? SMSType.CHANGE_MOBILE : SMSType.BIND
},
$changeUserMobile() {
if (!this.smsCode) {
this.$toast({
title: '请输入验证码'
})
return
}
if (!this.new_mobile) {
this.$toast({
title: '请输入新的手机号码'
})
return
}
changeUserMobile({
mobile: this.userInfo.mobile,
new_mobile: this.new_mobile,
code: this.smsCode,
action: this.userInfo.mobile ? 'change' : ''
}).then((res) => {
if (res.code == 1) {
this.showMobile = false
this.$toast({
title: res.msg
})
this.$getUserInfo()
}
})
},
// end
//
async $setUserInfo(value) {
const res = await setUserInfo({
field: this.fieldType,
value: value
})
if (res.code == 1) {
this.$toast({
title: res.msg
})
this.$getUserInfo()
}
},
// end
timeChange(timestamp) {
console.log(timestamp, 'timestamp')
},
onConfirm(value) {
this.$setUserInfo(value[0] + 1)
this.showPicker = false
},
changeSex(e) {
this.showPicker = true
this.fieldType = FieldType.SEX
},
//
countDownFinish() {
this.canSendSms = true
},
//
showPwdPop() {
if (!this.userInfo.mobile) {
this.$toast({
title: '请绑定手机后再设置密码'
})
return
}
this.smsCode = ''
this.smsType = SMSType.FINDPWD
this.showPwd = true
},
$forgetPwd() {
let { smsCode, pwd, comfirmPwd } = this
if (!smsCode) {
this.$toast({
title: '请填写短信验证码'
})
return
}
if (!pwd) {
this.$toast({
title: '请输入新密码'
})
return
}
if (!comfirmPwd) {
this.$toast({
title: '再次输入新密码确认'
})
return
}
if (pwd != comfirmPwd) {
this.$toast({
title: '两次密码输入不一致'
})
return
}
let data = {
mobile: this.userInfo.mobile,
code: smsCode,
password: pwd,
repassword: comfirmPwd
}
forgetPwd(data).then((res) => {
if (res.code == 1) {
this.showPwd = false
this.$toast({
title: '设置密码成功'
})
this.$getUserInfo()
}
})
},
// end
//
changeName() {
this.fieldType = FieldType.NICKNAME
this.newNickname = ''
this.showNickName = true
},
// end
async getPhoneNumber(e) {
const { encryptedData, iv } = e.detail
let data = {
code: this.code,
encrypted_data: encryptedData,
iv
}
this.fieldType = FieldType.MOBILE
if (encryptedData) {
this.$changeUserMobileMP(data)
}
},
$changeUserMobileMP(data) {
changeUserMobile(data).then((res) => {
if (res.code == 1) {
this.$toast({
title: res.msg
})
this.$getUserInfo()
}
// #ifdef MP-WEIXIN
getWxCode().then((res) => {
this.code = res
})
// #endif
})
},
uploadImage(path) {
uni.showLoading({
title: '正在上传中...',
mask: true
})
uploadFile(path)
.then((res) => {
uni.hideLoading()
this.$setUserInfo(res.url)
})
.catch(() => {
uni.hideLoading()
this.$toast({
title: '上传失败'
})
})
}
},
onLoad() {
this.$getUserInfo()
// #ifdef MP-WEIXIN
getWxCode().then((res) => {
this.code = res
})
// #endif
//
uni.$on('uAvatarCropper', (path) => {
console.log(path)
this.uploadImage(path)
})
this.getUserProfile = trottle(this.getUserProfile, 500, this)
},
onUnload() {
uni.$off('uAvatarCropper')
},
computed: {
...mapState(['token']),
...mapGetters(['appConfig'])
}
}
</script>
<style lang="scss">
.user-profile-container {
.user-profile {
border-top-left-radius: 28rpx;
border-top-right-radius: 28rpx;
.user-avatar-box {
padding: 30rpx;
background-color: white;
border-top-left-radius: 28rpx;
border-top-right-radius: 28rpx;
.user-avatar {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
}
}
.row-info {
padding: 30rpx 20rpx;
background-color: white;
.label {
width: 180rpx;
}
.bd-btn {
padding: 8rpx 24rpx;
border: 1px solid $-color-primary;
color: $-color-primary;
}
}
.license {
margin-top: 80rpx;
color: #a7a7a7;
text-align: center;
}
.bdb-line {
border-bottom: 1rpx solid #e5e5e5;
}
.save-btn {
margin-top: 40rpx;
height: 88rpx;
margin-left: 54rpx;
margin-right: 54rpx;
border-radius: 10rpx;
box-sizing: border-box;
}
.updata-btn {
margin: 0 30rpx;
margin-top: 40rpx;
background-color: #0cc267;
}
}
.modify-container {
padding-left: 30rpx;
padding-right: 30rpx;
padding-bottom: 30rpx;
width: 580rpx;
border-radius: 30rpx;
background-color: $-color-white;
.title {
padding: 26rpx 0rpx;
}
.modify-row {
padding: 32rpx 0rpx;
width: 100%;
border-bottom: 1rpx solid #e5e5e5;
.send-code-btn {
border: 1px solid $-color-primary;
width: 184rpx;
height: 62rpx;
color: $-color-primary;
}
}
.btn {
height: 80rpx;
padding: 0 180rpx;
border-radius: 20rpx;
margin-top: 60rpx;
}
}
}
</style>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,118 @@
<template>
<view class="user-spread-month-bill">
<view v-for="(item, index) in orderList" :key="index">
<view class="bill-time row normal sm">
{{item.date}}
</view>
<view class="show-panel row">
<view class="panel-item column-center">
<price-format :price="item.total_money" showSubscript :subScriptSize="26" color="#FF2C3C" :firstSize="36" :secondSize="36" />
<view class="lighter label mt10">预估收入</view>
</view>
<view class="panel-item column-center">
<view class="normal xxl">{{item.order_num}}</view>
<view class="lighter label mt10">成交笔数</view>
</view>
<view class="panel-item column-center" style="align-self: flex-end;">
<navigator hover-class="none" :url="'/bundle/pages/user_spread_month_bill_detail/user_spread_month_bill_detail?year=' + item.year + '&month=' + item.month" class="row lighter">
查看详情<u-icon name="arrow-right" size="28rpx" color="#666666" />
</navigator>
</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view slot="empty" class="data-null column-center">
<image src="/static/images/order_null.png" class="img-null"></image>
<view class="muted xs">暂无相关数据</view>
</view>
</loading-footer>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getMonthBill } from "@/api/user";
import { loadingType } from '@/utils/type';
import {loadingFun} from "@/utils/tools"
export default {
data() {
return {
loadingStatus: loadingType.LOADING,
page: 1,
orderList: []
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getMonthBillFun();
},
onReachBottom: function () {
this.getMonthBillFun()
},
methods: {
getMonthBillFun() {
let {
loadingStatus,
page,
orderList
} = this;
loadingFun(getMonthBill, page, orderList, loadingStatus).then(res => {
if(res) {
this.page = res.page;
this.orderList = res.dataList
this.loadingStatus = res.status
}
})
}
}
};
</script>
<style lang="scss">
.user-spread-month-bill {
.bill-time {
padding: 20rpx;
line-height: 34rpx;
}
.show-panel {
background-color: white;
padding: 36rpx 0 26rpx;
}
.show-panel {
.panel-item {
flex: 1;
line-height: 34rpx;
}
}
}
.data-null {
padding-top: 200rpx;
}
</style>

View File

@ -0,0 +1,282 @@
<template>
<view class="user-spread-month-bill">
<view class="header row white">
<view class="header-show column-center">
<view class="num">{{month}}</view>
<view class="label sm row" @tap="openPop">月份 <trigonometry color="white" opacity="1"></trigonometry></view>
</view>
<view class="header-show column-center">
<view class="num">{{order}}</view>
<view class="label sm">成交笔数</view>
</view>
<view class="header-show column-center">
<view>
<price-format showSubscript :subscriptSize="26" :firstSize="42" :secondSize="42" color="#ffffff" :price="money" />
</view>
<view class="label sm">累计预估收益</view>
</view>
</view>
<view class="content">
<view class="order-container">
<view v-for="(item, index) in orderList" :key="index" class="order-item bg-white mb20">
<view class="order-header row-between">
<view>订单编号:{{item.order_sn}}</view>
<view class="white guide-shop-btn row-center">导购订单</view>
</view>
<view class="order-content row">
<view class="order-goods-img">
<custom-image :src="item.image" width="100%" height="100%" radius="6px" />
</view>
<view class="order-goods-info ml10">
<view class="name row sm">{{item.goods_name}}</view>
<view class="pre-income muted">预估收益
<price-format showSubscript subScriptClass="nr" firstClass="nr" secondClass="nr" :color="primaryColor" weight="bold" :price="item.money" />
</view>
</view>
</view>
<view class="order-footer row-between">
<view class="time muted">{{item.create_time}}</view>
<view class="static" :style="'color: ' + (item.status == '待返佣' ? '#F95F2F' : '#07CE1B')">{{item.status}}</view>
</view>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image class="img-null" src="/static/images/order_null.png"></image>
<view class="xs muted">暂无账单明细</view>
</view>
</loading-footer>
</view>
</view>
<u-select v-model="showPop" :list="months" mode="single-column" @confirm="changeMonths" ></u-select>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getMonthOrderDetail } from "@/api/user";
import { loadingType } from '@/utils/type';
const months = [];
for(let i = 1; i <= 12; i ++) {
months.push({
value: i,
label: i + "月"
})
}
export default {
data() {
return {
loadingStatus: loadingType.LOADING,
page: 1,
orderList: [],
month: 1,
year: 2010,
//
money: 0,
//
order: 0,
//
months: months,
chooseMonth: 1,
showPop: false
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.year = options.year;
this.chooseMonth = [Number(options.month)]
this.month = Number(options.month)
},
onShow: function () {
this.getMonthOrderDetailFun();
},
onReachBottom: function () {
this.getMonthOrderDetailFun();
},
methods: {
getMonthOrderDetailFun() {
let {
page,
orderList,
loadingStatus,
year,
month
} = this;
if (loadingStatus == loadingType.FINISHED) return;
getMonthOrderDetail({
page_no: page,
year: year,
month: month
}).then(res => {
if (res.code == 1) {
let {
more,
list,
total_money,
total_order
} = res.data;
orderList.push(...list);
this.orderList = orderList;
this.page ++;
this.money = total_money;
this.order = total_order
if (!more) {
this.loadingStatus = loadingType.FINISHED;
}
if (orderList.length <= 0) {
this.loadingStatus = loadingType.EMPTY
return;
}
} else {
this.loadingStatus = loadingType.ERROR
}
});
},
openPop() {
this.showPop = true
},
closePop() {
this.showPop = false
},
changeMonths(e) {
const val = e[0].value;
this.chooseMonth = val
this.selectMonth()
},
cleanStatus() {
this.loadingStatus = loadingType.LOADING;
this.page = 1;
this.orderList = []
},
selectMonth(e) {
const {
chooseMonth,
month
} = this;
this.month = chooseMonth;
this.showPop = false
this.cleanStatus();
this.getMonthOrderDetailFun();
}
}
};
</script>
<style lang="scss">
.user-spread-month-bill .header {
height: 240rpx;
background-color: $-color-primary;
padding-top: 60rpx;
}
.user-spread-month-bill .header .header-show {
flex: 1;
align-self: flex-start;
}
.user-spread-month-bill .header .header-show .num {
font-size: 42rpx;
}
.user-spread-month-bill .content {
padding: 0 20rpx;
margin-top: -60rpx;
}
.user-spread-month-bill .content .order-container .order-item {
border-radius: 14rpx;
}
.user-spread-month-bill .content .order-container .order-item .order-header {
padding: 20rpx 30rpx;
border-bottom: $-solid-border;
}
.user-spread-month-bill .content .order-container .order-item .order-header .guide-shop-btn {
background: linear-gradient(80deg, #F95F2F 0%, #FF2C3C 100%);
border-radius: 4rpx;
width: 134rpx;
height: 42rpx;
}
.user-spread-month-bill .content .order-container .order-item .order-content {
padding: 20rpx 30rpx 20rpx 20rpx;
border-bottom: $-solid-border;
}
.user-spread-month-bill .content .order-container .order-item .order-content .order-goods-img {
width: 140rpx;
height: 140rpx;
flex: none;
}
.user-spread-month-bill .content .order-container .order-item .order-content .order-goods-info {
text-align: left;
}
.user-spread-month-bill .content .order-container .order-item .order-content .order-goods-info .name {
line-height: 36rpx;
}
.user-spread-month-bill .content .order-container .order-item .order-content .order-goods-info .pre-income {
line-height: 34rpx;
margin-top: 8rpx;
}
.user-spread-month-bill .content .order-container .order-item .order-footer {
padding: 20rpx 30rpx 20rpx 20rpx;
}
.user-spread-month-bill .content .order-container .order-item .order-footer .static {
color: #F95F2F;
}
.user-spread-month-bill .content .order-container .order-item .order-footer .wait-return {
color: #F95F2F;
}
.user-spread-month-bill .pop-header {
height: 80rpx;
}
.content .order-container .data-null {
padding-top: 200rpx;
}
</style>

View File

@ -0,0 +1,98 @@
<template>
<view class="user-promote-order">
<tabs :active="active" :line-width="40" @change="onChange">
<tab v-for="(item, index) in order" :key="index" :title="item.name">
<spread-order :ref="'order' + item.type" class="mt20" v-if="item.isShow" :type="item.type"></spread-order>
</tab>
</tabs>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { userOrderPromoteOrder } from "@/utils/type";
export default {
data() {
return {
order: [{
name: "全部",
type: userOrderPromoteOrder.ALL,
isShow: false
}, {
name: "待返佣",
type: userOrderPromoteOrder.WAIT_RETURN,
isShow: false
}, {
name: "已结算",
type: userOrderPromoteOrder.HANDLED,
isShow: false
}, {
name: "已失效",
type: userOrderPromoteOrder.INVALED,
isShow: false
}],
active: userOrderPromoteOrder.ALL
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let type = parseInt(options.type) || userOrderPromoteOrder.ALL;
this.changeShow(type);
},
onReachBottom: function () {
const {active, order} = this
this.$refs['order' + active][0].getPromoteOrderFun()
},
methods: {
onChange(e) {
this.changeShow(e);
},
changeShow(type) {
const {
order
} = this;
console.log('changeShow');
let index = order.findIndex(item => {
return item.type == type;
});
console.log(index);
if (index != -1) {
this.active = type;
this.order[index].isShow = true
console.log(this.order[index].isShow);
}
}
}
};
</script>
<style>
/* pages/user_spread_order/user_spread_order.wxss */
</style>

View File

@ -0,0 +1,165 @@
<template>
<!--pages/user_wallet/user_wallet.wxml-->
<view class="user-wallet">
<view class="contain bg-white mb20">
<view class="header">
<view class="white mb20">
<view class="xs">总资产</view>
<view style="font-size: 76rpx">{{wallet.user_money}}</view>
</view>
<view class="money white row">
<view class="item">
<view class="xs">累计充值()</view>
<view style="font-size: 38rpx">{{wallet.total_recharge_amount || 0}}</view>
</view>
<view class="item">
<view class="xs">累计消费()</view>
<view style="font-size: 38rpx">{{wallet.total_order_amount || 0}}</view>
</view>
<navigator v-if="wallet.open_racharge" style="height: 58rpx;" hover-class="none" url="/bundle/pages/user_payment/user_payment" class="row-center primary bg-white br60 btn" size="xs">充值</navigator>
</view>
</view>
<view class="nav row">
<navigator class="nav-item column-center" hover-class="none" url="/bundle/pages/balance_transfer/balance_transfer">
<image src="../../static/images/icon_yezz.png"></image>
<view class="mt10">余额转账</view>
</navigator>
<navigator class="nav-item column-center" hover-class="none" url="/bundle/pages/user_bill/user_bill?type=0">
<image src="../../static/images/icon_zhmx.png"></image>
<view class="mt10">账户明细</view>
</navigator>
<navigator class="nav-item column-center" hover-class="none" url="/bundle/pages/transfer_record/transfer_record">
<image src="../../static/images/icon_zzjl.png"></image>
<view class="mt10">转账记录</view>
</navigator>
<navigator class="nav-item column-center" hover-class="none" url="/bundle/pages/recharge_code/recharge_code">
<image src="../../static/images/icon_czjl.png"></image>
<view class="mt10">充值记录</view>
</navigator>
</view>
<view class="activity">
<view class="activity-title xl row">
<view class="mr20" style="width: 6rpx;height: 30rpx;background-color: #FF2C3C;"></view> 热门活动
</view>
<view class="activity-item row-between">
<view>
<view class="xl normal" style="font-weight: 500;">会员积分 限时兑换</view>
<view class="muted sm mt10">积分签到抵现金</view>
<navigator class="br60 bg-primary white join-btn row-center" url="/bundle/pages/user_sign/user_sign" hover-class="none">立即参与</navigator>
</view>
<image style="width:274rpx;height: 210rpx;" src="../../static/images/img_activity_jifen.png"></image>
</view>
</view>
</view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getWallet } from '@/api/user';
export default {
data() {
return {
wallet: {}
};
},
components: {
},
props: {},
onShow: function () {
this.getWalletFun();
},
methods: {
getWalletFun() {
getWallet().then(res => {
if (res.code == 1) {
this.wallet = res.data
}
});
}
}
};
</script>
<style lang="scss">
image {
width: 100%;
height: 100%;
}
.user-wallet {
.contain {
padding: 20rpx 30rpx 36rpx;
.header {
position: relative;
background:linear-gradient(180deg,rgba(255,44,60,1) 0%,rgba(255,49,106,1) 100%);
border-radius: 20rpx;
height: 320rpx;
padding: 50rpx 30rpx 30rpx;
box-sizing: border-box;
.money {
.item {
flex: 1;
}
}
.btn {
position: absolute;
right: 30rpx;
top: 50rpx;
padding: 0 51rpx;
}
}
.nav {
.nav-item {
width: 25%;
padding: 40rpx 0;
image {
width: 52rpx;
height: 52rpx;
}
}
}
}
}
.activity {
padding: 40rpx 0rpx;
.activity-title {
font-weight: bold;
}
.activity-item {
padding: 15rpx 40rpx;
box-shadow: 0px 0rpx 20rpx rgba(0, 0, 0, 0.16);
margin-top: 34rpx;
.join-btn {
height: 52rpx;
width: 156rpx;
margin-top: 24rpx;
}
}
}
</style>

View File

@ -0,0 +1,442 @@
<template>
<view class="user-withdraw">
<view class="user-tab-container">
<tabs :active="active" :line-width="40" @change="onChange" :config="{itemWidth: 200}">
<tab :title="item.name" :name="item.value" v-for="(item, index) in widthDrawWay" :key="index">
<template v-if="item.value == 1 || item.value == 2">
<view class="bg-white withdraw-container mt20">
<view class="input row-center">
<view style="font-size: 23px;align-self: flex-end;margin-bottom: 5px">¥</view>
<input v-model="money" placeholder="0.00"></input>
<view class="column" style="flex: none;">
<view class="xs primary" style="text-align: right;" @tap="allWithdraw">全部提现</view>
<view class="xs" style="color: #BBBBBB">可提现余额{{widthDrawConfig.able_withdraw}}
</view>
</view>
</view>
<view class="tips mt20 muted row xs" v-if="item.value == 2">
提示提现需扣除服务费{{widthDrawConfig.poundage_percent}}%请自行缴纳税款
<!-- <view class="primary ml10">¥ {{widthDrawConfig.able_withdraw}}</view> -->
</view>
</view>
<view class="withdraw-btn bg-primary lg white row-center" @tap="applyWithdrawFun(item.value)">
确认提现</view>
<navigator url="/bundle/pages/user_withdraw_code/user_withdraw_code" hover-class="none"
class="mt20 nr lighter row-center">提现记录</navigator>
</template>
<template v-if="item.value == 3">
<view class="bg-white form-container">
<view class="input-item row md">
<view class="input-label ">微信账号</view>
<input v-model="account" placeholder="请输入微信账号"></input>
</view>
<view class="input-item row md">
<view class="input-label ">真实姓名</view>
<input v-model="realName" placeholder="请输入真实姓名"></input>
</view>
<view class="input-item row md">
<view class="input-label ">备注</view>
<input v-model="remark" placeholder="(选填)"></input>
</view>
<view class="uploader-container row mt20">
<uploader @after-read="afterRead" :file-list="fileList" :max-upload="1"
:deletable="true" useSlot @delete="handleDelete">
<view>
<view class="upload-area row-center">
<image src="/static/images/uploader_icon.png"></image>
</view>
<view class="mt10 normal nr" style="line-height: 36rpx;text-align: center;">
微信收款码</view>
</view>
</uploader>
</view>
</view>
<view class="bg-white withdraw-container mt10">
<view class="input row-center">
<view style="font-size: 23px;align-self: flex-end;margin-bottom: 5px">¥</view>
<input v-model="money" placeholder="0.00"></input>
<view class="column" style="flex: none;">
<view class="xs primary" style="text-align: right;" @tap="allWithdraw">全部提现</view>
<view class="xs" style="color: #BBBBBB">可提现余额{{widthDrawConfig.able_withdraw}}
</view>
</view>
</view>
<view class="tips mt10 muted row xs">
提示提现需扣除服务费{{widthDrawConfig.poundage_percent}}%请自行缴纳税款
<!-- <view class="primary ml5">¥ {{widthDrawConfig.able_withdraw}}</view> -->
</view>
</view>
<view class="withdraw-btn bg-primary lg white row-center" @tap="applyWithdrawFun(item.value)">
确认提现</view>
<navigator url="/bundle/pages/user_withdraw_code/user_withdraw_code" hover-class="none"
class="mt20 nr lighter row-center">提现记录</navigator>
</template>
<template v-if="item.value == 4">
<view class="bg-white form-container">
<view class="input-item row md">
<view class="input-label ">支付宝账号</view>
<input v-model="account" placeholder="请输入支付宝账号"></input>
</view>
<view class="input-item row md">
<view class="input-label ">真实姓名</view>
<input v-model="realName" placeholder="请输入真实姓名"></input>
</view>
<view class="input-item row md">
<view class="input-label ">备注</view>
<input v-model="remark" placeholder="(选填)"></input>
</view>
<view class="uploader-container row mt20">
<uploader @after-read="afterRead" :file-list="fileList" :max-upload="1"
:deletable="true" useSlot @delete="handleDelete">
<view class="column-center">
<view class="upload-area row-center">
<image src="/static/images/uploader_icon.png"></image>
</view>
<view class="mt10 normal nr" style="line-height: 36rpx;text-align: center;">
支付宝收款码</view>
</view>
</uploader>
</view>
</view>
<view class="bg-white withdraw-container mt10">
<view class="input row-center">
<view style="font-size: 23px;align-self: flex-end;margin-bottom: 5px">¥</view>
<input v-model="money" placeholder="0.00"></input>
<view class="column" style="flex: none;">
<view class="xs primary" style="text-align: right;" @tap="allWithdraw">全部提现</view>
<view class="xs" style="color: #BBBBBB">可提现余额{{widthDrawConfig.able_withdraw}}
</view>
</view>
</view>
<view class="tips mt10 muted row xs">
提示提现需扣除服务费{{widthDrawConfig.poundage_percent}}%请自行缴纳税款
<!-- <view class="primary ml5">¥ {{widthDrawConfig.able_withdraw}}</view> -->
</view>
</view>
<view class="withdraw-btn bg-primary lg white row-center" @tap="applyWithdrawFun(item.value)">
确认提现</view>
<navigator url="/bundle/pages/user_withdraw_code/user_withdraw_code" hover-class="none"
class="mt20 nr lighter row-center">
提现记录
</navigator>
</template>
<template v-if="item.value == 5">
<view class="bg-white form-container">
<view class="input-item row md">
<view class="input-label ">银行卡账号</view>
<input v-model="account" placeholder="请输入银行卡账号"></input>
</view>
<view class="input-item row md">
<view class="input-label ">真实姓名</view>
<input v-model="realName" placeholder="请输入真实姓名"></input>
</view>
<view class="input-item row md">
<view class="input-label ">提现银行</view>
<input v-model="bank" placeholder="请输入提现银行"></input>
</view>
<view class="input-item row md">
<view class="input-label ">银行支行</view>
<input v-model="subbank" placeholder="请输入银行支行"></input>
</view>
<view class="input-item row md">
<view class="input-label ">备注</view>
<input v-model="remark" placeholder="(选填)"></input>
</view>
</view>
<view class="bg-white withdraw-container mt10">
<view class="input row-center">
<view style="font-size: 23px;align-self: flex-end;margin-bottom: 5px">¥</view>
<input v-model="money" placeholder="0.00"></input>
<view class="column" style="flex: none;">
<view class="xs primary" style="text-align: right;" @tap="allWithdraw">全部提现</view>
<view class="xs" style="color: #BBBBBB">可提现余额{{widthDrawConfig.able_withdraw}}
</view>
</view>
</view>
<view class="tips mt10 muted row xs">
提示提现需扣除服务费{{widthDrawConfig.poundage_percent}}%请自行缴纳税款
<!-- <view class="primary ml5">¥ {{widthDrawConfig.able_withdraw}}</view> -->
</view>
</view>
<view class="withdraw-btn bg-primary lg white row-center" @tap="applyWithdrawFun(item.value)">
确认提现</view>
<navigator url="/bundle/pages/user_withdraw_code/user_withdraw_code" hover-class="none"
class="mt20 nr lighter row-center">
提现记录
</navigator>
</template>
</tab>
</tabs>
</view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | LikeShop100%
// +----------------------------------------------------------------------
// |
// |
// |
// |
// | Giteehttps://gitee.com/likeshop_gitee/likeshop
// | 访https://www.likemarket.net
// | 访https://home.likemarket.net
// | 访http://doc.likemarket.net
// |
// |
// +----------------------------------------------------------------------
// | Author: LikeShopTeam
// +----------------------------------------------------------------------
import {
applyWithdraw,
getWithdrawConfig
} from "@/api/user";
import {
uploadFile,
trottle
} from "@/utils/tools";
import {
baseURL
} from '@/config/app';
import {
withdrawType
} from "@/utils/type"
export default {
data() {
return {
active: 0,
money: '',
account: '',
realName: '',
bank: '',
subbank: '',
qrCode: '',
remark: '',
fileList: [],
widthDrawConfig: {},
widthDrawWay: []
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.getWithdrawConfigFun();
this.applyWithdrawFun = trottle(this.applyWithdrawFun, 1000, this)
},
methods: {
allWithdraw(e) {
const {
widthDrawConfig
} = this;
console.log(widthDrawConfig, "widthDrawConfig")
this.money = widthDrawConfig.able_withdraw.toString()
},
onChange(e) {
this.active = e
this.account = "";
this.realName = "";
this.qrCode = "";
this.remark = ""
this.fileList = [];
},
getWithdrawConfigFun() {
getWithdrawConfig().then(res => {
if (res.code == 1) {
this.widthDrawConfig = res.data
this.widthDrawWay = res.data.type
}
});
},
afterRead(e) {
const file = e;
uni.showLoading({
title: '正在上传中...',
mask: true
});
file.forEach(item => {
uploadFile(item.path).then(res => {
uni.hideLoading();
this.fileList.push(res);
this.qrCode = res.url;
});
})
},
handleDelete(index) {
this.fileList.splice(index, 1)
},
//
applyWithdrawFun(type) {
let {
active,
account,
realName,
qrCode,
remark,
money,
bank,
subbank,
widthDrawWay
} = this;
console.log(realName, "###", active, "###", money);
switch (parseInt(type)) {
case withdrawType.ACCOUNT:
break;
case withdrawType.WECHAT:
break
case withdrawType.PAY_WECHAT:
case withdrawType.PAY_ALIPAY:
if (!account) return this.$toast({
title: '请输入账户信息'
})
if (!realName) return this.$toast({
title: '请输入真实姓名'
})
if (!qrCode) return this.$toast({
title: '请上传收款码'
})
break;
case withdrawType.BANK:
if (!account) return this.$toast({
title: '请输入账户信息'
})
if (!realName) return this.$toast({
title: '请输入真实姓名'
})
if (!bank) return this.$toast({
title: '请输入提现银行'
})
if (!subbank) return this.$toast({
title: '请输入银行支行'
})
}
if (!money) {
this.$toast({
title: '请输入提现金额'
});
return;
}
const data = {
type: widthDrawWay[active].value,
money: money,
account: account,
real_name: realName,
money_qr_code: qrCode,
remark: remark,
bank,
subbank
};
applyWithdraw(data).then(res => {
if (res.code == 1) {
this.$toast({
title: '提交成功'
}, {
tab: 2,
url: '/bundle/pages/widthdraw_result/widthdraw_result?id=' + res.data.id
});
}
});
}
}
};
</script>
<style lang="scss">
.van-tabs .van-tabs__wrap {
border-radius: 10rpx;
}
.van-tabs__line {
background: linear-gradient(90deg, #F79C0C 0%, #FF2C3C 100%);
bottom: 8rpx !important;
/* width: 50rpx !important; */
height: 6rpx !important;
border-radius: 100rpx;
}
.user-withdraw {
.user-tab-container {
padding: 20rpx 30rpx;
::v-deep .scroll-view-h {
background-color: #FFFFFF;
}
.withdraw-container {
padding: 52rpx 72rpx;
border-radius: 20rpx;
.input {
border-bottom: $-solid-border;
input {
width: 100%;
height: 94rpx;
text-align: left;
font-size: 66rpx;
margin-left: 30rpx;
}
}
}
.withdraw-btn {
background: linear-gradient(80deg, #F95F2F 0%, #FF2C3C 100%);
line-height: 44rpx;
height: 84rpx;
margin-top: 30rpx;
border-radius: 100rpx;
}
.form-container {
border-radius: 20rpx;
padding: 0 36rpx 26rpx;
line-height: 36rpx;
margin-top: 10rpx;
.input-item {
padding: 28rpx 0 30rpx;
border-bottom: $-solid-border;
}
.input-label {
width: 200rpx;
text-align: left;
line-height: 36rpx;
}
input {
flex: 1;
}
.uploader-container {
.upload-area {
width: 160rpx;
height: 160rpx;
border: 4rpx dashed #E5E5E5;
border-radius: 10rpx;
image {
width: 54rpx;
height: 44rpx;
}
}
}
}
}
}
</style>

View File

@ -0,0 +1,119 @@
<template>
<view class="user-withdraw-code">
<view class="withdraw-code-container mt10">
<view class="withdraw-code-contain">
<navigator v-for="(item, index) in withdrawRecords" :key="index" class="withdraw-code-item bg-white" hover-class="none"
:url="`/bundle/pages/widthdraw_result/widthdraw_result?id=${item.id}&type=1`">
<view class="row-between">
<view>{{item.desc}}</view>
<price-format showSubscript :subScriptSize="26" :firstSize="36" :secondSize="36" :price="item.left_money" />
</view>
<view class="row-between mt10">
<view class="muted xs time">{{item.create_time}}</view>
<view class="withdraw-status xs" :class="{'error-status' : item.status == 2 || item.status == 4, 'common-status': item.status == 3}">{{item.status_text}}</view>
</view>
<view v-if="item.description && item.status == 4" class="primary mt10 line1 xs">{{item.description}}</view>
</navigator>
</view>
<loading-footer :status="loadingStatus" slotEmpty>
<view class="data-null column-center" slot="empty">
<image src="/static/images/order_null.png" class="img-null"></image>
<text class="muted">暂无提现记录</text>
</view>
</loading-footer>
</view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | likeshop
// +----------------------------------------------------------------------
// |
// | giteehttps://gitee.com/likeshop_gitee
// | githubhttps://github.com/likeshop-github
// | 访https://www.likeshop.cn
// | 访https://home.likeshop.cn
// | 访http://doc.likeshop.cn
// | likeshop
// | likeshopgiteegithub
// | likeshop
// |
// | likeshop
// +----------------------------------------------------------------------
// | author: likeshop.cn.team
// +----------------------------------------------------------------------
import { getWithdrawRecords } from '@/api/user';
import { loadingType } from '@/utils/type.js';
import {loadingFun} from "@/utils/tools"
export default {
data() {
return {
loadingStatus: loadingType.LOADING,
page: 1,
withdrawRecords: []
};
},
components: {
},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getWithdrawRecordsFun();
},
onReachBottom: function () {
this.getWithdrawRecordsFun()
},
methods: {
getWithdrawRecordsFun() {
let {
loadingStatus,
withdrawRecords,
page
} = this;
loadingFun(getWithdrawRecords, page, withdrawRecords, loadingStatus).then(res => {
if(res) {
this.page = res.page;
this.withdrawRecords = res.dataList
this.loadingStatus = res.status
}
})
}
}
};
</script>
<style lang="scss">
.user-withdraw-code {
.withdraw-code-container {
.withdraw-code-item {
padding: 24rpx 30rpx;
.time {
line-height: 32rpx;
}
.withdraw-status {
color: #0CC21E;
}
.common-status {
color: #666666;
}
.error-status {
color: $-color-primary;
}
&:not(:last-of-type) {
border-bottom: var(--border);
}
}
}
.data-null {
padding-top: 200rpx;
}
}
</style>

View File

@ -0,0 +1,184 @@
<template>
<view class="pay-result">
<view class="contain bg-white">
<view style="border-top: 1rpx solid transparent;">
<view class="header column-center">
<view>
<image class="tips-icon" :src="getStatusImg"></image>
</view>
<view class="xl mt20 line1">{{widthdrawInfo.statusDesc}}</view>
</view>
<view class="column-center mt10">
<price-format :price="widthdrawInfo.money" color="#FF2C3C" showSubscript subscriptSize="30"
firstSize="46" secondSize="46" weight="500" />
</view>
<view class="info">
<view class="order-num row-between mt20">
<view class="ml20">流水号</view>
<view class="mr20">
{{widthdrawInfo.sn}}
</view>
</view>
<view v-if="widthdrawInfo.create_time" class="order-time row-between mt20">
<view class="ml20">提交时间</view>
<view class="mr20">{{widthdrawInfo.create_time}}</view>
</view>
<view class="order-pay-type row-between mt20">
<view class="ml20">提现至</view>
<view class="mr20">{{widthdrawInfo.typeDesc}}</view>
</view>
<view class="order-pay-money row-between mt20">
<view class="ml20">服务费</view>
<view class="mr20">
<price-format :price="widthdrawInfo.poundage" />
</view>
</view>
<view class="order-pay-money row-between mt20">
<view class="ml20">实际到账</view>
<view class="mr20">
<price-format :price="widthdrawInfo.left_money" />
</view>
</view>
</view>
<view class="line ml20" v-if="!type"></view>
<view class="opt-btn-contain row-center wrap" v-if="!type">
<navigator hover-class="none" class="check-order-btn row-center bg-primary br60 mt20"
url="/bundle/pages/user_withdraw_code/user_withdraw_code">
<view class="white bg-primary lg">查看历史提现记录</view>
</navigator>
<navigator hover-class="none" class="go-back-btn row-center br60 mt20" open-type="switchTab"
url="/pages/index/index">
<view class="primary br60 lg">返回首页</view>
</navigator>
</view>
</view>
</view>
<view class="muted mt20 row-center xs">* 审核通过后约72小时内到账请留意账户明细</view>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | LikeShop100%
// +----------------------------------------------------------------------
// |
// |
// |
// |
// | Giteehttps://gitee.com/likeshop_gitee/likeshop
// | 访https://www.likemarket.net
// | 访https://home.likemarket.net
// | 访http://doc.likemarket.net
// |
// |
// +----------------------------------------------------------------------
// | Author: LikeShopTeam
// +----------------------------------------------------------------------
import {
getWithdrawDetail
} from '@/api/user';
export default {
data() {
return {
widthdrawInfo: {},
type: ""
};
},
components: {},
props: {},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
this.id = options.id;
this.type = options.type
this.getWithdrawDetailFun();
},
methods: {
getWithdrawDetailFun() {
getWithdrawDetail({
id: this.id
}).then(res => {
if (res.code == 1) {
this.widthdrawInfo = res.data
}
});
}
},
computed: {
getStatusImg() {
switch (this.widthdrawInfo.status) {
case 1:
"";
case 2:
return '../../static/images/icon_cashOut_wait.png';
case 3:
return '/static/images/icon_paySuccess.png';
case 4:
return '../../static/images/icon_payFail.png';
}
}
}
};
</script>
<style lang="scss">
.pay-result {
overflow: hidden;
.contain {
/* height: 732rpx; */
margin-left: 20rpx;
margin-right: 20rpx;
border-radius: 10rpx;
margin-top: 78rpx;
padding-left: 20rpx;
padding-right: 20rpx;
padding-bottom: 40rpx;
position: relative;
.tips-icon {
width: 112rpx;
height: 112rpx;
}
.header {
margin-top: -56rpx;
}
.info {
margin-bottom: 40rpx;
.order-num {
align-items: flex-start;
}
}
.opt-btn-contain {
margin-top: 40rpx;
.check-order-btn {
width: 650rpx;
height: 84rpx;
}
.go-back-btn {
width: 650rpx;
height: 84rpx;
border: solid 1rpx $-color-primary;
box-sizing: border-box;
}
}
}
}
.line {
width: 650rpx;
border-top: 1px solid rgba(229, 229, 229, 1);
}
</style>

View File

@ -0,0 +1,85 @@
<template>
<view class="win-prize-code">
<view class="goods-list">
<view class="" v-for="(item, index) in bargainGoods" :key="index">
<view class="bg-white row code-item">
<u-image :src="item.prize_image" width="90rpx" height="90rpx" mode="aspectFill" radius="6rpx"></u-image>
<view class="ml20 desc">
<view class="nr line1 bold">{{item.title}}</view>
<view class="mt10 row-between">
<view class="xs lighter">抽奖时间{{item.create_time}}</view>
<!-- <view class="xs">+100</view> -->
</view>
</view>
</view>
</view>
</view>
<loading-footer slotEmpty :status="loadingStatus">
<view style="padding-top: 200rpx;" class="data-null column-center" slot="empty">
<image src="../../../static/images/order_null.png" class="img-null"></image>
<text class="xs muted">暂无中奖名单</text>
</view>
</loading-footer>
</view>
</template>
<script>
import {
loadingType
} from '@/utils/type';
import {
loadingFun
} from "@/utils/tools"
import {
luckyDrawWinningList
} from "@/api/user";
export default {
data() {
return {
loadingStatus: loadingType.EMPTY,
page: 1,
bargainGoods: [], //
}
},
methods: {
//
getLists() {
let {
loadingStatus,
bargainGoods,
page
} = this;
loadingFun(luckyDrawWinningList, page, bargainGoods, loadingStatus).then(res => {
if (res) {
this.page = res.page;
this.bargainGoods = res.dataList
this.loadingStatus = res.status
}
})
}
},
onLoad() {
this.getLists()
},
onReachBottom() {
this.getLists();
},
}
</script>
<style lang="scss" scoped>
.goods-list {
margin: 0 20rpx;
// margin-top: 20rpx;
.code-item {
margin-top: 20rpx;
padding: 26rpx 24rpx;
}
.desc {
width: 550rpx;
}
}
</style>

View File

@ -0,0 +1,107 @@
<template>
<view class="writeoff-order">
<template v-if="detail.id">
<view class="list">
<view class="item bg-white">
<view class="row-between title">
<view>联系人{{detail.consignee}}</view>
<view :class="[detail.verification_status == 0 ? 'primary' : 'muted']">{{detail.verification_status_desc}}</view>
</view>
<order-goods :list="detail.order_goods"></order-goods>
</view>
</view>
<view class="btns">
<button class="bg-primary br60 white btn" size="lg" @tap="showModal=true">已提货</button>
<navigator class="mt20" open-type="navigateBack" :delta="1" hover-class="none">
<button class="bg-white br60 btn" size="lg">返回核销列表</button>
</navigator>
</view>
</template>
<template v-else>
<view class="column-center" style="padding-top: 200rpx">
<image class="img-null" src="/static/images/order_null.png"></image>
<text class="lighter">抱歉该订单不存在</text>
<view class="btns" style="margin-top: 100rpx;">
<navigator style="width: 100%;" open-type="navigateBack" :delta="1" hover-class="none">
<button class="bg-primary br60 white" size="lg">返回核销列表</button>
</navigator>
</view>
</view>
</template>
<u-modal ref="uModalInput" v-model="showModal" show-cancel-button :confirm-color="primaryColor"
confirm-text="确定" @confirm="handleVerificationConfirm" title="确认核销" content="是否确认核销?">
</u-modal>
<loading-view v-if="isFirstLoading"></loading-view>
</view>
</template>
<script>
import {
verificationConfirm,
verification
} from '@/api/order'
export default {
data() {
return {
detail: {},
showModal: false,
isFirstLoading: true
}
},
methods: {
verificationFun() {
verification({
pickup_code: this.code
}).then(res => {
this.isFirstLoading = false
if(res.code == 1) {
this.detail = res.data
}
})
},
handleVerificationConfirm() {
verificationConfirm({
id: this.detail.id
}).then(res => {
if(res.code == 1) {
uni.$emit('refreshverify')
this.$toast({
title: res.msg
}, {
tab: 3,
url: 1
})
}
})
}
},
async onLoad(options) {
this.code = options.code
this.verificationFun()
console.log(options)
},
}
</script>
<style lang="scss">
.writeoff-order {
.list {
padding: 20rpx;
.item {
border-radius: 10rpx;
&:not(:last-of-type) {
margin-bottom: 20rpx;
}
.title {
padding: 20rpx;
}
}
}
.btns {
width: 100%;
padding: 0 40rpx 50rpx;
}
}
</style>

View File

@ -0,0 +1,169 @@
<template>
<view class="writeoff-order">
<u-tabs :list="order" :active-color="primaryColor" inactive-color="#333" :is-scroll="false" :current="current"
@change="changeCurrent"></u-tabs>
<view class="list">
<view class="item bg-white" v-for="(item, index) in orderList" :key="index">
<view class="row-between title">
<view>联系人{{item.consignee}}</view>
<view :class="[item.verification_status == 0 ? 'primary' : 'muted']">{{item.verification_status_desc}}</view>
</view>
<order-goods :list="item.order_goods"></order-goods>
</view>
</view>
<loading-footer :status="status" :slot-empty="true" @refresh="reflesh">
<view slot="empty" class="column-center" style="padding-top: 200rpx">
<image class="img-null" src="/static/images/order_null.png"></image>
<text class="lighter">暂无订单</text>
</view>
</loading-footer>
<view class="btns row-between">
<button class="bg-primary br60 white btn" size="lg" @tap="onScanCode">扫码核销</button>
<button class="bg-primary br60 white btn ml20" size="lg" @tap="showModal=true">手动核销</button>
</view>
<u-modal ref="uModalInput" v-model="showModal" show-cancel-button :confirm-color="primaryColor"
confirm-text="确定" @confirm="onConfirm" title="手动核销">
<view class="slot-content row-center" style="padding: 40rpx;">
<u-input type="number" v-model="code" :border="true" placeholder="请输入核销码" style="width: 100%" />
</view>
</u-modal>
</view>
</template>
<script>
import {
getVerifyLists,
verification
} from '@/api/order'
import {
loadingType
} from '@/utils/type';
import {
loadingFun,
isWeixinClient
} from '@/utils/tools';
import wechath5 from '@/utils/wechath5'
export default {
data() {
return {
page: 1,
orderList: [],
status: loadingType.LOADING,
current: 0,
showModal: false,
code: '',
order: [{
name: '待核销',
type: 0
}, {
name: '已核销',
type: 1
}]
}
},
methods: {
reflesh() {
this.page = 1
this.orderList = []
this.status = loadingType.LOADING
this.getVerifyListsFun();
},
changeCurrent(current) {
this.current = current
this.reflesh()
},
onScanCode() {
// #ifdef H5
if(!isWeixinClient()) return this.$toast({title: 'h5暂不支持扫码'})
wechath5.scanQRCode().then(res => {
this.toDetail(res)
})
// #endif
// #ifndef H5
uni.scanCode({
scanType: ['qrCode'],
success: (res) => {
console.log(res)
this.toDetail(res.result)
},
fail: (res) => {
console.log(res)
}
});
// #endif
},
async getVerifyListsFun() {
let {
page,
orderList,
status,
current,
order
} = this;
const type = order[current].type
const data = await loadingFun(getVerifyLists, page, orderList, status, {
type
})
if (!data) return
this.page = data.page
this.orderList = data.dataList
this.status = data.status
},
onConfirm() {
if(this.code === '') return this.$toast({title: '请输入核销码'})
this.toDetail(this.code)
},
toDetail(code) {
this.code = ''
uni.navigateTo({
url: `/bundle/pages/writeoff_detail/writeoff_detail?code=${code}`,
})
}
},
async onLoad() {
uni.$on("refreshverify", () => {
this.reflesh()
})
this.getVerifyListsFun()
},
onUnload() {
uni.$off('refreshverify')
},
onPullDownRefresh: function() {
this.reflesh()
},
onReachBottom: function() {
this.getVerifyListsFun()
},
}
</script>
<style lang="scss">
.writeoff-order {
padding-bottom: 120rpx;
.list {
padding: 20rpx;
.item {
border-radius: 10rpx;
&:not(:last-of-type) {
margin-bottom: 20rpx;
}
.title {
padding: 20rpx;
}
}
}
.btns {
position: fixed;
bottom: env(safe-area-inset-bottom);
width: 100%;
padding: 20rpx 25rpx;
.btn {
flex: 1;
}
}
}
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 570 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 440 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 614 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 757 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 653 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Some files were not shown because too many files have changed in this diff Show More