diff --git a/find.py b/find.py new file mode 100644 index 0000000..487974e --- /dev/null +++ b/find.py @@ -0,0 +1,163 @@ +""" +REPL 模式文件内容搜索工具 +支持正则或纯文本搜索,默认搜索当前目录 +""" +import os +import re +import sys + +# 硬编码排除目录 +EXCLUDE_DIRS = { + '.git', '.vs', 'node_modules', '__pycache__', '.idea', + 'miniprogram_npm', '_backup_pre_redesign', +} + +# 排除的文件扩展名 +EXCLUDE_EXTS = { + '.png', '.jpg', '.jpeg', '.gif', '.svg', '.ico', '.bmp', + '.mp3', '.mp4', '.wav', '.avi', + '.zip', '.rar', '.7z', '.tar', '.gz', + '.exe', '.dll', '.so', '.dylib', + '.pyc', '.pyo', '.class', '.o', '.obj', + '.db', '.sqlite', '.vsidx', +} + +# 默认搜索根目录 +DEFAULT_ROOT = os.path.dirname(os.path.abspath(__file__)) + + +def should_skip(dirpath): + """判断目录是否应跳过""" + parts = dirpath.replace('\\', '/').split('/') + return any(p in EXCLUDE_DIRS for p in parts) + + +def search(pattern, root=DEFAULT_ROOT, use_regex=True, max_results=50): + """搜索文件内容""" + try: + if use_regex: + compiled = re.compile(pattern, re.IGNORECASE) + except re.error as e: + print(f' 正则语法错误: {e}') + return + + count = 0 + for dirpath, dirnames, filenames in os.walk(root): + # 就地修改 dirnames 以跳过排除目录 + dirnames[:] = [d for d in dirnames if d not in EXCLUDE_DIRS] + + for fname in filenames: + ext = os.path.splitext(fname)[1].lower() + if ext in EXCLUDE_EXTS: + continue + + fpath = os.path.join(dirpath, fname) + relpath = os.path.relpath(fpath, root) + try: + with open(fpath, 'r', encoding='utf-8', errors='ignore') as f: + for lineno, line in enumerate(f, 1): + line_stripped = line.rstrip('\n\r') + if use_regex: + match = compiled.search(line_stripped) + if match: + highlight = line_stripped[:match.start()] + \ + f'>>> {match.group()} <<<' + \ + line_stripped[match.end():] + print(f' {relpath}:{lineno} {highlight}') + count += 1 + else: + if pattern.lower() in line_stripped.lower(): + print(f' {relpath}:{lineno} {line_stripped}') + count += 1 + + if count >= max_results: + print(f'\n ... 已达上限 {max_results} 条,停止') + return + except (PermissionError, OSError): + continue + + if count == 0: + print(' 未找到匹配内容') + else: + print(f'\n 共 {count} 条匹配') + + +def main(): + print('=== 文件内容搜索工具 ===') + print(f'搜索根目录: {DEFAULT_ROOT}') + print(f'排除目录: {EXCLUDE_DIRS}') + print() + print('命令:') + print(' /regex 正则搜索') + print(' /text 纯文本搜索') + print(' /max 设置结果上限(默认50)') + print(' /dir 切换搜索目录') + print(' /help 显示帮助') + print(' /quit 退出') + print() + print('直接输入内容默认使用正则搜索') + print() + + root = DEFAULT_ROOT + use_regex = True + max_results = 50 + + while True: + try: + raw = input('find> ').strip() + except (EOFError, KeyboardInterrupt): + print('\n再见') + break + + if not raw: + continue + + if raw == '/quit': + print('再见') + break + + if raw == '/help': + print(' /regex 正则搜索') + print(' /text 纯文本搜索') + print(' /max 设置结果上限') + print(' /dir 切换搜索目录') + print(' /help 显示帮助') + print(' /quit 退出') + print(' 直接输入内容默认使用正则搜索') + continue + + if raw.startswith('/regex '): + pattern = raw[7:].strip() + if pattern: + search(pattern, root, use_regex=True, max_results=max_results) + continue + + if raw.startswith('/text '): + pattern = raw[6:].strip() + if pattern: + search(pattern, root, use_regex=False, max_results=max_results) + continue + + if raw.startswith('/max '): + try: + max_results = int(raw[5:].strip()) + print(f' 结果上限设为 {max_results}') + except ValueError: + print(' 请输入数字') + continue + + if raw.startswith('/dir '): + new_dir = raw[5:].strip() + if os.path.isdir(new_dir): + root = os.path.abspath(new_dir) + print(f' 搜索目录切换为: {root}') + else: + print(f' 目录不存在: {new_dir}') + continue + + # 默认正则搜索 + search(raw, root, use_regex=use_regex, max_results=max_results) + + +if __name__ == '__main__': + main() diff --git a/pages/xiugai/xiugai.wxml b/pages/xiugai/xiugai.wxml index 5ce8a48..d5156be 100644 --- a/pages/xiugai/xiugai.wxml +++ b/pages/xiugai/xiugai.wxml @@ -3,18 +3,21 @@ - + + + - 点击更换头像 - + 点击更换头像 + + diff --git a/pages/xiugai/xiugai.wxss b/pages/xiugai/xiugai.wxss index 469cc97..4e176e4 100644 --- a/pages/xiugai/xiugai.wxss +++ b/pages/xiugai/xiugai.wxss @@ -1,477 +1,401 @@ /* pages/xiugai/xiugai.wxss */ -/* ====== 您的原始样式代码(完全未改动) ====== */ page { - background: linear-gradient(135deg, #fffaf0 0%, #f0f8ff 100%); - min-height: 100vh; - } - - .xiugai-page { - padding: 30rpx 40rpx 100rpx; - } - - /* ============ 头像区域样式 ============ */ - .avatar-section { - display: flex; - justify-content: center; - margin-bottom: 60rpx; - padding-top: 30rpx; - } - - .avatar-container { - position: relative; - display: flex; - flex-direction: column; - align-items: center; - } - - /* 头像图片 - 添加呼吸动画 */ - .avatar-image { - width: 200rpx; - height: 200rpx; - border-radius: 50%; - border: 6rpx solid #fff; - background-color: #f8f9fa; - z-index: 2; - position: relative; - /* 呼吸动画:温和的放大缩小 */ - animation: gentleBreath 3s ease-in-out infinite; - /* 基础阴影 */ - box-shadow: + background: linear-gradient(135deg, #fffaf0 0%, #f0f8ff 100%); + min-height: 100vh; +} + +.xiugai-page { + padding: 30rpx 40rpx 100rpx; +} + +/* ============ 头像区域样式 ============ */ +.avatar-section { + position: relative; + display: flex; + justify-content: center; + margin-bottom: 60rpx; + padding-top: 30rpx; +} + +.avatar-container { + position: relative; + display: flex; + flex-direction: column; + align-items: center; +} + +/* 头像包装器:精确居中,包含头像+光晕 */ +.avatar-image-wrapper { + position: relative; + width: 200rpx; + height: 200rpx; + flex-shrink: 0; + display: flex; + align-items: center; + justify-content: center; +} + +/* 头像图片 */ +.avatar-image { + width: 200rpx; + height: 200rpx; + border-radius: 50%; + border: 6rpx solid #fff; + background-color: #f8f9fa; + z-index: 2; + position: relative; + animation: gentleBreath 4s ease-in-out infinite; + box-shadow: 0 0 0 1rpx rgba(0, 200, 83, 0.3), 0 15rpx 40rpx rgba(0, 200, 83, 0.15); - } - - /* 温和的呼吸动画 */ - @keyframes gentleBreath { - 0%, 100% { - transform: scale(1); - box-shadow: - 0 0 0 2rpx rgba(0, 200, 83, 0.4), - 0 15rpx 40rpx rgba(0, 200, 83, 0.2); - } - 50% { - transform: scale(1.03); - box-shadow: - 0 0 0 5rpx rgba(0, 200, 83, 0.6), - 0 20rpx 50rpx rgba(0, 200, 83, 0.3); - } - } - - /* 边缘微光效果 - 更细腻 */ - .avatar-halo { - position: absolute; - top: -8rpx; - left: -8rpx; - right: -8rpx; - bottom: -8rpx; - border-radius: 50%; - background: transparent; - border: 2rpx solid #00C853; - animation: gentleGlow 2s ease-in-out infinite; - opacity: 0; - z-index: 1; - pointer-events: none; - } - - /* 温和的光晕动画 */ - @keyframes gentleGlow { - 0%, 100% { - opacity: 0; - transform: scale(0.98); - border-color: rgba(0, 200, 83, 0.3); - } - 50% { - opacity: 1; - transform: scale(1.05); - border-color: rgba(0, 200, 83, 0.8); - } - } - - /* 像素点环绕效果 */ - .avatar-container::before { - content: ''; - position: absolute; - top: -15rpx; - left: -15rpx; - right: -15rpx; - bottom: -15rpx; - border-radius: 50%; - background: + box-sizing: border-box; /* 关键:边框向内计算,不占宽度 */ +} + +/* ✅ 光晕精确居中:已计算头像 6rpx 边框的偏移量 */ +.avatar-halo { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); /* 强制居中,无视任何偏差 */ + width: 228rpx; /* 精确计算:200 + 6*2(边框) + 8*2(外延) = 228 */ + height: 228rpx; + border-radius: 50%; + background: transparent; + border: 3rpx solid transparent; + animation: gentleGlow 2s ease-in-out infinite, colorShift 3s ease-in-out infinite; + opacity: 0; + z-index: 1; + pointer-events: none; +} + +/* ✅ 像素点环绕也强制居中 */ +.avatar-image-wrapper::before { + content: ''; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 230rpx; + height: 230rpx; + border-radius: 50%; + background: radial-gradient(circle at 30% 30%, rgba(0, 200, 83, 0.1) 0%, transparent 50%), radial-gradient(circle at 70% 70%, rgba(100, 221, 23, 0.1) 0%, transparent 50%); - animation: pixelOrbit 4s linear infinite; - z-index: 0; - pointer-events: none; - } - - @keyframes pixelOrbit { - 0% { - transform: rotate(0deg); - } - 100% { - transform: rotate(360deg); - } - } - - /* 更换提示 */ - .avatar-hint { - margin-top: 25rpx; - font-size: 28rpx; - color: #666; - padding: 12rpx 30rpx; - background: rgba(255, 255, 255, 0.9); - border-radius: 25rpx; - border: 1rpx solid #eee; - box-shadow: 0 5rpx 15rpx rgba(0, 0, 0, 0.05); - position: relative; - overflow: hidden; - } - - /* 提示文字底部的微光 */ - .avatar-hint::before { - content: ''; - position: absolute; - bottom: 0; - left: 0; - right: 0; - height: 2rpx; - background: linear-gradient(90deg, transparent, #00C853, transparent); - animation: hintGlow 2s ease-in-out infinite; - } - - @keyframes hintGlow { - 0%, 100% { - opacity: 0.3; - } - 50% { - opacity: 1; - } - } - - /* 点击特效 - 缩放效果 */ - .avatar-container.active .avatar-image { - animation: clickScale 0.5s ease; - } - - @keyframes clickScale { - 0%, 100% { - transform: scale(1); - } - 50% { - transform: scale(0.95); - } - } - - /* 下载状态 */ - .avatar-container.downloading .avatar-image { - opacity: 0.7; - filter: grayscale(30%); - } - - /* 增强光晕效果 */ - .avatar-halo { - position: absolute; - top: -8rpx; - left: -8rpx; - right: -8rpx; - bottom: -8rpx; - border-radius: 50%; - background: transparent; - border: 3rpx solid transparent; - animation: gentleGlow 2s ease-in-out infinite, colorShift 3s ease-in-out infinite; - opacity: 0; - z-index: 1; - pointer-events: none; - } - - @keyframes gentleGlow { - 0%, 100% { - opacity: 0; - transform: scale(0.98); - } - 50% { - opacity: 1; - transform: scale(1.05); - } - } - - @keyframes colorShift { - 0% { - border-color: rgba(0, 200, 83, 0.5); - } - 33% { - border-color: rgba(100, 221, 23, 0.5); - } - 66% { - border-color: rgba(0, 255, 153, 0.5); - } - 100% { - border-color: rgba(0, 200, 83, 0.5); - } - } - - /* 头像呼吸效果 */ - .avatar-image { - width: 200rpx; - height: 200rpx; - border-radius: 50%; - border: 6rpx solid #fff; - background-color: #f8f9fa; - z-index: 2; - position: relative; - animation: gentleBreath 4s ease-in-out infinite; - box-shadow: - 0 0 0 1rpx rgba(0, 200, 83, 0.3), - 0 15rpx 40rpx rgba(0, 200, 83, 0.15); - } - - @keyframes gentleBreath { - 0%, 100% { + animation: pixelOrbit 4s linear infinite; + z-index: 0; + pointer-events: none; +} + +/* 温和的呼吸动画 */ +@keyframes gentleBreath { + 0%, 100% { transform: scale(1); box-shadow: - 0 0 0 2rpx rgba(0, 200, 83, 0.4), - 0 15rpx 40rpx rgba(0, 200, 83, 0.2); - } - 50% { + 0 0 0 2rpx rgba(0, 200, 83, 0.4), + 0 15rpx 40rpx rgba(0, 200, 83, 0.2); + } + 50% { transform: scale(1.03); box-shadow: - 0 0 0 5rpx rgba(0, 200, 83, 0.6), - 0 20rpx 50rpx rgba(0, 200, 83, 0.3); - } + 0 0 0 5rpx rgba(0, 200, 83, 0.6), + 0 20rpx 50rpx rgba(0, 200, 83, 0.3); } - - /* 表单区域 */ - .form-section { - background: white; - border-radius: 25rpx; - overflow: hidden; - margin-bottom: 50rpx; - box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.08); - border: 1rpx solid #f0f0f0; +} + +/* 光晕动画 */ +@keyframes gentleGlow { + 0%, 100% { + opacity: 0; + transform: translate(-50%, -50%) scale(0.98); } - - .form-item { - display: flex; - align-items: center; - padding: 40rpx; - border-bottom: 1rpx solid #f0f0f0; - min-height: 110rpx; + 50% { + opacity: 1; + transform: translate(-50%, -50%) scale(1.05); } - - .form-item:last-child { - border-bottom: none; +} + +@keyframes colorShift { + 0% { + border-color: rgba(0, 200, 83, 0.5); } - - .item-label { - width: 150rpx; - font-size: 32rpx; - color: #333; - font-weight: 500; - flex-shrink: 0; + 33% { + border-color: rgba(100, 221, 23, 0.5); } - - .item-value.readonly { - flex: 1; - font-size: 32rpx; - color: #666; + 66% { + border-color: rgba(0, 255, 153, 0.5); } - - .item-input { - flex: 1; - font-size: 32rpx; - color: #333; - height: 50rpx; - line-height: 50rpx; + 100% { + border-color: rgba(0, 200, 83, 0.5); } - - .placeholder { - color: #ccc; - font-size: 30rpx; +} + +@keyframes pixelOrbit { + 0% { + transform: translate(-50%, -50%) rotate(0deg); } - - /* 输入框容器 */ - .input-container { - flex: 1; - display: flex; - flex-direction: column; + 100% { + transform: translate(-50%, -50%) rotate(360deg); } - - /* 输入框错误样式 */ - .item-input.error { - border-bottom: 2rpx solid #ff4d4f; - animation: shake 0.5s; +} + +/* 更换提示 */ +.avatar-hint { + margin-top: 25rpx; + font-size: 28rpx; + color: #666; + padding: 12rpx 30rpx; + background: rgba(255, 255, 255, 0.9); + border-radius: 25rpx; + border: 1rpx solid #eee; + box-shadow: 0 5rpx 15rpx rgba(0, 0, 0, 0.05); + position: relative; + overflow: hidden; +} + +.avatar-hint::before { + content: ''; + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 2rpx; + background: linear-gradient(90deg, transparent, #00C853, transparent); + animation: hintGlow 2s ease-in-out infinite; +} + +@keyframes hintGlow { + 0%, 100% { + opacity: 0.3; } - - @keyframes shake { - 0%, 100% { transform: translateX(0); } - 10%, 30%, 50%, 70%, 90% { transform: translateX(-2rpx); } - 20%, 40%, 60%, 80% { transform: translateX(2rpx); } + 50% { + opacity: 1; } - - /* 错误提示 */ - .error-hint { - font-size: 24rpx; - color: #ff4d4f; - margin-top: 8rpx; - padding-left: 10rpx; - animation: fadeIn 0.3s; +} + +/* 点击特效 */ +.avatar-container.active .avatar-image { + animation: clickScale 0.5s ease; +} + +@keyframes clickScale { + 0%, 100% { + transform: scale(1); } - - /* 手机号正确提示 */ - .phone-hint { - font-size: 24rpx; - color: #00C853; - margin-top: 8rpx; - padding-left: 10rpx; - animation: fadeIn 0.3s; + 50% { + transform: scale(0.95); } - - @keyframes fadeIn { - from { opacity: 0; transform: translateY(-10rpx); } - to { opacity: 1; transform: translateY(0); } - } - - /* 保存按钮 */ - .save-btn { - width: 100%; - height: 100rpx; - line-height: 100rpx; - border-radius: 50rpx; - background: linear-gradient(135deg, #00C853 0%, #64DD17 100%); - color: white; - font-size: 34rpx; - font-weight: 500; - border: none; - position: relative; - overflow: hidden; - box-shadow: 0 15rpx 40rpx rgba(0, 200, 83, 0.25); - margin-top: 30rpx; - } - - .save-btn[disabled] { - background: linear-gradient(135deg, #cccccc 0%, #aaaaaa 100%); - color: #999; - box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.1); - } - - .btn-content { - position: relative; - z-index: 2; - display: flex; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; - } - - .btn-sparkle { - position: absolute; - top: 0; - left: -100%; - width: 100%; - height: 100%; - background: linear-gradient( +} + +/* 下载状态 */ +.avatar-container.downloading .avatar-image { + opacity: 0.7; + filter: grayscale(30%); +} + +/* 透明功能按钮 */ +.avatar-trigger-button { + position: absolute; + top: 30rpx; + left: 50%; + transform: translateX(-50%); + width: 200rpx; + height: 200rpx; + border-radius: 50%; + z-index: 100; + background: transparent; + border: none; + padding: 0; + margin: 0; + opacity: 0; + line-height: 1; + font-size: 0; +} + +.avatar-trigger-button::after { + border: none; +} + +/* ============ 表单区域 ============ */ +.form-section { + background: white; + border-radius: 25rpx; + overflow: hidden; + margin-bottom: 50rpx; + box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.08); + border: 1rpx solid #f0f0f0; +} + +.form-item { + display: flex; + align-items: center; + padding-left: 40rpx; + border-bottom: 1rpx solid #f0f0f0; + min-height: 110rpx; +} + +.form-item:last-child { + border-bottom: none; +} + +.item-label { + width: 150rpx; + font-size: 32rpx; + color: #333; + font-weight: 500; + flex-shrink: 0; +} + +.item-value.readonly { + flex: 1; + font-size: 32rpx; + color: #666; +} + +.item-input { + flex: 1; + font-size: 32rpx; + color: #333; + height: 50rpx; + line-height: 50rpx; +} + +.placeholder { + color: #ccc; + font-size: 30rpx; +} + +.input-container { + flex: 1; + display: flex; + flex-direction: column; +} + +.item-input.error { + border-bottom: 2rpx solid #ff4d4f; + animation: shake 0.5s; +} + +@keyframes shake { + 0%, 100% { transform: translateX(0); } + 10%, 30%, 50%, 70%, 90% { transform: translateX(-2rpx); } + 20%, 40%, 60%, 80% { transform: translateX(2rpx); } +} + +.error-hint { + font-size: 24rpx; + color: #ff4d4f; + margin-top: 8rpx; + padding-left: 10rpx; + animation: fadeIn 0.3s; +} + +.phone-hint { + font-size: 24rpx; + color: #00C853; + margin-top: 8rpx; + padding-left: 10rpx; + animation: fadeIn 0.3s; +} + +@keyframes fadeIn { + from { opacity: 0; transform: translateY(-10rpx); } + to { opacity: 1; transform: translateY(0); } +} + +/* ============ 保存按钮 ============ */ +.save-btn { + width: 100%; + height: 100rpx; + line-height: 100rpx; + border-radius: 50rpx; + background: linear-gradient(135deg, #00C853 0%, #64DD17 100%); + color: white; + font-size: 34rpx; + font-weight: 500; + border: none; + position: relative; + overflow: hidden; + box-shadow: 0 15rpx 40rpx rgba(0, 200, 83, 0.25); + margin-top: 30rpx; +} + +.save-btn[disabled] { + background: linear-gradient(135deg, #cccccc 0%, #aaaaaa 100%); + color: #999; + box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.1); +} + +.btn-content { + position: relative; + z-index: 2; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; +} + +.btn-sparkle { + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient( 90deg, transparent 0%, rgba(255, 255, 255, 0.2) 50%, transparent 100% - ); - animation: sparkleMove 2.5s ease-in-out infinite; - z-index: 1; - } - - @keyframes sparkleMove { - 0% { left: -100%; } - 100% { left: 100%; } - } - - .btn-hover { - opacity: 0.9; - transform: scale(0.98); - } - - /* 底部安全区域 */ - .safe-area { - height: 100rpx; - width: 100%; - } - - /* 🔥🔥🔥【修改开始:新增透明按钮样式】 */ - /* 说明:此样式仅作用于新增的 .avatar-trigger-button,使其透明并覆盖在头像区域 */ - /* 此修改不会影响上方任何原有样式,仅新增样式规则 */ - - /* 确保头像区域为相对定位,作为透明按钮的定位参考 */ - .avatar-section { - position: relative; - display: flex; - justify-content: center; - margin-bottom: 60rpx; - padding-top: 30rpx; - } - - /* 透明功能按钮样式 */ - .avatar-trigger-button { - /* 覆盖在原始头像容器上 */ - position: absolute; - top: 0; - left: 50%; - transform: translateX(-50%); - width: 200rpx; - height: 200rpx; - border-radius: 50%; - z-index: 100; - /* 关键:完全透明不可见 */ - background: transparent; - border: none; - padding: 0; - margin: 0; - opacity: 0; - - /* 清除所有默认样式 */ - line-height: 1; - font-size: 0; - } - - /* 移除按钮默认边框 */ - .avatar-trigger-button::after { - border: none; - } - /* 🔥🔥🔥【修改结束】 */ + ); + animation: sparkleMove 2.5s ease-in-out infinite; + z-index: 1; +} - /* ====== 以下为新增样式(手机号获取按钮) ====== */ +@keyframes sparkleMove { + 0% { left: -100%; } + 100% { left: 100%; } +} -/* 手机号行布局 */ +.btn-hover { + opacity: 0.9; + transform: scale(0.98); +} + +/* ============ 手机号获取按钮 ============ */ .phone-row { - flex: 1; - display: flex; - align-items: center; - justify-content: space-between; - } - - /* 手机号文本 */ - .phone-value { - font-size: 32rpx; - color: #333; - flex: 1; - } - - /* 获取手机号按钮 */ - .get-phone-btn { - flex-shrink: 0; - margin-left: 20rpx; - padding: 10rpx 24rpx; - background: #4a6cf7; - color: #fff; - font-size: 26rpx; - border-radius: 40rpx; - border: none; - line-height: 1.4; - height: 60rpx; - display: flex; - align-items: center; - justify-content: center; - } - - .phone-btn-hover { - opacity: 0.8; - } \ No newline at end of file + flex: 1; + display: flex; + align-items: center; + justify-content: space-between; +} + +.phone-value { + font-size: 32rpx; + color: #333; + flex: 1; +} + +.get-phone-btn { + flex-shrink: 0; + margin-left: 20rpx; + padding: 10rpx 24rpx; + background: #4a6cf7; + color: #fff; + font-size: 26rpx; + border-radius: 40rpx; + border: none; + line-height: 1.4; + height: 60rpx; + display: flex; + align-items: center; + justify-content: center; +} + +.phone-btn-hover { + opacity: 0.8; +} + +.safe-area { + height: 100rpx; + width: 100%; +} \ No newline at end of file