diff --git a/.env.development b/.env.development index 56c8d55..06cec22 100644 --- a/.env.development +++ b/.env.development @@ -9,6 +9,6 @@ VUE_APP_BASE_API = '' # 路由懒加载 VUE_CLI_BABEL_TRANSPILE_MODULES = true - -VUE_APP_BASE_API = 'http://127.0.0.1:30313' +VUE_APP_BASE_API = 'http://134.175.126.60:30313' +# VUE_APP_BASE_API = 'http://127.0.0.1:30313' port = 8888 diff --git a/src/App.vue b/src/App.vue index 12df51d..4a11e6a 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,16 +1,16 @@ diff --git a/src/views/system/xbmessage/index.vue b/src/views/system/xbmessage/index.vue index 50eeaa8..f0b779f 100644 --- a/src/views/system/xbmessage/index.vue +++ b/src/views/system/xbmessage/index.vue @@ -197,6 +197,8 @@ @@ -282,6 +284,8 @@ import { listXbmessage, delXbmessage, getGroupNameOptions } from "@/api/system/xbmessage"; import { parseTime } from "@/utils/ruoyi"; import PublishDialog from '@/components/PublishDialog.vue' +import { generatePromotionContent, createProductByPromotion, getProvinces, getCities, getAreas, getCategories, getUsernames, getERPAccounts, getProperties } from "@/api/system/jdorder"; +import { addToFavorites, getBySkuid } from "@/api/system/favoriteProduct"; export default { name: "Xbmessage", @@ -319,7 +323,124 @@ export default { // 群名称选项 groupNameOptions: [], publishDialogVisible: false, - publishInitialData: {} + publishInitialData: {}, + // 一键转链相关 + quickLinkVisible: false, + quickLinkProduct: null, + quickLinkResult: null, + parsedQuickLinkResult: null, + activeQuickLinkTab: 0, + activeQuickLinkWenanTab: {}, + quickLinkLoading: false, + // 发品相关 + quickLinkPublishDialog: { + visible: false, + loading: false, + wenanOptions: [], + productImages: [], + form: { + appid: '', + wenanIndex: 0, + title: '', + content: '', + extraImagesText: '', + whiteImages: '', + serviceSupport: ['NFR'], + userName: '', + province: 440000, + city: 440400, + district: 440402, + price: null, + originalPrice: null, + expressFee: 0, + stock: 999, + outerId: '', + itemBizType: 2, + spBizType: 3, + channelCatId: '', + channelPvJson: '', + stuffStatus: 100, + }, + rules: { + title: [{ required: true, message: '请输入标题', trigger: 'blur' }], + content: [{ required: true, message: '请输入文案内容', trigger: 'blur' }], + userName: [{ required: true, message: '请输入闲鱼会员名', trigger: 'blur' }], + price: [{ required: true, message: '请输入价格', trigger: 'blur' }], + expressFee: [{ required: true, message: '请输入运费', trigger: 'blur' }], + stock: [{ required: true, message: '请输入库存', trigger: 'blur' }], + itemBizType: [{ required: true, message: '请选择商品类型', trigger: 'change' }], + spBizType: [{ required: true, message: '请选择行业类型', trigger: 'change' }], + channelCatId: [{ required: true, message: '请选择类目', trigger: 'change' }] + } + }, + // 地区选项 + regionOptions: { + provinces: [], + cities: [], + areas: [] + }, + // 类目选项 + categoryOptions: [], + categoryLoading: false, + // 会员名选项 + userNameOptions: [], + userNameLoading: false, + // ERP账号选项 + erpAccountsOptions: [], + erpAccountLoading: false, + // 属性选项 + pvOptions: [], + selectedPv: {}, + // 商品类型选项 + itemBizTypeOptions: [ + { label: '普通商品', value: 2 }, + { label: '已验货', value: 0 }, + { label: '验货宝', value: 10 }, + { label: '闲鱼优品', value: 19 }, + { label: '闲鱼特卖', value: 24 }, + { label: '品牌捡漏', value: 26 } + ], + // 行业类型选项 + spBizTypeOptions: [ + { label: '手机', value: 1 }, + { label: '时尚', value: 2 }, + { label: '家电', value: 3 }, + { label: '乐器', value: 8 }, + { label: '数码3C', value: 9 }, + { label: '奢品', value: 16 }, + { label: '母婴', value: 17 }, + { label: '美妆', value: 18 }, + { label: '珠宝', value: 19 }, + { label: '游戏', value: 20 }, + { label: '家居', value: 21 }, + { label: '虚拟', value: 22 }, + { label: '图书', value: 24 }, + { label: '食品', value: 27 }, + { label: '玩具', value: 28 }, + { label: '其他', value: 99 } + ], + // 成色选项 + stuffStatusOptions: [ + { label: '不传', value: null }, + { label: '全新', value: 100 }, + { label: '99新', value: 99 }, + { label: '95新', value: 95 }, + { label: '9成新', value: 90 }, + { label: '8成新', value: 80 }, + { label: '7成新', value: 70 }, + { label: '6成新', value: 60 }, + { label: '5成新', value: 50 } + ], + // 服务支持选项 + serviceSupportOptions: [ + { label: '七天无理由退货', value: 'SDR' }, + { label: '描述不符包邮退', value: 'NFR' }, + { label: '描述不符全额退(虚拟)', value: 'VNR' }, + { label: '10分钟极速发货(虚拟)', value: 'FD_10MS' }, + { label: '24小时极速发货', value: 'FD_24HS' }, + { label: '48小时极速发货', value: 'FD_48HS' }, + { label: '正品保障', value: 'FD_GPA' } + ] }; }, created() { @@ -583,6 +704,857 @@ export default { this.download('system/xbmessage/export', { ...this.queryParams }, `xbmessage_${new Date().getTime()}.xlsx`) + }, + /** 一键转链 */ + openQuickLink(message) { + this.quickLinkProduct = message; + this.quickLinkResult = null; + this.parsedQuickLinkResult = null; + this.activeQuickLinkTab = 0; + this.activeQuickLinkWenanTab = {}; + this.quickLinkVisible = true; + }, + /** 生成转链内容 */ + generateQuickLink() { + this.quickLinkLoading = true; + this.$axios.post('/api/quickLink/generate', { + skuName: this.quickLinkProduct.skuName, + shopName: this.getJsonValue(this.quickLinkProduct.jsonQueryResult, 'shopInfo.shopName'), + firstPrice: this.quickLinkProduct.firstPrice, + commission: this.getJsonValue(this.quickLinkProduct.jsonQueryResult, 'commissionInfo.commission'), + commissionShare: this.getJsonValue(this.quickLinkProduct.jsonQueryResult, 'commissionInfo.commissionShare'), + spuid: this.getJsonValue(this.quickLinkProduct.jsonQueryResult, 'spuid'), + url: this.getJsonValue(this.quickLinkProduct.jsonQueryResult, 'url'), + wenan: this.quickLinkProduct.wenan, // 假设wenan是父消息的wenan + images: this.quickLinkProduct.images, // 假设images是父消息的images + }).then(response => { + this.quickLinkResult = response.data.result; + this.parsedQuickLinkResult = this.parseQuickLinkResult(this.quickLinkResult); + this.activeQuickLinkWenanTab = {}; // 重置文案版本tab + this.quickLinkLoading = false; + }).catch(error => { + this.quickLinkLoading = false; + this.$modal.msgError('生成转链内容失败: ' + error.message); + }); + }, + /** 解析转链结果 */ + parseQuickLinkResult(result) { + try { + const parsed = JSON.parse(result); + if (Array.isArray(parsed)) { + return parsed.map(item => ({ + ...item, + wenan: item.wenan || [] // 确保wenan存在 + })); + } + return []; + } catch (e) { + return []; + } + }, + /** 复制文本 */ + handleCopyText(text) { + this.$copyText(text).then(() => { + this.$modal.msgSuccess('复制成功'); + }).catch(() => { + this.$modal.msgError('复制失败'); + }); + }, + /** 复制图片URL */ + handleCopyImageUrl(url) { + this.$copyText(url).then(() => { + this.$modal.msgSuccess('复制成功'); + }).catch(() => { + this.$modal.msgError('复制失败'); + }); + }, + /** 预览图片 */ + handlePreviewImage(url) { + this.$previewImage({ + images: [url], + initialIndex: 0, + onClose: () => { + console.log('图片预览关闭'); + } + }); + }, + /** 打开发品对话框 */ + openQuickLinkPublish(product, productIndex) { + // 保存当前商品信息,用于发品成功后添加到常用商品 + this.currentXbMessageItem = product; + + this.quickLinkPublishDialog.form.title = product.skuName || '新品'; + this.quickLinkPublishDialog.form.content = product.wenan && product.wenan.length > 0 ? product.wenan[0].content : ''; + this.quickLinkPublishDialog.form.productImages = product.images || []; + this.quickLinkPublishDialog.form.extraImagesText = ''; + this.quickLinkPublishDialog.form.whiteImages = ''; + this.quickLinkPublishDialog.form.serviceSupport = []; + this.quickLinkPublishDialog.form.userName = ''; + this.quickLinkPublishDialog.form.province = null; + this.quickLinkPublishDialog.form.city = null; + this.quickLinkPublishDialog.form.district = null; + this.quickLinkPublishDialog.form.price = null; + this.quickLinkPublishDialog.form.originalPrice = null; + this.quickLinkPublishDialog.form.expressFee = null; + this.quickLinkPublishDialog.form.stock = null; + this.quickLinkPublishDialog.form.outerId = ''; + this.quickLinkPublishDialog.form.itemBizType = null; + this.quickLinkPublishDialog.form.spBizType = null; + this.quickLinkPublishDialog.form.channelCatId = null; + this.quickLinkPublishDialog.form.channelPvJson = ''; + this.quickLinkPublishDialog.form.stuffStatus = null; + this.quickLinkPublishDialog.wenanOptions = product.wenan || []; + this.quickLinkPublishDialog.productImages = product.images || []; + this.quickLinkPublishDialog.visible = true; + this.quickLinkPublishDialog.form.wenanIndex = 0; // 默认选中第一个文案版本 + this.quickLinkPublishDialog.form.appid = ''; // 清空账号 + this.quickLinkPublishDialog.form.userName = ''; // 清空会员名 + this.quickLinkPublishDialog.form.province = null; // 清空省市区 + this.quickLinkPublishDialog.form.city = null; + this.quickLinkPublishDialog.form.district = null; + this.quickLinkPublishDialog.form.price = null; + this.quickLinkPublishDialog.form.originalPrice = null; + this.quickLinkPublishDialog.form.expressFee = null; + this.quickLinkPublishDialog.form.stock = null; + this.quickLinkPublishDialog.form.outerId = ''; + this.quickLinkPublishDialog.form.itemBizType = null; + this.quickLinkPublishDialog.form.spBizType = null; + this.quickLinkPublishDialog.form.channelCatId = null; + this.quickLinkPublishDialog.form.channelPvJson = ''; + this.quickLinkPublishDialog.form.stuffStatus = null; + this.selectedPv = {}; + }, + /** 发品 */ + submitQuickLinkPublish() { + this.$refs.quickLinkPublishForm.validate(valid => { + if (valid) { + this.quickLinkPublishDialog.loading = true; + const payload = { + appid: this.quickLinkPublishDialog.form.appid || undefined, + title: this.quickLinkPublishDialog.form.title || undefined, + content: this.quickLinkPublishDialog.form.content || undefined, + images: this.quickLinkPublishDialog.form.productImages.filter(img => img.selected).map(img => img.url) || [], + extraImages: this.quickLinkPublishDialog.form.extraImagesText.split('\n').filter(url => url.trim() && url.trim().startsWith('http')) || [], + whiteImages: this.quickLinkPublishDialog.form.whiteImages ? [this.quickLinkPublishDialog.form.whiteImages] : [], + serviceSupport: (this.quickLinkPublishDialog.form.serviceSupport && this.quickLinkPublishDialog.form.serviceSupport.length) ? this.quickLinkPublishDialog.form.serviceSupport.join(',') : undefined, + userName: this.quickLinkPublishDialog.form.userName || undefined, + province: this.quickLinkPublishDialog.form.province || undefined, + city: this.quickLinkPublishDialog.form.city || undefined, + district: this.quickLinkPublishDialog.form.district || undefined, + price: this.cents(this.quickLinkPublishDialog.form.price) || undefined, + originalPrice: this.quickLinkPublishDialog.form.originalPrice != null ? this.cents(this.quickLinkPublishDialog.form.originalPrice) : undefined, + expressFee: this.cents(this.quickLinkPublishDialog.form.expressFee) || undefined, + stock: this.quickLinkPublishDialog.form.stock || undefined, + outerId: this.quickLinkPublishDialog.form.outerId || undefined, // 如果为空,后端自动生成 + skuid: this.currentXbMessageItem?.skuid || undefined, // 传递skuid给后端 + itemBizType: this.quickLinkPublishDialog.form.itemBizType || undefined, + spBizType: this.quickLinkPublishDialog.form.spBizType || undefined, + channelCatId: this.quickLinkPublishDialog.form.channelCatId || undefined, + channelPvJson: this.quickLinkPublishDialog.form.channelPvJson || undefined, + stuffStatus: this.quickLinkPublishDialog.form.stuffStatus || undefined, + }; + + createProductByPromotion(payload).then(response => { + this.quickLinkPublishDialog.loading = false; + if (response.code === 200) { + // 发品成功,弹窗显示商品ID、状态和商家编码 + const productId = response.data.product_id; + const productStatus = response.data.product_status; + const outerId = response.data.outer_id || response.data.outerId || ''; + + let successMsg = `发品提交成功!商品ID: ${productId}, 状态: ${productStatus}`; + if (outerId) { + successMsg += `, 商家编码: ${outerId}`; + } + + this.$modal.msgSuccess(successMsg); + + // 自动添加到常用商品 + this.addToFavoritesAfterPublish(productId, productStatus, outerId); + + this.quickLinkPublishDialog.visible = false; + } else { + this.$modal.msgError(response.msg || '发品失败'); + } + }).catch(error => { + this.quickLinkPublishDialog.loading = false; + console.error('发品失败', error); + this.$modal.msgError('发品失败,请稍后重试'); + }); + } + }); + }, + /** 复制原始转链数据 */ + handleCopyQuickLinkResult() { + this.$copyText(this.quickLinkResult).then(() => { + this.$modal.msgSuccess('复制成功'); + }).catch(() => { + this.$modal.msgError('复制失败'); + }); + }, + /** 选择所有图片 */ + selectAllQuickLinkImages(selected) { + this.quickLinkPublishDialog.productImages.forEach(img => { + img.selected = selected; + }); + }, + /** 反选图片 */ + invertQuickLinkSelection() { + this.quickLinkPublishDialog.productImages.forEach(img => { + img.selected = !img.selected; + }); + }, + /** 切换文案版本 */ + onQuickLinkWenanChange(index) { + this.quickLinkPublishDialog.form.wenanIndex = index; + }, + /** 切换闲管家账号 */ + onQuickLinkAppidChange(appid) { + this.quickLinkPublishDialog.form.appid = appid; + this.loadUserNameOptions(appid); + }, + /** 加载会员名选项 */ + loadUserNameOptions(appid) { + this.userNameLoading = true; + getUsernames({ pageNum: 1, pageSize: 200, appid }).then(response => { + if (response.code === 200) this.userNameOptions = response.data || []; + else this.$modal.msgError(response.msg || '加载会员名失败'); + this.userNameLoading = false; + }).catch(error => { + this.$modal.msgError('加载会员名失败'); + this.userNameLoading = false; + }); + }, + /** 切换省 */ + async onQuickLinkProvinceChange(province) { + this.quickLinkPublishDialog.form.city = null; + this.quickLinkPublishDialog.form.district = null; + this.regionOptions.areas = []; + await this.loadCityOptions(province); + }, + /** 加载市选项 */ + async loadCityOptions(province) { + this.regionOptions.cities = []; + if (province) { + try { + const response = await getCities(province); + if (response.code === 200) { + this.regionOptions.cities = response.data || []; + // 如果当前选中的城市不在新加载的城市列表中,清空城市和区县选择 + if (this.quickLinkPublishDialog.form.city && + !this.regionOptions.cities.find(city => city.value === this.quickLinkPublishDialog.form.city)) { + this.quickLinkPublishDialog.form.city = null; + this.quickLinkPublishDialog.form.district = null; + this.regionOptions.areas = []; + } + } else { + this.$modal.msgError(response.msg || '加载市失败'); + } + } catch (error) { + this.$modal.msgError('加载市失败'); + } + } + }, + /** 切换市 */ + async onQuickLinkCityChange(city) { + this.quickLinkPublishDialog.form.district = null; + await this.loadDistrictOptions(this.quickLinkPublishDialog.form.province, city); + }, + /** 加载区选项 */ + async loadDistrictOptions(province, city) { + this.regionOptions.areas = []; + if (province && city) { + try { + const response = await getAreas(province, city); + if (response.code === 200) { + this.regionOptions.areas = response.data || []; + // 如果当前选中的区县不在新加载的区县列表中,清空区县选择 + if (this.quickLinkPublishDialog.form.district && + !this.regionOptions.areas.find(area => area.value === this.quickLinkPublishDialog.form.district)) { + this.quickLinkPublishDialog.form.district = null; + } + } else { + this.$modal.msgError(response.msg || '加载区失败'); + } + } catch (error) { + this.$modal.msgError('加载区失败'); + } + } + }, + /** 切换区 */ + onQuickLinkDistrictChange(district) { + this.quickLinkPublishDialog.form.district = district; + }, + /** 切换商品类型 */ + onQuickLinkItemBizTypeChange(itemBizType) { + this.quickLinkPublishDialog.form.channelPvJson = ''; // 清空属性 + this.selectedPv = {}; + this.loadCategoryOptions(itemBizType); + }, + /** 切换行业类型 */ + onQuickLinkSpBizTypeChange(spBizType) { + this.quickLinkPublishDialog.form.channelPvJson = ''; // 清空属性 + this.selectedPv = {}; + }, + /** 加载类目选项 */ + loadCategoryOptions(itemBizType) { + this.categoryOptions = []; + this.categoryLoading = true; + const params = { + itemBizType, + spBizType: this.quickLinkPublishDialog.form.spBizType, + appid: this.quickLinkPublishDialog.form.appid + }; + getCategories(params).then(response => { + if (response.code === 200) this.categoryOptions = response.data || []; + else this.$modal.msgError(response.msg || '加载类目失败'); + this.categoryLoading = false; + }).catch(error => { + this.$modal.msgError('加载类目失败'); + this.categoryLoading = false; + }); + }, + /** 加载属性选项 */ + loadQuickLinkProperties() { + this.quickLinkPublishDialog.pvOptions = []; + this.selectedPv = {}; + if (this.quickLinkPublishDialog.form.channelCatId) { + this.$axios.get('/api/property/options', { params: { channelCatId: this.quickLinkPublishDialog.form.channelCatId } }).then(response => { + this.quickLinkPublishDialog.pvOptions = response.data || []; + }).catch(error => { + this.$modal.msgError('加载属性失败: ' + error.message); + }); + } + }, + /** 切换属性 */ + onQuickLinkPvChange(value) { + this.selectedPv[this.quickLinkPublishDialog.form.channelCatId] = value; + }, + /** 切换成色 */ + onQuickLinkStuffStatusChange(stuffStatus) { + this.quickLinkPublishDialog.form.stuffStatus = stuffStatus; + }, + /** 切换服务项 */ + onQuickLinkServiceSupportChange(serviceSupport) { + this.quickLinkPublishDialog.form.serviceSupport = serviceSupport; + }, + /** 切换会员名 */ + onQuickLinkUserNameChange(userName) { + this.quickLinkPublishDialog.form.userName = userName; + }, + + /** 打开一键转链弹窗 */ + openQuickLink(child) { + this.quickLinkProduct = child; + this.quickLinkResult = null; + this.parsedQuickLinkResult = null; + this.activeQuickLinkTab = 0; + this.activeQuickLinkWenanTab = {}; + this.quickLinkVisible = true; + }, + + /** 生成转链内容 */ + generateQuickLink() { + if (!this.quickLinkProduct) return; + + this.quickLinkLoading = true; + // 从线报消息中提取商品链接或信息 + const materialUrl = this.getJsonValue(this.quickLinkProduct.jsonQueryResult, 'materialUrl'); + const skuName = this.quickLinkProduct.skuName; + + let inputContent = ''; + if (materialUrl) { + inputContent = materialUrl; + } else if (skuName) { + inputContent = skuName; + } else { + this.$modal.msgError('无法获取商品信息'); + this.quickLinkLoading = false; + return; + } + + generatePromotionContent({ + promotionContent: inputContent + }).then(response => { + this.quickLinkLoading = false; + if (response.code === 200) { + this.quickLinkResult = response.msg || response.data || "转链成功"; + try { + if (typeof this.quickLinkResult === 'string') { + this.parsedQuickLinkResult = JSON.parse(this.quickLinkResult); + } else { + this.parsedQuickLinkResult = this.quickLinkResult; + } + // 初始化每个商品的文案标签页状态 + if (Array.isArray(this.parsedQuickLinkResult)) { + this.parsedQuickLinkResult.forEach((_, index) => { + this.$set(this.activeQuickLinkWenanTab, index, 0); + }); + } + } catch (e) { + console.log('数据解析失败,使用原始数据'); + this.parsedQuickLinkResult = {}; + } + this.$modal.msgSuccess("转链内容生成成功"); + } else { + this.$modal.msgError(response.msg || "转链失败"); + } + }).catch(error => { + this.quickLinkLoading = false; + console.error('转链失败:', error); + this.$modal.msgError("转链失败,请稍后重试"); + }); + }, + + /** 复制转链结果 */ + handleCopyQuickLinkResult() { + if (this.quickLinkResult) { + if (navigator.clipboard) { + navigator.clipboard.writeText(this.quickLinkResult).then(() => { + this.$modal.msgSuccess("复制成功"); + }).catch(() => { + this.fallbackCopyText(this.quickLinkResult); + }); + } else { + this.fallbackCopyText(this.quickLinkResult); + } + } + }, + + /** 复制文案内容 */ + handleCopyText(text) { + if (text) { + if (navigator.clipboard) { + navigator.clipboard.writeText(text).then(() => { + this.$modal.msgSuccess("复制成功"); + }).catch(() => { + this.fallbackCopyText(text); + }); + } else { + this.fallbackCopyText(text); + } + } + }, + + /** 复制图片链接 */ + handleCopyImageUrl(imageUrl) { + if (imageUrl) { + if (navigator.clipboard) { + navigator.clipboard.writeText(imageUrl).then(() => { + this.$modal.msgSuccess("图片链接复制成功"); + }).catch(() => { + this.fallbackCopyText(imageUrl); + }); + } else { + this.fallbackCopyText(imageUrl); + } + } + }, + + /** 预览图片 */ + handlePreviewImage(imageUrl) { + window.open(imageUrl, '_blank'); + }, + + /** 备用复制方法 */ + fallbackCopyText(text) { + const textArea = document.createElement("textarea"); + textArea.value = text; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + try { + document.execCommand('copy'); + this.$modal.msgSuccess("复制成功"); + } catch (err) { + this.$modal.msgError("复制失败"); + } + document.body.removeChild(textArea); + }, + + /** 打开发品弹窗 */ + openQuickLinkPublish(product, productIndex) { + const wenanIndex = this.activeQuickLinkWenanTab[productIndex] || 0; + const wenanContent = product && product.wenan && product.wenan[wenanIndex] ? (product.wenan[wenanIndex].content || '') : ''; + const images = Array.isArray(product.images) ? product.images : []; + const wenanOptions = Array.isArray(product.wenan) ? product.wenan.map((w, i) => ({ label: w.type || `版本${i+1}`, content: w.content || '' })) : []; + + this.quickLinkPublishDialog.wenanOptions = wenanOptions; + this.quickLinkPublishDialog.form = Object.assign({}, this.quickLinkPublishDialog.form, { + title: product.skuName || '', + content: wenanContent, + wenanIndex: wenanIndex, + extraImagesText: '', + whiteImages: '', + serviceSupport: this.quickLinkPublishDialog.form.serviceSupport, + userName: '', + province: this.quickLinkPublishDialog.form.province, + city: this.quickLinkPublishDialog.form.city, + district: this.quickLinkPublishDialog.form.district, + price: null, + originalPrice: null, + expressFee: 0, + stock: this.quickLinkPublishDialog.form.stock, + outerId: '', + itemBizType: this.quickLinkPublishDialog.form.itemBizType, + spBizType: this.quickLinkPublishDialog.form.spBizType, + channelCatId: '', + stuffStatus: this.quickLinkPublishDialog.form.stuffStatus, + channelPvJson: '' + }); + + // 预填原价 + const guessed = this.guessYuanPrice(product); + if (guessed != null) { + this.quickLinkPublishDialog.form.originalPrice = Number(Number(guessed).toFixed(2)); + } + + this.quickLinkPublishDialog.productImages = images.map(u => ({ url: u, selected: true })); + this.quickLinkPublishDialog.visible = true; + this.$nextTick(() => { + if (this.$refs.quickLinkPublishForm) { + this.$refs.quickLinkPublishForm.clearValidate(); + } + // 确保地区数据被加载 + this.ensureRegionDataLoaded(); + }); + }, + + /** 从商品信息中推测原价 */ + guessYuanPrice(product) { + const candidates = [ + product && product.price, + product && product.oriPrice, + product && product.originPrice, + product && product.jdPrice, + product && product.marketPrice, + product && product.opPrice, + ].filter(v => v != null); + + for (const v of candidates) { + const n = Number(v); + if (!Number.isNaN(n) && n > 0) { + return n; + } + } + return null; + }, + + /** 文案版本切换 */ + onQuickLinkWenanChange(val) { + if (this.quickLinkPublishDialog.wenanOptions && this.quickLinkPublishDialog.wenanOptions[val]) { + this.quickLinkPublishDialog.form.content = this.quickLinkPublishDialog.wenanOptions[val].content || ''; + } + }, + + /** 图片选择相关方法 */ + selectAllQuickLinkImages(flag) { + (this.quickLinkPublishDialog.productImages || []).forEach(it => { it.selected = !!flag; }); + }, + + invertQuickLinkSelection() { + (this.quickLinkPublishDialog.productImages || []).forEach(it => { it.selected = !it.selected; }); + }, + + /** 加载省份 */ + async loadProvinces() { + try { + const res = await getProvinces(); + if (res.code === 200) { + this.regionOptions.provinces = res.data || []; + // 如果有默认省份,自动加载对应的城市和区县 + if (this.quickLinkPublishDialog.form.province) { + await this.loadCityOptions(this.quickLinkPublishDialog.form.province); + if (this.quickLinkPublishDialog.form.city) { + await this.loadDistrictOptions(this.quickLinkPublishDialog.form.province, this.quickLinkPublishDialog.form.city); + } + } + } else { + this.$modal.msgError(res.msg || '加载省份失败'); + } + } catch (e) { this.$modal.msgError('加载省份失败'); } + }, + + /** 加载ERP账号 */ + async loadERPAccounts() { + this.erpAccountLoading = true; + try { + const res = await getERPAccounts(); + if (res.code === 200) this.erpAccountsOptions = res.data || []; + else this.$modal.msgError(res.msg || '加载应用失败'); + } catch (e) { this.$modal.msgError('加载应用失败'); } + this.erpAccountLoading = false; + }, + + /** 加载类目 */ + async loadCategories() { + const itemBizType = this.quickLinkPublishDialog.form.itemBizType; + const spBizType = this.quickLinkPublishDialog.form.spBizType; + const appid = this.quickLinkPublishDialog.form.appid; + if (!itemBizType) return; + + this.categoryLoading = true; + try { + const res = await getCategories({ itemBizType, spBizType, appid }); + if (res.code === 200) this.categoryOptions = res.data || []; + else this.$modal.msgError(res.msg || '加载类目失败'); + } catch (e) { this.$modal.msgError('加载类目失败'); } + this.categoryLoading = false; + }, + + /** 加载会员名 */ + async loadUsernames() { + this.userNameLoading = true; + try { + const res = await getUsernames({ pageNum: 1, pageSize: 200, appid: this.quickLinkPublishDialog.form.appid }); + if (res.code === 200) this.userNameOptions = res.data || []; + else this.$modal.msgError(res.msg || '加载会员名失败'); + } catch (e) { this.$modal.msgError('加载会员名失败'); } + this.userNameLoading = false; + }, + + /** 加载属性 */ + async loadQuickLinkProperties() { + const f = this.quickLinkPublishDialog.form; + if (!f.itemBizType || !f.spBizType || !f.channelCatId) { + this.pvOptions = []; this.selectedPv = {}; return; + } + try { + const res = await getProperties({ itemBizType: f.itemBizType, spBizType: f.spBizType, channelCatId: f.channelCatId, appid: f.appid }); + if (res.code === 200) { + this.pvOptions = res.data || []; + const keep = { ...this.selectedPv }; + this.selectedPv = {}; + (this.pvOptions || []).forEach(p => { if (keep[p.propertyId]) this.selectedPv[p.propertyId] = keep[p.propertyId]; }); + } else { + this.$modal.msgError(res.msg || '加载属性失败'); + } + } catch (e) { + this.$modal.msgError('加载属性失败'); + } + }, + + /** 提交发品 */ + submitQuickLinkPublish() { + this.$refs.quickLinkPublishForm.validate(valid => { + if (!valid) return; + + const f = this.quickLinkPublishDialog.form; + const selectedImages = (this.quickLinkPublishDialog.productImages || []) + .filter(it => it.selected) + .map(it => it.url) + .filter(Boolean); + const extraImages = String(f.extraImagesText || '') + .split(/\n+/) + .map(s => s.trim()) + .filter(Boolean); + const images = [...selectedImages, ...extraImages]; + + if (!images.length) { + this.$modal.msgError('请至少选择或填写一张图片'); + return; + } + + let channelPv = undefined; + if (f.channelPvJson && f.channelPvJson.trim()) { + try { channelPv = JSON.parse(f.channelPvJson); } + catch (e) { this.$modal.msgError('属性JSON格式不正确'); return; } + } + + const payload = { + appid: f.appid || undefined, + title: f.title, + content: f.content, + images: images, + whiteImages: f.whiteImages || undefined, + userName: f.userName, + province: f.province, + city: f.city, + district: f.district, + serviceSupport: (f.serviceSupport && f.serviceSupport.length) ? f.serviceSupport.join(',') : undefined, + price: this.cents(f.price), + originalPrice: f.originalPrice != null ? this.cents(f.originalPrice) : undefined, + expressFee: this.cents(f.expressFee), + stock: f.stock, + outerId: f.outerId || undefined, + itemBizType: f.itemBizType, + spBizType: f.spBizType, + channelCatId: f.channelCatId, + stuffStatus: f.stuffStatus || undefined, + channelPv: channelPv + }; + + this.quickLinkPublishDialog.loading = true; + createProductByPromotion(payload).then(res => { + this.quickLinkPublishDialog.loading = false; + if (res.code === 200) { + // 发品成功,弹窗显示商品ID、状态和商家编码 + const productId = res.data.product_id; + const productStatus = res.data.product_status; + const outerId = res.data.outer_id || res.data.outerId || ''; + + let successMsg = `发品提交成功!商品ID: ${productId}, 状态: ${productStatus}`; + if (outerId) { + successMsg += `, 商家编码: ${outerId}`; + } + + this.$modal.msgSuccess(successMsg); + + // 自动添加到常用商品 + this.addToFavoritesAfterPublish(productId, productStatus, outerId); + + this.quickLinkPublishDialog.visible = false; + } else { + this.$modal.msgError(res.msg || '发品失败'); + } + }).catch(err => { + this.quickLinkPublishDialog.loading = false; + console.error('发品失败', err); + this.$modal.msgError('发品失败,请稍后重试'); + }); + }); + }, + + /** 确保地区数据被加载 */ + async ensureRegionDataLoaded() { + // 如果省份数据未加载,先加载省份 + if (this.regionOptions.provinces.length === 0) { + await this.loadProvinces(); + } + + // 如果有省份但城市数据未加载,加载城市 + if (this.quickLinkPublishDialog.form.province && this.regionOptions.cities.length === 0) { + await this.loadCityOptions(this.quickLinkPublishDialog.form.province); + } + + // 如果有省份和城市但区县数据未加载,加载区县 + if (this.quickLinkPublishDialog.form.province && + this.quickLinkPublishDialog.form.city && + this.regionOptions.areas.length === 0) { + await this.loadDistrictOptions(this.quickLinkPublishDialog.form.province, this.quickLinkPublishDialog.form.city); + } + }, + + /** 价格转换(元转分) */ + cents(yuan) { + const n = Number(yuan); + if (Number.isNaN(n)) return undefined; + return Math.round(n * 100); + }, + + /** 发品成功后自动添加到常用商品 */ + async addToFavoritesAfterPublish(productId, productStatus, outerId) { + try { + // 获取当前线报消息项信息 + const currentItem = this.currentXbMessageItem; + if (!currentItem) { + console.warn('无法获取当前线报消息项信息'); + return; + } + + // 构建常用商品数据 + const favoriteData = { + skuid: currentItem.skuid || '', + productName: currentItem.skuName || currentItem.productName || '', + shopName: this.getShopName(currentItem), + shopId: this.getShopId(currentItem), + productUrl: currentItem.materialUrl || currentItem.productUrl || '', + productImage: this.getProductImage(currentItem), + price: currentItem.price || '', + commissionInfo: currentItem.commissionInfo || '', + productId: productId, + productStatus: productStatus, + remark: `自动添加 - 发品时间: ${new Date().toLocaleString()}${outerId ? `, 商家编码: ${outerId}` : ''}` + }; + + // 调用API添加到常用商品 + const res = await addToFavorites(favoriteData); + if (res.code === 200) { + console.log('已自动添加到常用商品'); + } else { + console.warn('自动添加到常用商品失败:', res.msg); + } + } catch (error) { + console.error('自动添加到常用商品出错:', error); + } + }, + + /** 获取店铺名称 */ + getShopName(item) { + if (item.jsonShopInfo) { + try { + const shopInfo = JSON.parse(item.jsonShopInfo); + return shopInfo.shopName || ''; + } catch (e) { + return ''; + } + } + return item.shopName || ''; + }, + + /** 获取店铺ID */ + getShopId(item) { + if (item.jsonShopInfo) { + try { + const shopInfo = JSON.parse(item.jsonShopInfo); + return shopInfo.shopId || ''; + } catch (e) { + return ''; + } + } + return item.shopId || ''; + }, + + /** 获取商品图片 */ + getProductImage(item) { + if (item.jsonQueryResult && item.jsonQueryResult.materialUrl) { + return item.jsonQueryResult.materialUrl; + } + if (item.productImage) { + return item.productImage; + } + return ''; + }, + + /** 添加到常用商品 */ + async addToFavorites(child) { + try { + // 检查是否已经添加到常用 + const existingProduct = await getBySkuid(child.skuid); + if (existingProduct && existingProduct.data) { + this.$modal.msgWarning("该商品已在常用列表中"); + return; + } + + // 构建常用商品数据 + const favoriteData = { + skuid: child.skuid, + productName: child.skuName, + shopName: this.getJsonValue(child.jsonQueryResult, 'shopInfo.shopName') || '', + shopId: this.getJsonValue(child.jsonQueryResult, 'shopInfo.shopId') || '', + productUrl: this.getJsonValue(child.jsonQueryResult, 'materialUrl') || '', + productImage: this.getJsonValue(child.jsonQueryResult, 'imageInfo.mainImage') || '', + price: child.firstPrice || '', + commissionInfo: this.getJsonValue(child.jsonQueryResult, 'commissionInfo.commissionShare') ? + `${this.getJsonValue(child.jsonQueryResult, 'commissionInfo.commissionShare')}%` : '', + category: this.getJsonValue(child.jsonQueryResult, 'categoryInfo.cid3Name') || '', + brand: this.getJsonValue(child.jsonQueryResult, 'brandName') || '', + remark: `来自线报消息: ${child.skuName}`, + isTop: 0, + sortWeight: 0 + }; + + // 添加到常用列表 + const result = await addToFavorites(favoriteData); + if (result.code === 200) { + this.$modal.msgSuccess("已添加到常用商品列表"); + } else { + this.$modal.msgError(result.msg || "添加失败"); + } + } catch (error) { + console.error('添加到常用失败:', error); + this.$modal.msgError("添加失败,请稍后重试"); + } } } }; @@ -615,4 +1587,139 @@ export default { font-weight: bold !important; line-height: 1.6; } + +/* 一键转链相关样式 */ +.img-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); + gap: 15px; +} + +.img-item { + border: 1px solid #e5e5e5; + border-radius: 6px; + padding: 8px; + text-align: center; + transition: all 0.3s ease; +} + +.img-item:hover { + border-color: #409EFF; + box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2); +} + +.img-item img { + width: 100%; + height: 120px; + object-fit: cover; + border-radius: 4px; + cursor: pointer; + transition: transform 0.2s ease; +} + +.img-item img:hover { + transform: scale(1.05); +} + +.img-actions { + display: flex; + justify-content: space-between; + align-items: center; + margin-top: 8px; +} + +.quick-link-dialog .el-dialog__body { + max-height: 75vh; + overflow-y: auto; + padding: 20px; +} + +.quick-link-dialog .el-dialog { + margin: 5vh auto !important; +} + +/* 响应式优化 */ +@media (max-width: 1600px) { + .quick-link-dialog .el-dialog { + width: 95% !important; + } +} + +@media (max-width: 1200px) { + .quick-link-dialog .el-dialog { + width: 98% !important; + } + + .img-grid { + grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); + gap: 12px; + } + + .img-item img { + height: 100px; + } +} + +/* 弹窗内容优化 */ +.quick-link-dialog .el-descriptions { + margin-bottom: 20px; +} + +.quick-link-dialog .el-tabs { + margin-top: 20px; +} + +.quick-link-dialog .el-alert { + margin-bottom: 25px; +} + +/* 发品弹窗优化 */ +.quick-link-dialog .el-form-item { + margin-bottom: 18px; +} + +.quick-link-dialog .el-form-item__label { + font-weight: 500; + color: #303133; +} + +.quick-link-dialog .el-input, +.quick-link-dialog .el-select, +.quick-link-dialog .el-textarea { + width: 100%; +} + +.quick-link-dialog .el-dialog__header { + padding: 20px 20px 10px 20px; + border-bottom: 1px solid #e4e7ed; +} + +.quick-link-dialog .el-dialog__footer { + padding: 15px 20px 20px 20px; + border-top: 1px solid #e4e7ed; + text-align: right; +} + +/* 转链结果展示优化 */ +.quick-link-dialog .el-tabs__content { + padding: 20px 0; +} + +.quick-link-dialog .el-descriptions-item__label { + font-weight: 500; + color: #606266; +} + +.quick-link-dialog .el-descriptions-item__content { + color: #303133; +} + +/* 按钮样式优化 */ +.quick-link-dialog .el-button { + margin-left: 8px; +} + +.quick-link-dialog .el-button:first-child { + margin-left: 0; +} \ No newline at end of file