完成编辑商品信息同步
This commit is contained in:
144
manifest.json
144
manifest.json
@@ -1,74 +1,74 @@
|
||||
{
|
||||
"name": "mall",
|
||||
"appid": "__UNI__YOUR_APP_ID__",
|
||||
"description": "A multi-role e-commerce application.",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": "100",
|
||||
"transformPx": false,
|
||||
"app-plus": {
|
||||
"usingComponents": true,
|
||||
"nvueStyleCompiler": "uni-app",
|
||||
"compilerVersion": 3,
|
||||
"splashscreen": {
|
||||
"alwaysShowBeforeRender": true,
|
||||
"waiting": true,
|
||||
"autoclose": true,
|
||||
"delay": 0
|
||||
},
|
||||
"modules": {},
|
||||
"distribute": {
|
||||
"android": {
|
||||
"permissions": [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.INTERNET\"/>"
|
||||
]
|
||||
},
|
||||
"ios": {},
|
||||
"sdkConfigs": {}
|
||||
}
|
||||
},
|
||||
"quickapp": {},
|
||||
"mp-weixin": {
|
||||
"appid": "",
|
||||
"setting": {
|
||||
"urlCheck": false
|
||||
},
|
||||
"usingComponents": true
|
||||
},
|
||||
"mp-alipay": {
|
||||
"usingComponents": true
|
||||
},
|
||||
"mp-baidu": {
|
||||
"usingComponents": true
|
||||
},
|
||||
"mp-toutiao": {
|
||||
"usingComponents": true
|
||||
},
|
||||
"uniStatistics": {
|
||||
"enable": false
|
||||
},
|
||||
"vueVersion": "3",
|
||||
"uni-app-x": {},
|
||||
"h5": {
|
||||
"title": "mall",
|
||||
"router": {
|
||||
"mode": "hash",
|
||||
"base": "./"
|
||||
}
|
||||
}
|
||||
"name": "mall",
|
||||
"appid": "__UNI__81482FF",
|
||||
"description": "A multi-role e-commerce application.",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": "100",
|
||||
"transformPx": false,
|
||||
"app-plus": {
|
||||
"usingComponents": true,
|
||||
"nvueStyleCompiler": "uni-app",
|
||||
"compilerVersion": 3,
|
||||
"splashscreen": {
|
||||
"alwaysShowBeforeRender": true,
|
||||
"waiting": true,
|
||||
"autoclose": true,
|
||||
"delay": 0
|
||||
},
|
||||
"modules": {},
|
||||
"distribute": {
|
||||
"android": {
|
||||
"permissions": [
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||
"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\"/>",
|
||||
"<uses-permission android:name=\"android.permission.INTERNET\"/>"
|
||||
]
|
||||
},
|
||||
"ios": {},
|
||||
"sdkConfigs": {}
|
||||
}
|
||||
},
|
||||
"quickapp": {},
|
||||
"mp-weixin": {
|
||||
"appid": "",
|
||||
"setting": {
|
||||
"urlCheck": false
|
||||
},
|
||||
"usingComponents": true
|
||||
},
|
||||
"mp-alipay": {
|
||||
"usingComponents": true
|
||||
},
|
||||
"mp-baidu": {
|
||||
"usingComponents": true
|
||||
},
|
||||
"mp-toutiao": {
|
||||
"usingComponents": true
|
||||
},
|
||||
"uniStatistics": {
|
||||
"enable": false
|
||||
},
|
||||
"vueVersion": "3",
|
||||
"uni-app-x": {},
|
||||
"h5": {
|
||||
"title": "mall",
|
||||
"router": {
|
||||
"mode": "hash",
|
||||
"base": "./"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
<view class="product-edit-page">
|
||||
<view class="page-header">
|
||||
<view class="back-link" @click="goBack">
|
||||
<text class="arrow">{"<"}</text>
|
||||
<text class="arrow"><</text>
|
||||
<text class="back-txt">返回</text>
|
||||
</view>
|
||||
<text class="header-title">编辑商品</text>
|
||||
@@ -232,41 +232,76 @@ async function loadCategoryOptions() {
|
||||
|
||||
async function fetchProductDetail(id: string, mId: string) {
|
||||
try {
|
||||
const { data, error } = await supa
|
||||
const res = await supa
|
||||
.from('ml_products')
|
||||
.select('*')
|
||||
.eq('id', id)
|
||||
.eq('merchant_id', mId)
|
||||
.single()
|
||||
.execute()
|
||||
|
||||
if (error) throw error
|
||||
if (data) {
|
||||
formData.value.id = data.id
|
||||
formData.value.name = data.name || ''
|
||||
formData.value.base_price = data.base_price || 0
|
||||
formData.value.available_stock = data.available_stock || 0
|
||||
formData.value.total_stock = data.total_stock || data.available_stock || 0
|
||||
formData.value.status = data.status || 1
|
||||
formData.value.main_image_url = data.main_image_url || ''
|
||||
formData.value.image_urls = data.image_urls || []
|
||||
formData.value.video_urls = data.video_urls || []
|
||||
formData.value.tags = data.tags || []
|
||||
if (res.error != null) {
|
||||
console.error('[ProductEdit] 查询失败:', res.error)
|
||||
uni.showToast({ title: '获取商品信息失败,或者无权限编辑', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
if (data.attributes && typeof data.attributes === 'object') {
|
||||
const attrs = data.attributes as Record<string, any>
|
||||
formData.value.attributes.unit = attrs['unit'] || '件'
|
||||
}
|
||||
|
||||
// Try to map category
|
||||
formData.value.category_id = data.category_id as string || ''
|
||||
if (formData.value.category_id) {
|
||||
const cat = categoryOptions.value.find((c: CategoryOption): boolean => c.id === formData.value.category_id)
|
||||
categoryName.value = cat ? cat.name : '未知分类'
|
||||
// .single() 返回时 data 可能是 UTSJSONObject 或包含一条记录的数组,兼容处理
|
||||
let row : UTSJSONObject | null = null
|
||||
if (res.data != null) {
|
||||
const raw = res.data
|
||||
if (Array.isArray(raw)) {
|
||||
const arr = raw as Array<UTSJSONObject>
|
||||
if (arr.length > 0) row = arr[0] as UTSJSONObject
|
||||
} else {
|
||||
row = raw as UTSJSONObject
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取详情失败', e)
|
||||
uni.showToast({ title: '获取商品信息失败,或者无权限编辑', icon: 'none' })
|
||||
|
||||
if (row == null) {
|
||||
uni.showToast({ title: '未找到该商品', icon: 'none' })
|
||||
return
|
||||
}
|
||||
|
||||
formData.value.id = row.getString('id') ?? ''
|
||||
formData.value.name = row.getString('name') ?? ''
|
||||
formData.value.base_price = row.getNumber('base_price') ?? 0
|
||||
formData.value.available_stock = row.getNumber('available_stock') ?? 0
|
||||
formData.value.total_stock = row.getNumber('total_stock') ?? row.getNumber('available_stock') ?? 0
|
||||
formData.value.status = row.getNumber('status') ?? 1
|
||||
formData.value.main_image_url = row.getString('main_image_url') ?? ''
|
||||
formData.value.category_id = row.getString('category_id') ?? ''
|
||||
|
||||
// image_urls / video_urls / tags 是 JSONB 数组,用 .get() 取原始值再强转
|
||||
const imgRaw = row.get('image_urls')
|
||||
if (imgRaw != null && Array.isArray(imgRaw)) {
|
||||
formData.value.image_urls = imgRaw as string[]
|
||||
}
|
||||
const vidRaw = row.get('video_urls')
|
||||
if (vidRaw != null && Array.isArray(vidRaw)) {
|
||||
formData.value.video_urls = vidRaw as string[]
|
||||
}
|
||||
const tagsRaw = row.get('tags')
|
||||
if (tagsRaw != null && Array.isArray(tagsRaw)) {
|
||||
formData.value.tags = tagsRaw as string[]
|
||||
}
|
||||
|
||||
// attributes JSONB 是对象,用 getJSON 取
|
||||
const attrsRaw = row.getJSON('attributes')
|
||||
if (attrsRaw != null) {
|
||||
formData.value.attributes.unit = attrsRaw.getString('unit') ?? '件'
|
||||
}
|
||||
|
||||
// 同步分类名称
|
||||
if (formData.value.category_id) {
|
||||
const cat = categoryOptions.value.find((c: CategoryOption): boolean => c.id === formData.value.category_id)
|
||||
categoryName.value = cat ? cat.name : ''
|
||||
}
|
||||
|
||||
console.log('[ProductEdit] 加载成功,id=', formData.value.id, 'name=', formData.value.name)
|
||||
} catch (e : any) {
|
||||
console.error('[ProductEdit] 获取详情异常:', e)
|
||||
uni.showToast({ title: '获取商品信息失败', icon: 'none' })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,54 @@ export async function fetchReportRows(reportId: string, params: any): Promise<Ar
|
||||
return Array.isArray(anyData) ? (anyData as Array<UTSJSONObject>) : ([] as Array<UTSJSONObject>)
|
||||
}
|
||||
|
||||
// 供 data-detail.uvue 使用:包含 period 字段的报表信息
|
||||
export type DataDetailReportInfo = {
|
||||
id: string
|
||||
title: string
|
||||
description: string
|
||||
definition: any
|
||||
updated_at: string
|
||||
period: string
|
||||
}
|
||||
|
||||
export async function fetchDataDetailReportInfo(reportId: string): Promise<DataDetailReportInfo | null> {
|
||||
const row = await rpcOrNull('rpc_data_detail_report_info', {
|
||||
p_report_id: reportId
|
||||
} as any)
|
||||
|
||||
if (row == null) return null
|
||||
|
||||
return {
|
||||
id: safeString(row.getAny?.('id')),
|
||||
title: safeString(row.getAny?.('title')),
|
||||
description: safeString(row.getAny?.('description')),
|
||||
definition: row.getAny?.('definition'),
|
||||
updated_at: safeString(row.getAny?.('updated_at')),
|
||||
period: safeString(row.getAny?.('period'))
|
||||
}
|
||||
}
|
||||
|
||||
// 供 data-detail.uvue 使用:支持排序和分页参数
|
||||
export async function fetchDataDetailRows(
|
||||
reportId: string,
|
||||
sortKey: string,
|
||||
sortDir: string,
|
||||
limit: number,
|
||||
offset: number
|
||||
): Promise<Array<UTSJSONObject>> {
|
||||
const result = await rpcOrNull('rpc_data_detail_rows', {
|
||||
p_report_id: reportId,
|
||||
p_sort_key: sortKey,
|
||||
p_sort_dir: sortDir,
|
||||
p_limit: limit,
|
||||
p_offset: offset
|
||||
} as any)
|
||||
|
||||
if (result == null) return []
|
||||
const anyData = result as any
|
||||
return Array.isArray(anyData) ? (anyData as Array<UTSJSONObject>) : ([] as Array<UTSJSONObject>)
|
||||
}
|
||||
|
||||
// 保留调用,但 RPC 是模拟数据
|
||||
export async function fetchDrilldown(reportId: string, itemId: string): Promise<Array<UTSJSONObject>> {
|
||||
return await rpcOrEmptyArray('rpc_data_detail_drill_items', {
|
||||
|
||||
@@ -13,18 +13,13 @@ export default defineConfig({
|
||||
// 生产环境构建配置
|
||||
rollupOptions: {
|
||||
output: {
|
||||
// 手动拆包策略:将第三方库拆分成独立文件,减少首屏主包体积
|
||||
// 将 vue + @dcloudio 合并到同一个 chunk,避免拆包后循环依赖导致 TDZ 错误
|
||||
// ("Cannot access '?' before initialization" in vendor-vue chunk)
|
||||
manualChunks(id) {
|
||||
if (id.includes("node_modules")) {
|
||||
// 将 vue 相关依赖拆分到 vendor-vue
|
||||
if (id.includes("vue")) {
|
||||
if (id.includes("vue") || id.includes("@dcloudio")) {
|
||||
return "vendor-vue";
|
||||
}
|
||||
// 将 dcloudio (uni-app) 相关依赖拆分
|
||||
if (id.includes("@dcloudio")) {
|
||||
return "vendor-uni";
|
||||
}
|
||||
// 其他 node_modules 依赖放入 vendor
|
||||
return "vendor";
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user