chore: 重写初始提交(清空历史,整理后全量提交)

This commit is contained in:
ywxapp
2026-08-16 16:54:14 +08:00
commit 6c1a106bc1
1808 changed files with 238144 additions and 0 deletions
+119
View File
@@ -0,0 +1,119 @@
<link rel="stylesheet" href="/assets/ywxapp/modules/cropper/cropper.css">
<style>
.readyimg { background: #f7f7f7; height: 420px; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.readyimg img { max-width: 100%; max-height: 100%; display: block; }
.img-preview { width: 150px; height: 150px; overflow: hidden; border-radius: 50%; border: 1px solid #eee; background: #f7f7f7; }
.img-preview img { width: 100%; }
</style>
<div class="uc-wrap">
<div class="layui-card">
<div class="layui-card-body">
<div class="layui-form-item">
<button type="button" class="layui-btn layui-btn-primary" id="pickBtn">
<i class="layui-icon">&#xe67c;</i> 选择图片
</button>
<input id="avatarImgUpload" type="file" accept="image/*" name="file" style="display:none">
<div class="layui-form-mid layui-word-aux">支持 jpg / png / gif,建议尺寸 150x150 以上,大小 4M 以内</div>
</div>
<div class="layui-row layui-col-space15">
<div class="layui-col-md9">
<div class="readyimg"><img id="cropImage" src=""></div>
</div>
<div class="layui-col-md3">
<div class="layui-form-mid">预览:</div>
<div class="img-preview" style="margin-top:8px;"></div>
</div>
</div>
<div class="layui-row layui-col-space15" style="margin-top:14px;">
<div class="layui-col-md9">
<button type="button" class="layui-btn" id="rotateLeft"><i class="layui-icon layui-icon-left"></i> 向左旋转</button>
<button type="button" class="layui-btn" id="rotateRight"><i class="layui-icon layui-icon-right"></i> 向右旋转</button>
<button type="button" class="layui-btn" id="resetImg"><i class="layui-icon layui-icon-refresh"></i> 重置</button>
</div>
<div class="layui-col-md3">
<button type="button" class="layui-btn layui-btn-fluid" id="confirmSave">保存修改</button>
</div>
</div>
</div>
</div>
</div>
<script>
layui.config({ base: '/assets/ywxapp/modules/' }).extend({ cropper: 'cropper/cropper' });
layui.use(['jquery', 'layer', 'cropper', 'http'], function () {
var $ = layui.$;
var layer = layui.layer;
var http = layui.http;
var $image = $('#cropImage');
var options = { aspectRatio: 1 / 1, preview: '.img-preview', viewMode: 1 };
var cropped = false;
// 选择图片
$('#pickBtn').on('click', function () { $('#avatarImgUpload').click(); });
$('#avatarImgUpload').on('change', function () {
var file = this.files[0];
if (!file) return;
var reader = new FileReader();
reader.onload = function (e) {
$image.attr('src', e.target.result);
$image.off('load.crop').on('load.crop', function () {
if (cropped) { $image.cropper('destroy'); }
$image.cropper(options);
cropped = true;
});
};
reader.readAsDataURL(file);
this.value = '';
});
// 旋转 / 重置
$('#rotateLeft').on('click', function () { if (cropped) $image.cropper('rotate', -15); });
$('#rotateRight').on('click', function () { if (cropped) $image.cropper('rotate', 15); });
$('#resetImg').on('click', function () { if (cropped) $image.cropper('reset'); });
// 保存:裁剪后上传
$('#confirmSave').on('click', function () {
if (!cropped) { layer.msg('请先选择图片', { icon: 2 }); return; }
var canvas = $image.cropper('getCroppedCanvas', { width: 300, height: 300 });
if (!canvas) { layer.msg('裁剪失败,请重试', { icon: 2 }); return; }
layer.load(1, { shade: [0.3, '#fff'] });
canvas.toBlob(function (blob) {
var fd = new FormData();
fd.append('file', blob, 'avatar.png');
fd.append('type', 'avatar');
http.post("{:url('user/profile/avatar')}", fd).then(function (res) {
layer.closeAll('loading');
if (res.code === 0 && res.data && res.data.src) {
layer.msg(res.msg || '头像上传成功', { icon: 1 });
refreshParentAvatar(res.data.src);
} else {
layer.msg(res.msg || '上传失败', { icon: 2 });
}
}).catch(function () {
layer.closeAll('loading');
layer.msg('网络错误,上传失败', { icon: 2 });
});
}, 'image/png');
});
// 刷新会员中心顶部头像与个人资料页预览
function refreshParentAvatar(src) {
try {
if (window !== top && parent.layui && parent.layui.ywxapp) {
var ts = '?t=' + Date.now();
parent.document.querySelectorAll('img.layui-nav-img').forEach(function (im) {
im.src = src + ts;
});
var prev = parent.document.getElementById('avatarPreview');
if (prev) { prev.src = src + ts; }
setTimeout(function () { parent.layui.ywxapp.closeThisTabs(); }, 700);
return;
}
} catch (e) { /* 跨域等情况忽略 */ }
setTimeout(function () { location.href = '/user/profile'; }, 700);
}
});
</script>
+137
View File
@@ -0,0 +1,137 @@
<div class="uc-wrap">
<div class="layui-card">
<div class="layui-card-header">个人资料</div>
<div class="layui-card-body" pad15>
<form class="layui-form" lay-filter="profileForm">
<div class="layui-form-item">
<label class="layui-form-label">头像</label>
<div class="layui-input-inline">
<img id="avatarPreview" src="{$profile.avatar|default=''}" class="layui-nav-img"
style="width:48px;height:48px;border-radius:50%;">
</div>
<div class="layui-form-mid layui-word-aux" style="padding-top:14px;">
<a href="{:url('user/Profile/avatar')}" class="layui-btn layui-btn-xs">修改头像</a>
</div>
</div>
<div class="layui-form-item" style="margin-bottom:0;">
<label class="layui-form-label">我的勋章</label>
<div class="layui-input-block">
{if $medals}
<div class="profile-medals">
{volist name="medals" id="m"}
<span class="profile-medal" title="{$m.title}{$m.create_at|date='Y-m-d'} 获得)">
{if $m.image}
<img src="{$m.image}" alt="{$m.title}">
{else/}
<i class="layui-icon layui-icon-trophy"></i>
{/if}
</span>
{/volist}
<a href="{:url('user/Medal/index')}" class="profile-medal-more">全部 </a>
</div>
{else/}
<div class="layui-form-mid layui-word-aux">暂无勋章,去 <a href="{:url('user/Task/index')}">任务中心</a> 领取吧</div>
{/if}
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">账号</label>
<div class="layui-input-inline">
<input type="text" value="{$profile.account|default=''}" class="layui-input" disabled>
</div>
<div class="layui-form-mid layui-word-aux">不可修改,用于登录</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">昵称</label>
<div class="layui-input-inline">
<input type="text" name="nickname" value="{$profile.nickname|default=''}" lay-verify="required"
placeholder="请输入昵称" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">手机号</label>
<div class="layui-input-inline">
<input type="text" name="mobile" value="{$profile.mobile|default=''}" lay-verify="phone"
placeholder="请输入手机号" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">邮箱</label>
<div class="layui-input-inline">
<input type="text" name="email" value="{$profile.email|default=''}" lay-verify="email"
placeholder="请输入邮箱" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">个人简介</label>
<div class="layui-input-block">
<textarea name="bio" placeholder="请输入个人简介" class="layui-textarea">{$profile.bio|default=''}</textarea>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="saveProfile">保存</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</form>
</div>
</div>
<div class="layui-card" style="margin-top:16px;">
<div class="layui-card-header">账号安全</div>
<div class="layui-card-body" pad15>
<div class="layui-form-item">
<label class="layui-form-label">登录密码</label>
<div class="layui-input-inline">
<input type="text" value="********" class="layui-input" disabled>
</div>
<div class="layui-form-mid layui-word-aux" style="padding-top:8px;">
<a href="{:url('user/Profile/password')}" class="layui-btn layui-btn-xs">修改密码</a>
</div>
</div>
</div>
</div>
</div>
<style>
.profile-medals { display:flex; flex-wrap:wrap; align-items:center; gap:10px; padding-top:4px; }
.profile-medal { display:inline-flex; align-items:center; justify-content:center; width:36px; height:36px;
border-radius:50%; background:linear-gradient(135deg,#fff7e6,#ffe7ba); overflow:hidden; cursor:default; }
.profile-medal img { width:36px; height:36px; object-fit:cover; }
.profile-medal .layui-icon { font-size:20px; color:#fa8c16; }
.profile-medal-more { font-size:12px; color:#999; padding-left:4px; }
.profile-medal-more:hover { color:#1e9fff; }
</style>
<script>
layui.use(['form', 'http', 'layer'], function () {
var form = layui.form, http = layui.http, layer = layui.layer, $ = layui.$;
form.on('submit(saveProfile)', function (obj) {
http.post('save', obj.field).then(function (res) {
if (res.code === 0) {
layer.msg('保存成功', { icon: 1 });
try {
if (window !== top && parent.layui && parent.layui.ywxapp) {
var nav = parent.document.querySelector('.layui-layout-admin .layui-nav-child, .user-nick');
if (nav) { nav.textContent = obj.field.nickname; }
}
} catch (e) {}
} else {
layer.msg(res.message || res.msg || '保存失败', { icon: 2 });
}
}).catch(function () {
layer.msg('请求失败', { icon: 2 });
});
return false;
});
});
</script>
+68
View File
@@ -0,0 +1,68 @@
<div class="uc-wrap">
<div class="layui-card">
<div class="layui-card-header">重置登录密码</div>
<div class="layui-card-body" pad15>
<div class="layui-form" lay-filter="passForm">
<div class="layui-form-item">
<label class="layui-form-label">当前密码</label>
<div class="layui-input-inline">
<input type="password" name="old_password" lay-verify="required" placeholder="请输入当前密码" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">新密码</label>
<div class="layui-input-inline">
<input type="password" name="password" id="LAY_password" lay-verify="pass" placeholder="6-12 位,不含空格" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">确认新密码</label>
<div class="layui-input-inline">
<input type="password" name="password_confirm" lay-verify="repass" placeholder="请输入确认密码" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block">
<button class="layui-btn" lay-submit lay-filter="setmypass">确认修改</button>
<button type="reset" class="layui-btn layui-btn-primary">重置</button>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
layui.use(['form', 'layer'], function () {
var form = layui.form, layer = layui.layer, $ = layui.$;
form.verify({
pass: [/^[\S]{6,12}$/, '密码必须 6 到 12 位,且不能出现空格'],
repass: function (value) {
if (value !== $('#LAY_password').val()) {
return '两次密码输入不一致';
}
}
});
form.on('submit(setmypass)', function (obj) {
$.post('/user/profile/passwordSave', obj.field, function (res) {
if (res.code === 1 || res.code === 0) {
layer.msg(res.msg || '修改成功', { icon: 1 });
setTimeout(function () {
if (window !== top && parent.layui && parent.layui.ywxapp) {
parent.layui.ywxapp.closeThisTabs();
} else {
location.href = '/user/index/index';
}
}, 800);
} else {
layer.msg(res.msg || '修改失败', { icon: 2 });
}
}, 'json').fail(function () {
layer.msg('请求失败', { icon: 2 });
});
return false;
});
});
</script>