253 lines
7.9 KiB
Plaintext
253 lines
7.9 KiB
Plaintext
<!-- 商家端 - 店铺编辑页面 -->
|
|
<template>
|
|
<view class="shop-edit-page">
|
|
<view class="section">
|
|
<view class="section-title">店铺信息</view>
|
|
|
|
<view class="form-item">
|
|
<text class="label">店铺名称 *</text>
|
|
<input class="input" v-model="shop.shop_name" placeholder="请输入店铺名称" maxlength="50"/>
|
|
</view>
|
|
|
|
<view class="form-item">
|
|
<text class="label">店铺Logo</text>
|
|
<view class="logo-uploader" @click="chooseLogo">
|
|
<image v-if="shop.shop_logo" :src="shop.shop_logo" class="logo-preview" mode="aspectFill"/>
|
|
<view v-else class="logo-placeholder">+</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="form-item">
|
|
<text class="label">店铺Banner</text>
|
|
<view class="banner-uploader" @click="chooseBanner">
|
|
<image v-if="shop.shop_banner" :src="shop.shop_banner" class="banner-preview" mode="aspectFill"/>
|
|
<view v-else class="banner-placeholder">点击上传店铺Banner</view>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="form-item">
|
|
<text class="label">店铺简介</text>
|
|
<textarea class="textarea" v-model="shop.description" placeholder="请输入店铺简介" maxlength="500"/>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="section">
|
|
<view class="section-title">联系方式</view>
|
|
|
|
<view class="form-item">
|
|
<text class="label">联系人</text>
|
|
<input class="input" v-model="shop.contact_name" placeholder="请输入联系人姓名"/>
|
|
</view>
|
|
|
|
<view class="form-item">
|
|
<text class="label">联系电话</text>
|
|
<input class="input" v-model="shop.contact_phone" type="number" placeholder="请输入联系电话"/>
|
|
</view>
|
|
</view>
|
|
|
|
<view class="submit-bar">
|
|
<view class="submit-btn" @click="saveShop">保存</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script lang="uts">
|
|
import supa from '@/components/supadb/aksupainstance.uts'
|
|
|
|
export default {
|
|
data() {
|
|
return {
|
|
merchantId: '',
|
|
shop: {
|
|
id: '',
|
|
shop_name: '',
|
|
shop_logo: '',
|
|
shop_banner: '',
|
|
description: '',
|
|
contact_name: '',
|
|
contact_phone: ''
|
|
}
|
|
}
|
|
},
|
|
|
|
onLoad() {
|
|
this.initMerchantId()
|
|
},
|
|
|
|
methods: {
|
|
async initMerchantId() {
|
|
try {
|
|
const session = supa.getSession()
|
|
if (session != null && session.user != null) {
|
|
this.merchantId = session.user.getString('id') || ''
|
|
}
|
|
if (!this.merchantId) {
|
|
this.merchantId = uni.getStorageSync('user_id') || ''
|
|
}
|
|
this.loadShop()
|
|
} catch (e) {
|
|
console.error('获取商户ID失败:', e)
|
|
}
|
|
},
|
|
|
|
async loadShop() {
|
|
try {
|
|
const response = await supa
|
|
.from('ml_shops')
|
|
.select('*')
|
|
.eq('merchant_id', this.merchantId)
|
|
.limit(1)
|
|
.execute()
|
|
|
|
if (response.error != null || !response.data || (response.data as any[]).length === 0) {
|
|
return
|
|
}
|
|
|
|
const rawData = (response.data as any[])[0] as UTSJSONObject
|
|
this.shop = {
|
|
id: rawData.getString('id') || '',
|
|
shop_name: rawData.getString('shop_name') || '',
|
|
shop_logo: rawData.getString('shop_logo') || '',
|
|
shop_banner: rawData.getString('shop_banner') || '',
|
|
description: rawData.getString('description') || '',
|
|
contact_name: rawData.getString('contact_name') || '',
|
|
contact_phone: rawData.getString('contact_phone') || ''
|
|
}
|
|
} catch (e) {
|
|
console.error('加载店铺失败:', e)
|
|
}
|
|
},
|
|
|
|
chooseLogo() {
|
|
uni.chooseImage({
|
|
count: 1,
|
|
success: (res) => {
|
|
this.shop.shop_logo = res.tempFilePaths[0]
|
|
}
|
|
})
|
|
},
|
|
|
|
chooseBanner() {
|
|
uni.chooseImage({
|
|
count: 1,
|
|
success: (res) => {
|
|
this.shop.shop_banner = res.tempFilePaths[0]
|
|
}
|
|
})
|
|
},
|
|
|
|
async uploadImageToSupa(localPath: string): Promise<string> {
|
|
if (localPath.startsWith('http://') || localPath.startsWith('https://')) {
|
|
return localPath
|
|
}
|
|
|
|
let ext = '.jpg'
|
|
const dotIndex = localPath.lastIndexOf('.')
|
|
if (dotIndex > -1) {
|
|
ext = localPath.substring(dotIndex).toLowerCase()
|
|
}
|
|
|
|
const uuid = Date.now().toString() + '_' + Math.floor(Math.random() * 1000)
|
|
const remotePath = `shops/${this.merchantId}_${uuid}${ext}`
|
|
|
|
try {
|
|
const uploadResult = await supa.storage.from('zhipao').upload(remotePath, localPath, {})
|
|
if (uploadResult.status == 200 || uploadResult.status == 201) {
|
|
const data = uploadResult.data
|
|
if (data != null) {
|
|
const dataObj = data as UTSJSONObject
|
|
const key = dataObj.getString('Key')
|
|
if (key != null && key != '') {
|
|
return `${supa.baseUrl}/storage/v1/object/public/${key}`
|
|
}
|
|
}
|
|
}
|
|
console.error('上传图片失败:', uploadResult.error)
|
|
return localPath
|
|
} catch (e) {
|
|
console.error('上传图片异常:', e)
|
|
return localPath
|
|
}
|
|
},
|
|
|
|
async saveShop() {
|
|
if (!this.shop.shop_name) {
|
|
uni.showToast({ title: '请输入店铺名称', icon: 'none' })
|
|
return
|
|
}
|
|
|
|
uni.showLoading({ title: '正在上传图片...' })
|
|
|
|
try {
|
|
let finalLogo = this.shop.shop_logo
|
|
if (finalLogo != '' && !finalLogo.startsWith('http')) {
|
|
finalLogo = await this.uploadImageToSupa(finalLogo)
|
|
}
|
|
|
|
let finalBanner = this.shop.shop_banner
|
|
if (finalBanner != '' && !finalBanner.startsWith('http')) {
|
|
finalBanner = await this.uploadImageToSupa(finalBanner)
|
|
}
|
|
|
|
uni.showLoading({ title: '保存中...' })
|
|
|
|
const shopData = {
|
|
shop_name: this.shop.shop_name,
|
|
shop_logo: finalLogo,
|
|
shop_banner: finalBanner,
|
|
description: this.shop.description,
|
|
contact_name: this.shop.contact_name,
|
|
contact_phone: this.shop.contact_phone,
|
|
updated_at: new Date().toISOString()
|
|
}
|
|
|
|
let response
|
|
if (this.shop.id) {
|
|
response = await supa
|
|
.from('ml_shops')
|
|
.update(shopData)
|
|
.eq('id', this.shop.id)
|
|
.execute()
|
|
} else {
|
|
shopData['merchant_id'] = this.merchantId
|
|
shopData['created_at'] = new Date().toISOString()
|
|
response = await supa
|
|
.from('ml_shops')
|
|
.insert(shopData)
|
|
.execute()
|
|
}
|
|
|
|
uni.hideLoading()
|
|
|
|
if (response.error != null) {
|
|
uni.showToast({ title: '保存失败', icon: 'none' })
|
|
return
|
|
}
|
|
|
|
uni.showToast({ title: '保存成功', icon: 'success' })
|
|
setTimeout(() => uni.navigateBack(), 1500)
|
|
} catch (e) {
|
|
uni.hideLoading()
|
|
uni.showToast({ title: '保存失败', icon: 'none' })
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<style>
|
|
.shop-edit-page { background-color: #f5f5f5; min-height: 100vh; padding-bottom: 160rpx; }
|
|
.section { background-color: #fff; margin-bottom: 20rpx; padding: 30rpx; }
|
|
.section-title { font-size: 30rpx; font-weight: bold; color: #333; margin-bottom: 30rpx; padding-bottom: 20rpx; border-bottom: 1rpx solid #f5f5f5; }
|
|
.form-item { margin-bottom: 30rpx; }
|
|
.label { font-size: 28rpx; color: #333; display: block; margin-bottom: 16rpx; }
|
|
.input { height: 72rpx; border: 1rpx solid #e5e5e5; border-radius: 8rpx; padding: 0 20rpx; font-size: 28rpx; }
|
|
.textarea { width: 100%; height: 150rpx; border: 1rpx solid #e5e5e5; border-radius: 8rpx; padding: 20rpx; font-size: 28rpx; box-sizing: border-box; }
|
|
.logo-uploader, .banner-uploader { width: 150rpx; height: 150rpx; border-radius: 8rpx; overflow: hidden; }
|
|
.banner-uploader { width: 100%; height: 200rpx; }
|
|
.logo-preview, .banner-preview { width: 100%; height: 100%; }
|
|
.logo-placeholder, .banner-placeholder { width: 100%; height: 100%; background-color: #f5f5f5; display: flex; align-items: center; justify-content: center; font-size: 40rpx; color: #999; border: 2rpx dashed #ddd; }
|
|
.submit-bar { position: fixed; bottom: 0; left: 0; right: 0; padding: 20rpx 30rpx; padding-bottom: calc(20rpx + env(safe-area-inset-bottom)); background-color: #fff; box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.05); }
|
|
.submit-btn { height: 88rpx; line-height: 88rpx; text-align: center; font-size: 32rpx; font-weight: bold; border-radius: 44rpx; background: linear-gradient(135deg, #007AFF 0%, #5856D6 100%); color: #fff; }
|
|
</style>
|