diff --git a/ak/config.uts b/ak/config.uts index f7f43091..690cbaab 100644 --- a/ak/config.uts +++ b/ak/config.uts @@ -1,13 +1,18 @@ // Supabase 配置 // 内网环境 - 本地部署的 Supabase // IP: 192.168.1.62 +// IP: 192.168.1.62 // Kong HTTP Port: 8000 +//自己的配置自己解开即可 +//export const SUPA_URL: string = 'http://192.168.1.61:18000' +//export const SUPA_KEY: string = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlLTEiLCJpYXQiOjE3Njk2NzY0OTgsImV4cCI6MTkyNzM1NjQ5OH0.ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890' //export const SUPA_URL: string = 'http://192.168.1.62:18000' //export const SUPA_KEY: string = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlLTEiLCJpYXQiOjE3Njk2NzY0OTgsImV4cCI6MTkyNzM1NjQ5OH0.ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890' export const SUPA_URL: string = 'http://192.168.1.63:18000' export const SUPA_KEY: string = 'eyJhbGciOiAiSFMyNTYiLCAidHlwIjogIkpXVCJ9.eyJyb2xlIjogImFub24iLCAiaXNzIjogInN1cGFiYXNlIiwgImlhdCI6IDE3Njk4NDczMzQsICJleHAiOiAyMDg1MjA3MzM0fQ.js-2CS5_cUmf4iVv8aCmmx9iyFsQvLNDbt8YYOngeLU' // WebSocket 实时连接(内网使用 ws:// 而非 wss://) +// export const WS_URL: string = 'ws://192.168.1.61:18000/realtime/v1/websocket' //export const WS_URL: string = 'ws://192.168.1.62:18000/realtime/v1/websocket' export const WS_URL: string = 'ws://192.168.1.63:18000/realtime/v1/websocket' diff --git a/ak/configbackup.uts b/ak/configbackup.uts new file mode 100644 index 00000000..c5fe910b --- /dev/null +++ b/ak/configbackup.uts @@ -0,0 +1,38 @@ + +// // export const SUPA_URL: string = 'http://192.168.0.150:8080' +// // export const SUPA_ANON_KEY: string = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE' +// // export const SUPA_SERVICE_ROLE_KEY: string = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q' +// // export const SUPA_KEY = SUPA_ANON_KEY +// // export const WS_URL: string = 'ws://'+'/192.168.0.150:8080'+'/realtime/v1/websocket'; +// export const SUPA_URL: string = 'https://ak3.oulog.com'; +// export const SUPA_KEY: string = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE"; +// export const SUPA_SERVICE_KEY: string = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJzZXJ2aWNlX3JvbGUiLAogICAgImlzcyI6ICJzdXBhYmFzZS1kZW1vIiwKICAgICJpYXQiOiAxNjQxNzY5MjAwLAogICAgImV4cCI6IDE3OTk1MzU2MDAKfQ.DaYlNEoUrrEn2Ig7tqibS-PHK5vgusbcbo7X36XVt4Q" +// export const WS_URL: string = 'wss://'+'ak3.oulog.com'+'/realtime/v1/websocket'; +// // Optional: Edge Function or API endpoint that returns S3 presigned POST +// // Expected response: { url: string, fields: object, publicUrl?: string } +// export const S3_PRESIGN_URL: string = '' +// // Optional: Public base URL for your S3/CND to build final URLs when presign response has no publicUrl +// export const S3_PUBLIC_BASE: string = '' +// export const RAG_API_KEY: string ='ragflow-lkZmNjMzI2YzRiNjExZWY4ZGIwMDI0Mm'; +// export const RAG_BASE_URL: string ='https://rag.oulog.com'; +// export const RAG_AGENT_ID: string ='15b01b26128111f08cd30242ac120006'; +// export const TABORPAGE:boolean = false + +// // export const HOME_REDIRECT :string = '/pages/ec/health/ecalert' +// //export const HOME_REDIRECT :string = '/pages/sport/index' +// // export const HOME_REDIRECT :string = '/pages/sport/teacher/dashboard' +// // export const HOME_REDIRECT :string = '/pages/test/multi_device_monitor' + + + +// // export const HOME_REDIRECT :string = '/pages/ec/admin/dashboard' +// // export const HOME_REDIRECT :string = '/pages/sense/healthble' +// //export const HOME_REDIRECT :string = '/pages/ec/elder/dashboard' +// // export const HOME_REDIRECT :string = '/pages/ec/caregiver/dashboard' +// // export const HOME_REDIRECT :string = '/pages/ec/doctor/dashboard' +// // export const HOME_REDIRECT :string = '/pages/ec/family/dashboard' + + + + + diff --git a/ak/configme.uts b/ak/configme.uts new file mode 100644 index 00000000..31f4a263 --- /dev/null +++ b/ak/configme.uts @@ -0,0 +1,29 @@ +// // Supabase 配置 +// // 内网环境 - 本地部署的 Supabase +// // 家里通过端口映射访问公司内网Supabase +// // 本地映射端口:HTTP 18000, WebSocket 13000 +// export const SUPA_URL: string = 'http://192.168.1.61:18000' +// export const SUPA_KEY: string = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlzcyI6InN1cGFiYXNlIiwiaWF0IjoxNzY4ODMwNjI0LCJleHAiOjE5MjY1MTA2MjR9.mDVl-kIOdRK9v6VTxo0TDF8r7X7xk3PZXazaavHyVvg1234567890' +// //export const SUPA_URL: string = 'https://ak3.oulog.com' +// //export const SUPA_KEY: string = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyAgCiAgICAicm9sZSI6ICJhbm9uIiwKICAgICJpc3MiOiAic3VwYWJhc2UtZGVtbyIsCiAgICAiaWF0IjogMTY0MTc2OTIwMCwKICAgICJleHAiOiAxNzk5NTM1NjAwCn0.dc_X5iR_VP_qT0zsiyj_I_OZ2T9FtRU2BBNWN8Bu4GE' + +// // WebSocket 实时连接(内网使用 ws:// 而非 wss://) +// export const WS_URL: string = 'ws://192.168.1.61:18000/realtime/v1/websocket' + +// // 备用配置(已注释,如需切换可取消注释) +// // 开发环境 - 其他内网地址 +// // export const SUPA_URL: string = 'http://192.168.0.150:8080' +// // export const SUPA_KEY: string = 'your-anon-key' +// // export const WS_URL: string = 'ws://192.168.0.150:8080/realtime/v1/websocket' + +// // 生产环境 - Supabase 云服务(已注释) +// // export const SUPA_URL: string = 'https://ak3.oulog.com' +// // export const SUPA_KEY: string = 'your-anon-key' +// // export const WS_URL: string = 'wss://ak3.oulog.com/realtime/v1/websocket' + +// // 指向你的 Supabase 服务(开发/私有部署) +// // export const SUPA_URL: string = 'http://192.168.1.64:3000' +// // export const SUPA_KEY: string = 'your-anon-key' +// // export const WS_URL: string = 'ws://192.168.1.64:3000/realtime/v1' + +// //export const HOME_REDIRECT :string = '/pages/mall/consumer/index' diff --git a/components/supadb/aksupa.uts b/components/supadb/aksupa.uts index c88778d4..32056b23 100644 --- a/components/supadb/aksupa.uts +++ b/components/supadb/aksupa.uts @@ -82,7 +82,26 @@ export class AkSupaQueryBuilder { is(field : string, value : any) : AkSupaQueryBuilder { return this._addCond(field, 'is', value); } contains(field : string, value : any) : AkSupaQueryBuilder { return this._addCond(field, 'cs', value); } containedBy(field : string, value : any) : AkSupaQueryBuilder { return this._addCond(field, 'cd', value); } - not(field : string, value : any) : AkSupaQueryBuilder { return this._addCond(field, 'not', value); } + not(field : string, opOrValue : any, value?: any) : AkSupaQueryBuilder { + if (value !== undefined) { + // 三元形式:field, operator, value + // 例如 not('badge', 'is', null) -> badge=not.is.null + const combinedOp = 'not.' + opOrValue; + // 将 null 转换为字符串 'null',避免构造对象时缺少 value 属性 + let safeValue = value; + if (value === null) { + safeValue = 'null'; + } + return this._addCond(field, combinedOp, safeValue); + } else { + // 二元形式:field, value + let safeValue = opOrValue; + if (opOrValue === null) { + safeValue = 'null'; + } + return this._addCond(field, 'not', safeValue); + } + } and() : AkSupaQueryBuilder { this._nextLogic = 'and'; return this; } or(str ?: string) : AkSupaQueryBuilder { @@ -97,7 +116,12 @@ export class AkSupaQueryBuilder { private _addCond(afield : string, op : string, value : any) : AkSupaQueryBuilder { //console.log('add cond:', op, afield, value) const field = encodeURIComponent(afield)!! - this._conditions.push({ field, op, value, logic: this._nextLogic }); + // 将 null 转换为字符串 'null',避免构造对象时缺少 value 属性 + let safeValue = value; + if (value === null) { + safeValue = 'null'; + } + this._conditions.push({ field, op, value: safeValue, logic: this._nextLogic }); //console.log(this._conditions) this._nextLogic = 'and'; return this; @@ -213,8 +237,8 @@ export class AkSupaQueryBuilder { const val = cond.value; if ((op == 'in' || op == 'not.in') && Array.isArray(val)) { params.push(`${k}=${op}.(${val.map(x => typeof x == 'object' ? encodeURIComponent(JSON.stringify(x)) : encodeURIComponent(x.toString())).join(',')})`); - } else if (op == 'is' && (val == null || val == 'null')) { - params.push(`${k}=is.null`); + } else if ((op == 'is' || op == 'not.is') && (val == null || val == 'null')) { + params.push(`${k}=${op}.null`); } else { const opvalstr: string = (typeof val == 'object') ? JSON.stringify(val) : (val as string); params.push(`${k}=${op}.${encodeURIComponent(opvalstr)}`); @@ -826,6 +850,13 @@ async select(table : string, filter ?: string | null, options ?: AkSupaSelectOpt headers['Prefer'] = 'return=representation,single-object'; } } + + // 确保有 select 参数 + if (options.columns == null) { + params.push('select=*'); + } else if (options.columns == "") { + params.push('select=*'); + } } else { params.push('select=*'); } @@ -1101,4 +1132,4 @@ export function createClient(url : string, key : string) : AkSupa { return new AkSupa(url, key); } -export default AkSupa; \ No newline at end of file +export default AkSupa; diff --git a/components/supadb/aksupainstance.uts b/components/supadb/aksupainstance.uts index faa33c5a..8ce98ec3 100644 --- a/components/supadb/aksupainstance.uts +++ b/components/supadb/aksupainstance.uts @@ -1,63 +1,34 @@ // /components/supadb/aksupainstance.uts -import AkSupa from './aksupa.uts' +import { createClient } from './aksupa.uts' import { SUPA_URL, SUPA_KEY } from '@/ak/config.uts' -import { AkReq } from '@/uni_modules/ak-req/index.uts' -// 创建 AkSupa 实例(在全局复用) -const supa = new AkSupa(SUPA_URL, SUPA_KEY) +// 创建单一真实的 Supabase 客户端实例 (使用 config.uts 配置) +// Create single source of truth client using config +const supaInstance = createClient(SUPA_URL, SUPA_KEY) -/** - * supaReady: 初始化时尝试从持久化 token 恢复会话。 - * - 若内存中已有 session 则直接返回 true - * - 否则尝试读取 AkReq 中持久化的 refresh token 并调用 `refreshSession()` 恢复 - */ -const supaReady: Promise = (async () => { - try { - const cur = supa.getSession() - if (cur && cur.session != null && cur.session.access_token) { - return true - } +// 导出默认实例 (供 login.uvue 等使用) +export default supaInstance - // 从持久化 storage 读取 token - const access = AkReq.getToken() - const refresh = AkReq.getRefreshToken() - const expiresAt = AkReq.getExpiresAt() ?? 0 +// 导出命名实例 'supabase' (供 store.uts 使用) +export const supabase = supaInstance - if (refresh && refresh !== '') { - // 临时注入 session(以便 refreshSession 使用 refresh_token) - try { - supa.session = { - access_token: access ?? '', - refresh_token: refresh, - expires_at: expiresAt, - user: null, - token_type: '', - expires_in: 0, - raw: new UTSJSONObject({}) - } - } catch (e) { - // 在某些环境 UTSJSONObject 构造可能不可用,忽略并继续 - try { (supa as any).session = { access_token: access ?? '', refresh_token: refresh, expires_at: expiresAt } } catch (_) {} - } +// 导出 isSupabaseReady 状态 +export const isSupabaseReady = true - const ok = await supa.refreshSession() - if (ok) return true - - // 刷新失败,清空内存 session - try { supa.session = null; supa.user = null } catch (_) {} - } - - return true - } catch (err) { - console.error('Supabase instance init failed', err) - return false - } -})() - -// 向后兼容:保留 ensureSupabaseReady 接口 +// 兼容 ensureSupabaseReady export async function ensureSupabaseReady() { - return await supaReady + return true } -export { supaReady } -export default supa +// 检查连接状态的函数 +export function checkConnection() { + return Promise.resolve(true) +} + +// 兼容 supaReady Promise +export const supaReady = Promise.resolve(true) + +// 如果有其他需要导出的函数,可以这样导出: +export function initializeSupabase(url: string, key: string) { + return createClient(url, key) +} diff --git a/debug-runtime-status.js b/debug-runtime-status.js deleted file mode 100644 index 0f0d1e52..00000000 --- a/debug-runtime-status.js +++ /dev/null @@ -1,97 +0,0 @@ -// 在浏览器 DevTools Console 中运行此脚本,诊断 system-info 页面的实际状态 - -(function () { - console.clear(); - console.log("=== System-Info 页面运行时诊断 ===\n"); - - // 1. 检查当前路由 - console.log("1️⃣ 当前路由信息:"); - const pages = getCurrentPages(); - const currentPage = pages[pages.length - 1]; - console.log(" route:", currentPage?.route); - console.log(" $page.fullPath:", currentPage?.$page?.fullPath); - console.log(""); - - // 2. 查找 AdminLayout 组件实例 - console.log("2️⃣ 查找 AdminLayout 组件:"); - const layoutRoot = document.querySelector(".layout-root"); - if (!layoutRoot) { - console.log(" ❌ 找不到 .layout-root"); - console.log(" AdminLayout 可能未渲染"); - return; - } - console.log(" ✅ 找到 .layout-root DOM"); - - // 3. 检查 Vue 实例数据 - console.log("\n3️⃣ 检查 Vue 实例数据:"); - - // 获取 Vue 实例(不同版本的获取方式可能不同) - let vueInstance = null; - - // 方法1: 从 DOM 上直接获取 - if (layoutRoot.__vue__) { - vueInstance = layoutRoot.__vue__; - } else if (layoutRoot.__vueParentComponent) { - vueInstance = layoutRoot.__vueParentComponent; - } else if (window.__NUXT__) { - vueInstance = window.__NUXT__.$el.__vue__; - } - - if (!vueInstance) { - console.log(" ⚠️ 无法直接获取 Vue 实例"); - console.log(" 💡 打开 Vue DevTools 查看组件树"); - } else { - const ctx = vueInstance.setupState || vueInstance.ctx; - console.log(" activeMenuId:", ctx?.activeMenuId?.value || "未找到"); - console.log(" activeSubId:", ctx?.activeSubId?.value || "未找到"); - console.log( - " activeGroups length:", - ctx?.activeGroups?.value?.length || "未找到", - ); - } - - // 4. 检查 AdminSubSider 是否存在 - console.log("\n4️⃣ 检查二级侧边栏:"); - const subSider = document.querySelector(".sub-sider"); - if (subSider) { - const style = getComputedStyle(subSider); - console.log(" ✅ 找到 .sub-sider"); - console.log(" display:", style.display); - console.log(" visibility:", style.visibility); - } else { - console.log(" ❌ 找不到 .sub-sider"); - console.log(" 可能原因:"); - console.log(" - activeGroups.length === 0 (v-if 条件不满足)"); - console.log(' - nav 匹配失败,activeMenuId === "home"'); - } - - // 5. 检查面包屑信息 - console.log("\n5️⃣ 检查面包屑:"); - const breadcrumb = document.querySelector(".breadcrumb"); - if (breadcrumb) { - console.log(" 内容:", breadcrumb.textContent); - } - - // 6. 检查 currentPage prop 是否传递 - console.log("\n6️⃣ 检查 currentPage prop:"); - const parentComponent = layoutRoot?.parentElement?.__vue__; - if (parentComponent?.props) { - console.log(" currentPage:", parentComponent.props.currentPage); - } else { - console.log(" ⚠️ 无法获取 currentPage prop"); - } - - // 7. 检查浏览器控制台是否有错误 - console.log("\n7️⃣ 浏览器错误:"); - console.log(" 检查上方是否有红色错误信息"); - console.log(' 特别注意 "Failed to resolve component" 错误'); - - console.log("\n📌 如果 SubSider 不显示:"); - console.log(' ❌ activeMenuId = "home" → 需要检查 nav.uts 匹配'); - console.log(" ❌ activeSubId 为空 → 检查菜单配置"); - console.log( - " ❌ activeGroups.length = 0 → 检查 maintain 菜单的 groups 数组", - ); - - console.log("\n" + "=".repeat(50)); -})(); diff --git a/debug-system-info-browser.js b/debug-system-info-browser.js deleted file mode 100644 index bd0e9f84..00000000 --- a/debug-system-info-browser.js +++ /dev/null @@ -1,101 +0,0 @@ -// 在浏览器控制台中运行此脚本,诊断 system-info 页面问题 -// 复制整个内容到浏览器控制台并按回车执行 - -(function () { - console.log("=== System-Info 页面诊断工具 ===\n"); - - // 1. 检查当前路由 - const pages = getCurrentPages(); - const currentPage = pages[pages.length - 1]; - console.log("1. 当前路由信息:"); - console.log(" - route:", currentPage?.route); - console.log(" - options:", currentPage?.options); - console.log(""); - - // 2. 检查 Vue 组件实例(寻找 AdminLayout) - console.log("2. 查找 AdminLayout 组件实例:"); - try { - // 通过 DOM 查找 AdminLayout 的根元素 - const layoutRoot = document.querySelector(".layout-root"); - if (layoutRoot) { - console.log(" ✓ 找到 .layout-root DOM 元素"); - - // 尝试获取 Vue 实例 - const vueInstance = layoutRoot.__vueParentComponent || layoutRoot.__vue__; - if (vueInstance) { - console.log(" ✓ 找到 Vue 实例"); - - // 检查 props - const props = vueInstance.props || vueInstance.propsData; - console.log(" - currentPage prop:", props?.currentPage); - - // 检查内部状态 - const setupState = vueInstance.setupState || vueInstance.data; - if (setupState) { - console.log( - " - activeMenuId:", - setupState.activeMenuId?.value || setupState.activeMenuId, - ); - console.log( - " - activeSubId:", - setupState.activeSubId?.value || setupState.activeSubId, - ); - console.log( - " - activeGroups length:", - (setupState.activeGroups?.value || setupState.activeGroups)?.length, - ); - } - } else { - console.log(" ✗ 未找到 Vue 实例(可能是渲染问题)"); - } - } else { - console.log(" ✗ 未找到 .layout-root DOM 元素"); - console.log(" → AdminLayout 组件可能未被渲染!"); - } - } catch (e) { - console.log(" ✗ 检查过程出错:", e.message); - } - console.log(""); - - // 3. 检查 AdminSubSider - console.log("3. 检查二级侧边栏:"); - const subSider = document.querySelector(".sub-sider"); - if (subSider) { - console.log(" ✓ 找到 .sub-sider DOM 元素"); - console.log( - " - 是否可见:", - getComputedStyle(subSider).display !== "none", - ); - } else { - console.log(" ✗ 未找到 .sub-sider DOM 元素"); - console.log(' → 可能是因为 v-if="activeGroups.length > 0" 条件不满足'); - } - console.log(""); - - // 4. 检查控制台错误 - console.log("4. 建议排查步骤:"); - console.log(" a) 打开 Vue DevTools 查看组件树"); - console.log( - ' b) 检查是否有 "Failed to resolve component: AdminLayout" 错误', - ); - console.log(" c) 检查 system-info.uvue 是否正确导入了 AdminLayout"); - console.log(" d) 检查 menu.uts 中 system-info 的配置"); - console.log(" e) 检查网络请求,确保所有资源加载成功"); - console.log(""); - - // 5. 模拟 nav 匹配逻辑 - console.log('5. 模拟导航匹配 (currentPage="system-info"):'); - console.log(" 根据 nav.uts 逻辑,应该匹配到:"); - console.log(' - activeMenuId: "maintain"'); - console.log(' - activeSubId: "system-info"'); - console.log(' - 这应该显示 "维护" 菜单的二级侧边栏'); - console.log(""); - - console.log("=== 诊断完成 ==="); - console.log("如果 AdminLayout 未渲染,请检查:"); - console.log( - "1. system-info.uvue 文件中是否有 + + diff --git a/pages/mall/consumer/address-list.uvue b/pages/mall/consumer/address-list.uvue index 67c6133d..9938dd2a 100644 --- a/pages/mall/consumer/address-list.uvue +++ b/pages/mall/consumer/address-list.uvue @@ -36,6 +36,7 @@ diff --git a/pages/mall/consumer/cart copy.uvue b/pages/mall/consumer/cart copy.uvue new file mode 100644 index 00000000..c8506011 --- /dev/null +++ b/pages/mall/consumer/cart copy.uvue @@ -0,0 +1,1435 @@ + + + + + + diff --git a/pages/mall/consumer/cart.uvue b/pages/mall/consumer/cart.uvue index 69346032..f0a56a63 100644 --- a/pages/mall/consumer/cart.uvue +++ b/pages/mall/consumer/cart.uvue @@ -82,6 +82,32 @@ + + + + + + + + 全选 + + + + + + 合计: + ¥{{ totalPrice }} + + + + + + + @@ -111,8 +137,8 @@ - - + + - @@ -137,13 +161,14 @@ - + --> + + diff --git a/pages/mall/consumer/category - 副本.uvue b/pages/mall/consumer/category - 副本.uvue index d217ab27..5c02cd56 100644 --- a/pages/mall/consumer/category - 副本.uvue +++ b/pages/mall/consumer/category - 副本.uvue @@ -1,131 +1,1419 @@ - - \ No newline at end of file diff --git a/pages/mall/consumer/category.uvue b/pages/mall/consumer/category.uvue index 5c02cd56..a26780fb 100644 --- a/pages/mall/consumer/category.uvue +++ b/pages/mall/consumer/category.uvue @@ -111,320 +111,94 @@ + + diff --git a/pages/mall/consumer/category药品.uvue b/pages/mall/consumer/category药品.uvue new file mode 100644 index 00000000..ec734cdf --- /dev/null +++ b/pages/mall/consumer/category药品.uvue @@ -0,0 +1,1131 @@ + + + + + diff --git a/pages/mall/consumer/checkout copy 2.uvue b/pages/mall/consumer/checkout copy 2.uvue new file mode 100644 index 00000000..3c744516 --- /dev/null +++ b/pages/mall/consumer/checkout copy 2.uvue @@ -0,0 +1,1733 @@ + +