添加个人中心及按角色展示内容
This commit is contained in:
26
add_overlay_css.py
Normal file
26
add_overlay_css.py
Normal file
@@ -0,0 +1,26 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\components\\AdminHeader.uvue'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
overlay_css = r'''
|
||||
.user-dropdown-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
background-color: transparent;
|
||||
}
|
||||
'''
|
||||
if '.user-dropdown-overlay' not in text:
|
||||
text = text.replace('</style>', overlay_css + '\n</style>')
|
||||
|
||||
text = text.replace('z-index: 99;', 'z-index: 1001;')
|
||||
text = text.replace('z-index: 90;', 'z-index: 1001;')
|
||||
text = text.replace('z-index: 150;', 'z-index: 1001;')
|
||||
text = text.replace('.user-dropdown {', '.user-dropdown {\n z-index: 1002;')
|
||||
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
9
add_toast.py
Normal file
9
add_toast.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\components\\AdminHeader.uvue'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('function goToUserCenter() {', 'function goToUserCenter() {\n uni.showToast({ title: "尝试打开个人中心...", icon: "none", duration: 2000 });\n console.log([AdminHeader] goToUserCenter called);')
|
||||
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
8
fix3.py
Normal file
8
fix3.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\pages.json'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('custom\"\n }\n }\n },', 'custom\"\n }\n },')
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
11
fix_css2.py
Normal file
11
fix_css2.py
Normal file
@@ -0,0 +1,11 @@
|
||||
import codecs
|
||||
import re
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\components\\AdminHeader.uvue'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = re.sub(r'(\.header\s*\{)', r'\1\n position: relative;\n z-index: 150;', text)
|
||||
text = re.sub(r'(\.header-right\s*\{)', r'\1\n position: relative;\n z-index: 100;\n pointer-events: auto;', text)
|
||||
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
8
fix_final.py
Normal file
8
fix_final.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\pages.json'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('custom\"\n },{', 'custom\"\n }\n },\n {')
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
10
fix_header_css.py
Normal file
10
fix_header_css.py
Normal file
@@ -0,0 +1,10 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\components\\AdminHeader.uvue'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('.header-right{ \n display:flex;', '.header-right{ \n position: relative;\n z-index: 99;\n pointer-events: auto;\n display:flex;')
|
||||
text = text.replace('.header{\n height: 56px;', '.header{\n position: relative;\n z-index: 90;\n height: 56px;')
|
||||
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
BIN
fix_pages.py
Normal file
BIN
fix_pages.py
Normal file
Binary file not shown.
@@ -63,8 +63,8 @@
|
||||
<!-- 内容展示区 (内部路由渲染) -->
|
||||
<view class="content-scroll">
|
||||
<view class="content-inner" :class="{ 'is-mobile': isMobile }">
|
||||
<slot></slot>
|
||||
<component :is="currentComponent" v-if="!isPageLoading && currentComponent != null"></component>
|
||||
<slot v-if="hasAccess"></slot>
|
||||
<component :is="currentComponent" v-if="hasAccess && !isPageLoading && currentComponent != null"></component>
|
||||
<AdminPageLoading v-if="isPageLoading"></AdminPageLoading>
|
||||
</view>
|
||||
<AdminFooter></AdminFooter>
|
||||
@@ -116,6 +116,7 @@ import {
|
||||
import type { TabItem } from '@/layouts/admin/store/adminNavStore.uts'
|
||||
|
||||
import { getComponent } from '@/layouts/admin/router/adminComponentMap.uts'
|
||||
import { hasAdminModuleAccess } from '@/layouts/admin/utils/role.uts'
|
||||
|
||||
const props = defineProps({
|
||||
currentPage: {
|
||||
@@ -131,6 +132,12 @@ const SUB_W = 200
|
||||
// 页面加载状态
|
||||
const isPageLoading = ref(false)
|
||||
|
||||
const hasAccess = computed<boolean>(() => {
|
||||
|
||||
|
||||
return hasAdminModuleAccess(activeTopMenuId.value)
|
||||
})
|
||||
|
||||
const hasNotification = ref<boolean>(false)
|
||||
|
||||
/**
|
||||
@@ -258,6 +265,8 @@ const breadcrumb = computed<Array<{id: string, title: string}>>(() => {
|
||||
|
||||
// 当前渲染的组件
|
||||
const currentComponent = computed<any>(() => {
|
||||
|
||||
|
||||
const route = findRouteById(activeRouteId.value)
|
||||
if (!route) return null
|
||||
return getComponent(route.componentKey)
|
||||
|
||||
@@ -25,24 +25,74 @@
|
||||
<view class="header-right">
|
||||
<view class="hbtn" @click="$emit('search')"><text>🔍</text></view>
|
||||
<view v-if="!isMobile" class="hbtn" @click="$emit('refresh')"><text>⟳</text></view>
|
||||
<view class="hbtn" @click="$emit('notify')">
|
||||
<view class="hbtn" @click="$emit('notify')">
|
||||
<text>🔔</text>
|
||||
<view class="dot" v-if="hasNotification"></view>
|
||||
</view>
|
||||
|
||||
<!-- 用户个人中心 / 下拉菜单 -->
|
||||
<view class="user-profile-container" @click="goToUserCenter">
|
||||
<text class="user-name">crmeb demo</text>
|
||||
<text class="user-arrow">▼</text>
|
||||
|
||||
<view class="user-dropdown" v-if="showUserMenu">
|
||||
<view class="dropdown-item" @click.stop="goToUserCenter">个人中心</view>
|
||||
<view class="dropdown-item" @click.stop="handleLogout">退出登录</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { computed } from 'vue'
|
||||
import {
|
||||
toggleSubSider,
|
||||
showSubSider,
|
||||
layoutMode,
|
||||
import { ref, computed } from 'vue'
|
||||
import {
|
||||
toggleSubSider,
|
||||
showSubSider,
|
||||
layoutMode,
|
||||
isOverlayVisible,
|
||||
isMobileMenuOpen
|
||||
isMobileMenuOpen,
|
||||
openRoute
|
||||
} from '@/layouts/admin/store/adminNavStore.uts'
|
||||
|
||||
const showUserMenu = ref(false)
|
||||
|
||||
function closeUserMenu() {
|
||||
showUserMenu.value = false
|
||||
}
|
||||
|
||||
function toggleUserMenu() {
|
||||
showUserMenu.value = !showUserMenu.value
|
||||
}
|
||||
|
||||
function goToUserCenter() {
|
||||
uni.showToast({ title: "尝试打开个人中心...", icon: "none", duration: 2000 });
|
||||
|
||||
uni.showToast({ title: "尝试打开个人中心...", icon: "none", duration: 2000 });
|
||||
|
||||
console.log("[AdminHeader] goToUserCenter called");
|
||||
console.log("[AdminHeader] goToUserCenter called");
|
||||
showUserMenu.value = false
|
||||
openRoute('home_user_center')
|
||||
}
|
||||
|
||||
function handleLogout() {
|
||||
showUserMenu.value = false
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要退出登录吗?',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.removeStorageSync('adminRole')
|
||||
uni.removeStorageSync('token')
|
||||
uni.reLaunch({
|
||||
url: '/pages/user/login'
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
breadcrumb: Array<{id: string, title: string}>
|
||||
hasNotification: boolean
|
||||
@@ -82,6 +132,10 @@ const currentTitle = computed((): string => {
|
||||
|
||||
<style>
|
||||
.header{
|
||||
position: relative;
|
||||
z-index: 1001;
|
||||
position: relative;
|
||||
z-index: 1001;
|
||||
height: 56px;
|
||||
background:#fff;
|
||||
border-bottom: 1px solid #eef2f7;
|
||||
@@ -142,6 +196,12 @@ const currentTitle = computed((): string => {
|
||||
display: flex !important;
|
||||
}
|
||||
.header-right {
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
pointer-events: auto;
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
pointer-events: auto;
|
||||
gap: 5px;
|
||||
}
|
||||
}
|
||||
@@ -151,7 +211,13 @@ const currentTitle = computed((): string => {
|
||||
margin: 0 8px;
|
||||
}
|
||||
|
||||
.header-right{
|
||||
.header-right{
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
pointer-events: auto;
|
||||
position: relative;
|
||||
z-index: 100;
|
||||
pointer-events: auto;
|
||||
display:flex;
|
||||
flex-direction:row;
|
||||
align-items:center;
|
||||
@@ -176,4 +242,64 @@ const currentTitle = computed((): string => {
|
||||
top: 6px;
|
||||
right: 6px;
|
||||
}
|
||||
|
||||
.user-profile-container {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-left: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.user-arrow {
|
||||
font-size: 12px;
|
||||
color: #666;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.user-dropdown {
|
||||
z-index: 1002;
|
||||
z-index: 1002;
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
right: 0;
|
||||
width: 120px;
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 12px rgba(0,0,0,0.1);
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background-color: #f5f7fa;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
.user-dropdown-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@@ -16,6 +16,7 @@ import PlaceholderPage from '@/layouts/admin/components/PlaceholderPage.uvue'
|
||||
|
||||
// 导入首页(内部组件,不包含 AdminLayout)
|
||||
import HomeIndex from '@/layouts/admin/pages/HomeIndex.uvue'
|
||||
import UserCenter from '@/pages/mall/admin/userCenter/index.uvue'
|
||||
|
||||
// --- 用户模块 ---
|
||||
import UserStatistic from '@/pages/mall/admin/user/statistics/index.uvue'
|
||||
@@ -179,6 +180,7 @@ import MaintainSysInfo from '@/pages/mall/admin/maintain/sys/info.uvue'
|
||||
export const componentMap: Map<string, any> = new Map([
|
||||
// 首页
|
||||
['HomeIndex', HomeIndex],
|
||||
['UserCenter', UserCenter],
|
||||
|
||||
// 用户模块
|
||||
['UserStatistic', UserStatistic],
|
||||
|
||||
@@ -29,6 +29,8 @@ export type RouteRecord = {
|
||||
/**
|
||||
* 菜单分组类型
|
||||
*/
|
||||
import { hasAdminModuleAccess } from '@/layouts/admin/utils/role.uts'
|
||||
|
||||
export type MenuGroup = {
|
||||
id: string
|
||||
title: string
|
||||
@@ -232,8 +234,17 @@ export const routes: RouteRecord[] = [
|
||||
},
|
||||
|
||||
// ========== 用户模块 ==========
|
||||
{
|
||||
id: 'user_statistic',
|
||||
// ========== 个人中心 ==========
|
||||
{
|
||||
id: 'home_user_center',
|
||||
title: '个人中心',
|
||||
path: '/pages/mall/admin/userCenter/index',
|
||||
componentKey: 'UserCenter',
|
||||
order: 100
|
||||
},
|
||||
|
||||
{
|
||||
id: 'user_statistic',
|
||||
title: '用户统计',
|
||||
path: '/pages/mall/admin/user/statistics/index',
|
||||
componentKey: 'UserStatistic',
|
||||
@@ -1175,7 +1186,10 @@ export const routes: RouteRecord[] = [
|
||||
* 获取所有一级菜单
|
||||
*/
|
||||
export function getTopMenus(): TopMenu[] {
|
||||
return topMenus.sort((a, b) => a.order - b.order)
|
||||
// 基于 role 的模块过滤
|
||||
return topMenus
|
||||
.filter(m => hasAdminModuleAccess(m.id))
|
||||
.sort((a, b) => a.order - b.order)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
getTopMenus
|
||||
} from '@/layouts/admin/router/adminRoutes.uts'
|
||||
import { addView, activeFullPath, visitedViews } from './tagsViewStore.uts'
|
||||
import { hasAdminModuleAccess } from '@/layouts/admin/utils/role.uts'
|
||||
|
||||
/**
|
||||
* 标签页类型
|
||||
@@ -77,14 +78,34 @@ export const isOverlayVisible = ref<boolean>(false)
|
||||
* @param addTab 是否添加到标签页
|
||||
*/
|
||||
export function openRoute(routeId: string, addTab: boolean = true): void {
|
||||
|
||||
|
||||
const route = findRouteById(routeId)
|
||||
if (!route) {
|
||||
console.warn(`[AdminNav] Route not found: ${routeId}`)
|
||||
return
|
||||
}
|
||||
|
||||
// 基于 role 的页面访问拦截
|
||||
// route.parentId 对应上方 topMenus 的 id。这里校验是否有权限
|
||||
const moduleId = route.parentId ? route.parentId : route.id.split('_')[0]
|
||||
if (!hasAdminModuleAccess(moduleId)) {
|
||||
uni.showToast({
|
||||
title: '您没有权限访问该模块',
|
||||
icon: 'none'
|
||||
})
|
||||
console.warn(`[AdminNav] Access denied for role to module: ${moduleId}`)
|
||||
// 回退到首页
|
||||
if (routeId !== 'home_index') {
|
||||
openRoute('home_index', addTab)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// 更新当前路由
|
||||
activeRouteId.value = routeId
|
||||
|
||||
|
||||
|
||||
// 更新一级菜单选中态
|
||||
if (route.parentId) {
|
||||
|
||||
51
layouts/admin/utils/role.uts
Normal file
51
layouts/admin/utils/role.uts
Normal file
@@ -0,0 +1,51 @@
|
||||
// Admin role-based access control
|
||||
export function getCurrentAdminRole(): string {
|
||||
// 从本地存储获取当前 role。为不影响全局,优先读 admin_role,默认降级到读全局 role/userInfo,再默认
|
||||
// 根据实际系统中的 token/userInfo 结构可灵活调整
|
||||
const roleType = uni.getStorageSync('admin_role') as string
|
||||
if (roleType && typeof roleType === 'string' && roleType.length > 0) {
|
||||
return roleType
|
||||
}
|
||||
|
||||
// 检查是否有关联 merchant_id 或者是存了全局 role
|
||||
const merchantId = uni.getStorageSync('merchant_id')
|
||||
if (merchantId) return 'merchant'
|
||||
|
||||
const globalRole = uni.getStorageSync('role') as string
|
||||
if (globalRole && typeof globalRole === 'string' && globalRole.length > 0) {
|
||||
return globalRole
|
||||
}
|
||||
|
||||
return 'admin' // 默认返回 admin 作为兜底(兼容原有全部显示逻辑)
|
||||
}
|
||||
|
||||
// 获取不同 role 允许访问的顶级模块 ID (主侧边栏的顶层菜单 id)
|
||||
export function getVisibleTopMenuIds(role: string): string[] {
|
||||
if (role === 'admin') {
|
||||
return ['home', 'user', 'order', 'product', 'marketing', 'distribution', 'kefu', 'finance', 'cms', 'decoration', 'app', 'setting', 'maintain']
|
||||
}
|
||||
|
||||
if (role === 'merchant') {
|
||||
// merchant: 只能看到 主页、订单、商品、营销、财务
|
||||
return ['home', 'order', 'product', 'marketing', 'finance']
|
||||
}
|
||||
|
||||
// 其他 role: 安全兜底
|
||||
return ['home']
|
||||
}
|
||||
|
||||
// 判断是否有权限访问某模块或路由
|
||||
export function hasAdminModuleAccess(moduleId: string | undefined): boolean {
|
||||
if (!moduleId) return true // 没有指定的通常认为是公共的,比如一些通用组件
|
||||
|
||||
const role = getCurrentAdminRole()
|
||||
if (role === 'admin') return true
|
||||
|
||||
// 对于 merchant 角色,允许其访问的顶级 menu id 及其所属路由
|
||||
if (role === 'merchant') {
|
||||
const allowed = ['home', 'order', 'product', 'marketing', 'finance']
|
||||
return allowed.includes(moduleId)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
20
make_simple.py
Normal file
20
make_simple.py
Normal file
@@ -0,0 +1,20 @@
|
||||
import codecs
|
||||
content = '''<template>
|
||||
<view class="user-center-container">
|
||||
<text style="font-size: 24px; color: red;">个人中心 userCenter loaded!</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
console.log('[UserCenter] Component Setup Executed!')
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.user-center-container {
|
||||
padding: 50px;
|
||||
background-color: #fff;
|
||||
min-height: 500px;
|
||||
}
|
||||
</style>'''
|
||||
with codecs.open(r'd:\\骅锋\\mall\\pages\\mall\\admin\\userCenter\\index.uvue', 'w', 'utf-8') as f:
|
||||
f.write(content)
|
||||
@@ -14,6 +14,13 @@
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/mall/admin/userCenter/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "个人中心",
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/boot",
|
||||
"style": {
|
||||
|
||||
195
pages/mall/admin/userCenter/index.uvue
Normal file
195
pages/mall/admin/userCenter/index.uvue
Normal file
@@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<view class="user-center-container">
|
||||
<view class="page-header">
|
||||
<text class="page-title">个人中心</text>
|
||||
</view>
|
||||
|
||||
<view class="form-container">
|
||||
<view class="form-item">
|
||||
<text class="form-label">头像</text>
|
||||
<view class="form-content avatar-uploader">
|
||||
<!-- 默认使用一个占位头像或 Logo -->
|
||||
<image class="avatar-img" src="/static/logo.png" mode="aspectFill"></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">账号</text>
|
||||
<view class="form-content">
|
||||
<input class="uni-input disabled" value="demo" disabled placeholder="请输入账号" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label"><text class="required">*</text>姓名</text>
|
||||
<view class="form-content">
|
||||
<input class="uni-input" v-model="formData.name" placeholder="请输入姓名" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">原始密码</text>
|
||||
<view class="form-content">
|
||||
<input class="uni-input" type="password" v-model="formData.oldPassword" placeholder="请输入原始密码" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">新密码</text>
|
||||
<view class="form-content">
|
||||
<input class="uni-input" type="password" v-model="formData.newPassword" placeholder="请输入新密码" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">确认密码</text>
|
||||
<view class="form-content">
|
||||
<input class="uni-input" type="password" v-model="formData.confirmPassword" placeholder="请再次输入新密码" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-actions">
|
||||
<button class="submit-btn" type="primary" @click="onSubmit">保存修改</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { reactive } from 'vue'
|
||||
|
||||
const formData = reactive({
|
||||
name: 'demo',
|
||||
oldPassword: '',
|
||||
newPassword: '',
|
||||
confirmPassword: ''
|
||||
})
|
||||
|
||||
const onSubmit = () => {
|
||||
if (formData.newPassword && formData.newPassword !== formData.confirmPassword) {
|
||||
uni.showToast({ title: '两次输入的新密码不一致', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!formData.name) {
|
||||
uni.showToast({ title: '姓名不能为空', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
uni.showLoading({ title: '保存中...' })
|
||||
setTimeout(() => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '保存成功(演示)', icon: 'success' })
|
||||
// 清空密码框
|
||||
formData.oldPassword = ''
|
||||
formData.newPassword = ''
|
||||
formData.confirmPassword = ''
|
||||
}, 500)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.user-center-container {
|
||||
padding: 20px;
|
||||
background-color: #f5f7f9;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.form-container {
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
padding: 30px 20px;
|
||||
max-width: 800px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.form-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
width: 100px;
|
||||
text-align: right;
|
||||
margin-right: 16px;
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.required {
|
||||
color: #f5222d;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.form-content {
|
||||
flex: 1;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.uni-input {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
padding: 0 12px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.uni-input:focus {
|
||||
border-color: #1890ff;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
background-color: #f5f7fa;
|
||||
color: #c0c4cc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.avatar-uploader {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.avatar-img {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 4px;
|
||||
background-color: #f0f2f5;
|
||||
border: 1px dashed #d9d9d9;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
margin-top: 40px;
|
||||
padding-left: 116px;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
width: 120px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
}
|
||||
.submit-btn:active {
|
||||
background-color: #096dd9;
|
||||
}
|
||||
</style>
|
||||
@@ -1,10 +1,100 @@
|
||||
signIn result:
|
||||
AkSupaSignInResult {access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI4Y…HNlfQ.5BvQq26lJUF23AEglMvA7EzJZvYN_hrp1Q2JA6o0s-w', refresh_token: 'ehhxnwgvgeyk', expires_at: 1773136334, user: UTSJSONObject2, token_type: 'bearer', …}
|
||||
login.uvue:175 🔍 开始校验商家端角色 -> UID: 8bdf11be-2838-4d96-8552-0949cde076d4, Email: test19@163.com
|
||||
login.uvue:216 ❌ 查询角色过程异常: TypeError: res.getData is not a function
|
||||
at login.uvue:180:23
|
||||
at Generator.next (<anonymous>)
|
||||
login.uvue:435 登录错误: Error: 商家身份校验失败,请联系管理员检查用户数据
|
||||
at login.uvue:221:9
|
||||
at Generator.next (<anonymous>)。
|
||||
打印这些东西
|
||||
GET http://localhost:5173/layouts/admin/AdminLayout.uvue?t=1773216297014&import net::ERR_ABORTED 500 (Internal Server Error)
|
||||
main.uts:16 [Vue warn]: Unhandled error during execution of async component loader
|
||||
at <AsyncComponentWrapper>
|
||||
at <PageBody>
|
||||
at <Page>
|
||||
at <Anonymous>
|
||||
at <KeepAlive>
|
||||
at <RouterView>
|
||||
at <Layout>
|
||||
at <App>
|
||||
warnHandler @ uni-h5.es.js:19975
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1381
|
||||
warn$1 @ vue.runtime.esm.js:1207
|
||||
logError @ vue.runtime.esm.js:1438
|
||||
errorHandler @ uni-h5.es.js:19600
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1381
|
||||
handleError @ vue.runtime.esm.js:1421
|
||||
onError @ vue.runtime.esm.js:3724
|
||||
(anonymous) @ vue.runtime.esm.js:3767
|
||||
Promise.catch
|
||||
setup @ vue.runtime.esm.js:3766
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1381
|
||||
setupStatefulComponent @ vue.runtime.esm.js:8985
|
||||
setupComponent @ vue.runtime.esm.js:8946
|
||||
mountComponent @ vue.runtime.esm.js:7262
|
||||
processComponent @ vue.runtime.esm.js:7228
|
||||
patch @ vue.runtime.esm.js:6694
|
||||
mountChildren @ vue.runtime.esm.js:6942
|
||||
processFragment @ vue.runtime.esm.js:7158
|
||||
patch @ vue.runtime.esm.js:6668
|
||||
mountChildren @ vue.runtime.esm.js:6942
|
||||
processFragment @ vue.runtime.esm.js:7158
|
||||
patch @ vue.runtime.esm.js:6668
|
||||
mountChildren @ vue.runtime.esm.js:6942
|
||||
mountElement @ vue.runtime.esm.js:6849
|
||||
processElement @ vue.runtime.esm.js:6814
|
||||
patch @ vue.runtime.esm.js:6682
|
||||
mountChildren @ vue.runtime.esm.js:6942
|
||||
mountElement @ vue.runtime.esm.js:6849
|
||||
processElement @ vue.runtime.esm.js:6814
|
||||
patch @ vue.runtime.esm.js:6682
|
||||
mountChildren @ vue.runtime.esm.js:6942
|
||||
processFragment @ vue.runtime.esm.js:7158
|
||||
patch @ vue.runtime.esm.js:6668
|
||||
componentUpdateFn @ vue.runtime.esm.js:7372
|
||||
run @ vue.runtime.esm.js:153
|
||||
instance.update @ vue.runtime.esm.js:7497
|
||||
setupRenderEffect @ vue.runtime.esm.js:7507
|
||||
mountComponent @ vue.runtime.esm.js:7274
|
||||
processComponent @ vue.runtime.esm.js:7228
|
||||
patch @ vue.runtime.esm.js:6694
|
||||
mountChildren @ vue.runtime.esm.js:6942
|
||||
mountElement @ vue.runtime.esm.js:6849
|
||||
processElement @ vue.runtime.esm.js:6814
|
||||
patch @ vue.runtime.esm.js:6682
|
||||
componentUpdateFn @ vue.runtime.esm.js:7372
|
||||
run @ vue.runtime.esm.js:153
|
||||
instance.update @ vue.runtime.esm.js:7497
|
||||
setupRenderEffect @ vue.runtime.esm.js:7507
|
||||
mountComponent @ vue.runtime.esm.js:7274
|
||||
processComponent @ vue.runtime.esm.js:7228
|
||||
patch @ vue.runtime.esm.js:6694
|
||||
componentUpdateFn @ vue.runtime.esm.js:7372
|
||||
run @ vue.runtime.esm.js:153
|
||||
instance.update @ vue.runtime.esm.js:7497
|
||||
setupRenderEffect @ vue.runtime.esm.js:7507
|
||||
mountComponent @ vue.runtime.esm.js:7274
|
||||
processComponent @ vue.runtime.esm.js:7228
|
||||
patch @ vue.runtime.esm.js:6694
|
||||
componentUpdateFn @ vue.runtime.esm.js:7453
|
||||
run @ vue.runtime.esm.js:153
|
||||
instance.update @ vue.runtime.esm.js:7497
|
||||
updateComponent @ vue.runtime.esm.js:7305
|
||||
processComponent @ vue.runtime.esm.js:7239
|
||||
patch @ vue.runtime.esm.js:6694
|
||||
componentUpdateFn @ vue.runtime.esm.js:7453
|
||||
run @ vue.runtime.esm.js:153
|
||||
instance.update @ vue.runtime.esm.js:7497
|
||||
callWithErrorHandling @ vue.runtime.esm.js:1381
|
||||
flushJobs @ vue.runtime.esm.js:1585
|
||||
Promise.then
|
||||
queueFlush @ vue.runtime.esm.js:1494
|
||||
queueJob @ vue.runtime.esm.js:1488
|
||||
scheduler @ vue.runtime.esm.js:3179
|
||||
resetScheduling @ vue.runtime.esm.js:236
|
||||
triggerEffects @ vue.runtime.esm.js:280
|
||||
triggerRefValue @ vue.runtime.esm.js:1033
|
||||
set value @ vue.runtime.esm.js:1078
|
||||
finalizeNavigation @ vue-router.mjs?v=ed041164:2474
|
||||
(anonymous) @ vue-router.mjs?v=ed041164:2384
|
||||
Promise.then
|
||||
pushWithRedirect @ vue-router.mjs?v=ed041164:2352
|
||||
push @ vue-router.mjs?v=ed041164:2278
|
||||
install @ vue-router.mjs?v=ed041164:2631
|
||||
use @ vue.runtime.esm.js:5190
|
||||
initRouter @ uni-h5.es.js:19886
|
||||
install @ uni-h5.es.js:19955
|
||||
use @ vue.runtime.esm.js:5190
|
||||
(anonymous) @ main.uts:16
|
||||
main.uts:16 TypeError: Failed to fetch dynamically imported module: http://localhost:5173/pages/mall/admin/homePage/index.uvue?t=1773216297014&import
|
||||
42
rebuild_html.py
Normal file
42
rebuild_html.py
Normal file
@@ -0,0 +1,42 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\components\\AdminHeader.uvue'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
# I will replace the user-profile-container entirely with a solid implementation, including the overlay.
|
||||
old_html = r''' <!-- 用户个人中心 / 下拉菜单 -->
|
||||
<view class="user-profile-container" @click="goToUserCenter">
|
||||
<text class="user-name">crmeb demo</text>
|
||||
<text class="user-arrow">▼</text>
|
||||
|
||||
<view class="user-dropdown" v-if="showUserMenu">
|
||||
<view class="dropdown-item" @click.stop="goToUserCenter">个人中心</view>
|
||||
<view class="dropdown-item" @click.stop="handleLogout">退出登录</view>
|
||||
</view>
|
||||
</view>'''
|
||||
|
||||
new_html = r''' <!-- 点击外部收起菜单的遮罩层 -->
|
||||
<view class="user-dropdown-overlay" v-if="showUserMenu" @click="closeUserMenu"></view>
|
||||
|
||||
<!-- 用户个人中心 / 下拉菜单 -->
|
||||
<view class="user-profile-container" @click="toggleUserMenu">
|
||||
<text class="user-name">crmeb demo</text>
|
||||
<text class="user-arrow">▼</text>
|
||||
|
||||
<view class="user-dropdown" v-if="showUserMenu">
|
||||
<view class="dropdown-item" @click.stop="goToUserCenter">个人中心</view>
|
||||
<view class="dropdown-item" @click.stop="handleLogout">退出登录</view>
|
||||
</view>
|
||||
</view>'''
|
||||
|
||||
text = text.replace(old_html, new_html)
|
||||
|
||||
# Add closeUserMenu to script if doesn't exist
|
||||
if 'function closeUserMenu' not in text:
|
||||
text = text.replace('function toggleUserMenu() {', 'function closeUserMenu() {\n showUserMenu.value = false\n}\n\nfunction toggleUserMenu() {')
|
||||
|
||||
# Adjust goToUserCenter to remove toast, just keep logic
|
||||
text = text.replace('uni.showToast({ title: "尝试打开个人中心...", icon: "none", duration: 2000 });\n console.log([AdminHeader] goToUserCenter called);\n console.log([AdminHeader] goToUserCenter called);', '')
|
||||
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
8
remove_broken_log.py
Normal file
8
remove_broken_log.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\AdminLayout.uvue'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('console.log([AdminLayout] Computing component for activeRouteId: );', '')
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
10
remove_broken_log2.py
Normal file
10
remove_broken_log2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\store\\adminNavStore.uts'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('console.log([AdminNavStore] openRoute called with: );', '')
|
||||
text = text.replace('console.log([AdminNavStore] activeRouteId set to: );', '')
|
||||
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
10
remove_broken_log3.py
Normal file
10
remove_broken_log3.py
Normal file
@@ -0,0 +1,10 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\components\\AdminHeader.uvue'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('console.log([AdminHeader] goToUserCenter called)', 'console.log([AdminHeader] goToUserCenter called)')
|
||||
text = text.replace('console.log([AdminHeader] goToUserCenter called);', '')
|
||||
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
8
remove_broken_log4.py
Normal file
8
remove_broken_log4.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\AdminLayout.uvue'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('console.log([AdminLayout] Computing hasAccess for: );', '')
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
25
replace_user.py
Normal file
25
replace_user.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import codecs
|
||||
|
||||
content = '''<template>
|
||||
<view class="user-center-container">
|
||||
<text style="font-size: 24px; color: red;">userCenter loaded!</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
console.log('[UserCenter] Component Setup Executed!')
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.user-center-container {
|
||||
padding: 50px;
|
||||
background-color: #fff;
|
||||
min-height: 500px;
|
||||
}
|
||||
</style>
|
||||
'''
|
||||
|
||||
with codecs.open(r'd:\\骅锋\\mall\\pages\\mall\\admin\\userCenter\\index.uvue', 'w', 'utf-8') as f:
|
||||
f.write(content)
|
||||
|
||||
print("userCenter replaced.")
|
||||
203
restore_content.py
Normal file
203
restore_content.py
Normal file
@@ -0,0 +1,203 @@
|
||||
import codecs
|
||||
|
||||
content = '''<template>
|
||||
<view class="user-center-container">
|
||||
<view class="page-header">
|
||||
<text class="page-title">个人中心</text>
|
||||
</view>
|
||||
|
||||
<view class="form-container">
|
||||
<view class="form-item">
|
||||
<text class="form-label">头像</text>
|
||||
<view class="form-content avatar-uploader">
|
||||
<!-- 默认使用一个占位头像或 Logo -->
|
||||
<image class="avatar-img" src="/static/logo.png" mode="aspectFill"></image>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">账号</text>
|
||||
<view class="form-content">
|
||||
<input class="uni-input disabled" value="crmeb demo" disabled placeholder="请输入账号" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label"><text class="required">*</text>姓名</text>
|
||||
<view class="form-content">
|
||||
<input class="uni-input" v-model="formData.name" placeholder="请输入姓名" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">原始密码</text>
|
||||
<view class="form-content">
|
||||
<input class="uni-input" type="password" v-model="formData.oldPassword" placeholder="请输入原始密码" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">新密码</text>
|
||||
<view class="form-content">
|
||||
<input class="uni-input" type="password" v-model="formData.newPassword" placeholder="请输入新密码" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">确认密码</text>
|
||||
<view class="form-content">
|
||||
<input class="uni-input" type="password" v-model="formData.confirmPassword" placeholder="请再次输入新密码" />
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-actions">
|
||||
<button class="submit-btn" type="primary" @click="onSubmit">保存修改</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="uts">
|
||||
import { reactive } from 'vue'
|
||||
|
||||
const formData = reactive({
|
||||
name: 'crmeb demo',
|
||||
oldPassword: '',
|
||||
newPassword: '',
|
||||
confirmPassword: ''
|
||||
})
|
||||
|
||||
const onSubmit = () => {
|
||||
if (formData.newPassword && formData.newPassword !== formData.confirmPassword) {
|
||||
uni.showToast({ title: '两次输入的新密码不一致', icon: 'none' })
|
||||
return
|
||||
}
|
||||
if (!formData.name) {
|
||||
uni.showToast({ title: '姓名不能为空', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
uni.showLoading({ title: '保存中...' })
|
||||
setTimeout(() => {
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '保存成功(演示)', icon: 'success' })
|
||||
// 清空密码框
|
||||
formData.oldPassword = ''
|
||||
formData.newPassword = ''
|
||||
formData.confirmPassword = ''
|
||||
}, 500)
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.user-center-container {
|
||||
padding: 20px;
|
||||
background-color: #f5f7f9;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.page-header {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.form-container {
|
||||
background-color: #fff;
|
||||
border-radius: 4px;
|
||||
padding: 30px 20px;
|
||||
max-width: 800px;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.form-item {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.form-label {
|
||||
width: 100px;
|
||||
text-align: right;
|
||||
margin-right: 16px;
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.required {
|
||||
color: #f5222d;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.form-content {
|
||||
flex: 1;
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.uni-input {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
padding: 0 12px;
|
||||
border: 1px solid #dcdfe6;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.uni-input:focus {
|
||||
border-color: #1890ff;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
background-color: #f5f7fa;
|
||||
color: #c0c4cc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.avatar-uploader {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.avatar-img {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 4px;
|
||||
background-color: #f0f2f5;
|
||||
border: 1px dashed #d9d9d9;
|
||||
}
|
||||
|
||||
.form-actions {
|
||||
margin-top: 40px;
|
||||
padding-left: 116px;
|
||||
}
|
||||
|
||||
.submit-btn {
|
||||
background-color: #1890ff;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
width: 120px;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
}
|
||||
.submit-btn:active {
|
||||
background-color: #096dd9;
|
||||
}
|
||||
</style>
|
||||
'''
|
||||
|
||||
with codecs.open(r'd:\\骅锋\\mall\\pages\\mall\\admin\\userCenter\\index.uvue', 'w', 'utf-8') as f:
|
||||
f.write(content)
|
||||
|
||||
print("个人中心内容重置完成!")
|
||||
4
script4.py
Normal file
4
script4.py
Normal file
@@ -0,0 +1,4 @@
|
||||
import codecs
|
||||
for line in codecs.open(r'd:\骅锋\mall\layouts\admin\store\adminNavStore.uts', 'r', 'utf-8'):
|
||||
if 'findRouteById' in line:
|
||||
print(line.strip())
|
||||
4
script5.py
Normal file
4
script5.py
Normal file
@@ -0,0 +1,4 @@
|
||||
import codecs
|
||||
for line in codecs.open(r'd:\骅锋\mall\layouts\admin\router\adminRoutes.uts', 'r', 'utf-8'):
|
||||
if 'function findRouteById' in line:
|
||||
print('Found!')
|
||||
4
script6.py
Normal file
4
script6.py
Normal file
@@ -0,0 +1,4 @@
|
||||
import codecs
|
||||
text = codecs.open(r'd:\骅锋\mall\layouts\admin\router\adminRoutes.uts', 'r', 'utf-8').read()
|
||||
start = text.find('function findRouteById')
|
||||
print(text[start:start+400])
|
||||
6
script7.py
Normal file
6
script7.py
Normal file
@@ -0,0 +1,6 @@
|
||||
import codecs
|
||||
text = codecs.open(r'd:\骅锋\mall\layouts\admin\router\adminRoutes.uts', 'r', 'utf-8').read()
|
||||
start = text.find('const routes')
|
||||
if start == -1:
|
||||
start = text.find('const adminRoutes')
|
||||
print(text[start:start+400])
|
||||
5
script8.py
Normal file
5
script8.py
Normal file
@@ -0,0 +1,5 @@
|
||||
import codecs
|
||||
text = codecs.open(r'd:\骅锋\mall\layouts\admin\AdminLayout.uvue', 'r', 'utf-8').read()
|
||||
for line in text.split('\n'):
|
||||
if 'activeRouteId' in line and 'import' in line:
|
||||
print(line)
|
||||
5
script9.py
Normal file
5
script9.py
Normal file
@@ -0,0 +1,5 @@
|
||||
import codecs
|
||||
text = codecs.open(r'd:\骅锋\mall\layouts\admin\AdminLayout.uvue', 'r', 'utf-8').read()
|
||||
for line in text.split('\n'):
|
||||
if 'activeRouteId' in line:
|
||||
print(line.strip())
|
||||
10
simplify.py
Normal file
10
simplify.py
Normal file
@@ -0,0 +1,10 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\components\\AdminHeader.uvue'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('@click="toggleUserMenu"', '@click="goToUserCenter"')
|
||||
text = text.replace('function goToUserCenter() {', 'function goToUserCenter() {\n console.log("[AdminHeader] goToUserCenter called");')
|
||||
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
10
simplify2.py
Normal file
10
simplify2.py
Normal file
@@ -0,0 +1,10 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\store\\adminNavStore.uts'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('function openRoute(routeId: string, addTab: boolean = true): void {', 'function openRoute(routeId: string, addTab: boolean = true): void {\n console.log([AdminNavStore] openRoute called with: );')
|
||||
text = text.replace('activeRouteId.value = routeId', 'activeRouteId.value = routeId\n console.log([AdminNavStore] activeRouteId set to: );')
|
||||
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
8
simplify3.py
Normal file
8
simplify3.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\AdminLayout.uvue'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('const currentComponent = computed<any>(() => {', 'const currentComponent = computed<any>(() => {\n console.log([AdminLayout] Computing component for activeRouteId: );')
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
9
simplify4.py
Normal file
9
simplify4.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\components\\AdminHeader.uvue'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('.user-profile-container {\n position: relative;', '.user-profile-container {\n position: relative;\n z-index: 100;\n pointer-events: auto;')
|
||||
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
10
simplify5.py
Normal file
10
simplify5.py
Normal file
@@ -0,0 +1,10 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\store\\adminNavStore.uts'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('console.log([AdminNavStore] openRoute called with: );', 'console.log([AdminNavStore] openRoute called with: );')
|
||||
text = text.replace('console.log([AdminNavStore] activeRouteId set to: );', 'console.log([AdminNavStore] activeRouteId set to: );')
|
||||
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
9
simplify6.py
Normal file
9
simplify6.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\AdminLayout.uvue'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('console.log([AdminLayout] Computing component for activeRouteId: );', 'console.log([AdminLayout] Computing component for activeRouteId: );')
|
||||
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
9
simplify7.py
Normal file
9
simplify7.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\AdminLayout.uvue'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('console.log([AdminLayout] Computing component for activeRouteId: )', 'console.log([AdminLayout] Computing component for activeRouteId: )')
|
||||
text = text.replace('console.log([AdminHeader] goToUserCenter called)', 'console.log([AdminHeader] goToUserCenter called)')
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
10
simplify8.py
Normal file
10
simplify8.py
Normal file
@@ -0,0 +1,10 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\store\\adminNavStore.uts'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('console.log([AdminNavStore] openRoute called with: );', 'console.log([AdminNavStore] openRoute called with: );')
|
||||
text = text.replace('console.log([AdminNavStore] activeRouteId set to: );', 'console.log([AdminNavStore] activeRouteId set to: );')
|
||||
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
9
simplify9.py
Normal file
9
simplify9.py
Normal file
@@ -0,0 +1,9 @@
|
||||
import codecs
|
||||
file_path = r'd:\\骅锋\\mall\\layouts\\admin\\AdminLayout.uvue'
|
||||
with codecs.open(file_path, 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace('const hasAccess = computed<boolean>(() => {', 'const hasAccess = computed<boolean>(() => {\n console.log([AdminLayout] Computing hasAccess for: );')
|
||||
|
||||
with codecs.open(file_path, 'w', 'utf-8') as f:
|
||||
f.write(text)
|
||||
5
test_html.py
Normal file
5
test_html.py
Normal file
@@ -0,0 +1,5 @@
|
||||
import codecs
|
||||
with codecs.open(r'd:\\骅锋\\mall\\layouts\\admin\\components\\AdminHeader.uvue', 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
start = text.find('user-profile-container')
|
||||
print(text[start-20:start+600])
|
||||
8
test_main.py
Normal file
8
test_main.py
Normal file
@@ -0,0 +1,8 @@
|
||||
import codecs
|
||||
with codecs.open(r'd:\\骅锋\\mall\\layouts\\admin\\AdminLayout.uvue', 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
import re
|
||||
match = re.search(r'<view\s+class=[\'"]main-content[\s\S]*?<\/view>', text)
|
||||
if match:
|
||||
print(match.group(0)[:500])
|
||||
6
test_main2.py
Normal file
6
test_main2.py
Normal file
@@ -0,0 +1,6 @@
|
||||
import codecs
|
||||
with codecs.open(r'd:\\骅锋\\mall\\layouts\\admin\\AdminLayout.uvue', 'r', 'utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
start = text.find('class="main-content"')
|
||||
print(text[start-50:start+300])
|
||||
25
test_replace_header.py
Normal file
25
test_replace_header.py
Normal file
@@ -0,0 +1,25 @@
|
||||
import codecs
|
||||
import re
|
||||
|
||||
with open('layouts/admin/components/AdminHeader.uvue', 'r', encoding='utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
new_html = r""" <view class="hbtn" @click="$emit('notify')">\n <text>🔔</text>\n <view class="dot" v-if="hasNotification"></view>\n </view>\n \n <!-- 用户个人中心 / 下拉菜单 -->\n <view class="user-profile-container" @click="toggleUserMenu">\n <text class="user-name">crmeb demo</text>\n <text class="user-arrow">▼</text>\n \n <view class="user-dropdown" v-if="showUserMenu">\n <view class="dropdown-item" @click.stop="goToUserCenter">个人中心</view>\n <view class="dropdown-item" @click.stop="handleLogout">退出登录</view>\n </view>\n </view>"""
|
||||
|
||||
new_html = new_html.replace(r'\n', '\n')
|
||||
|
||||
text = re.sub(r'<view class=\"hbtn\" @click=\"\$emit\(\'notify\'\)\">[\s\S]*?<\/view>\s*<\/view>', new_html + '\n </view>', text)
|
||||
|
||||
new_script = r"""import { ref, computed } from 'vue'\nimport {\n toggleSubSider,\n showSubSider,\n layoutMode,\n isOverlayVisible,\n isMobileMenuOpen,\n openRoute\n} from '@/layouts/admin/store/adminNavStore.uts'\n\nconst showUserMenu = ref(false)\n\nfunction toggleUserMenu() {\n showUserMenu.value = !showUserMenu.value\n}\n\nfunction goToUserCenter() {\n showUserMenu.value = false\n openRoute('demo_user_center')\n}\n\nfunction handleLogout() {\n showUserMenu.value = false\n uni.showModal({\n title: '提示',\n content: '确定要退出登录吗?',\n success: (res) => {\n if (res.confirm) {\n uni.reLaunch({\n url: '/pages/index/index'\n })\n }\n }\n })\n}"""
|
||||
new_script = new_script.replace(r'\n', '\n')
|
||||
|
||||
text = re.sub(r'import \{ computed \} from \'vue\'[\s\S]*?\} from \'@/layouts/admin/store/adminNavStore\.uts\'', new_script, text)
|
||||
|
||||
|
||||
new_style = r""".dot{\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background:#ff4d4f;\n position:absolute;\n top: 6px;\n right: 6px;\n}\n\n.user-profile-container {\n position: relative;\n display: flex;\n flex-direction: row;\n align-items: center;\n margin-left: 10px;\n cursor: pointer;\n}\n\n.user-name {\n font-size: 14px;\n color: #333;\n}\n\n.user-arrow {\n font-size: 12px;\n color: #666;\n margin-left: 4px;\n}\n\n.user-dropdown {\n position: absolute;\n top: 40px;\n right: 0;\n width: 120px;\n background-color: #fff;\n border-radius: 4px;\n box-shadow: 0 2px 12px rgba(0,0,0,0.1);\n z-index: 1000;\n display: flex;\n flex-direction: column;\n}\n\n.dropdown-item {\n height: 40px;\n line-height: 40px;\n text-align: center;\n font-size: 14px;\n color: #333;\n cursor: pointer;\n}\n\n.dropdown-item:hover {\n background-color: #f5f7fa;\n color: #1890ff;\n}"""
|
||||
new_style = new_style.replace(r'\n', '\n')
|
||||
text = re.sub(r'\.dot\{[\s\S]*?\}', new_style, text)
|
||||
|
||||
with open('layouts/admin/components/AdminHeader.uvue', 'w', encoding='utf-8') as f:
|
||||
f.write(text)
|
||||
|
||||
16
test_replace_map.py
Normal file
16
test_replace_map.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import codecs
|
||||
with open('layouts/admin/router/adminComponentMap.uts', 'r', encoding='utf-8') as f:
|
||||
text = f.read()
|
||||
|
||||
text = text.replace(
|
||||
"import HomeIndex from '@/pages/mall/admin/homePage/index.uvue'",
|
||||
"import HomeIndex from '@/pages/mall/admin/homePage/index.uvue'\nimport UserCenter from '@/pages/mall/admin/userCenter/index.uvue'"
|
||||
)
|
||||
|
||||
text = text.replace(
|
||||
"['HomeIndex', HomeIndex],",
|
||||
"['HomeIndex', HomeIndex],\n ['UserCenter', UserCenter],"
|
||||
)
|
||||
|
||||
with open('layouts/admin/router/adminComponentMap.uts', 'w', encoding='utf-8') as f:
|
||||
f.write(text)
|
||||
Reference in New Issue
Block a user