This commit is contained in:
2025-09-24 20:35:15 +08:00
parent 39679f7330
commit 8a458ff0a4
12033 changed files with 1537546 additions and 13292 deletions

View File

@@ -5,21 +5,60 @@ const _sfc_main = {
data() {
return {
avatarUrl: "/static/logo.png",
shopName: "我的店铺",
mobile: ""
shopName: "未登录",
mobile: "",
pendingJsCode: "",
logging: false,
vipIsVip: false,
vipStart: "",
vipEnd: ""
};
},
onLoad() {
onShow() {
this.fetchProfile();
this.loadVipFromStorage();
try {
if (common_vendor.index.getStorageSync("TOKEN")) {
this.$forceUpdate && this.$forceUpdate();
}
} catch (e) {
}
},
computed: {
isLoggedIn() {
try {
return !!common_vendor.index.getStorageSync("TOKEN");
} catch (e) {
return false;
}
},
mobileDisplay() {
const m = String(this.mobile || "");
return m.length === 11 ? m.slice(0, 3) + "****" + m.slice(7) : m || "未绑定手机号";
},
vipStartDisplay() {
return this.formatDisplay(this.vipStart);
},
vipEndDisplay() {
return this.formatDisplay(this.vipEnd);
}
},
methods: {
// 登录相关方法已移除
async fetchProfile() {
const hasToken = (() => {
try {
return !!common_vendor.index.getStorageSync("TOKEN");
} catch (e) {
return false;
}
})();
if (!hasToken) {
this.shopName = "未登录";
this.avatarUrl = "/static/logo.png";
this.mobile = "";
return;
}
try {
await common_http.get("/api/dashboard/overview");
} catch (e) {
@@ -36,11 +75,96 @@ const _sfc_main = {
} catch (e) {
}
},
loadVipFromStorage() {
try {
const isVip = String(common_vendor.index.getStorageSync("USER_VIP_IS_VIP") || "false").toLowerCase() === "true";
const start = common_vendor.index.getStorageSync("USER_VIP_START") || "";
const end = common_vendor.index.getStorageSync("USER_VIP_END") || "";
this.vipIsVip = isVip;
this.vipStart = start;
this.vipEnd = end;
} catch (e) {
}
},
formatDisplay(value) {
if (!value)
return "-";
const s = String(value);
const m = s.match(/^(\d{4}-\d{2}-\d{2})([ T](\d{2}:\d{2}))/);
if (m)
return `${m[1]} ${m[3]}`;
return s;
},
startLogin() {
if (this.logging)
return;
this.logging = true;
const tryOnce = async () => ({});
common_vendor.index.login({ provider: "weixin", success: async (res) => {
this.pendingJsCode = res.code || "";
if (!this.pendingJsCode) {
this.logging = false;
return common_vendor.index.showToast({ title: "获取登录code失败", icon: "none" });
}
try {
await tryOnce();
} catch (e) {
const msg = e && e.message || "";
if (msg.includes("40163") || msg.toLowerCase().includes("been used")) {
common_vendor.index.login({ provider: "weixin", success: async (r2) => {
const fresh = r2.code || "";
if (!fresh) {
this.logging = false;
return;
}
try {
await tryOnce();
} finally {
this.logging = false;
}
} });
return;
}
} finally {
this.logging = false;
}
}, fail: () => {
this.logging = false;
common_vendor.index.showToast({ title: "微信登录失败", icon: "none" });
} });
},
goLogin() {
common_vendor.index.navigateTo({ url: "/pages/auth/login" });
},
goRegister() {
common_vendor.index.navigateTo({ url: "/pages/auth/register" });
},
onGetPhoneNumber(e) {
if (this.logging)
return;
this.logging = true;
common_vendor.index.login({ provider: "weixin", success: (res) => {
const jsCode = res.code || "";
if (!jsCode) {
this.logging = false;
return common_vendor.index.showToast({ title: "获取登录code失败", icon: "none" });
}
Promise.resolve().finally(() => {
this.logging = false;
});
}, fail: () => {
this.logging = false;
common_vendor.index.showToast({ title: "微信登录失败", icon: "none" });
} });
},
goSmsLogin() {
common_vendor.index.navigateTo({ url: "/pages/my/sms-login" });
},
onAvatarError() {
this.avatarUrl = "/static/logo.png";
},
goVip() {
common_vendor.index.showToast({ title: "VIP会员开发中", icon: "none" });
common_vendor.index.navigateTo({ url: "/pages/my/vip" });
},
goMyOrders() {
common_vendor.index.switchTab({ url: "/pages/detail/index" });
@@ -72,11 +196,15 @@ const _sfc_main = {
logout() {
try {
common_vendor.index.removeStorageSync("TOKEN");
common_vendor.index.removeStorageSync("LOGINED");
common_vendor.index.removeStorageSync("LOGIN_PHONE");
common_vendor.index.removeStorageSync("DEFAULT_USER_ID");
common_vendor.index.setStorageSync("ENABLE_DEFAULT_USER", "false");
common_vendor.index.removeStorageSync("USER_AVATAR");
common_vendor.index.removeStorageSync("USER_NAME");
common_vendor.index.removeStorageSync("USER_MOBILE");
common_vendor.index.removeStorageSync("SHOP_NAME");
common_vendor.index.showToast({ title: "已退出", icon: "none" });
common_vendor.index.showToast({ title: "已清理本地信息", icon: "none" });
setTimeout(() => {
common_vendor.index.reLaunch({ url: "/pages/index/index" });
}, 300);
@@ -87,23 +215,34 @@ const _sfc_main = {
}
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return {
a: $data.avatarUrl,
b: common_vendor.o((...args) => $options.onAvatarError && $options.onAvatarError(...args)),
c: common_vendor.t($data.shopName),
d: common_vendor.t($options.mobileDisplay),
e: common_vendor.o((...args) => $options.goVip && $options.goVip(...args)),
f: common_vendor.o((...args) => $options.goMyOrders && $options.goMyOrders(...args)),
g: common_vendor.o((...args) => $options.goSupplier && $options.goSupplier(...args)),
h: common_vendor.o((...args) => $options.goCustomer && $options.goCustomer(...args)),
i: common_vendor.o((...args) => $options.goCustomerQuote && $options.goCustomerQuote(...args)),
j: common_vendor.o((...args) => $options.goShop && $options.goShop(...args)),
k: common_vendor.o((...args) => $options.editProfile && $options.editProfile(...args)),
l: common_vendor.o((...args) => $options.goProductSettings && $options.goProductSettings(...args)),
m: common_vendor.o((...args) => $options.goSystemParams && $options.goSystemParams(...args)),
n: common_vendor.o((...args) => $options.goAbout && $options.goAbout(...args)),
o: common_vendor.o((...args) => $options.logout && $options.logout(...args))
};
return common_vendor.e({
a: !$options.isLoggedIn
}, !$options.isLoggedIn ? {
b: common_vendor.o((...args) => $options.goLogin && $options.goLogin(...args)),
c: common_vendor.o((...args) => $options.goRegister && $options.goRegister(...args))
} : {}, {
d: $data.avatarUrl,
e: common_vendor.o((...args) => $options.onAvatarError && $options.onAvatarError(...args)),
f: common_vendor.t($data.shopName),
g: common_vendor.t($options.mobileDisplay),
h: common_vendor.t($data.vipIsVip ? "VIP" : "非VIP"),
i: common_vendor.t($options.vipStartDisplay),
j: common_vendor.t($options.vipEndDisplay),
k: $data.vipIsVip ? 1 : "",
l: common_vendor.o((...args) => $options.goVip && $options.goVip(...args)),
m: common_vendor.o((...args) => $options.goMyOrders && $options.goMyOrders(...args)),
n: common_vendor.o((...args) => $options.goSupplier && $options.goSupplier(...args)),
o: common_vendor.o((...args) => $options.goCustomer && $options.goCustomer(...args)),
p: common_vendor.o((...args) => $options.goCustomerQuote && $options.goCustomerQuote(...args)),
q: common_vendor.o((...args) => $options.goShop && $options.goShop(...args)),
r: common_vendor.o((...args) => $options.editProfile && $options.editProfile(...args)),
s: common_vendor.o((...args) => $options.goProductSettings && $options.goProductSettings(...args)),
t: common_vendor.o((...args) => $options.goSystemParams && $options.goSystemParams(...args)),
v: common_vendor.o((...args) => $options.goAbout && $options.goAbout(...args)),
w: $options.isLoggedIn
}, $options.isLoggedIn ? {
x: common_vendor.o((...args) => $options.logout && $options.logout(...args))
} : {});
}
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
wx.createPage(MiniProgramPage);

View File

@@ -1 +1 @@
<view class="me"><view class="card user"><image class="avatar" src="{{a}}" mode="aspectFill" binderror="{{b}}"/><view class="meta"><text class="name">{{c}}</text><text class="phone">{{d}}</text><text class="role">老板</text></view></view><view class="group"><view class="group-title">会员与订单</view><view class="cell" bindtap="{{e}}"><text>VIP会员</text><text class="arrow"></text></view><view class="cell" bindtap="{{f}}"><text>我的订单</text><text class="arrow"></text></view></view><view class="group"><view class="group-title">基础管理</view><view class="cell" bindtap="{{g}}"><text>供应商管理</text><text class="arrow"></text></view><view class="cell" bindtap="{{h}}"><text>客户管理</text><text class="arrow"></text></view><view class="cell" bindtap="{{i}}"><text>客户报价</text><text class="arrow"></text></view><view class="cell" bindtap="{{j}}"><text>店铺管理</text><text class="arrow"></text></view></view><view class="group"><view class="group-title">设置中心</view><view class="cell" bindtap="{{k}}"><text>账号与安全</text><text class="desc">修改头像、姓名、密码</text><text class="arrow"></text></view><view class="cell" bindtap="{{l}}"><text>商品设置</text><text class="arrow"></text></view><view class="cell" bindtap="{{m}}"><text>系统参数</text><text class="desc">低价提示、默认收款、单行折扣等</text><text class="arrow"></text></view><view class="cell" bindtap="{{n}}"><text>关于与协议</text><text class="arrow"></text></view><view class="cell danger" bindtap="{{o}}"><text>退出登录</text></view></view></view>
<view class="me"><view wx:if="{{a}}" class="card login"><view class="login-title">登录/注册以同步数据</view><button class="login-btn" type="primary" bindtap="{{b}}">登录</button><button class="login-btn minor" bindtap="{{c}}">注册</button></view><view class="card user"><image class="avatar" src="{{d}}" mode="aspectFill" binderror="{{e}}"/><view class="meta"><text class="name">{{f}}</text><text class="phone">{{g}}</text><text class="role">老板</text></view></view><view class="{{['card', 'vip', k && 'active']}}"><view class="vip-row"><text class="vip-badge">{{h}}</text><text class="vip-title">会员状态</text></view><view class="vip-meta"><view class="item"><text class="label">开始</text><text class="value">{{i}}</text></view><view class="item"><text class="label">结束</text><text class="value">{{j}}</text></view></view></view><view class="group"><view class="group-title">会员与订单</view><view class="cell" bindtap="{{l}}"><text>VIP会员</text><text class="arrow"></text></view><view class="cell" bindtap="{{m}}"><text>我的订单</text><text class="arrow"></text></view></view><view class="group"><view class="group-title">基础管理</view><view class="cell" bindtap="{{n}}"><text>供应商管理</text><text class="arrow"></text></view><view class="cell" bindtap="{{o}}"><text>客户管理</text><text class="arrow"></text></view><view class="cell" bindtap="{{p}}"><text>客户报价</text><text class="arrow"></text></view><view class="cell" bindtap="{{q}}"><text>店铺管理</text><text class="arrow"></text></view></view><view class="group"><view class="group-title">设置中心</view><view class="cell" bindtap="{{r}}"><text>账号与安全</text><text class="desc">修改头像、姓名、密码</text><text class="arrow"></text></view><view class="cell" bindtap="{{s}}"><text>商品设置</text><text class="arrow"></text></view><view class="cell" bindtap="{{t}}"><text>系统参数</text><text class="desc">低价提示、默认收款、单行折扣等</text><text class="arrow"></text></view><view class="cell" bindtap="{{v}}"><text>关于与协议</text><text class="arrow"></text></view><view wx:if="{{w}}" class="cell danger" bindtap="{{x}}"><text>退出登录</text></view></view></view>

View File

@@ -27,6 +27,27 @@
.me {
padding: 24rpx;
}
.card.login {
display: flex;
flex-direction: column;
gap: 16rpx;
padding: 22rpx;
background: #ffffff;
border-radius: 16rpx;
margin-bottom: 24rpx;
}
.login-title {
font-size: 28rpx;
font-weight: 700;
}
.login-btn.minor {
background: #f1f1f1;
color: #111;
}
.hint {
font-size: 22rpx;
color: #444;
}
.card.user {
display: flex;
gap: 18rpx;
@@ -60,6 +81,58 @@
font-size: 22rpx;
color: #444;
}
/* VIP 卡片样式 */
.card.vip {
margin-top: 24rpx;
padding: 22rpx;
background: #ffffff;
border-radius: 16rpx;
box-shadow: 0 6rpx 16rpx rgba(0, 0, 0, 0.12);
}
.card.vip.active {
border: 1rpx solid rgba(255, 208, 0, 0.6);
background-image: radial-gradient(60% 60% at 80% 0%, rgba(255, 214, 0, 0.08), transparent 60%);
}
.vip-row {
display: flex;
align-items: center;
gap: 12rpx;
margin-bottom: 10rpx;
}
.vip-badge {
background: #f1c40f;
color: #111;
font-weight: 800;
padding: 2rpx 10rpx;
border-radius: 8rpx;
font-size: 22rpx;
}
.vip-title {
font-size: 28rpx;
font-weight: 700;
color: #111;
}
.vip-meta {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8rpx 16rpx;
}
.vip-meta .item {
display: flex;
align-items: center;
gap: 10rpx;
}
.vip-meta .label {
width: 80rpx;
color: #444;
font-size: 24rpx;
}
.vip-meta .value {
color: #111;
font-size: 26rpx;
word-break: break-all;
}
.group {
margin-top: 24rpx;
background: #ffffff;
@@ -93,4 +166,57 @@
color: #dd524d;
justify-content: center;
font-weight: 700;
}
/* 简易对话框样式 */
.dialog-mask {
position: fixed;
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.45);
display: flex;
align-items: center;
justify-content: center;
z-index: 999;
}
.dialog {
width: 600rpx;
background: #fff;
border-radius: 16rpx;
padding: 24rpx;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.2);
}
.dialog-title {
font-size: 30rpx;
font-weight: 700;
margin-bottom: 16rpx;
}
.dialog-input {
width: 100%;
height: 72rpx;
padding: 0 16rpx;
border: 1rpx solid #e5e7eb;
border-radius: 10rpx;
background: #fff;
color: #111;
}
.dialog-actions {
display: flex;
gap: 16rpx;
margin-top: 18rpx;
justify-content: flex-end;
}
.dialog-btn {
padding: 16rpx 22rpx;
border-radius: 10rpx;
}
.dialog-btn.cancel {
background: #f1f1f1;
color: #111;
}
.dialog-btn.confirm {
background: #2979ff;
color: #fff;
}

View File

@@ -0,0 +1,77 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const _sfc_main = {
data() {
return {
form: { phone: "", password: "" },
showPwd: false,
submitting: false
};
},
methods: {
validatePhone(p) {
return /^1\d{10}$/.test(String(p || ""));
},
validate() {
if (!this.validatePhone(this.form.phone)) {
common_vendor.index.showToast({ title: "请输入有效手机号", icon: "none" });
return false;
}
if (!this.form.password) {
common_vendor.index.showToast({ title: "请输入密码", icon: "none" });
return false;
}
if (this.form.password.length < 6) {
common_vendor.index.showToast({ title: "密码至少6位", icon: "none" });
return false;
}
return true;
},
submit() {
if (this.submitting)
return;
if (!this.validate())
return;
this.submitting = true;
try {
common_vendor.index.setStorageSync("LOGIN_STATUS", "logged_in");
common_vendor.index.setStorageSync("LOGIN_PHONE", this.form.phone);
try {
const uid = common_vendor.index.getStorageSync("DEFAULT_USER_ID") || "";
const enable = common_vendor.index.getStorageSync("ENABLE_DEFAULT_USER") || "";
if (!enable)
common_vendor.index.setStorageSync("ENABLE_DEFAULT_USER", "true");
if (!uid)
common_vendor.index.setStorageSync("DEFAULT_USER_ID", "2");
} catch (e) {
}
common_vendor.index.showToast({ title: "登录成功(本地)", icon: "none" });
setTimeout(() => {
common_vendor.index.reLaunch({ url: "/pages/index/index" });
}, 500);
} finally {
this.submitting = false;
}
}
}
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return {
a: $data.form.phone,
b: common_vendor.o(common_vendor.m(($event) => $data.form.phone = $event.detail.value, {
trim: true
})),
c: !$data.showPwd,
d: $data.form.password,
e: common_vendor.o(common_vendor.m(($event) => $data.form.password = $event.detail.value, {
trim: true
})),
f: common_vendor.t($data.showPwd ? "隐藏" : "显示"),
g: common_vendor.o(($event) => $data.showPwd = !$data.showPwd),
h: $data.submitting,
i: common_vendor.o((...args) => $options.submit && $options.submit(...args))
};
}
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
wx.createPage(MiniProgramPage);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/my/password-login.js.map

View File

@@ -0,0 +1,4 @@
{
"navigationBarTitleText": "账号登录",
"usingComponents": {}
}

View File

@@ -0,0 +1 @@
<view class="login"><view class="card"><view class="title">手机号登录</view><view class="field"><text class="label">手机号</text><input class="input" type="number" placeholder="请输入手机号" maxlength="11" value="{{a}}" bindinput="{{b}}"/></view><view class="field"><text class="label">密码</text><input class="input" password="{{c}}" placeholder="请输入密码" maxlength="32" value="{{d}}" bindinput="{{e}}"/><view class="toggle" bindtap="{{g}}">{{f}}</view></view><view class="hint">本页面为静态实现,不调用后端接口,仅做本地校验与存储。</view><button class="primary" disabled="{{h}}" bindtap="{{i}}">登录</button></view></view>

View File

@@ -0,0 +1,81 @@
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场https://ext.dcloud.net.cn上很多三方插件均使用了这些样式变量
* 如果你是插件开发者建议你使用scss预处理并在插件代码中直接使用这些变量无需 import 这个文件方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者插件使用者你可以通过修改这些变量来定制自己的插件主题实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
*/
/* 颜色变量 */
/* 行为相关颜色 */
/* 藏青系主色(高亮) */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.login {
min-height: 100vh;
padding: 24rpx;
background: #ffffff;
}
.card {
margin-top: 60rpx;
background: #fff;
border: 2rpx solid #e5e7eb;
border-radius: 16rpx;
padding: 24rpx;
}
.title {
font-size: 36rpx;
font-weight: 800;
margin-bottom: 16rpx;
color: #111;
}
.field {
position: relative;
margin-bottom: 16rpx;
}
.label {
display: block;
margin-bottom: 8rpx;
color: #444;
}
.input {
width: 100%;
background: #f1f1f1;
border: 2rpx solid #e5e7eb;
border-radius: 12rpx;
padding: 14rpx;
color: #111;
}
.toggle {
position: absolute;
right: 12rpx;
top: 64rpx;
color: #4C8DFF;
font-size: 26rpx;
}
.hint {
color: #444;
font-size: 24rpx;
margin: 8rpx 0 16rpx;
}
.primary {
width: 100%;
background: #4C8DFF;
color: #fff;
border-radius: 999rpx;
padding: 20rpx 0;
font-weight: 800;
}

View File

@@ -0,0 +1,153 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const common_http = require("../../common/http.js");
const _sfc_main = {
data() {
return { phone: "", code: "", countdown: 0, timer: null, sending: false, logging: false, showDebug: true };
},
computed: {
btnText() {
return this.countdown > 0 ? `${this.countdown}s` : this.sending ? "发送中..." : "获取验证码";
},
trimmedPhone() {
return String(this.phone || "").trim();
},
sendBodyJson() {
return JSON.stringify({ phone: this.trimmedPhone, scene: "login" }, null, 2);
},
loginBodyJson() {
return JSON.stringify({ phone: this.trimmedPhone, code: String(this.code || "").trim() }, null, 2);
}
},
onUnload() {
if (this.timer)
clearInterval(this.timer);
},
methods: {
validatePhone(p) {
return /^1\d{10}$/.test(String(p || "").trim());
},
startCountdown(sec) {
this.countdown = sec;
if (this.timer)
clearInterval(this.timer);
this.timer = setInterval(() => {
if (this.countdown <= 1) {
clearInterval(this.timer);
this.timer = null;
this.countdown = 0;
return;
}
this.countdown--;
}, 1e3);
},
async sendCode() {
if (this.sending || this.countdown > 0)
return;
const p = String(this.phone || "").trim();
if (!this.validatePhone(p))
return common_vendor.index.showToast({ title: "请输入正确的手机号", icon: "none" });
this.sending = true;
try {
const res = await common_http.post("/api/auth/sms/send", { phone: p, scene: "login" });
const cd = Number(res && res.cooldownSec || 60);
this.startCountdown(cd);
common_vendor.index.showToast({ title: "验证码已发送", icon: "none" });
} catch (e) {
const msg = e && e.message || "发送失败";
common_vendor.index.showToast({ title: msg, icon: "none" });
} finally {
this.sending = false;
}
},
async doLogin() {
if (this.logging)
return;
const p = String(this.phone || "").trim();
const c = String(this.code || "").trim();
if (!this.validatePhone(p))
return common_vendor.index.showToast({ title: "请输入正确的手机号", icon: "none" });
if (!/^\d{6}$/.test(c))
return common_vendor.index.showToast({ title: "验证码格式不正确", icon: "none" });
this.logging = true;
try {
const data = await common_http.post("/api/auth/sms/login", { phone: p, code: c });
if (data && data.token) {
common_vendor.index.setStorageSync("TOKEN", data.token);
if (data.user && data.user.phone)
common_vendor.index.setStorageSync("USER_MOBILE", data.user.phone);
common_vendor.index.showToast({ title: "登录成功", icon: "none" });
setTimeout(() => {
common_vendor.index.reLaunch({ url: "/pages/index/index" });
}, 300);
}
} catch (e) {
const msg = e && e.message || "登录失败";
common_vendor.index.showToast({ title: msg, icon: "none" });
} finally {
this.logging = false;
}
},
async quickRegister() {
if (this.logging)
return;
const p = String(this.phone || "").trim();
if (!this.validatePhone(p))
return common_vendor.index.showToast({ title: "请输入正确的手机号", icon: "none" });
this.logging = true;
try {
const data = await common_http.post("/api/auth/register", { phone: p });
if (data && data.token) {
common_vendor.index.setStorageSync("TOKEN", data.token);
if (data.user && data.user.phone)
common_vendor.index.setStorageSync("USER_MOBILE", data.user.phone);
common_vendor.index.showToast({ title: "注册成功", icon: "none" });
setTimeout(() => {
common_vendor.index.reLaunch({ url: "/pages/index/index" });
}, 300);
}
} catch (e) {
const msg = e && e.message || "注册失败";
common_vendor.index.showToast({ title: msg, icon: "none" });
} finally {
this.logging = false;
}
},
copy(text) {
try {
common_vendor.index.setClipboardData({ data: String(text || "") });
common_vendor.index.showToast({ title: "已复制", icon: "none" });
} catch (e) {
}
},
toggleDebug() {
this.showDebug = !this.showDebug;
}
}
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return common_vendor.e({
a: $data.phone,
b: common_vendor.o(($event) => $data.phone = $event.detail.value),
c: $data.code,
d: common_vendor.o(($event) => $data.code = $event.detail.value),
e: common_vendor.t($options.btnText),
f: $data.countdown > 0 || $data.sending,
g: common_vendor.o((...args) => $options.sendCode && $options.sendCode(...args)),
h: $data.logging,
i: common_vendor.o((...args) => $options.doLogin && $options.doLogin(...args)),
j: $data.logging,
k: common_vendor.o((...args) => $options.quickRegister && $options.quickRegister(...args)),
l: common_vendor.t($data.showDebug ? "收起" : "展开"),
m: common_vendor.o((...args) => $options.toggleDebug && $options.toggleDebug(...args)),
n: $data.showDebug
}, $data.showDebug ? {
o: common_vendor.t($options.sendBodyJson),
p: common_vendor.o(($event) => $options.copy($options.sendBodyJson)),
q: common_vendor.t($options.loginBodyJson),
r: common_vendor.o(($event) => $options.copy($options.loginBodyJson))
} : {});
}
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
wx.createPage(MiniProgramPage);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/my/sms-login.js.map

View File

@@ -0,0 +1,4 @@
{
"navigationBarTitleText": "短信验证码登录",
"usingComponents": {}
}

View File

@@ -0,0 +1 @@
<view class="page sms-login"><view class="card"><view class="title">短信验证码登录</view><view class="form"><input class="input" type="number" maxlength="11" placeholder="请输入手机号" value="{{a}}" bindinput="{{b}}"/><view class="row"><input class="input code" type="number" maxlength="6" placeholder="请输入验证码" value="{{c}}" bindinput="{{d}}"/><button class="send" disabled="{{f}}" bindtap="{{g}}">{{e}}</button></view><button class="login" type="primary" disabled="{{h}}" bindtap="{{i}}">登录/注册</button><button class="login" disabled="{{j}}" bindtap="{{k}}">注册为店主</button></view><view class="hint">首次登录将自动创建店铺与店主用户。</view><view class="debug"><view class="debug-title" bindtap="{{m}}">请求体示例(点击{{l}}</view><view wx:if="{{n}}" class="debug-body"><view class="code-title">POST /api/auth/sms/send</view><view class="code-wrap"><text class="code">{{o}}</text><button size="mini" class="copy" bindtap="{{p}}">复制</button></view><view class="code-title">POST /api/auth/sms/login</view><view class="code-wrap"><text class="code">{{q}}</text><button size="mini" class="copy" bindtap="{{r}}">复制</button></view></view></view></view></view>

View File

@@ -0,0 +1,104 @@
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场https://ext.dcloud.net.cn上很多三方插件均使用了这些样式变量
* 如果你是插件开发者建议你使用scss预处理并在插件代码中直接使用这些变量无需 import 这个文件方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者插件使用者你可以通过修改这些变量来定制自己的插件主题实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
*/
/* 颜色变量 */
/* 行为相关颜色 */
/* 藏青系主色(高亮) */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
.sms-login {
padding: 24rpx;
}
.card {
background: #ffffff;
border-radius: 16rpx;
padding: 28rpx;
}
.title {
font-size: 32rpx;
font-weight: 700;
margin-bottom: 20rpx;
}
.form {
display: flex;
flex-direction: column;
gap: 16rpx;
}
.row {
display: flex;
gap: 12rpx;
}
.input {
background: #fff;
border: 1rpx solid #e5e7eb;
border-radius: 12rpx;
padding: 20rpx;
font-size: 28rpx;
flex: 1;
}
.input.code {
flex: 1;
}
.send {
min-width: 220rpx;
}
.login {
margin-top: 8rpx;
}
.hint {
margin-top: 12rpx;
font-size: 22rpx;
color: #444;
}
.debug {
margin-top: 20rpx;
}
.debug-title {
font-size: 26rpx;
color: #444;
}
.debug-body {
margin-top: 12rpx;
display: flex;
flex-direction: column;
gap: 12rpx;
}
.code-title {
font-size: 24rpx;
color: #444;
}
.code-wrap {
position: relative;
background: #fff;
border: 1rpx solid #e5e7eb;
border-radius: 12rpx;
padding: 16rpx;
}
.code {
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
font-size: 24rpx;
white-space: pre-wrap;
}
.copy {
position: absolute;
top: 8rpx;
right: 8rpx;
}

View File

@@ -0,0 +1,52 @@
"use strict";
const common_vendor = require("../../common/vendor.js");
const common_config = require("../../common/config.js");
const _sfc_main = {
data() {
return {
isVip: false,
expire: "",
price: common_config.VIP_PRICE_PER_MONTH
};
},
onShow() {
this.loadVip();
},
computed: {
expireDisplay() {
const s = String(this.expire || "");
return s || "11年11月11日";
}
},
methods: {
loadVip() {
try {
this.isVip = String(common_vendor.index.getStorageSync("USER_VIP_IS_VIP") || "false").toLowerCase() === "true";
this.expire = common_vendor.index.getStorageSync("USER_VIP_END") || "";
} catch (e) {
}
},
onPay() {
common_vendor.index.showToast({ title: "静态页面演示:支付功能未接入", icon: "none" });
}
}
};
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return common_vendor.e({
a: common_vendor.t($data.isVip ? "VIP会员" : "成为VIP会员"),
b: common_vendor.t($data.isVip ? "尊享专属特权" : "解锁更多权益"),
c: common_vendor.t($data.isVip ? "VIP会员" : "普通用户"),
d: $data.isVip ? 1 : "",
e: $data.isVip
}, $data.isVip ? {
f: common_vendor.t($options.expireDisplay)
} : {}, {
g: !$data.isVip
}, !$data.isVip ? {
h: common_vendor.t($data.price),
i: common_vendor.o((...args) => $options.onPay && $options.onPay(...args))
} : {});
}
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
wx.createPage(MiniProgramPage);
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/my/vip.js.map

View File

@@ -0,0 +1,8 @@
{
"navigationBarTitleText": "VIP会员",
"navigationBarBackgroundColor": "#1a1a2e",
"navigationBarTextStyle": "white",
"backgroundColor": "#1a1a2e",
"backgroundTextStyle": "light",
"usingComponents": {}
}

View File

@@ -0,0 +1 @@
<view class="vip-page" style="background:linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);min-height:100vh"><view class="main-content"><view class="vip-header"><view class="vip-crown"><text class="crown-icon">👑</text></view><text class="vip-title">{{a}}</text><text class="vip-subtitle">{{b}}</text><view class="{{['vip-status', d && 'active']}}"><text class="status-text">{{c}}</text></view></view><view class="features-section"><text class="section-title">会员功能</text><view class="feature-card"><view class="feature-icon">💾</view><text class="feature-text">永久存储数据</text></view></view><view wx:if="{{e}}" class="vip-info"><view class="info-card"><text class="info-label">会员状态</text><text class="info-value active">已激活</text></view><view class="info-card"><text class="info-label">有效期至</text><text class="info-value">{{f}}</text></view></view><view wx:if="{{g}}" class="purchase-section"><view class="price-card"><text class="price-label">会员价格</text><view class="price-display"><text class="price-symbol">¥</text><text class="price-amount">{{h}}</text><text class="price-period">/月</text></view></view><button class="purchase-btn" bindtap="{{i}}"><text class="btn-text">立即开通VIP</text></button></view></view><view class="bg-decoration"><view class="decoration-circle circle-1"></view><view class="decoration-circle circle-2"></view><view class="decoration-circle circle-3"></view></view></view>

View File

@@ -0,0 +1,264 @@
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场https://ext.dcloud.net.cn上很多三方插件均使用了这些样式变量
* 如果你是插件开发者建议你使用scss预处理并在插件代码中直接使用这些变量无需 import 这个文件方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者插件使用者你可以通过修改这些变量来定制自己的插件主题实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
*/
/* 颜色变量 */
/* 行为相关颜色 */
/* 藏青系主色(高亮) */
/* 文字基本颜色 */
/* 背景颜色 */
/* 边框颜色 */
/* 尺寸变量 */
/* 文字尺寸 */
/* 图片尺寸 */
/* Border Radius */
/* 水平间距 */
/* 垂直间距 */
/* 透明度 */
/* 文章场景相关 */
page {
background: #1a1a2e !important;
}
.vip-page {
min-height: 100vh;
width: 100%;
position: relative;
background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%) !important;
overflow: hidden;
display: flex;
flex-direction: column;
}
.main-content {
flex: 1;
padding: 60rpx 40rpx 40rpx;
position: relative;
z-index: 10;
}
/* VIP头部区域 */
.vip-header {
text-align: center;
margin-bottom: 80rpx;
}
.vip-header .vip-crown {
margin-bottom: 30rpx;
}
.vip-header .vip-crown .crown-icon {
font-size: 80rpx;
filter: drop-shadow(0 4rpx 12rpx rgba(255, 215, 0, 0.3));
}
.vip-header .vip-title {
display: block;
font-size: 48rpx;
font-weight: 700;
color: #fff;
margin-bottom: 16rpx;
text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.vip-header .vip-subtitle {
display: block;
font-size: 28rpx;
color: rgba(255, 255, 255, 0.8);
margin-bottom: 40rpx;
}
.vip-header .vip-status {
display: inline-block;
padding: 16rpx 32rpx;
border-radius: 50rpx;
background: rgba(0, 0, 0, 0.2);
-webkit-backdrop-filter: blur(10rpx);
backdrop-filter: blur(10rpx);
border: 1rpx solid rgba(255, 215, 0, 0.4);
}
.vip-header .vip-status.active {
background: linear-gradient(45deg, #ffd700, #ffed4e);
border: 1rpx solid rgba(255, 215, 0, 0.3);
}
.vip-header .vip-status.active .status-text {
color: #333;
}
.vip-header .vip-status .status-text {
font-size: 26rpx;
font-weight: 600;
color: #fff;
}
/* 会员功能区域 */
.features-section {
margin-bottom: 60rpx;
}
.features-section .section-title {
display: block;
font-size: 36rpx;
font-weight: 600;
color: #fff;
text-align: center;
margin-bottom: 40rpx;
}
.features-section .feature-card {
background: rgba(0, 0, 0, 0.15);
-webkit-backdrop-filter: blur(15rpx);
backdrop-filter: blur(15rpx);
border-radius: 24rpx;
padding: 40rpx;
text-align: center;
border: 1rpx solid rgba(255, 215, 0, 0.3);
transition: all 0.3s ease;
}
.features-section .feature-card:hover {
transform: translateY(-4rpx);
box-shadow: 0 12rpx 40rpx rgba(0, 0, 0, 0.15);
}
.features-section .feature-card .feature-icon {
font-size: 60rpx;
margin-bottom: 24rpx;
filter: drop-shadow(0 4rpx 12rpx rgba(255, 215, 0, 0.3));
}
.features-section .feature-card .feature-text {
display: block;
font-size: 32rpx;
font-weight: 600;
color: #fff;
letter-spacing: 1rpx;
}
/* VIP信息卡片 */
.vip-info {
margin-bottom: 60rpx;
}
.vip-info .info-card {
background: rgba(0, 0, 0, 0.15);
-webkit-backdrop-filter: blur(15rpx);
backdrop-filter: blur(15rpx);
border-radius: 20rpx;
padding: 32rpx;
margin-bottom: 20rpx;
border: 1rpx solid rgba(255, 215, 0, 0.3);
display: flex;
justify-content: space-between;
align-items: center;
}
.vip-info .info-card .info-label {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.8);
}
.vip-info .info-card .info-value {
font-size: 30rpx;
font-weight: 600;
color: #fff;
}
.vip-info .info-card .info-value.active {
color: #ffd700;
}
/* 购买区域 */
.purchase-section .price-card {
background: rgba(0, 0, 0, 0.15);
-webkit-backdrop-filter: blur(15rpx);
backdrop-filter: blur(15rpx);
border-radius: 24rpx;
padding: 40rpx;
text-align: center;
margin-bottom: 40rpx;
border: 1rpx solid rgba(255, 215, 0, 0.3);
}
.purchase-section .price-card .price-label {
display: block;
font-size: 28rpx;
color: rgba(255, 255, 255, 0.8);
margin-bottom: 16rpx;
}
.purchase-section .price-card .price-display {
display: flex;
align-items: baseline;
justify-content: center;
gap: 8rpx;
}
.purchase-section .price-card .price-display .price-symbol {
font-size: 32rpx;
color: #ffd700;
font-weight: 600;
}
.purchase-section .price-card .price-display .price-amount {
font-size: 60rpx;
font-weight: 700;
color: #ffd700;
}
.purchase-section .price-card .price-display .price-period {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.8);
}
.purchase-section .purchase-btn {
width: 100%;
height: 96rpx;
background: linear-gradient(45deg, #ffd700, #ffed4e);
border-radius: 50rpx;
border: none;
box-shadow: 0 8rpx 24rpx rgba(255, 215, 0, 0.3);
transition: all 0.3s ease;
}
.purchase-section .purchase-btn:active {
transform: translateY(2rpx);
box-shadow: 0 4rpx 16rpx rgba(255, 215, 0, 0.4);
}
.purchase-section .purchase-btn .btn-text {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
/* 背景装饰 */
.bg-decoration {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
pointer-events: none;
z-index: 1;
}
.bg-decoration .decoration-circle {
position: absolute;
border-radius: 50%;
background: rgba(255, 255, 255, 0.05);
}
.bg-decoration .decoration-circle.circle-1 {
width: 300rpx;
height: 300rpx;
top: -150rpx;
right: -100rpx;
}
.bg-decoration .decoration-circle.circle-2 {
width: 200rpx;
height: 200rpx;
bottom: 200rpx;
left: -100rpx;
}
.bg-decoration .decoration-circle.circle-3 {
width: 150rpx;
height: 150rpx;
top: 50%;
right: 50rpx;
transform: translateY(-50%);
}
/* 响应式调整 */
@media (max-width: 375px) {
.benefits-grid {
grid-template-columns: 1fr;
}
.vip-header .vip-title {
font-size: 42rpx;
}
.main-content {
padding: 40rpx 30rpx;
}
}