Compare commits

..

124 Commits

Author SHA1 Message Date
695d27c5cb chore: merge dev/1.0 into main
包含以下修复:
- ai-chat 键盘弹出、输入框闪烁、滚动、WebSocket 等问题
- 小米微信小程序魔方组件布局修复
- 三处 calc() 精度统一避免小米子像素舍入差异
- H5 构建配置优化
2026-05-14 08:43:45 +08:00
cd82ba2f27 fix: 统一 calc() 精度避免小米微信小程序子像素舍入差异
- diy-video-list.vue, diy-goods-list.vue: 删除重复的 3n+3 规则
  (33.33% 精度低于 33.3333333%,且与 3n 规则匹配同一组元素)
- diy-fenxiao-goods-list.vue: 两列布局统一 calc(50% - 10rpx),
  消除第2项 1rpx 的减数差异
2026-05-14 08:42:12 +08:00
698d419525 fix(diy-rubik-cube): 小米微信小程序魔方组件布局修复
- 取消注释 .template-left/.template-right 的 width: 50%,修复小米
  XWeb 引擎 flex-wrap 子像素舍入差异导致的布局错乱
- 重构 calcRowOneLeftOfTwoRight:将 'px' 追加移出主循环,统一在
  第二层循环处理,避免中途字符串转换
- 清理 calcRowOneLeftOfOneTopOfTwoBottom 中的无效空值表达式
- 优化 row1-lt-of2-rt 模板右侧最后一项条件判断 marginBottom
2026-05-13 18:23:56 +08:00
a252d42b62 fix(ai-chat): 消除键盘弹出时输入框闪烁
- 键盘垫高层不再使用 v-if 突然插入,改为始终存在(高度默认为0)
- 添加 CSS transition: height 0.25s ease 平滑过渡动画
2026-05-13 16:38:33 +08:00
69466f410c fix(ai-chat): 修复聊天页面键盘弹出时导航栏上移、输入框不可见、间距问题
- 自定义导航栏 position:absolute 固定在顶部,不随键盘上移
- textarea 设置 adjust-position=false,阻止系统上推页面
- 输入框后方加 spacer 垫高层,键盘弹出时将输入框推至键盘上方
- chat-content 根据平台设置不同 top 值(MP:0 / H5:44px)
- 去掉输入框多余的安全区域内边距
- scroll-view 底部 padding 随键盘高度动态调整
2026-05-13 16:01:15 +08:00
39245dfcac fix(ai-chat): 修复输入框定位及滚动问题并更新客服名称 2026-05-13 14:08:58 +08:00
80b18cee0f feat(ai-chat): 优化加载状态动画与流式消息过渡 2026-05-13 09:19:38 +08:00
b2688dc8a1 fix(ai-chat): 修复历史消息加载逻辑及超时问题 2026-05-13 09:00:20 +08:00
d5ca77e2d8 fix(ai-chat): 跳过健康检查避免服务误判 2026-05-13 08:40:01 +08:00
e789ab2ca3 fix(H5): 从 package.json 读取 UNI_APP_DOMAIN 兜底,确保 H5 发行域名正常注入 2026-05-12 11:39:43 +08:00
5e83771193 chore: 保留H5打包后的源目录 2026-05-12 09:59:43 +08:00
0d18041037 refactor: 使用 Intl.DateTimeFormat 生成时间戳 2026-05-12 08:48:55 +08:00
875cf0b428 feat(ai-chat): 增强Markdown解析及调整聊天气泡布局 2026-05-12 08:30:26 +08:00
e16402c9c1 fix(ai): 修复WebSocket重复回调及意外关闭问题 2026-05-11 17:14:26 +08:00
dee2887026 docs: 更新 readme 反映 H5 自动 ZIP 打包和统一配置方式 2026-05-11 11:56:37 +08:00
6033cc2fa0 feat(vue.config): H5 生产构建后自动打包 ZIP 2026-05-11 10:59:36 +08:00
c1fbabe07b refactor(vue.config): 简化UNI_OUTPUT_DIR逻辑,支持通用H5脚本+读取manifest base 2026-05-11 10:54:36 +08:00
221ef7bb6d refactor: 域名移至package.json脚本env中,config.js零改动 2026-05-11 10:29:33 +08:00
55c1e80ed7 refactor: 用 UNI_SCRIPT + DOMAIN_MAP 替代 #ifdef 环境常量 2026-05-11 10:27:33 +08:00
79202c4542 docs: 更新 package.json 和 readme.md 反映最新构建流程 2026-05-11 10:18:47 +08:00
3bff91e421 refactor: 统一版本信息注入方式
- feat(vue.config): 新增 VersionInjectPlugin,在 webpack emit 钩子中内联注入 __app_version 到 vendor.js / index.html
- refactor(scripts): mp-weixin.patch.js 精简为仅拷贝 site.js + ZIP 打包
- feat(index): 首页连击5次显示构建版本信息
- fix(util): 修复 openWxWorkServiceChat fail 回调语法错误
2026-05-11 09:36:57 +08:00
979384c2d6 feat(index): 新增固定版本触发区,标题不可见时也可连击5次查看版本 2026-05-09 17:27:53 +08:00
504e5322fb fix(scripts): vendor.js注入改为先清理旧行再注入,确保幂等 2026-05-09 17:21:02 +08:00
25fc0a59a8 fix(scripts): version.json改为生成version.js(CommonJS),兼容微信小程序require限制 2026-05-09 17:19:17 +08:00
34e27d0621 feat(index): 首页标题连击5次显示构建版本信息\nfix(scripts): explorer使用spawn避免GUI进程阻塞\nfix(index): version.json运行时读取,不依赖构建时require 2026-05-09 17:14:51 +08:00
913fc90176 feat(scripts): 构建时自动生成 version.json 并注入到 vendor.js 2026-05-09 17:04:12 +08:00
c1bac6d9e8 feat(scripts): ZIP文件名使用Git提交ID替换时间戳 2026-05-09 17:00:38 +08:00
31382a2388 refactor(util): 增加空回调函数 2026-05-09 11:16:30 +08:00
d009077183 update 2026-05-09 09:24:25 +08:00
133eb29a71 Merge branch 'dev/1.0' 2026-05-09 09:22:10 +08:00
a2616c9757 chore: 修改路由base路径为/hwappx/common/ 2026-05-09 09:17:38 +08:00
fb47da8095 refactor(privacy-popup): 优化隐私弹窗逻辑结构 2026-05-09 08:58:48 +08:00
37958cbe39 feat(privacy): 移除隐私弹窗配置检查逻辑 2026-05-09 08:47:24 +08:00
9f53f147ee chore: 移除所有调试日志 2026-05-08 16:09:19 +08:00
2342a14f2e fix(mp-weixin): 将 import 语句改为 require 2026-05-07 17:36:43 +08:00
36b0c22e47 fix: 修复二维码长按识别属性 2026-05-07 16:38:53 +08:00
4a52b9c229 fix(util): 去除URL中的双斜杠 2026-05-07 16:25:37 +08:00
9ec90a906f perf(diy-tab): optimize tab rendering with v-if 2026-05-07 16:14:28 +08:00
e125a5f39c chore: 添加修复长按菜单语法错误的脚本 2026-05-07 15:43:57 +08:00
8c0ec46dd8 style: 统一图片组件属性格式 2026-05-07 15:43:33 +08:00
b65ec35d3c chore: 更新 appid 2026-05-07 15:13:06 +08:00
d113d6125b feat(components): 在图片组件中添加长按显示菜单功能 2026-05-07 15:12:59 +08:00
2f24661cd9 fix(ai-service): 统一用户标识默认值为anonymous 2026-05-06 11:26:10 +08:00
50908a274b refactor(ai-service): 使用getUniacid方法统一获取uniacid 2026-05-06 11:13:08 +08:00
9e68562de5 chore(ai): 增加调试日志输出 2026-05-06 10:53:52 +08:00
8e5561c2a7 refactor(ai-service): 提取域名配置参数以减少重复代码 2026-04-30 16:39:55 +08:00
8d5c543a4f chore:扩大按钮【】 2026-04-28 17:51:54 +08:00
cf411407dd chore:名片可以分享了 2026-04-28 17:35:40 +08:00
86e4be302b chore:商品分类可以分享了 2026-04-28 11:31:32 +08:00
2fd06796e1 chore:加了输入框扩大按钮 2026-04-28 09:59:52 +08:00
60c51e551a chore:修改表情位置 2026-04-28 09:12:15 +08:00
d0d3ac47c6 chore:修改表情位置 2026-04-28 08:59:34 +08:00
af677f6565 chore:资源详情改为商品详情 2026-04-25 16:53:40 +08:00
f889efeb16 chore: 2026-04-25 16:45:41 +08:00
d026bb6180 chore:增加一个后台控制首页弹出的隐私权限 2026-04-25 16:15:17 +08:00
82b856f5d9 chore:表情的布局改为横板 2026-04-25 14:36:31 +08:00
7f33b6948a chore:min-height: 300px; 替换成 min-height: 0px; 2026-04-25 14:26:48 +08:00
3489b89a0b chore:智能客服加了表情 2026-04-25 14:15:03 +08:00
dc4f2769f9 chore:资源详情里的立即咨询可以跳转到智能客服 2026-04-25 11:58:03 +08:00
5cf87e4d56 chore:资源详情的背景设改为绿色 2026-04-25 11:27:32 +08:00
c9ca63cff5 chore:联系我们改为立即质询 2026-04-25 11:09:47 +08:00
a6072f4895 chore: 2026-04-25 10:22:27 +08:00
38947ddc62 chore:立即咨询点击会弹出对话框 2026-04-25 10:09:38 +08:00
cfe83ada38 chore:点击商品分类中的立即咨询不要跳转到智能客服,跳转到资源详情页面 2026-04-25 09:59:45 +08:00
1e9e0ffea8 chore:资源详情智能客服按钮同步智能客服 2026-04-25 09:50:45 +08:00
28acdfb621 chore:红色背景收一些 2026-04-25 09:29:23 +08:00
ad9f1c495b chore:联系我们改为立即质询 2026-04-25 09:22:33 +08:00
7c2a7468e7 chore:调整红色背景 2026-04-25 09:03:13 +08:00
b2051dcf92 chore:立即质询背景改红色 2026-04-25 08:48:06 +08:00
e3c86de84a chore:删除红色的立即质询 2026-04-25 08:42:03 +08:00
6e0eb5d4f3 chore:询底价改为立即咨询 2026-04-25 08:38:15 +08:00
9d186ff094 chore:发送字体按钮调整变大 2026-04-24 16:49:01 +08:00
8611ec4dc3 chore:发送按钮改为微信的发送按钮 2026-04-24 16:38:29 +08:00
89bfd94a07 chore:上传image-config.js 2026-04-24 15:46:42 +08:00
5cf8b7b467 chore:发送按钮调整变大 2026-04-23 15:24:32 +08:00
2cc0162435 chore:输入框不被遮挡了 2026-04-22 11:59:58 +08:00
d8e75a0c9e chore: 2026-04-21 14:15:46 +08:00
8af3c0ccb9 chore:微信小程序真机版本可以运行,微信小程序客服图标显示正常 2026-04-20 17:50:37 +08:00
d8b78168a8 chore:改了头像的地址 2026-04-20 15:44:58 +08:00
7675e8e04d chore: 2026-04-20 09:52:27 +08:00
88d05048a6 chore:长按图片可以识别图中二维码 2026-04-20 09:36:08 +08:00
28a92c0635 chore:ai-service.js 的代码url: 'wss://dev.aigc-quickapp.com/ws/aikefu',被替换 2026-04-18 11:36:18 +08:00
b5a47b8b4e chore:聊天页面的我和时间换位置 2026-04-17 16:03:30 +08:00
4f99e8b5f2 chore:H5的发送按钮变成正圆形 2026-04-17 15:18:31 +08:00
87fc49146c chore:时间居中 2026-04-17 14:19:43 +08:00
826fcfb024 chore:时间和智能助手在同一水平线上 2026-04-17 11:49:33 +08:00
7174d87b79 chore:用户的气泡中商品名称,商品ID,价格都左对齐 2026-04-17 10:13:07 +08:00
4bc747cd9c chore:增加了用户默认头像,自定义头像 2026-04-17 09:48:46 +08:00
e046868665 chore:用户点击自己头像可以自定义头像 2026-04-17 09:21:10 +08:00
19c3ec4f9f chore:小程序输入框向下移动 2026-04-17 08:44:01 +08:00
ffbc15929d chore:智能客服的历史时间回复正常 2026-04-16 14:03:37 +08:00
524280d816 chore:智能助手加了时间 2026-04-16 11:00:50 +08:00
6e736e0733 chore:资源详情页面的智能客服头像变为圆形 2026-04-16 10:02:50 +08:00
4891566793 chore:智能客服改了头像 2026-04-16 09:34:56 +08:00
b02f5fbc21 chore:智能客服换了头像 2026-04-15 17:46:06 +08:00
4f5a300afa chore:H5的智能客服聊天页面上面导航栏自定义的删除 2026-04-15 17:18:22 +08:00
aae6e76797 chore:智能客服聊天不乱窜了 2026-04-15 10:23:43 +08:00
3162d6a9f2 chore:H5的智能客服聊天正常 2026-04-15 09:08:10 +08:00
8010ac45a6 chore:智能客服图标换了 2026-04-14 17:29:17 +08:00
baebba4cef chore:导航栏删除在线客服 2026-04-14 16:30:42 +08:00
1be7155fe8 chore:智能客服的头像换了 2026-04-14 09:42:09 +08:00
611c0b930b chore:删除喜欢不喜欢有帮助没帮助 2026-04-13 17:29:13 +08:00
ec1903519d chore:用户提问和客服回答可以看见了 2026-04-13 09:30:08 +08:00
b1953a020d chore:喜欢不喜欢和👍水平 2026-04-10 15:10:41 +08:00
3ce26322e0 chore: 2026-04-09 16:04:11 +08:00
588ec60948 chore:发送按钮向上调动 2026-04-08 10:10:47 +08:00
962ea124fa chore:退出聊天界面后,在进入聊天页面后没有多余的气泡 2026-04-08 09:14:57 +08:00
0ca0fe3b0d chore:修改了客服样式 2026-04-07 15:21:29 +08:00
cef2b6e02e chore:客服回答不重复 2026-04-07 15:10:26 +08:00
e018f9a8b9 chore:修改H5商品价格样式 2026-03-31 09:38:16 +08:00
def8a6cf6f chore:横竖屏 2026-03-30 14:49:24 +08:00
857f295923 chore:H5和小程序都可以自己分辨横竖屏 2026-03-28 17:38:26 +08:00
50ee885b74 chore:微信小程序实现竖屏是竖屏,横屏是横屏 2026-03-25 14:44:25 +08:00
410f248510 chore:H5视频改比例 2026-03-25 09:39:48 +08:00
ba5fcfaab1 chore:微信小程序的视频改为竖屏播放 2026-03-24 16:43:00 +08:00
5a46bb8d69 chore:智能客服回答不重复 2026-03-19 14:26:32 +08:00
e33ad16d10 chore:商品详情页面右上角有跳转到智能客服 2026-03-17 09:53:24 +08:00
d8ba7ace0f chore:跳转智能客服的更多详情按钮放到商品页面里面 2026-03-16 17:21:33 +08:00
875072bb68 chore:商品可以分享给智能客服进行解答 2026-03-14 10:53:55 +08:00
0912b9b031 chore:智能客服加了商品的图标 2026-03-13 16:41:00 +08:00
7ffe4acc0f chore:隐藏了更多功能,录音图标 2026-03-13 13:57:24 +08:00
4bcf0cbd2d chore:可以正常清空聊天记录 2026-03-12 18:29:11 +08:00
fdf85dfec7 chore:更换头像正常 2026-03-12 18:25:12 +08:00
1d62b37060 chore:头像功能从相册选择功能正常了 2026-03-12 15:09:27 +08:00
192 changed files with 4243 additions and 2197 deletions

View File

@@ -41,13 +41,26 @@ const localDevConfig = ({
'local-2': { // 测试平台 'local-2': { // 测试平台
uniacid: 2, uniacid: 2,
domain: 'http://localhost:8050/', domain: 'http://localhost:8050/',
'47': { // 修改弹窗 },
uniacid: 47, '100': {
domain: 'https://5g.aigc-quickapp.com/', uniacid: 100,
}, domain: 'https://5g.aigc-quickapp.com/',
'2075': { // },
uniacid: 2075, '1': {
domain: 'https://xcx.aigc-quickapp.com/', uniacid: 1,
}, domain: 'https://5g.aigc-quickapp.com/',
})['47']; // 选择要使用的环境配置 },
'115': {
uniacid: 115,
domain: 'https://5g.aigc-quickapp.com/',
},
'47': { // 修改弹窗
uniacid: 47,
domain: 'https://5g.aigc-quickapp.com/',
},
'2075': { //
uniacid: 2075,
domain: 'https://xcx.aigc-quickapp.com/',
},
})['1']; // 选择要使用的环境配置
export default localDevConfig; export default localDevConfig;

View File

@@ -266,7 +266,6 @@
imgUrl: this.$util.img(share_data.imgUrl) imgUrl: this.$util.img(share_data.imgUrl)
}, },
res => { res => {
console.log(res);
} }
); );
} }

View File

@@ -5,6 +5,17 @@ import store from '@/store/index.js'
let currentConversationId = null; let currentConversationId = null;
const CONVERSATION_KEY = 'ai_conversation_id'; const CONVERSATION_KEY = 'ai_conversation_id';
/**
* 获取域名配置参数(避免重复代码)
*/
function getDomainParams() {
return {
imgDomain: Config.imgDomain,
h5Domain: Config.h5Domain,
baseUrl: Config.baseUrl
};
}
// 初始化时从本地读取会话ID // 初始化时从本地读取会话ID
try { try {
const saved = uni.getStorageSync(CONVERSATION_KEY); const saved = uni.getStorageSync(CONVERSATION_KEY);
@@ -16,12 +27,19 @@ try {
} }
export default { export default {
/**
* 获取uniacid
* @returns {number} uniacid
*/
getUniacid() {
return uni.getStorageSync('uniacid') || Config.uniacid; // 从缓存中获取uniacid,或使用默认uniacid
},
/** /**
* 发送普通消息(blocking 模式) * 发送普通消息(blocking 模式)
*/ */
async sendMessage(message, options = {}) { async sendMessage(message, options = {}) {
try { try {
const aiConfig = store.getters.globalAIKefuConfig;
const params = { const params = {
url: '/api/kefu/chat', url: '/api/kefu/chat',
data: { data: {
@@ -31,16 +49,14 @@ export default {
query: message, query: message,
response_mode: 'blocking', // 强制 blocking response_mode: 'blocking', // 强制 blocking
user: store.state.memberInfo?.id || 'anonymous', user: store.state.memberInfo?.id || 'anonymous',
conversation_id: this.getConversationId() || '' conversation_id: this.getConversationId() || '',
...getDomainParams()
}, },
header: { header: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
} }
}; };
console.log('Sending blocking request to:', params.url);
console.log('Request data:', params.data);
const response = await http.sendRequest({ const response = await http.sendRequest({
...params, ...params,
async: false async: false
@@ -52,7 +68,14 @@ export default {
} }
return result; return result;
} catch (error) { } catch (error) {
console.error('Dify API请求失败:', error); console.error('[AI Service] AiChat API请求失败,详细错误:', error);
console.error('[AI Service] 错误堆栈:', error.stack);
// 打印更多信息帮助调试
console.error('[AI Service] store 状态:', {
memberInfo: store.state.memberInfo,
uniacid: this.getUniacid(),
token: store.state.token
});
throw new Error('AI服务暂时不可用,请稍后重试'); throw new Error('AI服务暂时不可用,请稍后重试');
} }
}, },
@@ -63,21 +86,56 @@ export default {
async sendStreamMessage(message, onChunk, onComplete) { async sendStreamMessage(message, onChunk, onComplete) {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const socketTask = wx.connectSocket({ const match = Config.baseUrl.match(/^(?:https?:\/\/|wss?:\/\/)([^\/\s:]+)/);
url: 'wss://dev.aigc-quickapp.com/ws/aikefu', const domain = match ? match[1] : '';
header: {}
}); // 修复 5:Domain 提取失败时提前拒绝
if (!domain) {
const errorMsg = 'WebSocket 域名配置无效';
console.error(errorMsg);
reject(new Error(errorMsg));
if (onComplete) onComplete({ error: errorMsg });
return;
}
const wssUrl = `wss://${domain}/ws/aikefu`;
const socketTask = wx.connectSocket({
url: wssUrl,
header: {}
});
let content = ''; let content = '';
let conversationId = ''; let conversationId = '';
let isAuthenticated = false; let isAuthenticated = false;
let closedNormally = false;
let settled = false;
// 安全地拒绝(防止重复调用)
function safeReject(error) {
if (settled) return;
settled = true;
clearTimeout(timeout);
reject(error);
}
// 安全地完成
function safeResolve(result) {
if (settled) return;
settled = true;
clearTimeout(timeout);
resolve(result);
}
// 安全地触发 onComplete
function safeComplete(result) {
if (onComplete) onComplete(result);
}
socketTask.onOpen(() => { socketTask.onOpen(() => {
console.log('WebSocket 连接成功,开始认证...');
socketTask.send({ socketTask.send({
data: JSON.stringify({ data: JSON.stringify({
action: 'auth', action: 'auth',
uniacid: store.state.uniacid || '1', uniacid: this.getUniacid(),
token: store.state.token || 'test_token', token: store.state.token || 'test_token',
user_id: store.state.memberInfo?.id || 'anonymous' user_id: store.state.memberInfo?.id || 'anonymous'
}) })
@@ -87,51 +145,48 @@ export default {
socketTask.onMessage((res) => { socketTask.onMessage((res) => {
try { try {
const data = JSON.parse(res.data); const data = JSON.parse(res.data);
console.log('收到 WebSocket 消息:', data);
if (data.type === 'auth_success') { if (data.type === 'auth_success') {
console.log('认证成功,发送聊天消息...');
isAuthenticated = true; isAuthenticated = true;
socketTask.send({ socketTask.send({
data: JSON.stringify({ data: JSON.stringify({
action: 'chat', action: 'chat',
uniacid: store.state.uniacid || '1', uniacid: this.getUniacid(),
query: message, query: message,
user_id: store.state.memberInfo?.id || 'anonymous', user_id: store.state.memberInfo?.id || 'anonymous',
conversation_id: this.getConversationId() || '' conversation_id: this.getConversationId() || '',
...getDomainParams()
}) })
}); });
} else if (data.type === 'auth_failed') { } else if (data.type === 'auth_failed') {
const errorMsg = '认证失败,请重新登录'; const errorMsg = '认证失败,请重新登录';
console.error(errorMsg, data); console.error(errorMsg, data);
reject(new Error(errorMsg)); safeComplete({ error: errorMsg });
if (onComplete) onComplete({ error: errorMsg }); safeReject(new Error(errorMsg));
socketTask.close(); socketTask.close();
} }
// 处理流式消息块 // 处理流式消息块
else if (data.type === 'message' || data.event === 'message') { else if (data.event === 'message') {
const text = data.answer || data.content || data.text || ''; const text = data.answer || data.content || data.text || '';
content += text; content += text;
if (onChunk) onChunk(text); if (onChunk) onChunk(text);
} }
// 处理流结束 // 处理流结束
else if (data.event === 'message_end' || data.type === 'message_end') { else if (data.event === 'message_end') {
conversationId = data.conversation_id || ''; conversationId = data.conversation_id || '';
if (conversationId) { if (conversationId) {
this.setConversationId(conversationId); this.setConversationId(conversationId);
} }
if (onComplete) { closedNormally = true;
onComplete({ content, conversation_id: conversationId }); safeComplete({ content, conversation_id: conversationId });
} safeResolve({ content, conversation_id: conversationId });
resolve({ content, conversation_id: conversationId });
socketTask.close(); socketTask.close();
} }
// 可选:处理 done // 可选:处理 done
else if (data.type === 'done') { else if (data.type === 'done') {
console.log('对话完成:', data);
} }
} catch (e) { } catch (e) {
@@ -142,22 +197,19 @@ export default {
socketTask.onError((err) => { socketTask.onError((err) => {
const errorMsg = 'WebSocket 连接失败'; const errorMsg = 'WebSocket 连接失败';
console.error(errorMsg, err); console.error(errorMsg, err);
reject(new Error(errorMsg)); safeComplete({ error: errorMsg });
if (onComplete) onComplete({ error: errorMsg }); safeReject(new Error(errorMsg));
}); });
socketTask.onClose(() => { socketTask.onClose(() => {
console.log('WebSocket 连接已关闭'); if (!closedNormally && !settled) {
const errorMsg = 'WebSocket 连接意外关闭';
console.error(errorMsg);
safeComplete({ error: errorMsg });
safeReject(new Error(errorMsg));
}
}); });
const timeout = setTimeout(() => {
if (!isAuthenticated || content === '') {
console.warn('WebSocket 超时,强制关闭');
socketTask.close();
reject(new Error('AI服务响应超时'));
if (onComplete) onComplete({ error: 'AI服务响应超时' });
}
}, 10000);
}); });
// #endif // #endif
}, },
@@ -175,12 +227,14 @@ export default {
'Accept': 'text/event-stream', 'Accept': 'text/event-stream',
}, },
body: JSON.stringify({ body: JSON.stringify({
uniacid: store.state.uniacid || '1', uniacid: this.getUniacid(),
token: store.state.token || 'test_token',
inputs: {}, inputs: {},
query: message, query: message,
response_mode: 'streaming', response_mode: 'streaming',
user_id: store.state.memberInfo?.id || 'anonymous', user_id: store.state.memberInfo?.id || 'anonymous',
conversation_id: this.getConversationId() || '' conversation_id: this.getConversationId() || '',
...getDomainParams()
}) })
}); });
@@ -314,17 +368,19 @@ export default {
* 生成新会话(如需) * 生成新会话(如需)
*/ */
async generateConversationId() { async generateConversationId() {
const params = { const params = {
url: '/api/kefu/createConversation', url: '/api/kefu/createConversation',
data: { data: {
uniacid: store.state.uniacid, uniacid: this.getUniacid(),
user_id: store.state.memberInfo?.id || 'anonymous', token: store.state.token || 'test_token',
member_id: store.state.memberInfo?.id || '', user_id: store.state.memberInfo?.id || 'anonymous',
}, member_id: store.state.memberInfo?.id || 'anonymous',
header: { ...getDomainParams()
'Content-Type': 'application/json' },
} header: {
}; 'Content-Type': 'application/json'
}
};
const response = await http.sendRequest({ const response = await http.sendRequest({
...params, ...params,
async: false async: false
@@ -363,7 +419,10 @@ export default {
try { try {
const response = await http.sendRequest({ const response = await http.sendRequest({
url: '/api/kefu/clear-conversation', url: '/api/kefu/clear-conversation',
data: { conversation_id: conversationId }, data: {
conversation_id: conversationId,
...getDomainParams()
},
async: false async: false
}); });
return response.success; return response.success;
@@ -382,13 +441,14 @@ export default {
throw new Error('会话ID(conversation_id)是必填参数'); throw new Error('会话ID(conversation_id)是必填参数');
} }
const requestData = { const requestData = {
uniacid: params.uniacid || store.state.uniacid || '1', uniacid: params.uniacid || this.getUniacid(),
conversation_id: params.conversation_id, conversation_id: params.conversation_id,
user_id: params.user_id || store.state.memberInfo?.id || 'anonymous', user_id: params.user_id || store.state.memberInfo?.id || 'anonymous',
limit: params.limit || 20, limit: params.limit || 20,
offset: params.offset || 0, offset: params.offset || 0,
member_id: params.member_id || store.state.memberInfo?.id || '', member_id: params.member_id || store.state.memberInfo?.id || 'anonymous',
token: params.token || '' token: params.token || '',
...getDomainParams()
}; };
const response = await http.sendRequest({ const response = await http.sendRequest({
url: '/api/kefu/getHistory', url: '/api/kefu/getHistory',
@@ -427,13 +487,17 @@ export default {
if (window.currentEventSource) { if (window.currentEventSource) {
window.currentEventSource.close(); window.currentEventSource.close();
} }
const params = new URLSearchParams({ const paramsObj = {
uniacid: store.state.uniacid || '1', uniacid: this.getUniacid(),
user_id: store.state.memberInfo?.id || '123456', user_id: store.state.memberInfo?.id || 'anonymous',
member_id: store.state.memberInfo?.id || 'anonymous',
token: store.state.token || 'test_token',
query: message, query: message,
conversation_id: conversationId || '', conversation_id: conversationId || '',
stream: 'true' stream: 'true',
}); ...getDomainParams()
};
const params = new URLSearchParams(paramsObj);
const url = `${Config.baseUrl}/api/kefu/chat?${params.toString()}`; const url = `${Config.baseUrl}/api/kefu/chat?${params.toString()}`;
try { try {
const eventSource = new EventSource(url); const eventSource = new EventSource(url);

View File

@@ -18,22 +18,15 @@ try {
// 线上版本部署域名, 注意: 必须以 '/' 结尾,适用于小程序/H5/快应用等场景 // 线上版本部署域名, 注意: 必须以 '/' 结尾,适用于小程序/H5/快应用等场景
// 默认域名, 自定义发行时可以修改 // 默认域名, 自定义发行时可以修改
let defaultDomain = ''; let defaultDomain = '';
// #ifdef H5_XCX_5G_QUICKAPP_COM // #ifdef H5
defaultDomain = 'https://xcx20.5g-quickapp.com'; // 域名由 vue.config.js 中 DefinePlugin 注入的 process.env.UNI_APP_DOMAIN 传入
// #endif try {
if (process.env.UNI_APP_DOMAIN) {
// #ifdef H5_XCX_AIGC_QUICKAPP_COM defaultDomain = process.env.UNI_APP_DOMAIN;
defaultDomain = 'https://xcx.aigc-quickapp.com/'; }
// #endif } catch (e) {}
// #ifdef H5_5G_AIGC_QUICKAPP_COM
defaultDomain = 'https://5g.aigc-quickapp.com/';
// #endif
// #ifdef H5_TEST_AIGC_QUICKAPP_COM
defaultDomain = 'https://test.aigc-quickapp.com/';
// #endif // #endif
// 确保域名以 '/' 结尾 // 确保域名以 '/' 结尾
@@ -59,7 +52,6 @@ if (process?.env?.NODE_ENV === 'development') {
// 如果本地配置文件不存在或加载失败,保持使用默认配置 // 如果本地配置文件不存在或加载失败,保持使用默认配置
// 只在开发模式下输出提示信息 // 只在开发模式下输出提示信息
// #ifdef WEB // #ifdef WEB
console.log('本地配置文件 .local.config.js 不存在,使用默认配置');
// #endif // #endif
} }
} }

View File

@@ -2,6 +2,8 @@
* 客服统一处理服务 * 客服统一处理服务
* 整合各种客服方式,提供统一的调用接口 * 整合各种客服方式,提供统一的调用接口
*/ */
import IMAGE_CONFIG from './image-config.js';
export class CustomerService { export class CustomerService {
constructor(vueInstance, externalConfig = null) { constructor(vueInstance, externalConfig = null) {
this.vm = vueInstance; this.vm = vueInstance;
@@ -30,7 +32,6 @@ export class CustomerService {
// 优先级:外部传入 > vuex store > 空对象 // 优先级:外部传入 > vuex store > 空对象
const servicerConfig = this.externalConfig || this.vm.$store.state.servicerConfig || {}; const servicerConfig = this.externalConfig || this.vm.$store.state.servicerConfig || {};
console.log(`【实时客服配置】`, servicerConfig);
let platformConfig = null; let platformConfig = null;
@@ -118,9 +119,9 @@ export class CustomerService {
} }
/** /**
* 跳转到 AI 客服页面(Dify) * 跳转到 AI智能客服页面(AiChat)
*/ */
openDifyService() { openAiChatService() {
try { try {
// 清除未读数(如果存在) // 清除未读数(如果存在)
if (typeof this.vm.setAiUnreadCount === 'function') { if (typeof this.vm.setAiUnreadCount === 'function') {
@@ -134,7 +135,7 @@ export class CustomerService {
uni.navigateTo({ uni.navigateTo({
url: aiChatUrl, url: aiChatUrl,
fail: (err) => { fail: (err) => {
console.error('跳转 AI 客服失败:', err); console.error('跳转 AI智能客服失败:', err);
// H5 兜底 // H5 兜底
// #ifdef H5 // #ifdef H5
window.location.href = aiChatUrl; window.location.href = aiChatUrl;
@@ -143,7 +144,7 @@ export class CustomerService {
} }
}); });
} catch (e) { } catch (e) {
console.error('跳转 AI 客服异常:', e); console.error('跳转 AI智能客服异常:', e);
uni.showToast({ title: '打开客服失败', icon: 'none' }); uni.showToast({ title: '打开客服失败', icon: 'none' });
} }
} }
@@ -165,8 +166,6 @@ export class CustomerService {
} }
const config = this.getPlatformConfig(); const config = this.getPlatformConfig();
console.log('【当前客服配置】', config);
console.log('【客服类型】', config.type);
const { niushop = {}, sendMessageTitle = '', sendMessagePath = '', sendMessageImg = '' } = options; const { niushop = {}, sendMessageTitle = '', sendMessagePath = '', sendMessageImg = '' } = options;
@@ -178,31 +177,24 @@ export class CustomerService {
// 核心路由:根据 type 决定行为 // 核心路由:根据 type 决定行为
switch (config.type) { switch (config.type) {
case 'aikefu': case 'aikefu':
console.log('【跳转 AI 客服】目标路径: /pages_tool/ai-chat/index'); this.openAiChatService();
this.openDifyService();
break; break;
case 'wxwork': case 'wxwork':
console.log('【跳转企业微信客服】');
this.openWxworkService(false, config, options); this.openWxworkService(false, config, options);
break; break;
case 'third': case 'third':
console.log('【跳转第三方客服】');
this.openThirdService(config); this.openThirdService(config);
break; break;
case 'miniprogram': case 'miniprogram':
console.log('【跳转第三方小程序客服】');
this.openThirdService(config); this.openThirdService(config);
break; break;
case 'niushop': case 'niushop':
console.log('【跳转牛商客服】');
this.openNiushopService(niushop); this.openNiushopService(niushop);
break; break;
case 'weapp': case 'weapp':
console.log('【跳转微信官方客服】');
this.openWeappService(config, options); this.openWeappService(config, options);
break; break;
case 'aliapp': case 'aliapp':
console.log('【跳转支付宝客服】');
this.openAliappService(config); this.openAliappService(config);
break; break;
default: default:
@@ -223,7 +215,7 @@ export class CustomerService {
wx.navigateToMiniProgram({ wx.navigateToMiniProgram({
appId: 'wxeb490c6f9b154ef9', appId: 'wxeb490c6f9b154ef9',
path: `pages/contacts/externalContactDetail?url=${encodeURIComponent(wxworkConfig.contact_url)}`, path: `pages/contacts/externalContactDetail?url=${encodeURIComponent(wxworkConfig.contact_url)}`,
success: () => console.log('跳转企业微信成功'), success: () => {},
fail: (err) => { fail: (err) => {
console.error('跳转企业微信失败:', err); console.error('跳转企业微信失败:', err);
this.fallbackToOriginalService(); this.fallbackToOriginalService();
@@ -260,24 +252,20 @@ export class CustomerService {
} }
openThirdService(config) { openThirdService(config) {
console.log('【第三方客服配置】', config);
console.log('【配置字段】', Object.keys(config));
// 支持多种可能的字段名 // 支持多种可能的字段名
const miniAppId = config.mini_app_id || config.miniAppId || config.appid || config.appId || config.app_id; const miniAppId = config.mini_app_id || config.miniAppId || config.appid || config.appId || config.app_id;
const miniAppPath = config.mini_app_path || config.miniAppPath || config.path || config.page_path || ''; const miniAppPath = config.mini_app_path || config.miniAppPath || config.path || config.page_path || '';
console.log('【解析后的小程序配置】AppID:', miniAppId, 'Path:', miniAppPath);
// 优先处理第三方微信小程序客服 // 优先处理第三方微信小程序客服
if (miniAppId) { if (miniAppId) {
console.log('【跳转第三方小程序】AppID:', miniAppId, 'Path:', miniAppPath);
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
wx.navigateToMiniProgram({ wx.navigateToMiniProgram({
appId: miniAppId, appId: miniAppId,
path: miniAppPath, path: miniAppPath,
success: () => { success: () => {
console.log('【跳转第三方小程序成功】');
}, },
fail: (err) => { fail: (err) => {
console.error('【跳转第三方小程序失败】', err); console.error('【跳转第三方小程序失败】', err);
@@ -293,7 +281,6 @@ export class CustomerService {
// 处理第三方链接客服 // 处理第三方链接客服
if (config.third_url) { if (config.third_url) {
console.log('【跳转第三方链接】', config.third_url);
// #ifdef H5 // #ifdef H5
window.location.href = config.third_url; window.location.href = config.third_url;
// #endif // #endif
@@ -324,7 +311,7 @@ export class CustomerService {
// 此方法仅用于自定义跳转(如 useOfficial: false) // 此方法仅用于自定义跳转(如 useOfficial: false)
if (config.useOfficial !== false) { if (config.useOfficial !== false) {
// 不做任何事,应由 <button open-type="contact"> 触发 // 不做任何事,应由 <button open-type="contact"> 触发
console.log('使用微信官方客服,请确保按钮为 <button open-type="contact">');
return; return;
} }
this.handleCustomWeappService(config, options); this.handleCustomWeappService(config, options);
@@ -377,12 +364,12 @@ export class CustomerService {
openAliappService(config) { openAliappService(config) {
if (config.type === 'aikefu') { if (config.type === 'aikefu') {
this.openDifyService(); this.openAiChatService();
} else if (config.type === 'third') { } else if (config.type === 'third') {
this.openThirdService(config); this.openThirdService(config);
} else { } else {
// 支付宝原生客服由 button open-type="contact" 触发,此处不处理 // 支付宝原生客服由 button open-type="contact" 触发,此处不处理
console.log('使用支付宝官方客服');
} }
} }
@@ -471,13 +458,11 @@ export class CustomerService {
const shopInfo = this.vm.shopInfo || {}; const shopInfo = this.vm.shopInfo || {};
const config = this.getPlatformConfig(); const config = this.getPlatformConfig();
if (config?.type === 'aikefu') { // 优先使用指定的智能客服头像
return shopInfo.aiAgentimg || ''; if (config?.type === 'aikefu' || config?.type === 'wxwork' || config?.type === 'qyweixin') {
} else if (config?.type === 'wxwork' || config?.type === 'qyweixin') { return this.vm.$util.img(IMAGE_CONFIG.aiAvatar);
return shopInfo.aiAgentimg || '';
} else if (config?.type === 'third') {
return '';
} }
return shopInfo.kefuimg || this.vm.$util?.getDefaultImage()?.kefu || ''; return shopInfo.kefuimg || this.vm.$util?.getDefaultImage()?.kefu || '';
} }
@@ -580,7 +565,7 @@ export class CustomerService {
uni.navigateTo({ uni.navigateTo({
url: aiChatUrl, url: aiChatUrl,
fail: (err) => { fail: (err) => {
console.error('跳转 AI 客服失败:', err); console.error('跳转 AI智能客服失败:', err);
// #ifdef H5 // #ifdef H5
window.location.href = aiChatUrl; window.location.href = aiChatUrl;
// #endif // #endif
@@ -588,7 +573,7 @@ export class CustomerService {
} }
}); });
} catch (e) { } catch (e) {
console.error('跳转 AI 客服异常:', e); console.error('跳转 AI智能客服异常:', e);
uni.showToast({ title: '打开客服失败', icon: 'none' }); uni.showToast({ title: '打开客服失败', icon: 'none' });
} }
} }
@@ -644,8 +629,6 @@ export class CustomerService {
handleUnifiedKefuClick(options = {}) { handleUnifiedKefuClick(options = {}) {
const validation = this.validateConfig(); const validation = this.validateConfig();
console.log('【客服配置验证】', validation);
if (!validation.isValid) { if (!validation.isValid) {
console.error('客服配置无效:', validation.errors); console.error('客服配置无效:', validation.errors);
uni.showToast({ title: '客服暂不可用', icon: 'none' }); uni.showToast({ title: '客服暂不可用', icon: 'none' });
@@ -657,12 +640,10 @@ export class CustomerService {
} }
const platformConfig = this.getPlatformConfig(); const platformConfig = this.getPlatformConfig();
console.log('【当前客服配置】', platformConfig);
// 检查企业微信配置 // 检查企业微信配置
if (platformConfig.type === 'wxwork') { if (platformConfig.type === 'wxwork') {
const wxworkConfig = this.getWxworkConfig(); const wxworkConfig = this.getWxworkConfig();
console.log('【企业微信配置】', wxworkConfig);
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
if (!wxworkConfig?.enable || !wxworkConfig?.contact_url) { if (!wxworkConfig?.enable || !wxworkConfig?.contact_url) {

View File

@@ -200,7 +200,6 @@ export default {
}, },
methods: { methods: {
play(){ play(){
console.log(123)
}, },
async init() { async init() {

View File

@@ -164,7 +164,6 @@ export default {
// 商品详情 // 商品详情
if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = (this.goodsSkuDetail.goods_content); if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = (this.goodsSkuDetail.goods_content);
console.log(this.goodsSkuDetail.goods_content)
// if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = htmlParser(this.goodsSkuDetail.goods_content); // if (this.goodsSkuDetail.goods_content) this.goodsSkuDetail.goods_content = htmlParser(this.goodsSkuDetail.goods_content);
//商品服务 //商品服务

View File

@@ -316,11 +316,9 @@ function replaceVideo(html){
let rep = `<video style="width:100% !important;display:block;max-width: ${screenWidth} !important;"`; let rep = `<video style="width:100% !important;display:block;max-width: ${screenWidth} !important;"`;
var html = html.replace(/\\/g, '').replace(/<video/g, rep); var html = html.replace(/\\/g, '').replace(/<video/g, rep);
console.log(html)
html = html.replace(/<video [^>]*src=['"]([^'"]+)[^>]*>/gi, (match, capture) => { html = html.replace(/<video [^>]*src=['"]([^'"]+)[^>]*>/gi, (match, capture) => {
return rep + ' src="' + util.img(capture) + '"/>'; return rep + ' src="' + util.img(capture) + '"/>';
}); });
// console.log(html)
return html; return html;
} }

15
common/js/image-config.js Normal file
View File

@@ -0,0 +1,15 @@
/**
* 图片配置文件
* 将大图片上传到服务器后,请在此处配置网络URL
*/
// 替换为你上传后的实际图片URL
const IMAGE_CONFIG = {
// AI客服头像
aiAvatar: 'public/static/img/s-agent.jpg',
// 用户默认头像
userAvatar: 'public/static/img/s-user.jpg'
};
export default IMAGE_CONFIG;

View File

@@ -89,16 +89,13 @@ export default {
let platform = util.getDeviceInfo().platform; let platform = util.getDeviceInfo().platform;
switch (platform) { switch (platform) {
case 'android': case 'android':
console.log('运行Android上')
openMapByAndroid(arr[1], arr[0], name) openMapByAndroid(arr[1], arr[0], name)
break; break;
case 'ios': case 'ios':
console.log('运行iOS上')
openMapByIos(arr[1], arr[0], name) openMapByIos(arr[1], arr[0], name)
break; break;
default: default:
openMapByDefault(arr[1], arr[0], name) openMapByDefault(arr[1], arr[0], name)
console.log('运行在开发者工具上')
break; break;
} }
// #endif // #endif

View File

@@ -43,7 +43,6 @@ export class NavigationHelper {
query.select('.uni-page-head').boundingClientRect((rect) => { query.select('.uni-page-head').boundingClientRect((rect) => {
if (rect && rect.height > 0) { if (rect && rect.height > 0) {
console.log('直接查询导航栏高度成功:', rect.height)
resolve(rect.height) resolve(rect.height)
} else { } else {
console.warn('未找到 uni-page-head 元素或高度为0') console.warn('未找到 uni-page-head 元素或高度为0')
@@ -64,7 +63,6 @@ export class NavigationHelper {
const height = menuButtonInfo.bottom + const height = menuButtonInfo.bottom +
(menuButtonInfo.top - systemInfo.statusBarHeight) (menuButtonInfo.top - systemInfo.statusBarHeight)
console.log('微信小程序导航栏高度:', height)
resolve(height) resolve(height)
} catch (error) { } catch (error) {
console.error('微信小程序高度计算失败:', error) console.error('微信小程序高度计算失败:', error)
@@ -174,7 +172,6 @@ export class NavigationHelper {
// 处理服务请求 // 处理服务请求
async handleServiceRequest(event, component) { async handleServiceRequest(event, component) {
console.log('处理导航相关服务请求:', event.type)
// 安全检查事件目标 // 安全检查事件目标
if (this.shouldProcessNavigationRequest(event)) { if (this.shouldProcessNavigationRequest(event)) {
@@ -278,7 +275,6 @@ export class NavigationHelper {
// 清理缓存 // 清理缓存
clearCache() { clearCache() {
this.navigationCache.clear() this.navigationCache.clear()
console.log('导航缓存已清理')
} }
} }

View File

@@ -21,53 +21,35 @@ export default {
methods: { methods: {
// 判断是否已连接 // 判断是否已连接
checkOpenSocket() { checkOpenSocket() {
console.log('判断是否已连接');
// alert('判断是否已连接')
let self = this; let self = this;
uni.sendSocketMessage({ uni.sendSocketMessage({
data: 'ping', data: 'ping',
success: (res) => { success: (res) => {
console.log('连接成功,检查');
// alert('连接成功,检查')
// self.getChatList();
}, },
fail: (err) => { // 未连接打开websocket连接 fail: (err) => { // 未连接打开websocket连接
console.log('连接失败');
// alert('连接失败')
self.openConnection(); self.openConnection();
} }
}); });
}, },
openConnection() { // 打开连接 openConnection() { // 打开连接
console.log('打开连接');
// alert('打开连接')
// uni.closeSocket(); // 确保已经关闭后再重新打开 // uni.closeSocket(); // 确保已经关闭后再重新打开
uni.connectSocket({ uni.connectSocket({
url: config.webSocket, url: config.webSocket,
method: 'POST', method: 'POST',
success(res) { success(res) {
console.log('连接成功 connectSocket=', res);
// alert('连接成功 connectSocket=', res);
}, },
fail(err) { fail(err) {
console.log('连接失败 connectSocket=', err);
} }
}); });
// uni.onSocketOpen((res) => {
// console.log('连接成功', res);
// });
this.onSocketMessage(); // 打开成功监听服务器返回的消息 this.onSocketMessage(); // 打开成功监听服务器返回的消息
}, },
// 打开成功监听服务器返回的消息 // 打开成功监听服务器返回的消息
onSocketMessage() { // 消息 onSocketMessage() { // 消息
console.log("开始监听");
let that = this; let that = this;
this.pingInterval = config.pingInterval; this.pingInterval = config.pingInterval;
this.timeoutObj = null; this.timeoutObj = null;
uni.onSocketMessage((res) => { //type:init,connect,close,string,order,goods uni.onSocketMessage((res) => { //type:init,connect,close,string,order,goods
let msg = JSON.parse(res.data); let msg = JSON.parse(res.data);
console.log("监听该服务器消息", res);
if (msg.type == 'close') { if (msg.type == 'close') {
clearInterval(that.timeoutObj); clearInterval(that.timeoutObj);
that.timeoutObj = null; that.timeoutObj = null;
@@ -141,22 +123,18 @@ export default {
}, },
// 检测心跳reset // 检测心跳reset
reset() { reset() {
console.log("检测心跳");
clearInterval(this.timeoutObj); clearInterval(this.timeoutObj);
this.start(); // 启动心跳 this.start(); // 启动心跳
}, },
// 启动心跳 start // 启动心跳 start
start() { start() {
console.log("启动心跳");
let self = this; let self = this;
this.timeoutObj = setInterval(function () { this.timeoutObj = setInterval(function () {
uni.sendSocketMessage({ uni.sendSocketMessage({
data: 'ping', data: 'ping',
success: (res) => { success: (res) => {
console.log('连接中....');
}, },
fail: (err) => { fail: (err) => {
console.log('连接失败重新连接....');
self.openConnection(); self.openConnection();
} }
}); });

View File

@@ -34,7 +34,6 @@ export const makePhoneCall = (mobile) => {
uni.makePhoneCall({ uni.makePhoneCall({
phoneNumber: `${mobile}`, phoneNumber: `${mobile}`,
success(e) { success(e) {
console.log(e);
} }
}); });
} catch (err) { } catch (err) {

View File

@@ -132,9 +132,7 @@ export default {
let url = to; let url = to;
// 替换url中的前缀 // 替换url中的前缀
console.log('页面跳转 redirectTo', to, param, mode);
url = adaptSubpackageUrl(url); url = adaptSubpackageUrl(url);
console.log('adaptSubpackageUrl', url);
if (param != undefined) { if (param != undefined) {
Object.keys(param).forEach(function (key) { Object.keys(param).forEach(function (key) {
@@ -178,7 +176,6 @@ export default {
break; break;
default: default:
// 保留当前页面,跳转到应用内的某个页面,新增页面到栈顶,长度+1(上限10层) // 保留当前页面,跳转到应用内的某个页面,新增页面到栈顶,长度+1(上限10层)
console.log('保留当前页面,navigateTo跳转到应用内的某个页面', url);
uni.navigateTo({ uni.navigateTo({
url url
}); });
@@ -213,6 +210,8 @@ export default {
// console.log(img_path) // console.log(img_path)
path = img_path; path = img_path;
} }
// 修复:去除 URL 中的双斜杠,避免微信 downloadFile 域名匹配失败
path = path.replace(/([^:]\/)\/+/g, "$1");
} }
// path += '?t=' + parseInt(new Date().getTime() / 1000); // path += '?t=' + parseInt(new Date().getTime() / 1000);
@@ -621,12 +620,8 @@ export default {
appId: 'wxeb490c6f9b154ef9', // 是企业微信官方小程序的AppID(固定值, 由腾讯企业微信团队维护, 不需要修改,用于展示"添加企业微信联系人"的官方页面) appId: 'wxeb490c6f9b154ef9', // 是企业微信官方小程序的AppID(固定值, 由腾讯企业微信团队维护, 不需要修改,用于展示"添加企业微信联系人"的官方页面)
path: `pages/contacts/externalContactDetail?url=${encodeURIComponent(wxworkConfig?.contact_url)}`, path: `pages/contacts/externalContactDetail?url=${encodeURIComponent(wxworkConfig?.contact_url)}`,
success: () => { success: () => {
console.log('跳转企业微信成功');
}, },
fail: (err) => { fail: (err) => {
console.error('跳转企业微信失败:', err);
// 降级处理:使用原有客服方式
fallbackFunc && fallbackFunc();
} }
}); });
} else { } else {
@@ -907,12 +902,11 @@ export default {
}, },
success: res => { success: res => {
if (res.code >= 0) { if (res.code >= 0) {
uni.removeStorage({ uni.removeStorage({
key: 'source_member', key: 'source_member',
success: res => { success: res => {
console.log('删除成功', res) }
} })
})
} }
} }
}) })
@@ -936,27 +930,23 @@ export default {
success: res => { success: res => {
if (res.data.length) { if (res.data.length) {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
uni.requestSubscribeMessage({ uni.requestSubscribeMessage({
tmplIds: res.data, tmplIds: res.data,
success: (res) => { success: (res) => {
console.log("res", res) },
}, fail: (res) => {
fail: (res) => { }
console.log('fail', res) })
}
})
// #endif // #endif
// #ifdef MP-ALIPAY // #ifdef MP-ALIPAY
my.requestSubscribeMessage({ my.requestSubscribeMessage({
entityIds: res.data, entityIds: res.data,
success: res => { success: res => {
console.log("res", res) },
}, fail: res => {
fail: res => { }
console.log('fail', res) });
}
});
// #endif // #endif
} }
} }
@@ -1211,7 +1201,6 @@ export default {
let _isQuickApp = false; let _isQuickApp = false;
try { try {
const ua = navigator?.userAgent?.toLowerCase(); const ua = navigator?.userAgent?.toLowerCase();
// console.log('ua = ', ua);
_isQuickApp = ua.indexOf('quickapp') !== -1; _isQuickApp = ua.indexOf('quickapp') !== -1;
if (!_isQuickApp) { if (!_isQuickApp) {

View File

@@ -55,7 +55,6 @@ let Weixin = function () {
typeof callback == 'function' && callback(res); typeof callback == 'function' && callback(res);
}, },
fail: (res) => { fail: (res) => {
console.log('获取收货地址 fail',res);
alert(JSON.stringify(res)) alert(JSON.stringify(res))
} }
}); });

View File

@@ -0,0 +1,38 @@
/**
* 微信小程序图片长按识别二维码 mixin
* 自动为页面中的所有 image 组件添加 show-menu-by-longpress 属性
*/
export default {
data() {
return {
// 需要排除的图片类名(不需要长按识别的)
excludeImageClass: ['no-longpress', 'swiper-image', 'banner-image']
}
},
mounted() {
// #ifdef MP-WEIXIN
this.$nextTick(() => {
this.addLongpressToImages()
})
// #endif
},
methods: {
/**
* 为页面中的所有 image 添加长按识别支持
*/
addLongpressToImages() {
// 获取当前页面所有 image 组件
const images = document.querySelectorAll && document.querySelectorAll('image')
if (images) {
images.forEach(img => {
// 检查是否需要排除
const className = img.className || ''
const shouldExclude = this.excludeImageClass.some(cls => className.includes(cls))
if (!shouldExclude) {
img.setAttribute('show-menu-by-longpress', 'true')
}
})
}
}
}
}

View File

@@ -12,7 +12,7 @@
<view :class="['item', value.ornament.type]" :style="itemCss"> <view :class="['item', value.ornament.type]" :style="itemCss">
<view class="article-img"> <view class="article-img">
<image class="cover-img" :src="$util.img(item.cover_img)" mode="widthFix" <image class="cover-img" :src="$util.img(item.cover_img)" mode="widthFix"
@error="imgError(index)" /> @error="imgError(index)" show-menu-by-longpress/>
</view> </view>
<view class="info-wrap"> <view class="info-wrap">
<text class="title">{{ item.article_title }}</text> <text class="title">{{ item.article_title }}</text>

View File

@@ -17,7 +17,7 @@
<view class="fui-audio style3" :style="{ background: value.background }" v-else> <view class="fui-audio style3" :style="{ background: value.background }" v-else>
<!-- <audio src="/static/audio/bgm.mp3" controls loop></audio> --> <!-- <audio src="/static/audio/bgm.mp3" controls loop></audio> -->
<view class="img"> <view class="img">
<image :src="$util.img(value.imageUrl)"></image> <image :src="$util.img(value.imageUrl)" show-menu-by-longpress></image>
</view> </view>
<view class="content"> <view class="content">
<view class="name" :style="{ color: value.textcolor }">{{ value.text }}</view> <view class="name" :style="{ color: value.textcolor }">{{ value.text }}</view>
@@ -98,9 +98,7 @@ export default {
uni.setStorageSync('audio_list', audio_list) uni.setStorageSync('audio_list', audio_list)
} }
} }
console.log(uni.getStorageSync('audio_list'))
var n = this; var n = this;
// console.log(a)
a.onPlay(function () { a.onPlay(function () {
var e = setInterval(function () { var e = setInterval(function () {
var i = a.currentTime / a.duration * 100 + "%", s = Math.floor(Math.ceil(a.currentTime) / 60), o = (Math.ceil(a.currentTime) % 60 / 100).toFixed(2).slice(-2), r = Math.ceil(a.currentTime); var i = a.currentTime / a.duration * 100 + "%", s = Math.floor(Math.ceil(a.currentTime) / 60), o = (Math.ceil(a.currentTime) % 60 / 100).toFixed(2).slice(-2), r = Math.ceil(a.currentTime);
@@ -113,13 +111,12 @@ export default {
var s = n.$util.img(n.value.audioUrl), o = n.audios[n.value.id].seconds || 0, r = 0, u = 1; var s = n.$util.img(n.value.audioUrl), o = n.audios[n.value.id].seconds || 0, r = 0, u = 1;
0 == u && a.onEnded(function (e) { 0 == u && a.onEnded(function (e) {
c[t].status = !1, n.status = !1, c[t].seconds = 0, console.log(c), n.audios = c; c[t].status = !1, n.status = !1, c[t].seconds = 0, n.audios = c;
}); });
var c = n.audios; var c = n.audios;
c[t] || (c[t] = {}), a.paused && 0 == o ? (a.src = s, a.play(), 1 == u && (a.loop = !0), c[t] || (c[t] = {}), a.paused && 0 == o ? (a.src = s, a.play(), 1 == u && (a.loop = !0),
c[t].status = !0, n.status = !0, n.pauseOther(t)) : a.paused && o > 0 ? (a.play(), 0 == r ? a.seek(o) : a.seek(0), c[t].status = !0, n.status = !0, n.pauseOther(t)) : a.paused && o > 0 ? (a.play(), 0 == r ? a.seek(o) : a.seek(0),
c[t].status = !0, n.status = !0, n.pauseOther(t)) : (a.pause(), c[t].status = !1, n.status = !1), n.audios = c; c[t].status = !0, n.status = !0, n.pauseOther(t)) : (a.pause(), c[t].status = !1, n.status = !1), n.audios = c;
console.log(n.audios)
}, },
pauseOther: function (e) { pauseOther: function (e) {
var t = this; var t = this;
@@ -190,18 +187,14 @@ export default {
var u = s + ":" + o, c = that.audios; var u = s + ":" + o, c = that.audios;
c[t].audiowidth = i, c[t].Time = e, c[t].audiotime = u, c[t].seconds = r c[t].audiowidth = i, c[t].Time = e, c[t].audiotime = u, c[t].seconds = r
that.audios = c that.audios = c
// console.log(c)
console.log(that.audios[that.value.id].audiotime)
that.audiotime = that.audios[that.value.id].audiotime that.audiotime = that.audios[that.value.id].audiotime
that.audiowidth = that.audios[that.value.id].audiowidth that.audiowidth = that.audios[that.value.id].audiowidth
console.log(i)
that.lyg = i that.lyg = i
}, 1e3); }, 1e3);
}); });
this.audioContext.onEnded(() => { this.audioContext.onEnded(() => {
console.log('播放结束');
this.status = 0 this.status = 0
}); });
} }

View File

@@ -10,7 +10,7 @@
:style="{ fontSize: value.titleStyle.fontSize * 2 + 'rpx', color: value.titleStyle.textColor, fontWeight: value.titleStyle.fontWeight ? 'bold' : '' }"> :style="{ fontSize: value.titleStyle.fontSize * 2 + 'rpx', color: value.titleStyle.textColor, fontWeight: value.titleStyle.fontWeight ? 'bold' : '' }">
{{ value.titleStyle.leftText }} {{ value.titleStyle.leftText }}
</view> </view>
<image v-else class="left-img" :src="$util.img(value.titleStyle.leftImg)" mode="heightFix"></image> <image v-else class="left-img" :src="$util.img(value.titleStyle.leftImg)" mode="heightFix" show-menu-by-longpress></image>
<view class="head-content" v-if="value.titleStyle.style == 'style-1'" <view class="head-content" v-if="value.titleStyle.style == 'style-1'"
:style="{ color: value.titleStyle.textColor }">低至0元免费拿</view> :style="{ color: value.titleStyle.textColor }">低至0元免费拿</view>
<view class="head-right" <view class="head-right"
@@ -28,7 +28,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(index)" /> @error="imageError(index)" show-menu-by-longpress/>
</view> </view>
<view class="content" <view class="content"
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.btnStyle.control"> v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.btnStyle.control">
@@ -41,7 +41,7 @@
<view class="bg"> <view class="bg">
<view class="curr" :style="{ width: progress(item) * 2 + 'rpx' }"> <view class="curr" :style="{ width: progress(item) * 2 + 'rpx' }">
<image class="progress-bar" mode="widthFix" <image class="progress-bar" mode="widthFix"
:src="$util.img('public/uniapp/bargain/progress_bar_01.png')" /> :src="$util.img('public/uniapp/bargain/progress_bar_01.png')" show-menu-by-longpress/>
</view> </view>
</view> </view>
<view class="num" v-if="item.is_bargaining"> <view class="num" v-if="item.is_bargaining">
@@ -89,7 +89,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(index)" :lazy-load="true" /> @error="imageError(index)" :lazy-load="true" show-menu-by-longpress/>
<image class="bg" <image class="bg"
v-if="value.saleStyle.control && value.template == 'horizontal-slide' && value.style != 'style-2'" v-if="value.saleStyle.control && value.template == 'horizontal-slide' && value.style != 'style-2'"
:src="$util.img('public/uniapp/bargain/bg.png')" mode="widthFix" /> :src="$util.img('public/uniapp/bargain/bg.png')" mode="widthFix" />
@@ -134,7 +134,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(dataIndex)" :lazy-load="true" /> @error="imageError(dataIndex)" :lazy-load="true" show-menu-by-longpress/>
<image class="bg" <image class="bg"
v-if="value.saleStyle.control && value.template == 'horizontal-slide' && value.style != 'style-2'" v-if="value.saleStyle.control && value.template == 'horizontal-slide' && value.style != 'style-2'"
:src="$util.img('public/uniapp/bargain/bg.png')" mode="widthFix" /> :src="$util.img('public/uniapp/bargain/bg.png')" mode="widthFix" />

View File

@@ -2,7 +2,7 @@
<view data-component-name="diy-category-item" class="item-wrap" :class="type"> <view data-component-name="diy-category-item" class="item-wrap" :class="type">
<block v-if="type == 'category' && category.child_list && category.child_list.length"> <block v-if="type == 'category' && category.child_list && category.child_list.length">
<view class="category-adv" v-if="category.image_adv" @tap.stop="diyRedirectTo(category.link_url)"> <view class="category-adv" v-if="category.image_adv" @tap.stop="diyRedirectTo(category.link_url)">
<image :src="$util.img(category.image_adv)" mode="widthFix" /> <image :src="$util.img(category.image_adv)" mode="widthFix" show-menu-by-longpress />
</view> </view>
<block v-if="value.level == 2"> <block v-if="value.level == 2">
@@ -11,7 +11,7 @@
<view class="category-item" v-for="(one, oneIndex) in category.child_list" :key="oneIndex" <view class="category-item" v-for="(one, oneIndex) in category.child_list" :key="oneIndex"
@tap.stop="$util.redirectTo('/pages_goods/list', { category_id: one.category_id })"> @tap.stop="$util.redirectTo('/pages_goods/list', { category_id: one.category_id })">
<view class="img-box"> <view class="img-box">
<image :src="$util.img(one.image)" mode="widthFix" /> <image :src="$util.img(one.image)" mode="widthFix" show-menu-by-longpress />
</view> </view>
<view class="name">{{ one.category_name }}</view> <view class="name">{{ one.category_name }}</view>
</view> </view>
@@ -25,7 +25,7 @@
<view class="category-item" v-for="(two, twoIndex) in one.child_list" :key="twoIndex" <view class="category-item" v-for="(two, twoIndex) in one.child_list" :key="twoIndex"
@tap.stop="$util.redirectTo('/pages_goods/list', { category_id: two.category_id })"> @tap.stop="$util.redirectTo('/pages_goods/list', { category_id: two.category_id })">
<view class="img-box"> <view class="img-box">
<image :src="$util.img(two.image)" mode="widthFix" :lazy-load="true" /> <image :src="$util.img(two.image)" mode="widthFix" :lazy-load="true" show-menu-by-longpress />
</view> </view>
<view class="name">{{ two.category_name }}</view> <view class="name">{{ two.category_name }}</view>
</view> </view>
@@ -82,10 +82,10 @@
<block v-if="goodsList.length"> <block v-if="goodsList.length">
<view class="goods-item" v-for="(item, index) in goodsList" :key="index"> <view class="goods-item" v-for="(item, index) in goodsList" :key="index">
<view class="goods-img" @tap.stop="toDetail(item)"> <view class="goods-img" @tap.stop="toDetail(item)">
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)" /> <image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)" show-menu-by-longpress />
<view class="color-base-bg goods-tag" v-if="item.label_name">{{ item.label_name }} <view class="color-base-bg goods-tag" v-if="item.label_name">{{ item.label_name }}
</view>
</view> </view>
</view>
<view class="info-wrap"> <view class="info-wrap">
<view class="name-wrap" @tap.stop="toDetail(item)"> <view class="name-wrap" @tap.stop="toDetail(item)">
<view class="goods-name">{{ isEnEnv ? item.en_goods_name : item.goods_name }}</view> <view class="goods-name">{{ isEnEnv ? item.en_goods_name : item.goods_name }}</view>
@@ -99,17 +99,14 @@
<text class="unit price-style small">.{{ <text class="unit price-style small">.{{
parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text> parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text>
</block> </block>
<block v-else>
<text class="unit price-style small">{{ $lang('Make') ? $lang('Make') : '询底价' }}</text>
</block>
</view> </view>
<view class="member-price-tag" <view class="member-price-tag"
v-if="item.member_price && item.member_price == showPrice(item)"> v-if="item.member_price && item.member_price == showPrice(item)">
<image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix" /> <image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix" show-menu-by-longpress />
</view> </view>
<view class="member-price-tag" v-else-if="item.promotion_type == 1"> <view class="member-price-tag" v-else-if="item.promotion_type == 1">
<image :src="$util.img('public/uniapp/index/discount.png')" <image :src="$util.img('public/uniapp/index/discount.png')"
mode="widthFix" /> mode="widthFix" show-menu-by-longpress />
</view> </view>
</view> </view>
<view class="footer-wrap"> <view class="footer-wrap">
@@ -120,6 +117,12 @@
<text>{{ showMarketPrice(item) }}</text> <text>{{ showMarketPrice(item) }}</text>
</view> </view>
</view> </view>
<view class="ai-chat-btn-wrap" v-if="item.isinformation == 1">
<view class="ai-chat-btn" @tap.stop="sendToAIChat(item)">
立即咨询
</view>
</view>
<!-- <view class="right-wrap" v-if="value.template == 2 || value.template == 4"> <!-- <view class="right-wrap" v-if="value.template == 2 || value.template == 4">
<block v-if="item.is_virtual"> <block v-if="item.is_virtual">
<view class="color-base-bg select-sku" @tap.stop="toDetail(item)">立即购买</view> <view class="color-base-bg select-sku" @tap.stop="toDetail(item)">立即购买</view>
@@ -155,7 +158,7 @@
</view> </view>
</block> </block>
<view class="category-empty" v-else> <view class="category-empty" v-else>
<image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix" /> <image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix" show-menu-by-longpress />
</view> </view>
<!-- <view class="end-tips" ref="endTips" v-if="last && (categoryId == -1 || !category.child_list || (category.child_list && categoryId == category.child_list.length - 1))">已经到底了~</view> <!-- <view class="end-tips" ref="endTips" v-if="last && (categoryId == -1 || !category.child_list || (category.child_list && categoryId == category.child_list.length - 1))">已经到底了~</view>
<view class="end-tips" ref="endTips" v-else @tap.stop="switchCategory('next')"> <view class="end-tips" ref="endTips" v-else @tap.stop="switchCategory('next')">
@@ -174,34 +177,30 @@
:data-template="value.template"> :data-template="value.template">
<view class="goods-item" v-for="(item, index) in goodsList" :key="index"> <view class="goods-item" v-for="(item, index) in goodsList" :key="index">
<view class="goods-img" @tap.stop="toDetail(item)"> <view class="goods-img" @tap.stop="toDetail(item)">
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)" <image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"
:lazy-load="true" /> :lazy-load="true" show-menu-by-longpress />
<view class="color-base-bg goods-tag" v-if="item.label_name">{{ item.label_name }}</view> <view class="color-base-bg goods-tag" v-if="item.label_name">{{ item.label_name }}</view>
</view> </view>
<view class="info-wrap"> <view class="info-wrap">
<view class="name-wrap" @tap.stop="toDetail(item)"> <view class="name-wrap" @tap.stop="toDetail(item)">
<view class="goods-name">{{ isEnEnv ? item.en_goods_name : item.goods_name }}</view> <view class="goods-name">{{ isEnEnv ? item.en_goods_name : item.goods_name }}</view>
</view> </view>
<view class="price-wrap"> <view class="price-wrap">
<view class="discount-price"> <view class="discount-price">
<block v-if="item.isinformation == 0"> <block v-if="item.isinformation == 0">
<text class="unit price-style small">¥</text> <text class="unit price-style small">¥</text>
<text class="price price-style large">{{ <text class="price price-style large">{{
parseFloat(showPrice(item)).toFixed(2).split('.')[0] }}</text> parseFloat(showPrice(item)).toFixed(2).split('.')[0] }}</text>
<text class="unit price-style small">.{{ <text class="unit price-style small">.{{
parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text> parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text>
</block> </block>
<block v-else> </view>
<text class="unit price-style small">{{ $lang('Make') ? $lang('Make') : '询底价' }}</text>
</block>
</view>
<view class="member-price-tag" <view class="member-price-tag"
v-if="item.member_price && item.member_price == showPrice(item)"> v-if="item.member_price && item.member_price == showPrice(item)">
<image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix" /> <image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix" show-menu-by-longpress />
</view> </view>
<view class="member-price-tag" v-else-if="item.promotion_type == 1"> <view class="member-price-tag" v-else-if="item.promotion_type == 1">
<image :src="$util.img('public/uniapp/index/discount.png')" mode="widthFix" /> <image :src="$util.img('public/uniapp/index/discount.png')" mode="widthFix" show-menu-by-longpress />
</view> </view>
</view> </view>
<view class="footer-wrap"> <view class="footer-wrap">
@@ -212,6 +211,12 @@
<text>{{ showMarketPrice(item) }}</text> <text>{{ showMarketPrice(item) }}</text>
</view> </view>
</view> </view>
<view class="ai-chat-btn-wrap" v-if="item.isinformation == 1">
<view class="ai-chat-btn" @tap.stop="sendToAIChat(item)">
立即咨询
</view>
</view>
<view class="right-wrap" v-if="value.template == 2"> <view class="right-wrap" v-if="value.template == 2">
<block v-if="item.is_virtual"> <block v-if="item.is_virtual">
<view class="color-base-bg select-sku" @tap.stop="toDetail(item)">立即购买</view> <view class="color-base-bg select-sku" @tap.stop="toDetail(item)">立即购买</view>
@@ -718,6 +723,15 @@ export default {
} }
} }
}, },
/**
* 跳转到商品详情
* @param {Object} item 商品信息
*/
sendToAIChat(item) {
this.$util.redirectTo('/pages_goods/detail', {
goods_id: item.goods_id
});
},
diyRedirectTo(link) { diyRedirectTo(link) {
if (!link) return; if (!link) return;
this.$util.diyRedirectTo(JSON.parse(link)); this.$util.diyRedirectTo(JSON.parse(link));
@@ -1384,4 +1398,25 @@ export default {
color: var(--main-color); color: var(--main-color);
} }
} }
.ai-chat-btn-wrap {
display: flex;
justify-content: flex-end;
margin-top: auto;
padding-top: 10rpx;
}
.ai-chat-btn {
background-color: #ff0000;
color: #fff;
padding: 12rpx 30rpx;
border-radius: 40rpx;
font-size: 26rpx;
font-weight: 500;
line-height: 1.2;
text-align: center;
white-space: nowrap;
display: inline-block;
}
</style> </style>

View File

@@ -43,7 +43,7 @@
<view class="category-item" :id="'category-one-' + index" v-for="(item, index) in templateFourData" <view class="category-item" :id="'category-one-' + index" v-for="(item, index) in templateFourData"
:key="index" :class="{ select: oneCategorySelect == index }" @tap.stop="templateFourOneFn(index)"> :key="index" :class="{ select: oneCategorySelect == index }" @tap.stop="templateFourOneFn(index)">
<view class="image-warp" :class="[{ 'color-base-border': oneCategorySelect == index }]"> <view class="image-warp" :class="[{ 'color-base-border': oneCategorySelect == index }]">
<image :src="$util.img(item.image)" mode="aspectFill" /> <image :src="$util.img(item.image)" mode="aspectFill" show-menu-by-longpress/>
</view> </view>
<view :class="['text', { 'color-base-bg': oneCategorySelect == index }]">{{ item.category_name }} <view :class="['text', { 'color-base-bg': oneCategorySelect == index }]">{{ item.category_name }}
</view> </view>
@@ -52,7 +52,7 @@
<view class="category-item-all" @tap.stop="$refs.templateFourPopup.open()"> <view class="category-item-all" @tap.stop="$refs.templateFourPopup.open()">
<view class="category-item-all-wrap"> <view class="category-item-all-wrap">
<text class="text">展开</text> <text class="text">展开</text>
<image class="img" :src="$util.img('/public/uniapp/category/unfold.png')" mode="aspectFill"></image> <image class="img" :src="$util.img('/public/uniapp/category/unfold.png')" mode="aspectFill" show-menu-by-longpress></image>
</view> </view>
</view> </view>
<uni-popup type="top" ref="templateFourPopup" :top="uniPopupTop"> <uni-popup type="top" ref="templateFourPopup" :top="uniPopupTop">
@@ -61,7 +61,7 @@
<view class="item" :class="{ selected: oneCategorySelect == index }" <view class="item" :class="{ selected: oneCategorySelect == index }"
@tap.stop="templateFourOneFn(index)" v-for="(item, index) in templateFourData" :key="index"> @tap.stop="templateFourOneFn(index)" v-for="(item, index) in templateFourData" :key="index">
<view class="image-warp" :class="[{ 'color-base-border': oneCategorySelect == index }]"> <view class="image-warp" :class="[{ 'color-base-border': oneCategorySelect == index }]">
<image :src="$util.img(item.image)" mode="aspectFill"></image> <image :src="$util.img(item.image)" mode="aspectFill" show-menu-by-longpress></image>
</view> </view>
<view :class="['text', { 'color-base-bg': oneCategorySelect == index }]">{{ <view :class="['text', { 'color-base-bg': oneCategorySelect == index }]">{{
item.category_name }}</view> item.category_name }}</view>
@@ -119,12 +119,12 @@
</view> </view>
</block> </block>
<view class="category-empty" v-else> <view class="category-empty" v-else>
<image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix"></image> <image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix" show-menu-by-longpress></image>
<view class="tips">暂时没有分类哦!</view> <view class="tips">暂时没有分类哦!</view>
</view> </view>
</view> </view>
<view class="category-empty" v-else> <view class="category-empty" v-else>
<image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix"></image> <image :src="$util.img('public/uniapp/category/empty.png')" mode="widthFix" show-menu-by-longpress></image>
<view class="tips">暂时没有分类哦!</view> <view class="tips">暂时没有分类哦!</view>
</view> </view>

View File

@@ -256,7 +256,6 @@ export default {
try { try {
// 发送视频被点击播放事件 // 发送视频被点击播放事件
this.$emit('channel-video-click-play', item); this.$emit('channel-video-click-play', item);
console.log('播放视频:', item);
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
// 在微信小程序环境中调用视频播放接口 // 在微信小程序环境中调用视频播放接口
@@ -289,7 +288,6 @@ export default {
*/ */
imgError(index) { imgError(index) {
// 图片加载失败的处理逻辑 // 图片加载失败的处理逻辑
console.log('图片加载失败:', index);
// 为失败的图片设置默认图片 // 为失败的图片设置默认图片
const item = this.value.list[index]; const item = this.value.list[index];
if (item) { if (item) {
@@ -306,7 +304,6 @@ export default {
addMouseDragScroll() { addMouseDragScroll() {
// 只在Web环境中添加 // 只在Web环境中添加
// #ifndef MP // #ifndef MP
console.log('addMouseDragScroll called');
let isDragging = false; let isDragging = false;
let startX = 0; let startX = 0;
@@ -329,11 +326,9 @@ export default {
const handleMouseDown = (e) => { const handleMouseDown = (e) => {
// 检查是否点击在组件内 // 检查是否点击在组件内
if (this.$el.contains(e.target)) { if (this.$el.contains(e.target)) {
console.log('mousedown event in component:', e);
// 查找可滚动元素 // 查找可滚动元素
currentScrollElement = findScrollableParent(e.target); currentScrollElement = findScrollableParent(e.target);
if (currentScrollElement) { if (currentScrollElement) {
console.log('Found scrollable element:', currentScrollElement);
isDragging = true; isDragging = true;
startX = e.pageX; startX = e.pageX;
startScrollLeft = currentScrollElement.scrollLeft; startScrollLeft = currentScrollElement.scrollLeft;
@@ -345,17 +340,14 @@ export default {
// 鼠标移动事件 // 鼠标移动事件
const handleMouseMove = (e) => { const handleMouseMove = (e) => {
if (!isDragging || !currentScrollElement) return; if (!isDragging || !currentScrollElement) return;
console.log('mousemove event:', e);
e.preventDefault(); e.preventDefault();
const dx = e.pageX - startX; const dx = e.pageX - startX;
currentScrollElement.scrollLeft = startScrollLeft - dx; currentScrollElement.scrollLeft = startScrollLeft - dx;
console.log('scrollLeft:', currentScrollElement.scrollLeft);
}; };
// 鼠标释放事件 // 鼠标释放事件
const handleMouseUp = () => { const handleMouseUp = () => {
if (isDragging && currentScrollElement) { if (isDragging && currentScrollElement) {
console.log('mouseup event');
currentScrollElement.style.cursor = 'grab'; currentScrollElement.style.cursor = 'grab';
} }
isDragging = false; isDragging = false;
@@ -368,21 +360,17 @@ export default {
document.addEventListener('mouseup', handleMouseUp); document.addEventListener('mouseup', handleMouseUp);
document.addEventListener('mouseleave', handleMouseUp); document.addEventListener('mouseleave', handleMouseUp);
console.log('Global mouse event listeners added');
// 组件销毁时移除事件监听器 // 组件销毁时移除事件监听器
this.$once('hook:beforeDestroy', () => { this.$once('hook:beforeDestroy', () => {
document.removeEventListener('mousedown', handleMouseDown); document.removeEventListener('mousedown', handleMouseDown);
document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mouseup', handleMouseUp); document.removeEventListener('mouseup', handleMouseUp);
document.removeEventListener('mouseleave', handleMouseUp); document.removeEventListener('mouseleave', handleMouseUp);
console.log('Global mouse event listeners removed');
}); });
// 为所有.channel-nav元素添加必要的样式 // 为所有.channel-nav元素添加必要的样式
setTimeout(() => { setTimeout(() => {
const channelNavs = document.querySelectorAll('.channel-nav'); const channelNavs = document.querySelectorAll('.channel-nav');
console.log('Found channel-nav elements:', channelNavs.length);
channelNavs.forEach(element => { channelNavs.forEach(element => {
element.style.overflowX = 'auto'; element.style.overflowX = 'auto';
element.style.overflowY = 'hidden'; element.style.overflowY = 'hidden';
@@ -391,11 +379,9 @@ export default {
element.style.maxWidth = '100%'; element.style.maxWidth = '100%';
element.style.cursor = 'grab'; element.style.cursor = 'grab';
element.style.userSelect = 'none'; // 防止文本选择 element.style.userSelect = 'none'; // 防止文本选择
console.log('Added styles to channel-nav:', element);
}); });
}, 100); // 延迟执行,确保DOM已完全渲染 }, 100); // 延迟执行,确保DOM已完全渲染
console.log('Mouse drag scroll setup completed');
// #endif // #endif
} }
} }

View File

@@ -24,7 +24,7 @@
<!-- 跳转式视频播放 --> <!-- 跳转式视频播放 -->
<view v-else @tap.stop="playVideo" class="video-container"> <view v-else @tap.stop="playVideo" class="video-container">
<view class="video-cover-wrap" :style="[coverStyle]"> <view class="video-cover-wrap" :style="[coverStyle]">
<image class="video-cover" :src="$util.img(value.coverUrl)" mode="aspectFill"></image> <image class="video-cover" :src="$util.img(value.coverUrl)" mode="aspectFill" show-menu-by-longpress></image>
<view class="channel-play-btn" v-if="showPlayBtn" :style="[playBtnStyle]"> <view class="channel-play-btn" v-if="showPlayBtn" :style="[playBtnStyle]">
<view class="play-icon-css"></view> <view class="play-icon-css"></view>
</view> </view>
@@ -139,7 +139,6 @@ export default {
const enableEmbedMode = Boolean(this.value?.embedMode) const enableEmbedMode = Boolean(this.value?.embedMode)
&& Boolean(this.value?.feedToken) && Boolean(this.value?.feedToken)
&& wechatChannelUtil.isEmbedModeSupported(); && wechatChannelUtil.isEmbedModeSupported();
console.log('enableEmbedMode', enableEmbedMode);
return enableEmbedMode; return enableEmbedMode;
// #endif // #endif
return false return false

View File

@@ -91,7 +91,6 @@ export default {
// 页面跳转 // 页面跳转
redirectTo(item) { redirectTo(item) {
if (!item.wap_url || this.$util.getCurrRoute() != this.$util.MEMBER_PAGE_URL || this.storeToken) { if (!item.wap_url || this.$util.getCurrRoute() != this.$util.MEMBER_PAGE_URL || this.storeToken) {
console.log(item);
this.$util.diyRedirectTo(item); this.$util.diyRedirectTo(item);
} else { } else {
this.$refs.login.open(item.wap_url); this.$refs.login.open(item.wap_url);

View File

@@ -5,7 +5,7 @@
:class="[value.ornament.type]" :style="goodsItemCss"> :class="[value.ornament.type]" :style="goodsItemCss">
<view class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(index)" /> :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(index)" show-menu-by-longpress/>
</view> </view>
<view class="info-wrap" <view class="info-wrap"
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control"> v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control">
@@ -337,7 +337,7 @@ export default {
width: calc(50% - 10rpx); width: calc(50% - 10rpx);
&:nth-child(2n + 2) { &:nth-child(2n + 2) {
width: calc(50% - 11rpx); width: calc(50% - 10rpx);
margin-right: 0; margin-right: 0;
} }

View File

@@ -6,7 +6,7 @@
<view class="button-box" @tap.stop="$util.diyRedirectTo(item.link)" <view class="button-box" @tap.stop="$util.diyRedirectTo(item.link)"
:style="{ width: value.imageSize + 'px', height: value.imageSize + 'px', fontSize: value.imageSize + 'px' }"> :style="{ width: value.imageSize + 'px', height: value.imageSize + 'px', fontSize: value.imageSize + 'px' }">
<image v-if="!item.iconType || item.iconType == 'img'" :src="$util.img(item.imageUrl)" mode="aspectFit" <image v-if="!item.iconType || item.iconType == 'img'" :src="$util.img(item.imageUrl)" mode="aspectFit"
:show-menu-by-longpress="true" /> show-menu-by-longpress />
<diy-icon v-else-if="item.iconType && item.iconType == 'icon'" :icon="item.icon" <diy-icon v-else-if="item.iconType && item.iconType == 'icon'" :icon="item.icon"
:value="item.style ? item.style : null"></diy-icon> :value="item.style ? item.style : null"></diy-icon>
</view> </view>

View File

@@ -9,7 +9,7 @@
<view class="li-item" v-for="(item, index) in list" :key="index"> <view class="li-item" v-for="(item, index) in list" :key="index">
<image class="brand-pic" :src="$util.img(item.image_url)" mode="aspectFit" <image class="brand-pic" :src="$util.img(item.image_url)" mode="aspectFit"
@tap.stop="handlerClick(item)" @error="imgError(index)" @tap.stop="handlerClick(item)" @error="imgError(index)"
:style="itemCss" /> :style="itemCss" show-menu-by-longpress/>
</view> </view>
</view> </view>
</view> </view>

View File

@@ -8,7 +8,8 @@
<image class="goods-img" <image class="goods-img"
:src="$util.img(item.goods_image, { size: goodsValue.template == 'large-mode' ? 'big' : 'mid' })" :src="$util.img(item.goods_image, { size: goodsValue.template == 'large-mode' ? 'big' : 'mid' })"
mode="widthFix" @error="imgError(index)" mode="widthFix" @error="imgError(index)"
:style="{ borderRadius: goodsValue.imgAroundRadius * 2 + 'rpx' }" /> :style="{ borderRadius: goodsValue.imgAroundRadius * 2 + 'rpx' }"
show-menu-by-longpress />
<view class="sell-out" v-if="item.stock <= 0"> <view class="sell-out" v-if="item.stock <= 0">
<text class="iconfont icon-shuqing"></text> <text class="iconfont icon-shuqing"></text>
</view> </view>
@@ -48,9 +49,9 @@
<view class="member-price" <view class="member-price"
v-if="(item.member_price && item.member_price == showPrice(item)) || item.promotion_type == 1"> v-if="(item.member_price && item.member_price == showPrice(item)) || item.promotion_type == 1">
<image v-if="item.member_price && item.member_price == showPrice(item)" <image v-if="item.member_price && item.member_price == showPrice(item)"
:src="$util.img('public/uniapp/index/VIP.png')" /> :src="$util.img('public/uniapp/index/VIP.png')" show-menu-by-longpress />
<image v-else-if="item.promotion_type == 1" <image v-else-if="item.promotion_type == 1"
:src="$util.img('public/uniapp/index/discount.png')" /> :src="$util.img('public/uniapp/index/discount.png')" show-menu-by-longpress />
</view> </view>
<view v-if="goodsValue.priceStyle.lineControl && showMarketPrice(item)" <view v-if="goodsValue.priceStyle.lineControl && showMarketPrice(item)"
class="delete-price price-font" class="delete-price price-font"
@@ -117,7 +118,7 @@
<view class="goods-img-wrap"> <view class="goods-img-wrap">
<image class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(index)" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" @error="imgError(index)"
:lazy-load="true" /> :lazy-load="true" show-menu-by-longpress />
<view class="sell-out" v-if="item.stock <= 0"> <view class="sell-out" v-if="item.stock <= 0">
<text class="iconfont icon-shuqing"></text> <text class="iconfont icon-shuqing"></text>
</view> </view>
@@ -156,9 +157,9 @@
<view class="member-price" <view class="member-price"
v-if="(item.member_price && item.member_price == showPrice(item)) || item.promotion_type == 1"> v-if="(item.member_price && item.member_price == showPrice(item)) || item.promotion_type == 1">
<image v-if="item.member_price && item.member_price == showPrice(item)" <image v-if="item.member_price && item.member_price == showPrice(item)"
:src="$util.img('public/uniapp/index/VIP.png')" /> :src="$util.img('public/uniapp/index/VIP.png')" show-menu-by-longpress />
<image v-else-if="item.promotion_type == 1" <image v-else-if="item.promotion_type == 1"
:src="$util.img('public/uniapp/index/discount.png')" /> :src="$util.img('public/uniapp/index/discount.png')" show-menu-by-longpress />
</view> </view>
<view v-if="goodsValue.priceStyle.lineControl && showMarketPrice(item)" <view v-if="goodsValue.priceStyle.lineControl && showMarketPrice(item)"
class="delete-price price-font" class="delete-price price-font"
@@ -184,7 +185,7 @@
<view class="goods-img-wrap"> <view class="goods-img-wrap">
<image class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(dataItem.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(dataItem.goods_image, { size: 'mid' })" mode="widthFix"
@error="imgError(dataIndex)" :lazy-load="true" /> @error="imgError(dataIndex)" :lazy-load="true" show-menu-by-longpress />
<view class="sell-out" v-if="dataItem.stock <= 0"> <view class="sell-out" v-if="dataItem.stock <= 0">
<text class="iconfont icon-shuqing"></text> <text class="iconfont icon-shuqing"></text>
</view> </view>
@@ -226,9 +227,9 @@
v-if="(dataItem.member_price && dataItem.member_price == showPrice(dataItem)) || dataItem.promotion_type == 1"> v-if="(dataItem.member_price && dataItem.member_price == showPrice(dataItem)) || dataItem.promotion_type == 1">
<image <image
v-if="dataItem.member_price && dataItem.member_price == showPrice(dataItem)" v-if="dataItem.member_price && dataItem.member_price == showPrice(dataItem)"
:src="$util.img('public/uniapp/index/VIP.png')" /> :src="$util.img('public/uniapp/index/VIP.png')" show-menu-by-longpress />
<image v-else-if="dataItem.promotion_type == 1" <image v-else-if="dataItem.promotion_type == 1"
:src="$util.img('public/uniapp/index/discount.png')" /> :src="$util.img('public/uniapp/index/discount.png')" show-menu-by-longpress />
</view> </view>
<view v-if="goodsValue.priceStyle.lineControl && showMarketPrice(dataItem)" <view v-if="goodsValue.priceStyle.lineControl && showMarketPrice(dataItem)"
class="delete-price" class="delete-price"
@@ -1017,10 +1018,6 @@ export default {
width: calc(33.3333333% - 14rpx); width: calc(33.3333333% - 14rpx);
box-sizing: border-box; box-sizing: border-box;
&:nth-child(3n + 3) {
width: calc(33.33% - 15rpx);
}
&:nth-of-type(1), &:nth-of-type(1),
&:nth-of-type(2), &:nth-of-type(2),
&:nth-of-type(3) { &:nth-of-type(3) {

View File

@@ -17,7 +17,7 @@
<div class="goods-img-wrap"> <div class="goods-img-wrap">
<image class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image class="goods-img" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(dataItem.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(dataItem.goods_image, { size: 'mid' })" mode="widthFix"
@error="imgError(index, dataIndex)" :lazy-load="true" /> @error="imgError(index, dataIndex)" :lazy-load="true" show-menu-by-longpress />
<view class="sell-out" v-if="dataItem.stock <= 0"> <view class="sell-out" v-if="dataItem.stock <= 0">
<text class="iconfont icon-shuqing"></text> <text class="iconfont icon-shuqing"></text>
</view> </view>
@@ -33,7 +33,7 @@
<view class="label-wrap" v-if="goodsValue.labelStyle.support" <view class="label-wrap" v-if="goodsValue.labelStyle.support"
:style="{ background: goodsValue.labelStyle.bgColor, color: goodsValue.labelStyle.color }"> :style="{ background: goodsValue.labelStyle.bgColor, color: goodsValue.labelStyle.color }">
<image :src="$util.img('app/component/view/goods_recommend/img/label.png')" <image :src="$util.img('app/component/view/goods_recommend/img/label.png')"
mode="widthFix" /> mode="widthFix" show-menu-by-longpress />
<text>{{ goodsValue.labelStyle.title }}</text> <text>{{ goodsValue.labelStyle.title }}</text>
</view> </view>
<view class="discount-price"> <view class="discount-price">

View File

@@ -23,7 +23,7 @@
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
mode="aspectFill" mode="aspectFill"
:style="{ maxWidth: value.imageSize * 2 + 'rpx', maxHeight: value.imageSize * 2 + 'rpx', borderRadius: value.aroundRadius * 2 + 'rpx' }" :style="{ maxWidth: value.imageSize * 2 + 'rpx', maxHeight: value.imageSize * 2 + 'rpx', borderRadius: value.aroundRadius * 2 + 'rpx' }"
:show-menu-by-longpress="true" /> show-menu-by-longpress />
<diy-icon v-if="item.iconType == 'icon'" :icon="item.icon" <diy-icon v-if="item.iconType == 'icon'" :icon="item.icon"
:value="item.style ? item.style : null" :value="item.style ? item.style : null"
@@ -69,7 +69,7 @@
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
mode="aspectFill" mode="aspectFill"
:style="{ maxWidth: value.imageSize * 2 + 'rpx', maxHeight: value.imageSize * 2 + 'rpx', borderRadius: value.aroundRadius * 2 + 'rpx' }" :style="{ maxWidth: value.imageSize * 2 + 'rpx', maxHeight: value.imageSize * 2 + 'rpx', borderRadius: value.aroundRadius * 2 + 'rpx' }"
:show-menu-by-longpress="true" /> show-menu-by-longpress />
<diy-icon v-if="item.iconType == 'icon'" :icon="item.icon" <diy-icon v-if="item.iconType == 'icon'" :icon="item.icon"
:value="item.style ? item.style : null" :value="item.style ? item.style : null"
:style="{ maxWidth: value.imageSize * 2 + 'rpx', maxHeight: value.imageSize * 2 + 'rpx', width: '100%', height: '100%' }"></diy-icon> :style="{ maxWidth: value.imageSize * 2 + 'rpx', maxHeight: value.imageSize * 2 + 'rpx', width: '100%', height: '100%' }"></diy-icon>
@@ -164,7 +164,6 @@ export default {
return; return;
} }
} }
console.log(link)
this.$util.diyRedirectTo(link); this.$util.diyRedirectTo(link);
}, },
swiperChange(e) { swiperChange(e) {

View File

@@ -358,11 +358,6 @@ export default {
}); });
} else data = this.setPagestyle; } else data = this.setPagestyle;
console.log(`diy-group ['diyDataArray'] = `, {
data: data,
diyData: this.diyData,
diyGlobalData: this.diyGlobalData,
})
return data; return data;
} }
}, },

View File

@@ -7,7 +7,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(index)"> @error="imageError(index)" show-menu-by-longpress>
</image> </image>
</view> </view>
<view class="content" <view class="content"
@@ -44,7 +44,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(index)" /> @error="imageError(index)" show-menu-by-longpress/>
<image class="bg" v-if="value.saleStyle.control" <image class="bg" v-if="value.saleStyle.control"
:src="$util.img('public/uniapp/groupbuy/bg.png')" mode="widthFix" /> :src="$util.img('public/uniapp/groupbuy/bg.png')" mode="widthFix" />
<view class="num" v-if="value.saleStyle.control" <view class="num" v-if="value.saleStyle.control"
@@ -85,7 +85,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(dataIndex)" /> @error="imageError(dataIndex)" show-menu-by-longpress/>
<image class="bg" v-if="value.saleStyle.control" <image class="bg" v-if="value.saleStyle.control"
:src="$util.img('public/uniapp/groupbuy/bg.png')" mode="widthFix" /> :src="$util.img('public/uniapp/groupbuy/bg.png')" mode="widthFix" />
<view class="num" v-if="value.saleStyle.control" <view class="num" v-if="value.saleStyle.control"

View File

@@ -2,7 +2,7 @@
<view data-component-name="diy-hot-area" :style="hotAreaWarp" class="hot-area-box"> <view data-component-name="diy-hot-area" :style="hotAreaWarp" class="hot-area-box">
<view class="simple-graph-wrap"> <view class="simple-graph-wrap">
<image :style="{ height: value.imgHeight }" :src="$util.img(value.imageUrl)" mode="widthFix" <image :style="{ height: value.imgHeight }" :src="$util.img(value.imageUrl)" mode="widthFix"
:show-menu-by-longpress="true" /> show-menu-by-longpress />
<!-- 热区功能 --> <!-- 热区功能 -->
<view class="heat-map" v-for="(mapItem, mapIndex) in value.heatMapData" :key="mapIndex" :style="{ <view class="heat-map" v-for="(mapItem, mapIndex) in value.heatMapData" :key="mapIndex" :style="{
width: mapItem.width + '%', width: mapItem.width + '%',

View File

@@ -15,12 +15,12 @@
'width': (item.imgWidth / 2 + 'rpx') + ';', 'width': (item.imgWidth / 2 + 'rpx') + ';',
'height': (item.imgHeight / 2 + 'rpx') + ';' 'height': (item.imgHeight / 2 + 'rpx') + ';'
}" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')" }" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
:show-menu-by-longpress="true" @tap.stop="redirectTo(item.link)"></image> show-menu-by-longpress @tap.stop="redirectTo(item.link)"></image>
<image v-else :style="{ <image v-else :style="{
'width': (item.imgWidth / 2 + 'rpx') + ';', 'width': (item.imgWidth / 2 + 'rpx') + ';',
'height': (item.imgHeight / 2 + 'rpx') + ';' 'height': (item.imgHeight / 2 + 'rpx') + ';'
}" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')" }" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
:show-menu-by-longpress="true" @tap.stop="previewImg(item.imageUrl)"></image> show-menu-by-longpress @tap.stop="previewImg(item.imageUrl)"></image>
</view> </view>
<!-- 文字部分 --> <!-- 文字部分 -->

View File

@@ -4,7 +4,7 @@
<block v-if="imgAdsValue.list.length == 1"> <block v-if="imgAdsValue.list.length == 1">
<view class="simple-graph-wrap" :style="imgAdsSwiper" @tap.stop="handlerClick(imgAdsValue.list[0].link)"> <view class="simple-graph-wrap" :style="imgAdsSwiper" @tap.stop="handlerClick(imgAdsValue.list[0].link)">
<image :style="{ height: imgAdsValue.list[0].imgHeight }" <image :style="{ height: imgAdsValue.list[0].imgHeight }"
:src="$util.img(imgAdsValue.list[0].imageUrl)" mode="widthFix" :show-menu-by-longpress="true" /> :src="$util.img(imgAdsValue.list[0].imageUrl)" mode="widthFix" show-menu-by-longpress />
</view> </view>
</block> </block>
<swiper v-else class="swiper" :style="{ height: swiperHeight }" :class="{ <swiper v-else class="swiper" :style="{ height: swiperHeight }" :class="{
@@ -18,7 +18,7 @@
:key="index" v-if="item.imageUrl" @tap.stop="handlerClick(item.link)"> :key="index" v-if="item.imageUrl" @tap.stop="handlerClick(item.link)">
<view class="item" :style="imgAdsSwiper + 'height: ' + item.imgHeight"> <view class="item" :style="imgAdsSwiper + 'height: ' + item.imgHeight">
<image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'" <image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'"
:show-menu-by-longpress="true" /> show-menu-by-longpress />
</view> </view>
</swiper-item> </swiper-item>
</swiper> </swiper>

View File

@@ -58,9 +58,9 @@
:key="index" @tap.stop="toCateGoodsList(item.category_id_2, 2)"> :key="index" @tap.stop="toCateGoodsList(item.category_id_2, 2)">
<view class="item-box"> <view class="item-box">
<image :src="$util.img(item.image)" v-if="item.image" <image :src="$util.img(item.image)" v-if="item.image"
mode="aspectFill" /> mode="aspectFill" show-menu-by-longpress/>
<image :src="$util.getDefaultImage().goods" v-else <image :src="$util.getDefaultImage().goods" v-else
mode="aspectFill" /> mode="aspectFill" show-menu-by-longpress/>
<view>{{ item.category_name }}</view> <view>{{ item.category_name }}</view>
</view> </view>
</view> </view>
@@ -73,9 +73,9 @@
:key="index" @tap.stop="toCateGoodsList(item.category_id_2, 2)"> :key="index" @tap.stop="toCateGoodsList(item.category_id_2, 2)">
<view class="item-box"> <view class="item-box">
<image :src="$util.img(item.image)" v-if="item.image" <image :src="$util.img(item.image)" v-if="item.image"
mode="aspectFill" /> mode="aspectFill" show-menu-by-longpress/>
<image :src="$util.getDefaultImage().goods" v-else <image :src="$util.getDefaultImage().goods" v-else
mode="aspectFill" /> mode="aspectFill" show-menu-by-longpress/>
<view>{{ item.category_name }}</view> <view>{{ item.category_name }}</view>
</view> </view>
</view> </view>
@@ -88,7 +88,7 @@
:key="index" v-if="index >= (page - 1) * 10 && index < page * 10" :key="index" v-if="index >= (page - 1) * 10 && index < page * 10"
@tap.stop="toCateGoodsList(item.category_id_2, 2)"> @tap.stop="toCateGoodsList(item.category_id_2, 2)">
<view class="item-box"> <view class="item-box">
<image :src="item.image" mode="aspectFill" /> <image :src="item.image" mode="aspectFill" show-menu-by-longpress/>
<view>{{ item.category_name }}</view> <view>{{ item.category_name }}</view>
</view> </view>
</view> </view>
@@ -104,19 +104,19 @@
<!-- 分类广告 --> <!-- 分类广告 -->
<image class="category_adv" v-if="cateList[pageIndex].image_adv" <image class="category_adv" v-if="cateList[pageIndex].image_adv"
:src="$util.img(cateList[pageIndex].image_adv)" mode="widthFix" /> :src="$util.img(cateList[pageIndex].image_adv)" mode="widthFix" show-menu-by-longpress/>
<view class="goods-list double-column" v-if="goodsList[pageIndex].list.length"> <view class="goods-list double-column" v-if="goodsList[pageIndex].list.length">
<view class="goods-item" v-for="(item, index) in goodsList[pageIndex].list" <view class="goods-item" v-for="(item, index) in goodsList[pageIndex].list"
:key="index" @tap.stop="toDetail(item)"> :key="index" @tap.stop="toDetail(item)">
<view class="goods-img"> <view class="goods-img">
<image :src="goodsImg(item.goods_image)" mode="widthFix" <image :src="goodsImg(item.goods_image)" mode="widthFix"
@error="imgError(index)" /> @error="imgError(index)" show-menu-by-longpress/>
<view class="color-base-bg goods-tag" <view class="color-base-bg goods-tag"
v-if="value.goodsTag == 'default' && goodsTag(item) != ''">{{ v-if="value.goodsTag == 'default' && goodsTag(item) != ''">{{
goodsTag(item) }}</view> goodsTag(item) }}</view>
<view class="goods-tag-img" v-if="value.goodsTag == 'diy'"> <view class="goods-tag-img" v-if="value.goodsTag == 'diy'">
<image :src="$util.img(value.tagImg.imageUrl)" /> <image :src="$util.img(value.tagImg.imageUrl)" show-menu-by-longpress/>
</view> </view>
</view> </view>
<view class="info-wrap"> <view class="info-wrap">
@@ -133,11 +133,11 @@
<view class="member-price-tag" <view class="member-price-tag"
v-if="item.member_price && item.member_price == showPrice(item)"> v-if="item.member_price && item.member_price == showPrice(item)">
<image :src="$util.img('public/uniapp/index/VIP.png')" <image :src="$util.img('public/uniapp/index/VIP.png')"
mode="widthFix" /> mode="widthFix" show-menu-by-longpress/>
</view> </view>
<view class="member-price-tag" v-else-if="item.promotion_type == 1"> <view class="member-price-tag" v-else-if="item.promotion_type == 1">
<image :src="$util.img('public/uniapp/index/discount.png')" <image :src="$util.img('public/uniapp/index/discount.png')"
mode="widthFix" /> mode="widthFix" show-menu-by-longpress/>
</view> </view>
</view> </view>
<view class="pro-info"> <view class="pro-info">

View File

@@ -3,7 +3,7 @@
<view class="fui-list-group merchgroup" v-for="(item, index) in value.list" :key="index"> <view class="fui-list-group merchgroup" v-for="(item, index) in value.list" :key="index">
<view class="fui-list jump" v-if="index == 0"> <view class="fui-list jump" v-if="index == 0">
<view class="fui-list-media"> <view class="fui-list-media">
<image class="round" :src="$util.img(item.imageUrl)" style="border-radius:6rpx"></image> <image class="round" :src="$util.img(item.imageUrl)" style="border-radius:6rpx" show-menu-by-longpress></image>
</view> </view>
<view class="fui-list-inner"> <view class="fui-list-inner">
<view class="title" style="height: 75rpx;"> <view class="title" style="height: 75rpx;">

View File

@@ -1,7 +1,7 @@
<template> <template>
<view data-component-name="diy-listmenu" class="diy-listmenu" :style="style"> <view data-component-name="diy-listmenu" class="diy-listmenu" :style="style">
<view class="fui-cell-group"> <view class="fui-cell-group">
<!-- <image mode="widthFix" style="width: 100%;" :src="$util.img(item.imageUrl)"></image> --> <!-- <image mode="widthFix" style="width: 100%;" :src="$util.img(item.imageUrl)" show-menu-by-longpress></image> -->
<view v-for="(item, index) in value.list" @tap.stop="redirectTo(item.link)" class="fui-cell" <view v-for="(item, index) in value.list" @tap.stop="redirectTo(item.link)" class="fui-cell"
:class="item.iconType == 'img' ? 'img-cell' : ''"> :class="item.iconType == 'img' ? 'img-cell' : ''">

View File

@@ -25,7 +25,7 @@
<block v-if="value.isShowAnchorInfo"> <block v-if="value.isShowAnchorInfo">
<image <image
:src="liveInfo.anchor_img != '' ? $util.img(liveInfo.anchor_img) : $util.getDefaultImage().head" :src="liveInfo.anchor_img != '' ? $util.img(liveInfo.anchor_img) : $util.getDefaultImage().head"
class="anchor-img" @error="liveInfo.anchor_img = $util.getDefaultImage().head" /> class="anchor-img" @error="liveInfo.anchor_img = $util.getDefaultImage().head" show-menu-by-longpress/>
<text class="anchor-name">主播:{{ liveInfo.anchor_name }}</text> <text class="anchor-name">主播:{{ liveInfo.anchor_name }}</text>
</block> </block>
<text class="separate" v-if="value.isShowAnchorInfo && value.isShowLiveGood">|</text> <text class="separate" v-if="value.isShowAnchorInfo && value.isShowLiveGood">|</text>
@@ -109,7 +109,6 @@ export default {
} }
}) })
.catch(err => { .catch(err => {
console.log('get live status', err);
}); });
// 往后间隔1分钟或更慢的频率去轮询获取直播状态 // 往后间隔1分钟或更慢的频率去轮询获取直播状态
@@ -127,8 +126,7 @@ export default {
clearInterval(timer); clearInterval(timer);
} }
}) })
.catch(err => { .catch(err => {
console.log('get live status', err);
}); });
}, 60000); }, 60000);
// #endif // #endif

View File

@@ -6,7 +6,7 @@
<view class="info-wrap" :style="infoStyle" v-if="memberInfo"> <view class="info-wrap" :style="infoStyle" v-if="memberInfo">
<view class="headimg" @tap.stop="getWxAuth"> <view class="headimg" @tap.stop="getWxAuth">
<image :src="memberInfo.headimg ? $util.img(memberInfo.headimg) : $util.getDefaultImage().head" <image :src="memberInfo.headimg ? $util.img(memberInfo.headimg) : $util.getDefaultImage().head"
mode="widthFix" @error="memberInfo.headimg = $util.getDefaultImage().head" /> mode="widthFix" @error="memberInfo.headimg = $util.getDefaultImage().head" show-menu-by-longpress/>
</view> </view>
<view class="info"> <view class="info">
<!-- #ifdef MP --> <!-- #ifdef MP -->
@@ -66,7 +66,7 @@
<view class="info-wrap" v-else :style="infoStyle" @tap.stop="redirect($util.MEMBER_PAGE_URL)"> <view class="info-wrap" v-else :style="infoStyle" @tap.stop="redirect($util.MEMBER_PAGE_URL)">
<view class="headimg"> <view class="headimg">
<image :src="$util.getDefaultImage().head" mode="widthFix"></image> <image :src="$util.getDefaultImage().head" mode="widthFix" show-menu-by-longpress></image>
</view> </view>
<view class="info"> <view class="info">
<view class="nickname"><text class="name">{{ $lang('login') }}</text></view> <view class="nickname"><text class="name">{{ $lang('login') }}</text></view>
@@ -117,7 +117,7 @@
</block> </block>
<block v-if="value.style == 3"> <block v-if="value.style == 3">
<view class="super-info"> <view class="super-info">
<image :src="$util.img('public/uniapp/member/open_member.png')" class="title" mode="heightFix" /> <image :src="$util.img('public/uniapp/member/open_member.png')" class="title" mode="heightFix" show-menu-by-longpress/>
<view class="desc">开通可享更多权益</view> <view class="desc">开通可享更多权益</view>
</view> </view>
<view class="super-text"> <view class="super-text">
@@ -130,7 +130,7 @@
<view class="member-info-style4" v-show="value.style == 4"> <view class="member-info-style4" v-show="value.style == 4">
<view class="super-member" v-if="superMember" :style="superMemberStyle"> <view class="super-member" v-if="superMember" :style="superMemberStyle">
<view class="super-info"> <view class="super-info">
<image :src="$util.img('app/component/view/member_info/img/style_4_vip_huangguan.png')" class="title" mode="widthFix" /> <image :src="$util.img('app/component/view/member_info/img/style_4_vip_huangguan.png')" class="title" mode="widthFix" show-menu-by-longpress/>
<view class="desc">开通可享更多权益</view> <view class="desc">开通可享更多权益</view>
</view> </view>
<view class="super-text" :class="{ 'more' : memberInfo && memberInfo.member_level_type }"> <view class="super-text" :class="{ 'more' : memberInfo && memberInfo.member_level_type }">
@@ -203,7 +203,7 @@
<text class="label">头像</text> <text class="label">头像</text>
<button open-type="chooseAvatar" @chooseavatar="onChooseAvatar"> <button open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<image :src="avatarUrl ? avatarUrl : $util.getDefaultImage().head" <image :src="avatarUrl ? avatarUrl : $util.getDefaultImage().head"
@error="avatarUrl = $util.getDefaultImage().head" mode="aspectFill" /> @error="avatarUrl = $util.getDefaultImage().head" mode="aspectFill" show-menu-by-longpress/>
<text class="iconfont icon-right color-tip"></text> <text class="iconfont icon-right color-tip"></text>
</button> </button>
</view> </view>
@@ -218,7 +218,7 @@
<button open-type="getAuthorize" scope="userInfo" @getAuthorize="aliappGetUserinfo" <button open-type="getAuthorize" scope="userInfo" @getAuthorize="aliappGetUserinfo"
:plain="true" class="border-0"> :plain="true" class="border-0">
<image :src="avatarUrl ? avatarUrl : $util.getDefaultImage().head" <image :src="avatarUrl ? avatarUrl : $util.getDefaultImage().head"
@error="avatarUrl = $util.getDefaultImage().head" mode="aspectFill" /> @error="avatarUrl = $util.getDefaultImage().head" mode="aspectFill" show-menu-by-longpress/>
<text class="iconfont icon-right color-tip"></text> <text class="iconfont icon-right color-tip"></text>
</button> </button>
</view> </view>

View File

@@ -6,7 +6,7 @@
style="margin-right: 10rpx;"> style="margin-right: 10rpx;">
<view class="icon-block"> <view class="icon-block">
<template v-if="value.style == 3"> <template v-if="value.style == 3">
<image :src="$util.img('public/uniapp/member/order/wait_pay.png')" mode="widthFix" /> <image :src="$util.img('public/uniapp/member/order/wait_pay.png')" mode="widthFix" show-menu-by-longpress/>
<view class="icon-shade" <view class="icon-shade"
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_pay_shade.png') + ')'"> :style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_pay_shade.png') + ')'">
</view> </view>
@@ -25,7 +25,7 @@
style="margin-right: 10rpx;"> style="margin-right: 10rpx;">
<view class="icon-block"> <view class="icon-block">
<template v-if="value.style == 3"> <template v-if="value.style == 3">
<image :src="$util.img('public/uniapp/member/order/wait_send.png')" mode="widthFix"></image> <image :src="$util.img('public/uniapp/member/order/wait_send.png')" mode="widthFix" show-menu-by-longpress></image>
<view class="icon-shade" <view class="icon-shade"
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_send_shade.png') + ')'"> :style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_send_shade.png') + ')'">
</view> </view>
@@ -44,7 +44,7 @@
style="margin-right: 10rpx;"> style="margin-right: 10rpx;">
<view class="icon-block"> <view class="icon-block">
<template v-if="value.style == 3"> <template v-if="value.style == 3">
<image :src="$util.img('public/uniapp/member/order/wait_confirm.png')" mode="widthFix" /> <image :src="$util.img('public/uniapp/member/order/wait_confirm.png')" mode="widthFix" show-menu-by-longpress/>
<view class="icon-shade" <view class="icon-shade"
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_confirm_shade.png') + ')'"> :style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_confirm_shade.png') + ')'">
</view> </view>
@@ -63,7 +63,7 @@
style="margin-right: 10rpx;"> style="margin-right: 10rpx;">
<view class="icon-block"> <view class="icon-block">
<template v-if="value.style == 3"> <template v-if="value.style == 3">
<image :src="$util.img('public/uniapp/member/order/wait_use.png')" mode="widthFix" /> <image :src="$util.img('public/uniapp/member/order/wait_use.png')" mode="widthFix" show-menu-by-longpress/>
<view class="icon-shade" <view class="icon-shade"
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_rate_shade.png') + ')'"> :style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/wait_rate_shade.png') + ')'">
</view> </view>
@@ -79,7 +79,7 @@
<view class="item-wrap" @tap.stop="redirect('/pages_tool/order/activist')"> <view class="item-wrap" @tap.stop="redirect('/pages_tool/order/activist')">
<view class="icon-block"> <view class="icon-block">
<template v-if="value.style == 3"> <template v-if="value.style == 3">
<image :src="$util.img('public/uniapp/member/order/refunding.png')" mode="widthFix" /> <image :src="$util.img('public/uniapp/member/order/refunding.png')" mode="widthFix" show-menu-by-longpress/>
<view class="icon-shade" <view class="icon-shade"
:style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/refunding_shade.png') + ')'"> :style="'-webkit-mask-image: url(' + $util.img('public/uniapp/member/order/refunding_shade.png') + ')'">
</view> </view>

View File

@@ -7,7 +7,7 @@
:style="itemCss" @tap.stop="handlerClick(item)"> :style="itemCss" @tap.stop="handlerClick(item)">
<view class="merch-img"> <view class="merch-img">
<image class="cover-img" :src="$util.img(item.merch_image)" mode="widthFix" <image class="cover-img" :src="$util.img(item.merch_image)" mode="widthFix"
@error="imgError(index)" /> @error="imgError(index)" show-menu-by-longpress />
</view> </view>
<view class="info-wrap"> <view class="info-wrap">
<text class="title">{{ item.merch_name }}</text> <text class="title">{{ item.merch_name }}</text>
@@ -30,7 +30,7 @@
:style="{ fontSize: value.imageSize * 2 + 'rpx', width: value.imageSize * 2 + 'rpx', height: value.imageSize * 2 + 'rpx' }"> :style="{ fontSize: value.imageSize * 2 + 'rpx', width: value.imageSize * 2 + 'rpx', height: value.imageSize * 2 + 'rpx' }">
<image <image
:src="$util.img(item.merch_image) || $util.img('public/uniapp/default_img/goods.png')" :src="$util.img(item.merch_image) || $util.img('public/uniapp/default_img/goods.png')"
mode="aspectFill" :show-menu-by-longpress="true" mode="aspectFill" show-menu-by-longpress
style="max-width: 80rpx; max-height: 80rpx; border-radius: 50rpx;" /> style="max-width: 80rpx; max-height: 80rpx; border-radius: 50rpx;" />
</view> </view>
<text class="graphic-text" <text class="graphic-text"
@@ -119,7 +119,6 @@ export default {
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
} }
console.log(obj)
return obj; return obj;
}, },
// 子项样式 // 子项样式
@@ -140,14 +139,12 @@ export default {
} }
return obj; return obj;
} }
}, },
methods: { methods: {
getList() { getList() {
console.log(121)
var data = { var data = {
num: this.value.count num: this.value.count
}; };
console.log(this.value)
if (this.value.sources == 'diy') { if (this.value.sources == 'diy') {
data.num = 0; data.num = 0;
data.merch_id_arr = this.value.merchIds.toString(); data.merch_id_arr = this.value.merchIds.toString();

View File

@@ -25,10 +25,10 @@
<view class="notes-img-wrap" :class="{ 'notes-img-wrap-list': item.cover_type == 1 }"> <view class="notes-img-wrap" :class="{ 'notes-img-wrap-list': item.cover_type == 1 }">
<image v-if="item.cover_type == 0" :src="$util.img(item.img)" @error="imageError(i)" <image v-if="item.cover_type == 0" :src="$util.img(item.img)" @error="imageError(i)"
mode="aspectFill" class="notes-item-image" /> mode="aspectFill" class="notes-item-image" show-menu-by-longpress/>
<image v-else v-for="(imgItem, imgIndex) in item.img" :key="imgIndex" <image v-else v-for="(imgItem, imgIndex) in item.img" :key="imgIndex"
:src="$util.img(imgItem)" @error="imageError(i)" mode="aspectFit" :src="$util.img(imgItem)" @error="imageError(i)" mode="aspectFit"
class="notes-item-image-li" /> class="notes-item-image-li" show-menu-by-longpress/>
</view> </view>
<view class="notes-item-con"> <view class="notes-item-con">

View File

@@ -75,8 +75,6 @@ export default {
// 允许从相机和相册扫码,h5端不起作用 // 允许从相机和相册扫码,h5端不起作用
uni.scanCode({ uni.scanCode({
success: function (res) { success: function (res) {
console.log('条码类型:' + res.scanType);
console.log('条码内容:' + res.result);
} }
}); });
// #endif // #endif

View File

@@ -3,9 +3,9 @@
<view class="fui-picture"> <view class="fui-picture">
<view v-for="(item, index) in value.list" style="line-height: 0;"> <view v-for="(item, index) in value.list" style="line-height: 0;">
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" <image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)"
v-if="item.link.wap_url" @tap.stop="handlerClick(item)"></image> v-if="item.link.wap_url" @tap.stop="handlerClick(item)" show-menu-by-longpress></image>
<image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-else <image mode="widthFix" style="width: 100%;height:auto" :src="$util.img(item.imageUrl)" v-else
@tap.stop="handlerClick(item)"></image> @tap.stop="handlerClick(item)" show-menu-by-longpress></image>
</view> </view>
<!-- <view wx:if="{{!childitem.linkurl}}" bindtap="previewImg" data-src="{{childitem.imgurl}}" style="padding:{{diyitem.style.paddingtop==0?0:diyitem.style.paddingtop+'rpx'}} {{diyitem.style.paddingleft==0?0:diyitem.style.paddingleft+'rpx'}}" wx:for="{{diyitem.data}}" wx:for-index="childid" wx:for-item="childitem" wx:key="{{childid}}"> <!-- <view wx:if="{{!childitem.linkurl}}" bindtap="previewImg" data-src="{{childitem.imgurl}}" style="padding:{{diyitem.style.paddingtop==0?0:diyitem.style.paddingtop+'rpx'}} {{diyitem.style.paddingleft==0?0:diyitem.style.paddingleft+'rpx'}}" wx:for="{{diyitem.data}}" wx:for-index="childid" wx:for-item="childitem" wx:key="{{childid}}">
<image mode="widthFix" src="{{childitem.imgurl}}" style="{{bannerheight?'height:'+bannerheight+'px':'height:auto'}}"></image> <image mode="widthFix" src="{{childitem.imgurl}}" style="{{bannerheight?'height:'+bannerheight+'px':'height:auto'}}"></image>

View File

@@ -7,7 +7,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(index)" /> @error="imageError(index)" show-menu-by-longpress/>
</view> </view>
<view class="content" <view class="content"
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control"> v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control">
@@ -66,7 +66,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(index)" /> @error="imageError(index)" show-menu-by-longpress/>
</view> </view>
<view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]" <view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]"
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl"> v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
@@ -117,7 +117,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(dataIndex)" /> @error="imageError(dataIndex)" show-menu-by-longpress/>
</view> </view>
<view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]" <view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]"
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl"> v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">

View File

@@ -10,18 +10,18 @@
:style="{ fontSize: value.titleStyle.fontSize * 2 + 'rpx', color: value.titleStyle.textColor, fontWeight: value.titleStyle.fontWeight ? 'bold' : '' }"> :style="{ fontSize: value.titleStyle.fontSize * 2 + 'rpx', color: value.titleStyle.textColor, fontWeight: value.titleStyle.fontWeight ? 'bold' : '' }">
{{ value.titleStyle.leftText }} {{ value.titleStyle.leftText }}
</view> </view>
<image v-else class="left-img" :src="$util.img(value.titleStyle.leftImg)" mode="heightFix" /> <image v-else class="left-img" :src="$util.img(value.titleStyle.leftImg)" mode="heightFix" show-menu-by-longpress/>
<view class="head-content"> <view class="head-content">
<view class="img-warp"> <view class="img-warp">
<block v-if="headData && headData.member_list && headData.member_list.length"> <block v-if="headData && headData.member_list && headData.member_list.length">
<image v-for="(item, index) in headData.member_list" :key="index" <image v-for="(item, index) in headData.member_list" :key="index"
:src="$util.img(item.member_img || 'public/static/img/default_img/square.png')" :src="$util.img(item.member_img || 'public/static/img/default_img/square.png')"
mode="aspectFill" @error="headImageError(index)" /> mode="aspectFill" @error="headImageError(index)" show-menu-by-longpress/>
</block> </block>
<block v-else> <block v-else>
<image :src="$util.img('public/static/img/default_img/square.png')" mode="aspectFill" /> <image :src="$util.img('public/static/img/default_img/square.png')" mode="aspectFill" show-menu-by-longpress/>
<image :src="$util.img('public/static/img/default_img/square.png')" mode="aspectFill" /> <image :src="$util.img('public/static/img/default_img/square.png')" mode="aspectFill" show-menu-by-longpress/>
<image :src="$util.img('public/static/img/default_img/square.png')" mode="aspectFill" /> <image :src="$util.img('public/static/img/default_img/square.png')" mode="aspectFill" show-menu-by-longpress/>
</block> </block>
</view> </view>
<view :style="{ color: value.titleStyle.textColor }"> <view :style="{ color: value.titleStyle.textColor }">
@@ -43,7 +43,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(index)" /> @error="imageError(index)" show-menu-by-longpress/>
</view> </view>
<view class="content" <view class="content"
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control"> v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.priceStyle.lineControl || value.btnStyle.control">
@@ -105,7 +105,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(index)" /> @error="imageError(index)" show-menu-by-longpress/>
<view v-if="value.groupStyle.control && value.style == 'style-1'" class="num" :style="{ <view v-if="value.groupStyle.control && value.style == 'style-1'" class="num" :style="{
color: value.theme == 'diy' ? value.groupStyle.color : '', color: value.theme == 'diy' ? value.groupStyle.color : '',
background: value.theme == 'diy' ? 'linear-gradient(to right,' + value.groupStyle.bgColorStart + ',' + value.groupStyle.bgColorEnd + ')' : '' background: value.theme == 'diy' ? 'linear-gradient(to right,' + value.groupStyle.bgColorStart + ',' + value.groupStyle.bgColorEnd + ')' : ''
@@ -165,7 +165,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(dataIndex)" /> @error="imageError(dataIndex)" show-menu-by-longpress/>
<view v-if="value.groupStyle.control && value.style != 'style-2'" class="num" :style="{ <view v-if="value.groupStyle.control && value.style != 'style-2'" class="num" :style="{
color: value.theme == 'diy' ? value.groupStyle.color : '', color: value.theme == 'diy' ? value.groupStyle.color : '',
background: value.theme == 'diy' ? 'linear-gradient(to right,' + value.groupStyle.bgColorStart + ',' + value.groupStyle.bgColorEnd + ')' : '' background: value.theme == 'diy' ? 'linear-gradient(to right,' + value.groupStyle.bgColorStart + ',' + value.groupStyle.bgColorEnd + ')' : ''

View File

@@ -7,7 +7,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(index)" /> @error="imageError(index)" show-menu-by-longpress/>
</view> </view>
<view class="content" <view class="content"
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.btnStyle.control"> v-if="value.goodsNameStyle.control || value.priceStyle.mainControl || value.btnStyle.control">
@@ -45,7 +45,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(index)" /> @error="imageError(index)" show-menu-by-longpress/>
</view> </view>
<view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]" <view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]"
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl"> v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
@@ -79,7 +79,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(dataIndex)" /> @error="imageError(dataIndex)" show-menu-by-longpress/>
</view> </view>
<view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]" <view :class="['content', { 'multi-content': value.nameLineMode == 'multiple' }]"
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl"> v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">

View File

@@ -10,7 +10,7 @@
<view class="quick-img" v-if="item.imageUrl || item.icon"> <view class="quick-img" v-if="item.imageUrl || item.icon">
<image v-if="item.iconType == 'img'" <image v-if="item.iconType == 'img'"
:src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')"
mode="heightFix" :show-menu-by-longpress="true"></image> mode="heightFix" show-menu-by-longpress ></image>
<diy-icon v-if="item.iconType == 'icon'" :icon="item.icon" <diy-icon v-if="item.iconType == 'icon'" :icon="item.icon"
:value="item.style ? item.style : null" :style="{ fontSize: '60rpx' }"></diy-icon> :value="item.style ? item.style : null" :style="{ fontSize: '60rpx' }"></diy-icon>
</view> </view>

View File

@@ -11,7 +11,7 @@
<view :class="['item', value.mode]" @tap.stop="handlerClick(value.list[0].link, value.list[0].imageUrl)" <view :class="['item', value.mode]" @tap.stop="handlerClick(value.list[0].link, value.list[0].imageUrl)"
:style="{ marginRight: value.imageGap * 2 + 'rpx', width: list[0].imgWidth, height: list[0].imgHeight + 'px' }"> :style="{ marginRight: value.imageGap * 2 + 'rpx', width: list[0].imgWidth, height: list[0].imgHeight + 'px' }">
<image :src="$util.img(value.list[0].imageUrl)" :mode="list[0].imageMode || 'scaleToFill'" <image :src="$util.img(value.list[0].imageUrl)" :mode="list[0].imageMode || 'scaleToFill'"
:style="list[0].pageItemStyle" :show-menu-by-longpress="true" /> :style="list[0].pageItemStyle" show-menu-by-longpress />
</view> </view>
</view> </view>
@@ -19,9 +19,9 @@
<template v-for="(item, index) in list"> <template v-for="(item, index) in list">
<template v-if="index > 0"> <template v-if="index > 0">
<view :key="index" :class="['item', value.mode]" @tap.stop="handlerClick(item.link, item.imageUrl)" <view :key="index" :class="['item', value.mode]" @tap.stop="handlerClick(item.link, item.imageUrl)"
:style="{ marginBottom: value.imageGap * 2 + 'rpx', width: item.imgWidth, height: item.imgHeight + 'px' }"> :style="{ marginBottom: index < list.length - 1 ? value.imageGap * 2 + 'rpx' : 0, width: item.imgWidth, height: item.imgHeight + 'px' }">
<image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'" <image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'"
:style="item.pageItemStyle" :show-menu-by-longpress="true" /> :style="item.pageItemStyle" show-menu-by-longpress />
</view> </view>
</template> </template>
</template> </template>
@@ -35,7 +35,7 @@
:style="{ marginRight: value.imageGap * 2 + 'rpx', width: list[0].imgWidth, height: list[0].imgHeight + 'px' }" :style="{ marginRight: value.imageGap * 2 + 'rpx', width: list[0].imgWidth, height: list[0].imgHeight + 'px' }"
@tap.stop="handlerClick(value.list[0].link, value.list[0].imageUrl)"> @tap.stop="handlerClick(value.list[0].link, value.list[0].imageUrl)">
<image :src="$util.img(value.list[0].imageUrl)" :mode="list[0].imageMode || 'scaleToFill'" <image :src="$util.img(value.list[0].imageUrl)" :mode="list[0].imageMode || 'scaleToFill'"
:style="list[0].pageItemStyle" :show-menu-by-longpress="true" /> :style="list[0].pageItemStyle" show-menu-by-longpress />
</view> </view>
</view> </view>
@@ -44,7 +44,7 @@
:style="{ marginBottom: value.imageGap * 2 + 'rpx', width: list[1].imgWidth, height: list[1].imgHeight + 'px' }" :style="{ marginBottom: value.imageGap * 2 + 'rpx', width: list[1].imgWidth, height: list[1].imgHeight + 'px' }"
@tap.stop="handlerClick(value.list[1].link, value.list[1].imageUrl)"> @tap.stop="handlerClick(value.list[1].link, value.list[1].imageUrl)">
<image :src="$util.img(value.list[1].imageUrl)" :mode="list[1].imageMode || 'scaleToFill'" <image :src="$util.img(value.list[1].imageUrl)" :mode="list[1].imageMode || 'scaleToFill'"
:style="list[1].pageItemStyle" :show-menu-by-longpress="true" /> :style="list[1].pageItemStyle" show-menu-by-longpress />
</view> </view>
<view class="template-bottom"> <view class="template-bottom">
<template v-for="(item, index) in list"> <template v-for="(item, index) in list">
@@ -55,7 +55,7 @@
height: item.imgHeight + 'px' height: item.imgHeight + 'px'
}"> }">
<image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'" <image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'"
:style="item.pageItemStyle" :show-menu-by-longpress="true" /> :style="item.pageItemStyle" show-menu-by-longpress />
</view> </view>
</template> </template>
</template> </template>
@@ -68,7 +68,7 @@
@tap.stop="handlerClick(item.link, item.imageUrl)" @tap.stop="handlerClick(item.link, item.imageUrl)"
:style="{ marginRight: value.imageGap * 2 + 'rpx', marginBottom: value.imageGap * 2 + 'rpx', width: item.widthStyle, height: item.imgHeight + 'px' }"> :style="{ marginRight: value.imageGap * 2 + 'rpx', marginBottom: value.imageGap * 2 + 'rpx', width: item.widthStyle, height: item.imgHeight + 'px' }">
<image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'" <image :src="$util.img(item.imageUrl)" :mode="item.imageMode || 'scaleToFill'"
:style="item.pageItemStyle" :show-menu-by-longpress="true" /> :style="item.pageItemStyle" show-menu-by-longpress />
</view> </view>
</template> </template>
</view> </view>
@@ -235,8 +235,6 @@ export default {
*/ */
calcRowOneLeftOfTwoRight() { calcRowOneLeftOfTwoRight() {
let rightHeight = 0; // 右侧两图平分高度 let rightHeight = 0; // 右侧两图平分高度
let divide = 'left'; // 划分规则,left:左,right:右
if (this.list[1].imgWidth === this.list[2].imgWidth) divide = 'right';
uni.getSystemInfo({ uni.getSystemInfo({
success: res => { success: res => {
this.list.forEach((item, index) => { this.list.forEach((item, index) => {
@@ -246,12 +244,14 @@ export default {
item.imgWidth = item.imgWidth / 2; item.imgWidth = item.imgWidth / 2;
item.imgHeight = item.imgWidth * ratio; item.imgHeight = item.imgWidth * ratio;
rightHeight = (item.imgHeight - uni.upx2px(this.value.imageGap * 2)) / 2; rightHeight = (item.imgHeight - uni.upx2px(this.value.imageGap * 2)) / 2;
item.imgWidth += 'px';
} else { } else {
item.imgWidth = this.list[0].imgWidth;
item.imgHeight = rightHeight; item.imgHeight = rightHeight;
} }
}); });
// 统一追加 px 单位
this.list.forEach((item) => {
item.imgWidth += 'px';
});
} }
}); });
}, },
@@ -311,7 +311,6 @@ export default {
this.list.forEach((item, index) => { this.list.forEach((item, index) => {
item.imgWidth += 'px'; item.imgWidth += 'px';
item.imgHeight;
}); });
} }
}); });
@@ -482,7 +481,7 @@ export default {
// 一左两右 // 一左两右
.rubik-cube .template-left, .rubik-cube .template-left,
.rubik-cube .template-right { .rubik-cube .template-right {
// width: 50%; width: 50%;
box-sizing: border-box; box-sizing: border-box;
} }

View File

@@ -5,7 +5,7 @@
@tap.stop="handlerSearchClick"> @tap.stop="handlerSearchClick">
<block v-if="[1, 2].includes(value.searchStyle)"> <block v-if="[1, 2].includes(value.searchStyle)">
<view class="img" v-if="value.searchStyle == 2 && value.iconType == 'img'"> <view class="img" v-if="value.searchStyle == 2 && value.iconType == 'img'">
<image :src="$util.img(value.imageUrl)" mode="heightFix" /> <image :src="$util.img(value.imageUrl)" mode="heightFix" show-menu-by-longpress/>
</view> </view>
<diy-icon class="icon" v-if="value.searchStyle == 2 && value.iconType == 'icon'" :icon="value.icon" <diy-icon class="icon" v-if="value.searchStyle == 2 && value.iconType == 'icon'" :icon="value.icon"
:value="value.style ? value.style : 'null'" :value="value.style ? value.style : 'null'"
@@ -32,7 +32,7 @@
</view> </view>
<view class="img" v-if="value.iconType == 'img'" <view class="img" v-if="value.iconType == 'img'"
@tap.stop="handlerRedirectToClick(value.searchLink)"> @tap.stop="handlerRedirectToClick(value.searchLink)">
<image :src="$util.img(value.imageUrl)" mode="heightFix" /> <image :src="$util.img(value.imageUrl)" mode="heightFix" show-menu-by-longpress/>
</view> </view>
<diy-icon class="icon" v-if="value.iconType == 'icon'" :icon="value.icon" <diy-icon class="icon" v-if="value.iconType == 'icon'" :icon="value.icon"
:value="value.style ? value.style : 'null'" :value="value.style ? value.style : 'null'"

View File

@@ -11,7 +11,7 @@
:style="{ fontSize: value.titleStyle.fontSize * 2 + 'rpx', color: value.titleStyle.textColor, fontWeight: value.titleStyle.fontWeight ? 'bold' : '' }"> :style="{ fontSize: value.titleStyle.fontSize * 2 + 'rpx', color: value.titleStyle.textColor, fontWeight: value.titleStyle.fontWeight ? 'bold' : '' }">
{{ value.titleStyle.leftText }} {{ value.titleStyle.leftText }}
</view> </view>
<image v-else class="title-img" :src="$util.img(value.titleStyle.leftImg)" mode="heightFix" /> <image v-else class="title-img" :src="$util.img(value.titleStyle.leftImg)" mode="heightFix" show-menu-by-longpress/>
<text v-if="value.titleStyle.style == 'style-2' && isFuture" <text v-if="value.titleStyle.style == 'style-2' && isFuture"
:style="{ color: value.titleStyle.textColor }" class="seckill-style-name">距离开始</text> :style="{ color: value.titleStyle.textColor }" class="seckill-style-name">距离开始</text>
<view class="time" :style="{ background: value.titleStyle.timeBgColor }"> <view class="time" :style="{ background: value.titleStyle.timeBgColor }">
@@ -40,7 +40,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(index)" /> @error="imageError(index)" show-menu-by-longpress/>
</view> </view>
<view class="content"> <view class="content">
<view class="goods-name" v-if="value.goodsNameStyle.control" <view class="goods-name" v-if="value.goodsNameStyle.control"
@@ -57,7 +57,7 @@
}"> }">
<image v-if="value.style == 'style-2'" class="progress-bar" <image v-if="value.style == 'style-2'" class="progress-bar"
:src="$util.img('public/uniapp/seckill/progress_bar_01.png')" :src="$util.img('public/uniapp/seckill/progress_bar_01.png')"
mode="widthFix" /> mode="widthFix" show-menu-by-longpress/>
</view> </view>
</view> </view>
<view class="num" <view class="num"
@@ -110,7 +110,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(index)" /> @error="imageError(index)" show-menu-by-longpress/>
</view> </view>
<view class="content" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl"> <view class="content" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
<view class="goods-name" v-if="value.goodsNameStyle.control" <view class="goods-name" v-if="value.goodsNameStyle.control"
@@ -155,7 +155,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(index)" /> @error="imageError(index)" show-menu-by-longpress/>
</view> </view>
<view class="content" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl"> <view class="content" v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
<view class="goods-name" v-if="value.goodsNameStyle.control" <view class="goods-name" v-if="value.goodsNameStyle.control"
@@ -166,7 +166,7 @@
<view class="discount-price" v-if="value.priceStyle.mainControl"> <view class="discount-price" v-if="value.priceStyle.mainControl">
<image v-if="value.style == 'style-2'" class="tag" <image v-if="value.style == 'style-2'" class="tag"
:src="$util.img('addon/seckill/component/view/seckill/img/style_4_tag.png')" :src="$util.img('addon/seckill/component/view/seckill/img/style_4_tag.png')"
mode="widthFix" /> mode="widthFix" show-menu-by-longpress/>
<text class="unit price-style small" <text class="unit price-style small"
:style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">¥</text> :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">¥</text>
<text class="price price-style large" <text class="price price-style large"
@@ -194,7 +194,7 @@
<view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"> <view class="img-wrap" :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }">
<image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }" <image :style="{ borderRadius: value.imgAroundRadius * 2 + 'rpx' }"
:src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix" :src="$util.img(item.goods_image, { size: 'mid' })" mode="widthFix"
@error="imageError(dataIndex, pageIndex)" /> @error="imageError(dataIndex, pageIndex)" show-menu-by-longpress/>
</view> </view>
<view class="content" <view class="content"
v-if="value.goodsNameStyle.control || value.priceStyle.mainControl"> v-if="value.goodsNameStyle.control || value.priceStyle.mainControl">
@@ -206,7 +206,7 @@
<view class="discount-price" v-if="value.priceStyle.mainControl"> <view class="discount-price" v-if="value.priceStyle.mainControl">
<image v-if="value.style == 'style-2'" class="tag" <image v-if="value.style == 'style-2'" class="tag"
:src="$util.img('addon/seckill/component/view/seckill/img/style_4_tag.png')" :src="$util.img('addon/seckill/component/view/seckill/img/style_4_tag.png')"
mode="widthFix" /> mode="widthFix" show-menu-by-longpress/>
<text class="unit price-style small" <text class="unit price-style small"
:style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">¥</text> :style="{ color: value.theme == 'diy' ? value.priceStyle.mainColor : '' }">¥</text>
<text class="price price-style large" <text class="price price-style large"

View File

@@ -22,8 +22,8 @@
</view> </view>
<view class="store-image" @tap.stop="selectStore()"> <view class="store-image" @tap.stop="selectStore()">
<image :src="$util.img(globalStoreInfo.store_image)" <image :src="$util.img(globalStoreInfo.store_image)"
v-if="globalStoreInfo && globalStoreInfo.store_image" mode="aspectFill"></image> v-if="globalStoreInfo && globalStoreInfo.store_image" mode="aspectFill" show-menu-by-longpress></image>
<image :src="$util.getDefaultImage().store" v-else mode="aspectFill"></image> <image :src="$util.getDefaultImage().store" v-else mode="aspectFill" show-menu-by-longpress></image>
</view> </view>
</view> </view>
</block> </block>
@@ -33,8 +33,8 @@
<view class="store-info"> <view class="store-info">
<view class="store-image" @tap.stop="selectStore()"> <view class="store-image" @tap.stop="selectStore()">
<image :src="$util.img(globalStoreInfo.store_image)" <image :src="$util.img(globalStoreInfo.store_image)"
v-if="globalStoreInfo && globalStoreInfo.store_image" mode="aspectFill"></image> v-if="globalStoreInfo && globalStoreInfo.store_image" mode="aspectFill" show-menu-by-longpress></image>
<image :src="$util.getDefaultImage().store" v-else mode="aspectFill"></image> <image :src="$util.getDefaultImage().store" v-else mode="aspectFill" show-menu-by-longpress></image>
</view> </view>
<view class="info-box" :style="{ color: value.textColor }"> <view class="info-box" :style="{ color: value.textColor }">
<block v-if="globalStoreInfo && globalStoreInfo.store_id"> <block v-if="globalStoreInfo && globalStoreInfo.store_id">

View File

@@ -30,12 +30,14 @@
<!-- 内容区域 --> <!-- 内容区域 -->
<view class="tab-content" :style="[contentStyle]"> <view class="tab-content" :style="[contentStyle]">
<view v-for="(tab, idx) in mergedValue.tabs" :key="getPanelKey(tab, idx)" class="tab-panel" <view v-for="(tab, idx) in mergedValue.tabs" :key="getPanelKey(tab, idx)"
class="tab-panel"
:class="{ active: activeTab === idx }" :class="{ active: activeTab === idx }"
v-if="activeTab === idx"
:style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]"> :style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]">
<view v-if="tab.components && tab.components.length > 0" class="tab-components"> <view v-if="tab.components && tab.components.length > 0" class="tab-components">
<!-- 渲染每个标签下的组件 --> <!-- 渲染每个标签下的组件 -->
<diy-group v-if="tab.components" :diyData="{ value: tab.components, global: diyGlobal, tabIndex: idx }" <diy-group :diyData="{ value: tab.components, global: diyGlobal, tabIndex: idx }"
:scrollTop="tab.scrollTop || 0" /> :scrollTop="tab.scrollTop || 0" />
</view> </view>
</view> </view>
@@ -46,12 +48,14 @@
<template v-else-if="mergedValue.tabPosition === 'bottom'"> <template v-else-if="mergedValue.tabPosition === 'bottom'">
<!-- 内容区域 --> <!-- 内容区域 -->
<view class="tab-content" :style="[contentStyle]"> <view class="tab-content" :style="[contentStyle]">
<view v-for="(tab, idx) in mergedValue.tabs" :key="getPanelKey(tab, idx)" class="tab-panel" <view v-for="(tab, idx) in mergedValue.tabs" :key="getPanelKey(tab, idx)"
class="tab-panel"
:class="{ active: activeTab === idx }" :class="{ active: activeTab === idx }"
v-if="activeTab === idx"
:style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]"> :style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]">
<view v-if="tab.components && tab.components.length > 0" class="tab-components"> <view v-if="tab.components && tab.components.length > 0" class="tab-components">
<!-- 渲染每个标签下的组件 --> <!-- 渲染每个标签下的组件 -->
<diy-group v-if="tab.components" :diyData="{ value: tab.components, global: diyGlobal, tabIndex: idx }" <diy-group :diyData="{ value: tab.components, global: diyGlobal, tabIndex: idx }"
:scrollTop="tab.scrollTop || 0" /> :scrollTop="tab.scrollTop || 0" />
</view> </view>
</view> </view>
@@ -110,12 +114,14 @@
<!-- 右侧内容区域 --> <!-- 右侧内容区域 -->
<view class="tab-content" :style="[contentStyle]"> <view class="tab-content" :style="[contentStyle]">
<view v-for="(tab, idx) in mergedValue.tabs" :key="getPanelKey(tab, idx)" class="tab-panel" <view v-for="(tab, idx) in mergedValue.tabs" :key="getPanelKey(tab, idx)"
class="tab-panel"
:class="{ active: activeTab === idx }" :class="{ active: activeTab === idx }"
v-if="activeTab === idx"
:style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]"> :style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]">
<view v-if="tab.components && tab.components.length > 0" class="tab-components"> <view v-if="tab.components && tab.components.length > 0" class="tab-components">
<!-- 渲染每个标签下的组件 --> <!-- 渲染每个标签下的组件 -->
<diy-group v-if="tab.components" :diyData="{ value: tab.components, global: diyGlobal }" <diy-group :diyData="{ value: tab.components, global: diyGlobal }"
:scrollTop="tab.scrollTop || 0" /> :scrollTop="tab.scrollTop || 0" />
</view> </view>
</view> </view>
@@ -128,12 +134,14 @@
<view class="tab-layout-horizontal"> <view class="tab-layout-horizontal">
<!-- 左侧内容区域 --> <!-- 左侧内容区域 -->
<view class="tab-content" :style="[contentStyle]"> <view class="tab-content" :style="[contentStyle]">
<view v-for="(tab, idx) in mergedValue.tabs" :key="getPanelKey(tab, idx)" class="tab-panel" <view v-for="(tab, idx) in mergedValue.tabs" :key="getPanelKey(tab, idx)"
class="tab-panel"
:class="{ active: activeTab === idx }" :class="{ active: activeTab === idx }"
v-if="activeTab === idx"
:style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]"> :style="[panelStyle, activeTab === idx ? panelActiveStyle : {}]">
<view v-if="tab.components && tab.components.length > 0" class="tab-components"> <view v-if="tab.components && tab.components.length > 0" class="tab-components">
<!-- 渲染每个标签下的组件 --> <!-- 渲染每个标签下的组件 -->
<diy-group v-if="tab.components" :diyData="{ value: tab.components, global: diyGlobal }" <diy-group :diyData="{ value: tab.components, global: diyGlobal }"
:scrollTop="tab.scrollTop || 0" /> :scrollTop="tab.scrollTop || 0" />
</view> </view>
</view> </view>
@@ -213,10 +221,7 @@ export default {
// 组件创建钩子 // 组件创建钩子
created() { created() {
console.log(`diy-tab-create`, {
value: this.mergedValue,
tabs: this.mergedValue.tabs
});
}, },
// 组件挂载钩子 // 组件挂载钩子
@@ -913,7 +918,7 @@ export default {
// ===== 主容器样式 ===== // ===== 主容器样式 =====
.tab-diy-component-preview-container { .tab-diy-component-preview-container {
width: 100%; width: 100%;
min-height: 300px; min-height: 0px;
display: flex; display: flex;
border: 1px solid #e0e0e0; border: 1px solid #e0e0e0;
border-radius: 4px; border-radius: 4px;
@@ -1135,7 +1140,6 @@ export default {
// ===== 标签面板样式 ===== // ===== 标签面板样式 =====
.tab-panel { .tab-panel {
display: none;
opacity: 0; opacity: 0;
transform: translateY(8px); transform: translateY(8px);
transition: opacity var(--animation-duration, 0.3s) var(--animation-timing-function, ease-in-out), transform var(--animation-duration, 0.3s) var(--animation-timing-function, ease-in-out); transition: opacity var(--animation-duration, 0.3s) var(--animation-timing-function, ease-in-out), transform var(--animation-duration, 0.3s) var(--animation-timing-function, ease-in-out);
@@ -1143,10 +1147,10 @@ export default {
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
min-height: 200px; min-height: 200px;
// 显示/隐藏由 v-show 控制,不使用 display: none
// 激活状态 // 激活状态
&.active { &.active {
display: block;
opacity: 1; opacity: 1;
transform: translateY(0); transform: translateY(0);
transition: opacity var(--animation-duration, 0.3s) var(--animation-timing-function, ease-in-out), transform var(--animation-duration, 0.3s) var(--animation-timing-function, ease-in-out); transition: opacity var(--animation-duration, 0.3s) var(--animation-timing-function, ease-in-out), transform var(--animation-duration, 0.3s) var(--animation-timing-function, ease-in-out);

View File

@@ -89,14 +89,14 @@
<view class="style9-box"> <view class="style9-box">
<view class="style9-center"> <view class="style9-center">
<view class="left-img"> <view class="left-img">
<image :src="$util.img('public/uniapp/diy/style9-1.png')" /> <image :src="$util.img('public/uniapp/diy/style9-1.png')" show-menu-by-longpress/>
</view> </view>
<text class="style9-title" <text class="style9-title"
:style="{ fontSize: value.fontSize * 2 + 'rpx', color: value.textColor, fontWeight: value.fontWeight }"> :style="{ fontSize: value.fontSize * 2 + 'rpx', color: value.textColor, fontWeight: value.fontWeight }">
{{ value.text }} {{ value.text }}
</text> </text>
<view class="right-img"> <view class="right-img">
<image :src="$util.img('public/uniapp/diy/style9-2.png')" /> <image :src="$util.img('public/uniapp/diy/style9-2.png')" show-menu-by-longpress/>
</view> </view>
<view class="style9-more" v-if="value.more.isShow" :style="{ color: value.more.color }" <view class="style9-more" v-if="value.more.isShow" :style="{ color: value.more.color }"
@tap.stop="handlerClick(value.more.link)"> @tap.stop="handlerClick(value.more.link)">
@@ -114,7 +114,7 @@
<view class="style10-box"> <view class="style10-box">
<view class="style10-center"> <view class="style10-center">
<view class="left-img"> <view class="left-img">
<image :src="$util.img('public/uniapp/diy/style10-1.png')"></image> <image :src="$util.img('public/uniapp/diy/style10-1.png')" show-menu-by-longpress></image>
</view> </view>
<text class="style10-title" v-if="$util.img('public/uniapp/diy/style10-3.png')" :style="{ <text class="style10-title" v-if="$util.img('public/uniapp/diy/style10-3.png')" :style="{
backgroundImage: 'url(' + $util.img('public/uniapp/diy/style10-3.png') + ')', backgroundImage: 'url(' + $util.img('public/uniapp/diy/style10-3.png') + ')',
@@ -128,7 +128,7 @@
{{ value.text }} {{ value.text }}
</text> </text>
<view class="right-img"> <view class="right-img">
<image :src="$util.img('public/uniapp/diy/style10-2.png')"></image> <image :src="$util.img('public/uniapp/diy/style10-2.png')" show-menu-by-longpress></image>
</view> </view>
<view class="style10-more" v-if="value.more.isShow" :style="{ color: value.more.color }" <view class="style10-more" v-if="value.more.isShow" :style="{ color: value.more.color }"
@tap.stop="handlerClick(value.more.link)"> @tap.stop="handlerClick(value.more.link)">
@@ -164,10 +164,10 @@
</view> </view>
<image class="center-img" :src="$util.img('public/uniapp/diy/style11-1.png')" <image class="center-img" :src="$util.img('public/uniapp/diy/style11-1.png')"
mode="widthFix"></image> mode="widthFix" show-menu-by-longpress></image>
<image class="right-img" :src="$util.img('public/uniapp/diy/style11-2.png')" <image class="right-img" :src="$util.img('public/uniapp/diy/style11-2.png')"
mode="widthFix"></image> mode="widthFix" show-menu-by-longpress></image>
</view> </view>
</view> </view>
</view> </view>
@@ -190,7 +190,7 @@
</view> </view>
</view> </view>
<view class="style13" v-else-if="value.style == 'style-13'"> <view class="style13" v-else-if="value.style == 'style-13'">
<image class="left-img" :src="$util.img('public/uniapp/diy/style13-1.png')" mode="widthFix"></image> <image class="left-img" :src="$util.img('public/uniapp/diy/style13-1.png')" mode="widthFix" show-menu-by-longpress></image>
<view class="style13-title" :style="{ <view class="style13-title" :style="{
fontSize: value.fontSize * 2 + 'rpx', fontSize: value.fontSize * 2 + 'rpx',
color: value.textColor, color: value.textColor,
@@ -198,7 +198,7 @@
}"> }">
{{ value.text }} {{ value.text }}
</view> </view>
<image class="right-img" :src="$util.img('public/uniapp/diy/style13-1.png')" mode="widthFix"></image> <image class="right-img" :src="$util.img('public/uniapp/diy/style13-1.png')" mode="widthFix" show-menu-by-longpress></image>
</view> </view>
<view class="style14" v-else-if="value.style == 'style-14'"> <view class="style14" v-else-if="value.style == 'style-14'">
<view class="title-wrap"> <view class="title-wrap">

View File

@@ -6,10 +6,10 @@
<view v-for="(item, index) in value.list" :key="index" class="goods-item" @tap="showVideo(item)"> <view v-for="(item, index) in value.list" :key="index" class="goods-item" @tap="showVideo(item)">
<view class="goods-img-wrap"> <view class="goods-img-wrap">
<image class="goods-img" style="border-radius:10rpx 10rpx 0 0;" :src="$util.img(item.imageUrl)" <image class="goods-img" style="border-radius:10rpx 10rpx 0 0;" :src="$util.img(item.imageUrl)"
mode="widthFix" @error="imgError(index)"></image> mode="widthFix" @error="imgError(index)" show-menu-by-longpress ></image>
<view style="position:absolute;top:10rpx;right:10rpx;"> <view style="position:absolute;top:10rpx;right:10rpx;">
<image style="width:30rpx;" :src="$util.img('addon/personnel/shop/view/enterprise/play.png')" <image style="width:30rpx;" :src="$util.img('addon/personnel/shop/view/enterprise/play.png')"
mode="widthFix"></image> mode="widthFix" show-menu-by-longpress ></image>
</view> </view>
</view> </view>
<view class="info-wrap"> <view class="info-wrap">
@@ -34,10 +34,10 @@
'max-height': '200rpx;', 'max-height': '200rpx;',
'border-radius': '8rpx;' 'border-radius': '8rpx;'
}" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')" mode="widthFix" }" :src="$util.img(item.imageUrl) || $util.img('public/uniapp/default_img/goods.png')" mode="widthFix"
:show-menu-by-longpress="true"></image> show-menu-by-longpress ></image>
<view style="position:absolute;top:10rpx;right:10rpx;"> <view style="position:absolute;top:10rpx;right:10rpx;">
<image style="width:30rpx;" <image style="width:30rpx;"
:src="$util.img('addon/personnel/shop/view/enterprise/play.png')" mode="widthFix"> :src="$util.img('addon/personnel/shop/view/enterprise/play.png')" mode="widthFix" show-menu-by-longpress >
</image> </image>
</view> </view>
</view> </view>
@@ -53,9 +53,19 @@
<!-- 视频播放弹窗 --> <!-- 视频播放弹窗 -->
<uni-popup ref="videoPopup" type="center" style="background:transparent;width:100%;height:100%;"> <uni-popup ref="videoPopup" type="center" style="background:transparent;width:100%;height:100%;">
<view class="video-container" style="position:fixed;top:30%;width:100%;left:0;"> <view class="video-container" :style="popupVideoStyle">
<video class="adaptive-video" :autoPauseIfNavigate="true" :autoPauseIfOpenNative="true" <video
:autoplay="false" :enableAutoRotation="true" id="myVideo" :src="video_url" :controls="true"></video> ref="popupVideoRef"
class="adaptive-video"
:autoPauseIfNavigate="true"
:autoPauseIfOpenNative="true"
:autoplay="false"
:enableAutoRotation="true"
id="myVideo"
:src="video_url"
:controls="true"
@loadedmetadata="onPopupVideoLoaded"
></video>
</view> </view>
</uni-popup> </uni-popup>
</view> </view>
@@ -104,7 +114,6 @@ export default {
style += 'box-shadow:' + (this.value.ornament.type == 'shadow' ? '0 0 10rpx ' + this.value.ornament.color : '') + ';'; style += 'box-shadow:' + (this.value.ornament.type == 'shadow' ? '0 0 10rpx ' + this.value.ornament.color : '') + ';';
style += 'border:' + (this.value.ornament.type == 'stroke' ? '2rpx solid ' + this.value.ornament.color : '') + ';'; style += 'border:' + (this.value.ornament.type == 'stroke' ? '2rpx solid ' + this.value.ornament.color : '') + ';';
console.log(this.value);
return style; return style;
}, },
@@ -126,19 +135,76 @@ export default {
isIndicatorDots() { isIndicatorDots() {
return this.value.carousel.type != 'hide' && return this.value.carousel.type != 'hide' &&
1 != Math.ceil(this.value.list.length / (this.value.pageCount * this.value.rowCount)); 1 != Math.ceil(this.value.list.length / (this.value.pageCount * this.value.rowCount));
},
// 弹窗视频容器样式
popupVideoStyle() {
let style = 'position:fixed;width:100%;left:0;';
if (this.popupVideoRatio) {
// 根据视频比例设置位置
if (this.popupVideoRatio === 'portrait') {
// 竖屏视频:居中显示,使用9/16比例
style += 'top:50%;transform:translateY(-50%);';
style += 'aspect-ratio: 9 / 16;';
} else {
// 横屏视频:靠近顶部显示,使用16/9比例
style += 'top:20%;';
style += 'aspect-ratio: 16 / 9;';
}
} else {
// 默认:居中显示,使用竖屏比例
style += 'top:50%;transform:translateY(-50%);';
style += 'aspect-ratio: 9 / 16;';
}
return style;
} }
}, },
methods: { methods: {
// 显示视频播放弹窗 // 显示视频播放弹窗
showVideo(item) { showVideo(item) {
this.video_url = item.videoUrl; this.video_url = item.videoUrl;
// 重置视频比例为null,等待新的检测结果
this.popupVideoRatio = null;
this.$refs.videoPopup.open(); this.$refs.videoPopup.open();
}, },
// 图片加载错误处理 // 图片加载错误处理
imgError(index) { imgError(index) {
// 图片加载失败的处理逻辑 // 图片加载失败的处理逻辑
console.log('图片加载失败:', index); },
// 弹窗视频加载完成事件
onPopupVideoLoaded(event) {
this.$nextTick(() => {
let width = 0;
let height = 0;
// H5 端:获取真实视频宽高
// #ifdef H5
const video = this.$refs.popupVideoRef;
if (video) {
width = video.videoWidth || 0;
height = video.videoHeight || 0;
}
// #endif
// 微信小程序端:通过事件对象获取视频宽高
// #ifdef MP-WEIXIN
if (event && event.detail) {
width = event.detail.width || 0;
height = event.detail.height || 0;
}
// #endif
if (width && height) {
this.popupVideoRatio = width >= height ? 'landscape' : 'portrait';
} else {
// 获取失败,默认竖屏
this.popupVideoRatio = 'portrait';
}
});
} }
} }
} }
@@ -164,10 +230,6 @@ export default {
width: calc(33.3333333% - 14rpx); width: calc(33.3333333% - 14rpx);
box-sizing: border-box; box-sizing: border-box;
&:nth-child(3n + 3) {
width: calc(33.33% - 15rpx);
}
&:nth-of-type(1), &:nth-of-type(1),
&:nth-of-type(2), &:nth-of-type(2),
&:nth-of-type(3) { &:nth-of-type(3) {

View File

@@ -1,7 +1,36 @@
<template> <template>
<video data-component-name="diy-video" class="diy-video" :src="$util.img(value.videoUrl)" <view class="video-container" :style="containerStyle">
:poster="$util.img(value.imageUrl)" :style="videoWarpCss" objectFit="cover" <!-- H5端使用原生video标签 -->
@tap="handlerClick(value.videoUrl)"></video> <!-- #ifdef H5 -->
<video
ref="videoRef"
data-component-name="diy-video"
class="diy-video h5-video"
:src="videoUrl"
:poster="posterUrl"
:style="videoWarpCss"
controls
preload="metadata"
@loadedmetadata="onVideoLoaded"
@click="handlerClick(videoUrl)"
></video>
<!-- #endif -->
<!-- 微信小程序端使用uni-app的video组件 -->
<!-- #ifdef MP-WEIXIN -->
<video
ref="videoRef"
data-component-name="diy-video"
class="diy-video mp-video"
:src="videoUrl"
:poster="posterUrl"
:style="videoWarpCss"
controls
@loadedmetadata="onVideoLoaded"
@error="onVideoError"
></video>
<!-- #endif -->
</view>
</template> </template>
<script> <script>
@@ -15,27 +44,149 @@ export default {
} }
}, },
data() { data() {
return {}; return {
videoRatio: null, // 视频比例:'landscape'(横屏)或 'portrait'(竖屏)
videoUrl: '',
posterUrl: ''
};
},
created() {
this.initVideoData();
}, },
created() { },
mixins: [DiyMinx], mixins: [DiyMinx],
watch: { watch: {
// 组件刷新监听 value: {
componentRefresh: function (nval) { } immediate: true,
handler(newVal) {
if (newVal) {
this.initVideoData();
}
}
}
}, },
computed: { computed: {
videoWarpCss: function () { videoWarpCss: function () {
var obj = ''; var obj = '';
if (this.value.componentAngle == 'round') { if (this.value && this.value.componentAngle == 'round') {
obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; obj += 'border-top-left-radius:' + this.value.topAroundRadius * 2 + 'rpx;';
obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;'; obj += 'border-top-right-radius:' + this.value.topAroundRadius * 2 + 'rpx;';
obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; obj += 'border-bottom-left-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;'; obj += 'border-bottom-right-radius:' + this.value.bottomAroundRadius * 2 + 'rpx;';
} }
return obj; return obj;
},
// 动态计算容器比例
containerStyle() {
let style = '';
if (this.videoRatio === 'landscape') {
// 横屏视频:16/9比例
style += 'aspect-ratio: 16 / 9;';
} else if (this.videoRatio === 'portrait') {
// 竖屏视频:9/16比例
style += 'aspect-ratio: 9 / 16;';
} else {
// 未加载完成 → 默认使用竖屏比例
style += 'aspect-ratio: 9 / 16;';
}
return style;
} }
}, },
methods: { methods: {
// 初始化视频数据
initVideoData() {
this.videoUrl = this.getVideoUrl();
this.posterUrl = this.getPosterUrl();
// H5端:预加载视频获取宽高
// #ifdef H5
this.preloadVideoForRatio();
// #endif
},
// 获取视频URL
getVideoUrl() {
if (!this.value || !this.value.videoUrl) return '';
const videoUrl = this.value.videoUrl;
// 如果是完整的http/https链接,直接使用
if (videoUrl.indexOf('http://') === 0 || videoUrl.indexOf('https://') === 0) {
return videoUrl;
}
// 否则使用$util.img()处理
return this.$util.img(videoUrl);
},
// 获取封面图URL
getPosterUrl() {
if (!this.value || !this.value.imageUrl) return '';
return this.$util.img(this.value.imageUrl);
},
// H5端:预加载视频获取宽高比例
preloadVideoForRatio() {
const videoUrl = this.videoUrl;
if (!videoUrl) return;
const video = document.createElement('video');
video.preload = 'metadata';
video.src = videoUrl;
video.muted = true;
video.playsInline = true;
video.addEventListener('loadedmetadata', () => {
const width = video.videoWidth;
const height = video.videoHeight;
if (width && height) {
this.videoRatio = width >= height ? 'landscape' : 'portrait';
}
});
video.addEventListener('error', (e) => {
console.error('H5端预加载视频失败:', e);
});
// 触发加载
video.load();
},
// 视频加载完成事件(组件内video标签)
onVideoLoaded(event) {
let width = 0;
let height = 0;
// #ifdef H5
if (event && event.target) {
width = event.target.videoWidth || 0;
height = event.target.videoHeight || 0;
}
// #endif
// #ifdef MP-WEIXIN
if (event && event.detail) {
width = event.detail.width || 0;
height = event.detail.height || 0;
}
// #endif
if (width && height) {
this.videoRatio = width >= height ? 'landscape' : 'portrait';
}
},
// 视频播放事件
onVideoPlay() {
},
// 视频暂停事件
onVideoPause() {
},
// 视频错误事件
onVideoError(event) {
console.error('视频加载失败:', event);
},
async handlerClick(videoUrl) { async handlerClick(videoUrl) {
await this.__$emitEvent({ await this.__$emitEvent({
eventName: 'video-tap', data: videoUrl, promiseCallback: (event, handler, awaitedResult) => { eventName: 'video-tap', data: videoUrl, promiseCallback: (event, handler, awaitedResult) => {
@@ -48,11 +199,32 @@ export default {
</script> </script>
<style scoped> <style scoped>
video { .video-container {
width: 100%; width: 100%;
position: relative;
overflow: hidden;
background-color: #000;
} }
.diy-video>>>.uni-video-container { /* 基础样式 */
background-color: transparent; .diy-video {
width: 100%;
height: 100%;
display: block;
} }
</style>
/* H5端样式 */
/* #ifdef H5 */
.h5-video {
object-fit: cover;
}
/* #endif */
/* 微信小程序端样式 */
/* #ifdef MP-WEIXIN */
.mp-video {
width: 100%;
height: 100%;
}
/* #endif */
</style>

View File

@@ -149,9 +149,8 @@ export const wechatChannelUtil = {
wx.openChannelsActivity({ wx.openChannelsActivity({
feedId: item.feedId, feedId: item.feedId,
finderUserName: item.finderUserName, finderUserName: item.finderUserName,
success: (res) => { success: (res) => {
console.log('打开视频号成功', res); resolve(res);
resolve(res);
}, },
fail: (err) => { fail: (err) => {
this.handleError(err, item); this.handleError(err, item);

View File

@@ -2,7 +2,6 @@ export default {
methods: { methods: {
// 异步触发事件 // 异步触发事件
async __$emitEvent(payload = {eventName: '__unnamedEvent', data: {}, promiseCallback: null}) { async __$emitEvent(payload = {eventName: '__unnamedEvent', data: {}, promiseCallback: null}) {
// console.log('__$emitEvent', payload)
await this.$eventBus.emit(payload.eventName, payload.data, payload.promiseCallback) await this.$eventBus.emit(payload.eventName, payload.data, payload.promiseCallback)
}, },

View File

@@ -13,14 +13,14 @@
<view class="message-item " :class="message.isItMe ? 'right' : 'left'"> <view class="message-item " :class="message.isItMe ? 'right' : 'left'">
<block v-if="message.isItMe"> <block v-if="message.isItMe">
<view class="head_img"> <view class="head_img">
<image class="img" :src="myHeadImg" v-if="myHeadImg" @error="myHeadImgError" mode="aspectFit"/> <image class="img" :src="myHeadImg" v-if="myHeadImg" @error="myHeadImgError" mode="aspectFit" show-menu-by-longpress/>
<image class="img" :src="defaultHead" mode="aspectFit" v-else/> <image class="img" :src="defaultHead" mode="aspectFit" v-else show-menu-by-longpress/>
</view> </view>
</block> </block>
<block v-else> <block v-else>
<view class="head_img"> <view class="head_img">
<image class="img" :src="avatar" mode="aspectFit" v-if="avatar"></image> <image class="img" :src="avatar" mode="aspectFit" v-if="avatar" show-menu-by-longpress></image>
<image class="img" :src="defaultHead" mode="aspectFit" v-else></image> <image class="img" :src="defaultHead" mode="aspectFit" v-else show-menu-by-longpress></image>
</view> </view>
</block> </block>
<view class="chat_text"> <view class="chat_text">
@@ -34,20 +34,20 @@
<view class="message-item " :class="message.isItMe ? 'right' : 'left'"> <view class="message-item " :class="message.isItMe ? 'right' : 'left'">
<block v-if="message.isItMe"> <block v-if="message.isItMe">
<view class="head_img"> <view class="head_img">
<image class="img" :src="myHeadImg" v-if="myHeadImg" mode="aspectFit"></image> <image class="img" :src="myHeadImg" v-if="myHeadImg" mode="aspectFit" show-menu-by-longpress></image>
<image class="img" :src="defaultHead" mode="aspectFit" v-else></image> <image class="img" :src="defaultHead" mode="aspectFit" v-else show-menu-by-longpress></image>
</view> </view>
</block> </block>
<block v-else> <block v-else>
<view class="head_img"> <view class="head_img">
<image class="img" :src="avatar" mode="aspectFit" v-if="avatar"></image> <image class="img" :src="avatar" mode="aspectFit" v-if="avatar" show-menu-by-longpress></image>
<image class="img" :src="defaultHead" mode="aspectFit" v-else></image> <image class="img" :src="defaultHead" mode="aspectFit" v-else show-menu-by-longpress></image>
</view> </view>
</block> </block>
<view class="chat_img"> <view class="chat_img">
<text class="iconfont icon-warn margin-right color-base-text" v-if="message.isItMe && !message.sendStatus"></text> <text class="iconfont icon-warn margin-right color-base-text" v-if="message.isItMe && !message.sendStatus"></text>
<view class="content_img" @click="previewMedia($util.img(message.image))" :style="{ backgroundImage: 'url(' + $util.img(message.image) + ')' }"> <view class="content_img" @click="previewMedia($util.img(message.image))" :style="{ backgroundImage: 'url(' + $util.img(message.image) + ')' }">
<!-- <image class="img_img" :src="$util.img(message.image)" mode="aspectFit"></image> --> <!-- <image class="img_img" :src="$util.img(message.image)" mode="aspectFit" show-menu-by-longpress></image> -->
</view> </view>
<!-- <text class="iconfont icon-warn margin-left" v-if="!message.isItMe && !message.sendStatus"></text> --> <!-- <text class="iconfont icon-warn margin-left" v-if="!message.isItMe && !message.sendStatus"></text> -->
</view> </view>
@@ -64,7 +64,7 @@
</view> </view>
<uni-popup ref="imgPopup" type="center"> <uni-popup ref="imgPopup" type="center">
<view class="imagePop"> <view class="imagePop">
<image :src="$util.img(currImg)" mode="aspectFit"></image> <image :src="$util.img(currImg)" mode="aspectFit" show-menu-by-longpress></image>
</view> </view>
</uni-popup> </uni-popup>
</view> </view>

View File

@@ -18,7 +18,6 @@
v-if="fixBtnShow && hasValidKefuConfig && isWeappOfficialKefu" v-if="fixBtnShow && hasValidKefuConfig && isWeappOfficialKefu"
class="btn-item common-bg" class="btn-item common-bg"
open-type="contact" open-type="contact"
:style="{ backgroundImage: currentKefuImg ? `url(${currentKefuImg})` : '', backgroundSize: '100% 100%' }"
> >
<text class="icox icox-kefu" v-if="!kefuimg"></text> <text class="icox icox-kefu" v-if="!kefuimg"></text>
</button> </button>
@@ -28,8 +27,13 @@
v-if="fixBtnShow && hasValidKefuConfig && !isWeappOfficialKefu && !showWeappSystemKefu" v-if="fixBtnShow && hasValidKefuConfig && !isWeappOfficialKefu && !showWeappSystemKefu"
class="btn-item common-bg" class="btn-item common-bg"
@click="handleUnifiedKefuClick" @click="handleUnifiedKefuClick"
:style="{ backgroundImage: currentKefuImg ? `url(${currentKefuImg})` : '', backgroundSize: '100% 100%' }"
> >
<image
v-if="currentKefuImg"
:src="currentKefuImg"
mode="aspectFill"
class="kefu-img"
show-menu-by-longpress></image>
<text class="ai-icon" v-if="isAIKefu && !currentKefuImg">🤖</text> <text class="ai-icon" v-if="isAIKefu && !currentKefuImg">🤖</text>
<text class="ai-icon" v-if="isWxworkKefu && !currentKefuImg">💬</text> <text class="ai-icon" v-if="isWxworkKefu && !currentKefuImg">💬</text>
<text class="ai-icon" v-if="!isAIKefu && !isWxworkKefu && !currentKefuImg">👤</text> <text class="ai-icon" v-if="!isAIKefu && !isWxworkKefu && !currentKefuImg">👤</text>
@@ -40,8 +44,13 @@
v-if="fixBtnShow && hasValidKefuConfig && !isWeappOfficialKefu && showWeappSystemKefu" v-if="fixBtnShow && hasValidKefuConfig && !isWeappOfficialKefu && showWeappSystemKefu"
class="btn-item common-bg" class="btn-item common-bg"
@click="handleUnifiedKefuClick" @click="handleUnifiedKefuClick"
:style="{ backgroundImage: currentKefuImg ? `url(${currentKefuImg})` : '', backgroundSize: '100% 100%' }"
> >
<image
v-if="currentKefuImg"
:src="currentKefuImg"
mode="aspectFill"
class="kefu-img"
show-menu-by-longpress></image>
<text class="ai-icon" v-if="isAIKefu && !currentKefuImg">🤖</text> <text class="ai-icon" v-if="isAIKefu && !currentKefuImg">🤖</text>
<text class="ai-icon" v-if="isWxworkKefu && !currentKefuImg">💬</text> <text class="ai-icon" v-if="isWxworkKefu && !currentKefuImg">💬</text>
<text class="ai-icon" v-if="!isAIKefu && !isWxworkKefu && !currentKefuImg">👤</text> <text class="ai-icon" v-if="!isAIKefu && !isWxworkKefu && !currentKefuImg">👤</text>
@@ -52,7 +61,6 @@
v-if="fixBtnShow && hasValidKefuConfig && showWeappSystemKefu" v-if="fixBtnShow && hasValidKefuConfig && showWeappSystemKefu"
class="btn-item common-bg" class="btn-item common-bg"
open-type="contact" open-type="contact"
:style="{ backgroundImage: currentKefuImg ? `url(${currentKefuImg})` : '', backgroundSize: '100% 100%' }"
> >
<text class="icox icox-kefu" v-if="!kefuimg"></text> <text class="icox icox-kefu" v-if="!kefuimg"></text>
</button> </button>
@@ -178,7 +186,6 @@ export default {
uni.getStorage({ uni.getStorage({
key: 'shopInfo', key: 'shopInfo',
success: (e) => { success: (e) => {
console.log('【调试】当前 shopInfo:', e.data);
this.shopInfo = e.data; this.shopInfo = e.data;
}, },
fail: () => { fail: () => {
@@ -304,6 +311,13 @@ export default {
font-weight: bold; font-weight: bold;
} }
.kefu-img {
width: 100%;
height: 100%;
display: block;
border-radius: 50%;
}
.ai-icon { .ai-icon {
font-size: 40rpx; font-size: 40rpx;
width: 100%; width: 100%;

View File

@@ -8,7 +8,7 @@
:src="mOption.src" :src="mOption.src"
mode="widthFix" mode="widthFix"
@click="toTopClick" @click="toTopClick"
/> show-menu-by-longpress/>
</template> </template>
<script> <script>

View File

@@ -3,12 +3,12 @@
<swiper :indicator-dots="advList.length > 1" indicator-active-color="#ffffff" :autoplay="true" :interval="3000" :duration="1000" v-if="advList.length > 1" @change="changeSwiper" :current="currentIndex" :style="{ height: swiperHeight + 'px' }" class="item-wrap"> <swiper :indicator-dots="advList.length > 1" indicator-active-color="#ffffff" :autoplay="true" :interval="3000" :duration="1000" v-if="advList.length > 1" @change="changeSwiper" :current="currentIndex" :style="{ height: swiperHeight + 'px' }" class="item-wrap">
<swiper-item v-for="(item, index) in advList" :key="index" @click="jumppage(item.adv_url)"> <swiper-item v-for="(item, index) in advList" :key="index" @click="jumppage(item.adv_url)">
<view class="image-box"> <view class="image-box">
<image :src="$util.img(item.adv_image)" mode="widthFix" :id="'content-wrap' + index"/> <image :src="$util.img(item.adv_image)" mode="widthFix" :id="'content-wrap' + index" show-menu-by-longpress/>
</view> </view>
</swiper-item> </swiper-item>
</swiper> </swiper>
<view v-else class="container-box item-wrap"> <view v-else class="container-box item-wrap">
<image :src="$util.img(advList[0]['adv_image'])" mode="widthFix" lazy-load="true" @load="imageLoad" @click="jumppage(advList[0].adv_url)"/> <image :src="$util.img(advList[0]['adv_image'])" mode="widthFix" lazy-load="true" @load="imageLoad" @click="jumppage(advList[0].adv_url)" show-menu-by-longpress/>
</view> </view>
</view> </view>
</template> </template>

View File

@@ -1,7 +1,7 @@
<template> <template>
<view class="message"> <view class="message">
<view class="goods-item" v-if="goodsInfo.goods_name || goodsInfo.en_goods_name"> <view class="goods-item" v-if="goodsInfo.goods_name || goodsInfo.en_goods_name">
<image :src="$util.img(goodsInfo.sku_image)" mode="aspectFill"></image> <image :src="$util.img(goodsInfo.sku_image)" mode="aspectFill" show-menu-by-longpress></image>
<view class="goods-info"> <view class="goods-info">
<view class="goods-name">{{ goodsInfo.sku_name ? goodsInfo.sku_name : (isEnEnv ? goodsInfo.en_goods_name : goodsInfo.goods_name) }}</view> <view class="goods-name">{{ goodsInfo.sku_name ? goodsInfo.sku_name : (isEnEnv ? goodsInfo.en_goods_name : goodsInfo.goods_name) }}</view>
<view class="goods-bottom"> <view class="goods-bottom">
@@ -14,7 +14,7 @@
</view> </view>
</view> </view>
<view class="goods-item" v-else-if="goodsDetail"> <view class="goods-item" v-else-if="goodsDetail">
<image :src="$util.img(goodsDetail.sku_image)" mode="aspectFill"></image> <image :src="$util.img(goodsDetail.sku_image)" mode="aspectFill" show-menu-by-longpress></image>
<view class="goods-info"> <view class="goods-info">
<view class="goods-name">{{ goodsDetail.sku_name ? goodsDetail.sku_name : (isEnEnv ? goodsDetail.en_goods_name : goodsDetail.goods_name) }}</view> <view class="goods-name">{{ goodsDetail.sku_name ? goodsDetail.sku_name : (isEnEnv ? goodsDetail.en_goods_name : goodsDetail.goods_name) }}</view>
<view class="goods-bottom"> <view class="goods-bottom">

View File

@@ -1,7 +1,7 @@
<template> <template>
<view class="message"> <view class="message">
<view class="goods-item" v-if="orderdetails"> <view class="goods-item" v-if="orderdetails">
<image :src="$util.img(orderdetails.order_goods ? orderdetails.order_goods[0].sku_image : '')" mode="aspectFill"></image> <image :src="$util.img(orderdetails.order_goods ? orderdetails.order_goods[0].sku_image : '')" mode="aspectFill" show-menu-by-longpress></image>
<view class="goods-info"> <view class="goods-info">
<view class="goods-name">{{ orderdetails.order_goods ? orderdetails.order_goods[0].sku_name : '' }}</view> <view class="goods-name">{{ orderdetails.order_goods ? orderdetails.order_goods[0].sku_name : '' }}</view>
<view class="font-size-goods-tag">订单状态:{{ orderdetails.order_status_name }}</view> <view class="font-size-goods-tag">订单状态:{{ orderdetails.order_status_name }}</view>
@@ -16,7 +16,7 @@
</view> </view>
</view> </view>
<view class="goods-item" v-else-if="orderInfo"> <view class="goods-item" v-else-if="orderInfo">
<image :src="$util.img(orderInfo.order_goods ? orderInfo.order_goods[0].sku_image : '')" mode="aspectFill"></image> <image :src="$util.img(orderInfo.order_goods ? orderInfo.order_goods[0].sku_image : '')" mode="aspectFill" show-menu-by-longpress></image>
<view class="goods-info"> <view class="goods-info">
<view class="goods-name">{{ orderInfo.order_goods ? orderInfo.order_goods[0].sku_name : '' }}</view> <view class="goods-name">{{ orderInfo.order_goods ? orderInfo.order_goods[0].sku_name : '' }}</view>
<view class="font-size-goods-tag">订单状态:{{ orderInfo.order_status_name }}</view> <view class="font-size-goods-tag">订单状态:{{ orderInfo.order_status_name }}</view>

View File

@@ -1,7 +1,7 @@
<template> <template>
<view class="goods"> <view class="goods">
<view class="goods-msg"> <view class="goods-msg">
<image :src="$util.img(goodsInfo.sku_image)" mode="aspectFill"></image> <image :src="$util.img(goodsInfo.sku_image)" mode="aspectFill" show-menu-by-longpress></image>
<view class="goods-item"> <view class="goods-item">
<view class="title">{{ isEnEnv ? goodsInfo.en_goods_name : goodsInfo.goods_name }}</view> <view class="title">{{ isEnEnv ? goodsInfo.en_goods_name : goodsInfo.goods_name }}</view>
<view class="goods-sku"> <view class="goods-sku">

View File

@@ -10,7 +10,7 @@
</view> </view>
<view v-if="copyright && copyright.gov_record" class="gov-wrap" @click="toHref(copyright.gov_url)" target="_blank"> <view v-if="copyright && copyright.gov_record" class="gov-wrap" @click="toHref(copyright.gov_url)" target="_blank">
<image :src="$util.img('public/uniapp/common/gov_record.png')" alt="公安备案" /> <image :src="$util.img('public/uniapp/common/gov_record.png')" alt="公安备案" show-menu-by-longpress/>
<text>{{ copyright.gov_record }}</text> <text>{{ copyright.gov_record }}</text>
</view> </view>
</view> --> </view> -->

View File

@@ -1,6 +1,6 @@
<template> <template>
<view class="empty" :class="{ fixed: fixed }"> <view class="empty" :class="{ fixed: fixed }">
<view class="empty_img"><image :src="$util.img('public/uniapp/common/common-empty.png')" mode="aspectFit"></image></view> <view class="empty_img"><image :src="$util.img('public/uniapp/common/common-empty.png')" mode="aspectFit" show-menu-by-longpress></image></view>
<view class="color-tip margin-top title" :style="{ color: textColor + ' !important' }">{{ text }}</view> <view class="color-tip margin-top title" :style="{ color: textColor + ' !important' }">{{ text }}</view>
<view class="color-tip margin-bottom font-size-sub">{{ subText }}</view> <view class="color-tip margin-bottom font-size-sub">{{ subText }}</view>
<button type="primary" size="mini" class="button mini" @click="goIndex()" v-if="isIndex">{{ emptyBtn.text }}</button> <button type="primary" size="mini" class="button mini" @click="goIndex()" v-if="isIndex">{{ emptyBtn.text }}</button>

View File

@@ -89,7 +89,7 @@
</view> </view>
<view class="box img-boxs"> <view class="box img-boxs">
<view class="img-box" v-for="(v, k) in item.img_lists" :key="k" @click="uploadImg(index)"> <view class="img-box" v-for="(v, k) in item.img_lists" :key="k" @click="uploadImg(index)">
<image :src="$util.img(v)" mode="aspectFill"></image> <image :src="$util.img(v)" mode="aspectFill" show-menu-by-longpress></image>
<text class="iconfont icon-guanbi" @click.stop="delImg(k, index)"></text> <text class="iconfont icon-guanbi" @click.stop="delImg(k, index)"></text>
</view> </view>
<view class="img-box" @click="addImg(index)"><text class="iconfont icon-add1"></text></view> <view class="img-box" @click="addImg(index)"><text class="iconfont icon-add1"></text></view>

View File

@@ -6,7 +6,7 @@
<view class="sku-info" :style="{ height: systemInfo.windowHeight * 2 + 'rpx' }"> <view class="sku-info" :style="{ height: systemInfo.windowHeight * 2 + 'rpx' }">
<view class="header"> <view class="header">
<view class="img-wrap" @click="previewMedia()"> <view class="img-wrap" @click="previewMedia()">
<image :src="$util.img(goodsDetail.sku_image, { size: 'mid' })" @error="imageError()" /> <image :src="$util.img(goodsDetail.sku_image, { size: 'mid' })" @error="imageError()" show-menu-by-longpress/>
</view> </view>
<view class="main"> <view class="main">
<view class="goodname">{{ goodsDetail.sku_name ? goodsDetail.sku_name : (isEnEnv ? <view class="goodname">{{ goodsDetail.sku_name ? goodsDetail.sku_name : (isEnEnv ?
@@ -33,7 +33,7 @@
@click="change(item_value.sku_id, item_value.spec_id)"> @click="change(item_value.sku_id, item_value.spec_id)">
<image v-if="item_value.image" <image v-if="item_value.image"
:src="$util.img(item_value.image, { size: 'small' })" :src="$util.img(item_value.image, { size: 'small' })"
@error="valueImageError(index, index_value)" /> @error="valueImageError(index, index_value)" show-menu-by-longpress/>
<text>{{ item_value.spec_value_name }}</text> <text>{{ item_value.spec_value_name }}</text>
</view> </view>
</view> </view>

View File

@@ -5,14 +5,14 @@
<view class="header"> <view class="header">
<block v-if="type == 'point' && goodsDetail.type && goodsDetail.type != 1"> <block v-if="type == 'point' && goodsDetail.type && goodsDetail.type != 1">
<view class="img-wrap" v-if="goodsDetail.type == 2"> <view class="img-wrap" v-if="goodsDetail.type == 2">
<image :src="goodsDetail.image ? $util.img(goodsDetail.image) : $util.img('public/uniapp/point/coupon.png')" mode="aspectFit" /> <image :src="goodsDetail.image ? $util.img(goodsDetail.image) : $util.img('public/uniapp/point/coupon.png')" mode="aspectFit" show-menu-by-longpress/>
</view> </view>
<view class="img-wrap" v-if="goodsDetail.type == 3"> <view class="img-wrap" v-if="goodsDetail.type == 3">
<image :src="goodsDetail.image ? $util.img(goodsDetail.image) : $util.img('public/uniapp/point/hongbao.png')" mode="aspectFit" /> <image :src="goodsDetail.image ? $util.img(goodsDetail.image) : $util.img('public/uniapp/point/hongbao.png')" mode="aspectFit" show-menu-by-longpress/>
</view> </view>
</block> </block>
<view v-else class="img-wrap" @click="previewMedia()"> <view v-else class="img-wrap" @click="previewMedia()">
<image :src="$util.img(goodsDetail.sku_image, { size: 'mid' })" @error="imageError()" mode="aspectFit" /> <image :src="$util.img(goodsDetail.sku_image, { size: 'mid' })" @error="imageError()" mode="aspectFit" show-menu-by-longpress/>
</view> </view>
<view class="main"> <view class="main">
@@ -151,7 +151,7 @@
selected: item_value['selected'] || skuId == item_value.sku_id, selected: item_value['selected'] || skuId == item_value.sku_id,
disabled: item_value['disabled'] || (!item_value['selected'] && disabled) disabled: item_value['disabled'] || (!item_value['selected'] && disabled)
}" class="items" @click="change(item_value.sku_id, item_value.spec_id)"> }" class="items" @click="change(item_value.sku_id, item_value.spec_id)">
<image v-if="item_value.image" :src="$util.img(item_value.image, { size: 'small' })" @error="valueImageError(index, index_value)" /> <image v-if="item_value.image" :src="$util.img(item_value.image, { size: 'small' })" @error="valueImageError(index, index_value)" show-menu-by-longpress/>
<text>{{ item_value.spec_value_name }}</text> <text>{{ item_value.spec_value_name }}</text>
</view> </view>
</view> </view>

View File

@@ -0,0 +1,80 @@
<template>
<image
:src="src"
:mode="mode"
:lazy-load="lazyLoad"
:fade-show="fadeShow"
:webp="webp"
:show-menu-by-longpress="enableLongpress"
:class="imageClass"
:style="imageStyle"
@load="onLoad"
@error="onError"
@tap="onClick"
>
<slot></slot>
</image>
</template>
<script>
export default {
name: 'NsImage',
props: {
// 图片路径
src: {
type: String,
required: true
},
// 图片裁剪模式
mode: {
type: String,
default: 'aspectFill'
},
// 是否开启长按识别二维码(默认开启)
enableLongpress: {
type: Boolean,
default: true
},
// 是否懒加载
lazyLoad: {
type: Boolean,
default: false
},
// 图片显示动画
fadeShow: {
type: Boolean,
default: true
},
// 支持webp
webp: {
type: Boolean,
default: false
},
// 自定义类名
imageClass: {
type: [String, Array, Object],
default: ''
},
// 自定义样式
imageStyle: {
type: [String, Object],
default: ''
}
},
methods: {
onLoad(e) {
this.$emit('load', e)
},
onError(e) {
this.$emit('error', e)
},
onClick(e) {
this.$emit('tap', e)
}
}
}
</script>
<style lang="scss" scoped>
/* 可添加全局图片样式 */
</style>

View File

@@ -18,7 +18,7 @@
<view class="item-wrap" v-if="isOpenCaptcha"> <view class="item-wrap" v-if="isOpenCaptcha">
<text class="label">验证码</text> <text class="label">验证码</text>
<input type="number" placeholder="请输入验证码" v-model="formData.vercode" maxlength="4" /> <input type="number" placeholder="请输入验证码" v-model="formData.vercode" maxlength="4" />
<image :src="captcha.img" class="captcha" @click="getCaptcha"></image> <image :src="captcha.img" class="captcha" @click="getCaptcha" show-menu-by-longpress></image>
</view> </view>
<view class="item-wrap"> <view class="item-wrap">
<text class="label">动态码</text> <text class="label">动态码</text>
@@ -79,7 +79,7 @@
<text class="label">头像</text> <text class="label">头像</text>
<button open-type="chooseAvatar" @chooseavatar="onChooseAvatar"> <button open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<image :src="avatarUrl ? avatarUrl : $util.getDefaultImage().head" <image :src="avatarUrl ? avatarUrl : $util.getDefaultImage().head"
@error="avatarUrl = $util.getDefaultImage().head" mode="aspectFill" /> @error="avatarUrl = $util.getDefaultImage().head" mode="aspectFill" show-menu-by-longpress/>
<text class="iconfont icon-right color-tip"></text> <text class="iconfont icon-right color-tip"></text>
</button> </button>
</view> </view>
@@ -96,7 +96,7 @@
<button open-type="getAuthorize" scope="userInfo" @getAuthorize="aliappGetUserinfo" <button open-type="getAuthorize" scope="userInfo" @getAuthorize="aliappGetUserinfo"
:plain="true" class="border-0"> :plain="true" class="border-0">
<image :src="avatarUrl ? avatarUrl : $util.getDefaultImage().head" <image :src="avatarUrl ? avatarUrl : $util.getDefaultImage().head"
@error="avatarUrl = $util.getDefaultImage().head" mode="aspectFill" /> @error="avatarUrl = $util.getDefaultImage().head" mode="aspectFill" show-menu-by-longpress/>
<text class="iconfont icon-right color-tip"></text> <text class="iconfont icon-right color-tip"></text>
</button> </button>
</view> </view>

View File

@@ -16,7 +16,7 @@
<view v-if="data.navStyle == 2" class="content-wrap" @click="toLink(data.moreLink.wap_url)"> <view v-if="data.navStyle == 2" class="content-wrap" @click="toLink(data.moreLink.wap_url)">
<view class="title-wrap" :style="{ color: data.textNavColor }"> <view class="title-wrap" :style="{ color: data.textNavColor }">
<view> <view>
<image :src="$util.img(data.topNavImg)" mode="heightFix"></image> <image :src="$util.img(data.topNavImg)" mode="heightFix" show-menu-by-longpress></image>
</view> </view>
<view :style="{ color: data.textNavColor }">{{ data.title }}</view> <view :style="{ color: data.textNavColor }">{{ data.title }}</view>
</view> </view>
@@ -24,7 +24,7 @@
<view v-if="data.navStyle == 3" class="content-wrap"> <view v-if="data.navStyle == 3" class="content-wrap">
<view class="title-wrap" @click="toLink(data.moreLink.wap_url)"> <view class="title-wrap" @click="toLink(data.moreLink.wap_url)">
<image :src="$util.img(data.topNavImg)" mode="aspectFit"></image> <image :src="$util.img(data.topNavImg)" mode="aspectFit" show-menu-by-longpress></image>
</view> </view>
<view class="search" @click="$util.redirectTo('/pages_tool/goods/search')" :style="{ height: menuButtonInfo.height - 2 + 'px', lineHeight: menuButtonInfo.height - 2 + 'px' }"> <view class="search" @click="$util.redirectTo('/pages_tool/goods/search')" :style="{ height: menuButtonInfo.height - 2 + 'px', lineHeight: menuButtonInfo.height - 2 + 'px' }">
<text class="iconfont icon-sousuo3"></text> <text class="iconfont icon-sousuo3"></text>

View File

@@ -55,31 +55,27 @@ export default {
mounted() { mounted() {
this.listenPrivacySettingChange() this.listenPrivacySettingChange()
this.curPageShow() this.curPageShow()
this.proactive()
}, },
created() { created() {
try { try {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
//查询微信侧记录的用户是否有待同意的隐私政策信息
wx.getPrivacySetting({ wx.getPrivacySetting({
success: (res) => { success: (res) => {
// console.log('隐私政策信息', res);
// console.log(res.privacyContractName);
this.privacyContractName = res.privacyContractName this.privacyContractName = res.privacyContractName
} }
}); });
// #endif // #endif
// #ifdef QUICKAPP-WEBVIEW || H5 // #ifdef QUICKAPP-WEBVIEW || H5
if (this.$util.isQuickApp()) { if (this.$util.isQuickApp() && typeof has != 'undefined' && has?.getPrivacySetting) {
if (typeof has != 'undefined' && has?.getPrivacySetting) { has.getPrivacySetting({
has.getPrivacySetting({ success: (res) => {
success: (res) => { if (res.privacyContractName) {
if (res.privacyContractName) { this.privacyContractName = res.privacyContractName
this.privacyContractName = res.privacyContractName }
} },
}, })
})
}
} }
// #endif // #endif
} catch (e) { } catch (e) {
@@ -87,39 +83,50 @@ export default {
} }
}, },
methods: { methods: {
/**
* 统一弹窗 + 关闭其他页面的弹窗
*/
showPrivacyPopup() {
this.popUp()
this.closeOtherPagePopUp(this.disPopUp)
},
/**
* 根据是否需要授权决定弹窗或 emit agree
*/
checkAndShow(needAuthorization) {
if (needAuthorization) {
const privacyAgreed = uni.getStorageSync('privacyAgreed');
if (privacyAgreed) {
this.$emit('agree')
} else {
this.showPrivacyPopup()
}
} else {
this.$emit('agree')
}
},
getPrivacySettingByQuickApp() { getPrivacySettingByQuickApp() {
// #ifdef QUICKAPP-WEBVIEW || H5 || WEB // #ifdef QUICKAPP-WEBVIEW || H5 || WEB
if (this.$util.isQuickApp()) { if (!this.$util.isQuickApp()) return;
if (typeof has != 'undefined' && has?.getPrivacySetting) { if (typeof has != 'undefined' && has?.getPrivacySetting) {
has.getPrivacySetting({ has.getPrivacySetting({
success: (res) => { success: (res) => {
// console.log(res) this.checkAndShow(res.needAuthorization)
if (res.needAuthorization) { },
this.popUp() })
// 额外逻辑:当前页面的隐私弹窗弹起的时候,关掉其他页面的隐私弹窗 } else {
this.closeOtherPagePopUp(this.disPopUp) this.checkAndShow(!uni.getStorageSync('privacyAgreed'))
} else {
this.$emit('agree')
}
},
})
} else {
// 属于嵌入到快应用Webview组件中的情况,按照H5的方式来处理,判断是否已经授权
if (uni.getStorageSync('privacyAgreed')) {
this.$emit('agree')
} else {
this.popUp()
// 额外逻辑:当前页面的隐私弹窗弹起的时候,关掉其他页面的隐私弹窗
this.closeOtherPagePopUp(this.disPopUp)
}
}
} }
// #endif // #endif
}, },
/**
* 监听平台侧的隐私授权事件
*/
listenPrivacySettingChange() { listenPrivacySettingChange() {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
// 监听微信侧隐私政策授权变化事件
if (wx.onNeedPrivacyAuthorization) { if (wx.onNeedPrivacyAuthorization) {
wx.onNeedPrivacyAuthorization((resolve) => { wx.onNeedPrivacyAuthorization((resolve) => {
if (typeof this.privacyAuthorization === 'function') { if (typeof this.privacyAuthorization === 'function') {
@@ -130,58 +137,28 @@ export default {
// #endif // #endif
// #ifdef QUICKAPP-WEBVIEW || H5 || WEB // #ifdef QUICKAPP-WEBVIEW || H5 || WEB
if (this.$util.isQuickApp()) { if (this.$util.isQuickApp() && typeof has != 'undefined' && has?.onPrivacySettingChange) {
// 监听快速应用侧隐私政策授权变化事件 has.onPrivacySettingChange((res) => {
if (typeof has != 'undefined' && has?.onPrivacySettingChange) { this.checkAndShow(res.needAuthorization)
has.onPrivacySettingChange((res) => { })
// console.log(res)
if (res.needAuthorization) {
this.popUp()
// 额外逻辑:当前页面的隐私弹窗弹起的时候,关掉其他页面的隐私弹窗
this.closeOtherPagePopUp(this.disPopUp)
} else {
this.$emit('agree')
}
})
}
} }
// #endif // #endif
// 主动查询用户隐私政策授权状态,针对快速应用
this.getPrivacySettingByQuickApp();
}, },
// 主动查询用户隐私政策授权状态
/**
* 主动查询隐私授权状态并弹窗
*/
proactive() { proactive() {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
if (wx.getPrivacySetting) { if (wx.getPrivacySetting) {
wx.getPrivacySetting({ wx.getPrivacySetting({
success: (res) => { success: (res) => {
// console.log(res) this.checkAndShow(res.needAuthorization)
if (res.needAuthorization) {
// 检查本地存储中是否已经同意过隐私政策
const privacyAgreed = uni.getStorageSync('privacyAgreed');
if (!privacyAgreed) {
this.popUp()
// 额外逻辑:当前页面的隐私弹窗弹起的时候,关掉其他页面的隐私弹窗
this.closeOtherPagePopUp(this.disPopUp)
} else {
this.$emit('agree')
}
} else {
this.$emit('agree')
}
}, },
}); });
} else { } else {
// 检查本地存储中是否已经同意过隐私政策 // 低版本基础库直接检查本地存储
const privacyAgreed = uni.getStorageSync('privacyAgreed'); this.checkAndShow(!uni.getStorageSync('privacyAgreed'))
if (privacyAgreed) {
this.$emit('agree');
} else {
this.popUp()
// 额外逻辑:当前页面的隐私弹窗弹起的时候,关掉其他页面的隐私弹窗
this.closeOtherPagePopUp(this.disPopUp)
}
} }
// #endif // #endif
@@ -190,29 +167,24 @@ export default {
// #endif // #endif
// #ifdef H5 || WEB // #ifdef H5 || WEB
// 检查本地存储中是否已经同意过隐私政策 this.checkAndShow(!uni.getStorageSync('privacyAgreed'))
const privacyAgreed = uni.getStorageSync('privacyAgreed');
if (privacyAgreed) {
this.$emit('agree');
} else {
this.popUp()
// 额外逻辑:当前页面的隐私弹窗弹起的时候,关掉其他页面的隐私弹窗
this.closeOtherPagePopUp(this.disPopUp)
}
// #endif // #endif
}, },
//初始化监听程序
/**
* 初始化监听程序(页面级)
*/
curPageShow() { curPageShow() {
closeOtherPagePopUpHooks.add(this.disPopUp) closeOtherPagePopUpHooks.add(this.disPopUp)
this.privacyAuthorization = resolve => { this.privacyAuthorization = resolve => {
this.privacyResolves.add(resolve) this.privacyResolves.add(resolve)
//打开弹窗 this.showPrivacyPopup()
this.popUp()
// 额外逻辑:当前页面的隐私弹窗弹起的时候,关掉其他页面的隐私弹窗
this.closeOtherPagePopUp(this.disPopUp)
} }
}, },
// 额外逻辑:当前页面的隐私弹窗弹起的时候,关掉其他页面的隐私弹窗
/**
* 弹窗时关掉其他页面的隐私弹窗,避免重叠
*/
closeOtherPagePopUp(closePopUp) { closeOtherPagePopUp(closePopUp) {
closeOtherPagePopUpHooks.forEach(hook => { closeOtherPagePopUpHooks.forEach(hook => {
if (closePopUp !== hook) { if (closePopUp !== hook) {
@@ -220,16 +192,12 @@ export default {
} }
}) })
}, },
//打开隐私协议
openPrivacyContract() { openPrivacyContract() {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
wx.openPrivacyContract({ wx.openPrivacyContract({
success(res) { success(res) {},
// console.log('打开隐私协议', res); fail(err) {}
},
fail(err) {
// console.error('打开隐私协议失败', err)
}
}); });
// #endif // #endif
@@ -237,59 +205,44 @@ export default {
if (this.$util.isQuickApp()) { if (this.$util.isQuickApp()) {
if (typeof has != 'undefined' && has?.openPrivacySetting) { if (typeof has != 'undefined' && has?.openPrivacySetting) {
has.openPrivacySetting({ has.openPrivacySetting({
success: (res) => { success: (res) => {},
// console.log('打开隐私协议', res); fail: (err) => {}
},
fail: (err) => {
// console.error('打开隐私协议失败', err)
}
}); });
} else { } else {
// 属于嵌入到快应用Webview组件中的情况,按照H5的方式来处理
this.$util.redirectTo(privacyContractPage); this.$util.redirectTo(privacyContractPage);
} }
} else { } else {
// H5 环境下的处理逻辑
this.$util.redirectTo(privacyContractPage); this.$util.redirectTo(privacyContractPage);
} }
// #endif // #endif
}, },
//打开用户服务协议
openPrivacyService() { openPrivacyService() {
// #ifdef QUICKAPP-WEBVIEW || H5 || WEB // #ifdef QUICKAPP-WEBVIEW || H5 || WEB
if (this.$util.isQuickApp()) { if (this.$util.isQuickApp()) {
if (typeof has != 'undefined' && has?.openPrivacySetting) { if (typeof has != 'undefined' && has?.openPrivacySetting) {
has.openPrivacySetting({ has.openPrivacySetting({
success: (res) => { success: (res) => {},
// console.log('打开用户服务协议', res); fail: (err) => {}
},
fail: (err) => {
// console.error('打开用户服务协议失败', err)
}
}); });
} else { } else {
// 属于嵌入到快应用Webview组件中的情况,按照H5的方式来处理
this.$util.redirectTo(privacyServicePage); this.$util.redirectTo(privacyServicePage);
} }
} else { } else {
// H5 环境下的处理逻辑
this.$util.redirectTo(privacyServicePage); this.$util.redirectTo(privacyServicePage);
} }
// #endif // #endif
}, },
// 不同意
handleDisagree() { handleDisagree() {
this.privacyResolves.forEach(resolve => { this.privacyResolves.forEach(resolve => {
resolve({ resolve({ event: 'disagree' })
event: 'disagree',
})
}) })
this.privacyResolves.clear() this.privacyResolves.clear()
//关闭弹窗
this.disPopUp() this.disPopUp()
// 保存用户授权状态到本地存储,无论同意还是不同意,都不再重复弹出
uni.setStorageSync('privacyAgreed', true); uni.setStorageSync('privacyAgreed', true);
//退出小程序
uni.showModal({ uni.showModal({
content: '未同意隐私协议,无法使用相关功能', content: '未同意隐私协议,无法使用相关功能',
success: () => { success: () => {
@@ -297,7 +250,7 @@ export default {
} }
}) })
}, },
// 同意并继续
handleAgree() { handleAgree() {
this.privacyResolves.forEach(resolve => { this.privacyResolves.forEach(resolve => {
resolve({ resolve({
@@ -306,28 +259,23 @@ export default {
}) })
}) })
this.privacyResolves.clear() this.privacyResolves.clear()
//关闭弹窗
this.disPopUp() this.disPopUp()
// 保存用户授权状态到本地存储,用于所有环境 uni.setStorageSync('privacyAgreed', true);
uni.setStorageSync('privacyAgreed', true);
this.$emit('agree') this.$emit('agree')
}, },
//打开弹窗
popUp() { popUp() {
this.showPop = true; this.showPop = true;
}, },
//关闭弹窗
disPopUp() { disPopUp() {
this.showPop = false; this.showPop = false;
}, },
}, },
beforeDestroy() { beforeDestroy() {
// 清理事件监听器和集合
this.privacyResolves.clear() this.privacyResolves.clear()
closeOtherPagePopUpHooks.delete(this.disPopUp) closeOtherPagePopUpHooks.delete(this.disPopUp)
// 注意:这里需要根据实际情况清理微信和快速应用的事件监听器
// 由于微信的 wx.onNeedPrivacyAuthorization 没有对应的 off 方法,这里可能需要其他方式处理
}, },
} }
</script> </script>

View File

@@ -6,7 +6,7 @@
:src="$util.img('public/uniapp/common/mescroll-totop.png')" :src="$util.img('public/uniapp/common/mescroll-totop.png')"
mode="widthFix" mode="widthFix"
@click="toTopClick" @click="toTopClick"
/> show-menu-by-longpress/>
</template> </template>
<script> <script>

View File

@@ -89,7 +89,6 @@ export default {
} }
}, },
endVal() { endVal() {
console.log(123)
if (this.autoplay) { if (this.autoplay) {
this.start() this.start()
} }

View File

@@ -164,7 +164,6 @@
appId: 'wxeb490c6f9b154ef9', // 企业微信小程序AppID appId: 'wxeb490c6f9b154ef9', // 企业微信小程序AppID
path: `pages/contacts/externalContactDetail?url=${encodeURIComponent(contactUrl)}`, path: `pages/contacts/externalContactDetail?url=${encodeURIComponent(contactUrl)}`,
success: () => { success: () => {
console.log('跳转企业微信成功');
this.$util.showToast({ this.$util.showToast({
title: '跳转成功', title: '跳转成功',
icon: 'success' icon: 'success'
@@ -189,7 +188,6 @@
this.wxWorkSDK.addContact({ this.wxWorkSDK.addContact({
userId: contactId userId: contactId
}, (res) => { }, (res) => {
console.log('打开用户资料成功:', res);
}, (err) => { }, (err) => {
console.error('打开用户资料失败:', err); console.error('打开用户资料失败:', err);
this.showError('打开用户资料失败'); this.showError('打开用户资料失败');

View File

@@ -3,5 +3,5 @@ export const lang = {
title: '商品分类', title: '商品分类',
search:'商品搜索', search:'商品搜索',
seeMore : '查看更多', seeMore : '查看更多',
Make: "询底价" Make: "立即咨询"
} }

View File

@@ -2,7 +2,7 @@ export const lang = {
//title为每个页面的标题 //title为每个页面的标题
title: '', title: '',
select: '选择', select: '选择',
details:'资源详情', details:'商品详情',
params: '参数', params: '参数',
service: '商品服务', service: '商品服务',
allGoods: '全部商品', allGoods: '全部商品',
@@ -11,7 +11,7 @@ export const lang = {
home:'首页', home:'首页',
cart:'购物车', cart:'购物车',
leave:'立即留言', leave:'立即留言',
make:'联系我们', make:'立即咨询',
send:'配送', send:'配送',
express:'快递发货', express:'快递发货',
@@ -22,7 +22,7 @@ export const lang = {
status:'该商品已下架', status:'该商品已下架',
sellout:'库存不足', sellout:'库存不足',
max:'已达最大限购数量', max:'已达最大限购数量',
makebtn:'价格电议', makebtn:'立即咨询',
sales:'销量', sales:'销量',
stock:'库存', stock:'库存',
kefu:'客服', kefu:'客服',

View File

@@ -6,6 +6,6 @@ export const lang = {
Price:'价格', Price:'价格',
Filter:'筛选', Filter:'筛选',
Search:'请输入您要搜索的商品', Search:'请输入您要搜索的商品',
Make:'立即询底价', Make:'立即咨询',
} }

View File

@@ -71,11 +71,14 @@
"scope.userLocation" : { "scope.userLocation" : {
"desc" : "为了更好地为您提供服务" "desc" : "为了更好地为您提供服务"
}, },
"scope.writePhotosAlbum" : {
"desc" : "为了更好地为您提供服务"
},
"scope.userClipboard" : { "scope.userClipboard" : {
"desc" : "为了方便您复制信息" "desc" : "为了方便您复制信息"
},
"scope.camera" : {
"desc" : "用于拍照上传头像"
},
"scope.writePhotosAlbum" : {
"desc" : "用于从相册选择和保存头像"
} }
}, },
"requiredPrivateInfos" : [ "chooseLocation", "getLocation", "chooseAddress" ], "requiredPrivateInfos" : [ "chooseLocation", "getLocation", "chooseAddress" ],

View File

@@ -1,9 +1,6 @@
{ {
"scripts": { "scripts": {
"mp-weixin": "node scripts/mp-weixin.patch.js", "mp-weixin": "node scripts/mp-weixin.patch.js"
"mp-weixin:patch": "node scripts/mp-weixin.patch.js --no-zip",
"mp-weixin:dev": "node scripts/mp-weixin.patch.js --mode development",
"mp-weixin:dev:patch": "node scripts/mp-weixin.patch.js --mode development --no-zip"
}, },
"devDependencies": { "devDependencies": {
"dart-sass": "^1.25.0", "dart-sass": "^1.25.0",
@@ -28,44 +25,40 @@
"h5-xcx20.5g-quickapp.com": { "h5-xcx20.5g-quickapp.com": {
"title": "H5-xcx20.5g-quickapp.com", "title": "H5-xcx20.5g-quickapp.com",
"env": { "env": {
"UNI_PLATFORM": "h5" "UNI_PLATFORM": "h5",
"UNI_APP_DOMAIN": "https://xcx20.5g-quickapp.com/"
}, },
"define": { "define": {
"H5_XCX_5G_QUICKAPP_COM": true,
"H5_PRODUCTION": true,
"PRODUCTION": true "PRODUCTION": true
} }
}, },
"h5-xcx.aigc-quickapp.com": { "h5-xcx.aigc-quickapp.com": {
"title": "H5-xcx.aigc-quickapp.com", "title": "H5-xcx.aigc-quickapp.com",
"env": { "env": {
"UNI_PLATFORM": "h5" "UNI_PLATFORM": "h5",
"UNI_APP_DOMAIN": "https://xcx.aigc-quickapp.com/"
}, },
"define": { "define": {
"H5_XCX_AIGC_QUICKAPP_COM": true,
"H5_PRODUCTION": true,
"PRODUCTION": true "PRODUCTION": true
} }
}, },
"h5-5g.aigc-quickapp.com": { "h5-5g.aigc-quickapp.com": {
"title": "H5-5g.aigc-quickapp.com", "title": "H5-5g.aigc-quickapp.com",
"env": { "env": {
"UNI_PLATFORM": "h5" "UNI_PLATFORM": "h5",
"UNI_APP_DOMAIN": "https://5g.aigc-quickapp.com/"
}, },
"define": { "define": {
"H5_5G_AIGC_QUICKAPP_COM": true,
"H5_PRODUCTION": true,
"PRODUCTION": true "PRODUCTION": true
} }
}, },
"h5-test.aigc-quickapp.com": { "h5-test.aigc-quickapp.com": {
"title": "H5-test.aigc-quickapp.com", "title": "H5-test.aigc-quickapp.com",
"env": { "env": {
"UNI_PLATFORM": "h5" "UNI_PLATFORM": "h5",
"UNI_APP_DOMAIN": "https://test.aigc-quickapp.com/"
}, },
"define": { "define": {
"H5_TEST_AIGC_QUICKAPP_COM": true,
"H5_PRODUCTION": true,
"PRODUCTION": true "PRODUCTION": true
} }
} }

View File

@@ -43,7 +43,7 @@
{ {
"path": "detail", "path": "detail",
"style": { "style": {
"navigationBarTitleText": "资源详情" "navigationBarTitleText": "商品详情"
} }
}, },
{ {
@@ -318,7 +318,7 @@
{ {
"path": "ai-chat/index", "path": "ai-chat/index",
"style": { "style": {
"navigationBarTitleText": "AI 客服" "navigationBarTitleText": "AI智能客服"
} }
}, },
{ {

View File

@@ -9,7 +9,7 @@
<image :src="$util.img(siteInfo.logo_square)" mode="aspectFill"></image> <image :src="$util.img(siteInfo.logo_square)" mode="aspectFill"></image>
</view> </view>
<view class="info-box" :style="{ color: '#ffffff' }"> <view class="info-box" :style="{ color: '#ffffff' }">
<text class="font-size-base">{{ siteInfo.site_name }}</text> <text class="font-size-base" @tap="onTitleTap">{{ siteInfo.site_name }}</text>
<text>{{ followOfficialAccount.welcomeMsg }}</text> <text>{{ followOfficialAccount.welcomeMsg }}</text>
</view> </view>
</view> </view>
@@ -17,6 +17,10 @@
}}</view> }}</view>
</view> </view>
<!-- <view class="page-header" v-if="diyData.global && diyData.global.navBarSwitch" :style="{ backgroundImage: bgImg }">
<ns-navbar :title-color="textNavColor" :data="diyData.global" :scrollTop="scrollTop" :isBack="false"/>
</view> -->
<diy-index-page v-if="topIndexValue" ref="indexPage" :value="topIndexValue" :bgUrl="bgUrl" <diy-index-page v-if="topIndexValue" ref="indexPage" :value="topIndexValue" :bgUrl="bgUrl"
:scrollTop="scrollTop" :diyGlobal="diyData.global" class="diy-index-page"> :scrollTop="scrollTop" :diyGlobal="diyData.global" class="diy-index-page">
<template v-slot:components> <template v-slot:components>
@@ -39,17 +43,35 @@
<view @touchmove.prevent.stop> <view @touchmove.prevent.stop>
<uni-popup ref="uniPopupWindow" type="center" class="wap-floating" :maskClick="false"> <uni-popup ref="uniPopupWindow" type="center" class="wap-floating" :maskClick="false">
<view class="small-bot"> <view class="small-bot">
<!-- <view class="adver-time" wx:if="{{startadv.params.style=='default'&&startadv.params.canclose==1}}">
<view bindtap="adverclose">跳过</view>
<view class="time">{{clock}}s</view>
</view>
<view class="adver-time" wx:if="{{startadv.params.style=='default'&&startadv.params.canclose==0}}">
<view class="time" style="line-height: 64rpx;">{{clock}}s</view>
</view> -->
<swiper autoplay="true" :circular="true" indicator-active-color="#fff" <swiper autoplay="true" :circular="true" indicator-active-color="#fff"
indicator-color="rgba(255,255,255,0.6)" :indicator-dots="true" interval="3000"> indicator-color="rgba(255,255,255,0.6)" :indicator-dots="true" interval="3000">
<swiper-item v-for="(item, index) in adv.list" :key="index"> <swiper-item v-for="(item, index) in adv.list" :key="index">
<image class="slide-image" @click="$util.diyRedirectTo(item.link)" height="100%" <image class="slide-image" @click="$util.diyRedirectTo(item.link)" height="100%"
:src="$util.img(item.imageUrl)" width="100%"></image> :src="$util.img(item.imageUrl)" width="100%" show-menu-by-longpress></image>
<!-- <image bindtap="adverclose" class="slide-image" height="100%" src="{{item.imgurl}}" width="100%" wx:if="{{item.click==1}}" show-menu-by-longpress></image> -->
</swiper-item> </swiper-item>
</swiper> </swiper>
<view bindtap="adverclose" class="small-bot-close" @click="closePopupWindow"> <view bindtap="adverclose" class="small-bot-close" @click="closePopupWindow">
<i class="iconfont icon-round-close" style="color:#fff"></i> <i class="iconfont icon-round-close" style="color:#fff"></i>
</view> </view>
</view> </view>
<!-- <view class="image-wrap">
<swiper class="swiper" style="width:100%;height: 1200rpx;" :autoplay="true" interval="3000" circular="true" :indicator-dots="true" indicator-color="#000" indicator-active-color="red">
<swiper-item class="swiper-item" v-for="(item, index) in adv.list" :key="index" v-if="item.imageUrl" @click="$util.diyRedirectTo(item.link)">
<view class="item">
<image :src="$util.img(item.imageUrl)" mode="aspectFit" show-menu-by-longpress></image>
</view>
</swiper-item>
</swiper>
</view>
<text class="iconfont icon-round-close" @click="closePopupWindow"></text> -->
</uni-popup> </uni-popup>
</view> </view>
</template> </template>
@@ -63,7 +85,7 @@
<view @touchmove.prevent class="official-accounts-inner" v-if="wechatQrcode"> <view @touchmove.prevent class="official-accounts-inner" v-if="wechatQrcode">
<uni-popup ref="officialAccountsPopup" type="center"> <uni-popup ref="officialAccountsPopup" type="center">
<view class="official-accounts-wrap"> <view class="official-accounts-wrap">
<image class="content" :src="$util.img(wechatQrcode)" mode="aspectFit"></image> <image class="content" :src="$util.img(wechatQrcode)" mode="aspectFit" show-menu-by-longpress></image>
<text class="desc">关注了解更多</text> <text class="desc">关注了解更多</text>
<text class="close iconfont icon-round-close" @click="officialAccountsClose"></text> <text class="close iconfont icon-round-close" @click="officialAccountsClose"></text>
</view> </view>
@@ -74,12 +96,12 @@
<uni-popup ref="collectPopupWindow" type="top" class="wap-floating wap-floating-collect"> <uni-popup ref="collectPopupWindow" type="top" class="wap-floating wap-floating-collect">
<view v-if="showTip" class="collectPopupWindow" <view v-if="showTip" class="collectPopupWindow"
:style="{ marginTop: (collectTop + statusBarHeight) * 2 + 'rpx' }"> :style="{ marginTop: (collectTop + statusBarHeight) * 2 + 'rpx' }">
<image :src="$util.img('public/uniapp/index/collect2.png')" mode="aspectFit" /> <image :src="$util.img('public/uniapp/index/collect2.png')" mode="aspectFit" show-menu-by-longpress/>
<text @click="closeCollectPopupWindow">我知道了</text> <text @click="closeCollectPopupWindow">我知道了</text>
</view> </view>
</uni-popup> </uni-popup>
<!-- 选择门店弹出框 --> <!-- 选择门店弹出框,定位当前位置,展示最近的一个门店 -->
<view @touchmove.prevent.stop class="choose-store"> <view @touchmove.prevent.stop class="choose-store">
<uni-popup ref="chooseStorePopup" type="center" :maskClick="false" class="choose-store"> <uni-popup ref="chooseStorePopup" type="center" :maskClick="false" class="choose-store">
<view class="choose-store-popup"> <view class="choose-store-popup">
@@ -114,161 +136,26 @@
</view> </view>
</uni-popup> </uni-popup>
</view> </view>
<hover-nav :need="true"></hover-nav> <hover-nav :need="true"></hover-nav>
<!-- 隐私协议 -->
<!-- 隐私协议弹窗 UI (新增) -->
<view v-if="showPrivacyModal" class="privacy-modal-mask" @touchmove.prevent>
<view class="privacy-modal-container">
<view class="modal-header">用户隐私保护提示</view>
<view class="modal-body">
<text>感谢您使用本应用,在使用前您应当阅读并同意</text>
<text class="link" @click="viewPrivacy('privacy')">《隐私条款》</text>
<text class="link" @click="viewPrivacy('agreement')">《用户服务协议》</text>
<text>,当点击同意并继续时,即表示您已理解并同意该条款内容,该条款将对您产生法律约束力;如您不同意,将无法继续使用相关功能。</text>
</view>
<view class="modal-footer">
<view class="btn btn-disagree" @click="handleDisagree">不同意</view>
<view class="btn btn-agree" @click="handleAgree">同意并继续</view>
</view>
</view>
</view>
<!-- 隐私协议组件 (原有) -->
<privacy-popup ref="privacyPopup"></privacy-popup> <privacy-popup ref="privacyPopup"></privacy-popup>
<to-top v-if="showTop" @toTop="scrollToTopNative()"></to-top> <to-top v-if="showTop" @toTop="scrollToTopNative()"></to-top>
<ns-login ref="login"></ns-login> <ns-login ref="login"></ns-login>
<!-- 版本信息触发区(固定定位,不可见,始终可点击) -->
<view class="version-trigger" @tap="onTitleTap"></view>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
import diyJs from '@/common/js/diy.js'; import diyJs from '@/common/js/diy.js';
import scroll from '@/common/js/scroll-view.js'; import scroll from '@/common/js/scroll-view.js';
import indexJs from './public/js/index.js'; import indexJs from './public/js/index.js';
export default { export default {
mixins: [diyJs, scroll, indexJs], mixins: [diyJs, scroll, indexJs]
data() {
return {
minScrollTop: 100,
wechatQrcode: '',
diyRoute: '/pages/index/index',
showPrivacyModal: false // 新增:控制隐私弹窗显示
};
},
onLoad(option) {
// #ifdef H5
if (option.module && option.module == 'locationPicker') {
option.name = '';
}
// #endif
this.name = option.name || 'DIY_VIEW_INDEX';
},
onShow() {
this.getFollowQrcode();
// 页面显示时检查隐私设置
this.checkPrivacySetting();
},
mounted() {
this.unsubscribe = this.$eventBus?.onMany([
'rubik-cube-tap',
'picture-tap',
'text-tap',
'goods-list-tap',
'presale-tap',
'notes-tap',
'merch-list-tap',
'map-tap',
'img-ads-tap',
'many-goods-list-tap',
'search-tap',
], this._handleDiyGroupInteractionEvent);
},
beforeDestroy() {
if (this.unsubscribe) this.unsubscribe();
},
methods: {
// 检查隐私弹窗逻辑
checkPrivacySetting() {
// 模拟检查本地存储,看用户是否已经同意过
// 实际项目中请替换为你真实的存储逻辑
const hasAgreed = uni.getStorageSync('HAS_AGREED_PRIVACY');
if (!hasAgreed) {
// 延迟显示,防止遮挡页面渲染
setTimeout(() => {
this.showPrivacyModal = true;
}, 500);
}
},
// 用户点击同意
handleAgree() {
// 保存同意状态
uni.setStorageSync('HAS_AGREED_PRIVACY', true);
this.showPrivacyModal = false;
},
// 用户点击不同意
handleDisagree() {
// 微信小程序环境下,不同意通常退出小程序
// #ifdef MP-WEIXIN
uni.exitMiniProgram();
// #endif
// H5 或 App 下可以提示或直接不显示内容
// #ifndef MP-WEIXIN
uni.showToast({
title: '您已拒绝协议,无法使用',
icon: 'none',
duration: 2000
});
// 这里可以选择关闭页面或保持弹窗
// this.showPrivacyModal = false;
// #endif
},
// 查看具体条款(可选功能)
viewPrivacy(type) {
// 这里可以跳转到具体的条款页面,或者使用你现有的 privacy-popup 组件
// 假设你有现成的组件逻辑:
if (this.$refs.privacyPopup) {
// 假设 privacy-popup 组件有一个 show 方法
// this.$refs.privacyPopup.show(type);
}
uni.showToast({
title: '请在此处实现查看条款逻辑',
icon: 'none'
});
},
getFollowQrcode() {
if (!this.$util.isWeiXin()) return;
this.$api.sendRequest({
url: '/wechat/api/wechat/followqrcode',
success: res => {
if (res.code >= 0 && res.data) {
this.wechatQrcode = res.data.qrcode;
}
}
});
},
officialAccountsOpen() {
this.$refs.officialAccountsPopup.open();
},
officialAccountsClose() {
this.$refs.officialAccountsPopup.close();
},
_handleDiyGroupInteractionEvent(payload) {
// #ifdef H5
return true;
// #endif
if (this.storeToken) {
return true;
}
this.$refs.login?.open();
return false;
}
}
}; };
</script> </script>
@@ -314,74 +201,6 @@ export default {
.small-bot-close i { .small-bot-close i {
font-size: 60rpx; font-size: 60rpx;
} }
/* 新增:隐私弹窗样式 */
.privacy-modal-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.6); // 半透明背景
z-index: 9999; // 确保层级最高
display: flex;
justify-content: center;
align-items: center;
}
.privacy-modal-container {
width: 80%;
background-color: #ffffff;
border-radius: 12rpx;
padding: 40rpx 30rpx;
text-align: center;
}
.modal-header {
font-size: 36rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
}
.modal-body {
font-size: 28rpx;
color: #666;
line-height: 1.6;
text-align: left;
margin-bottom: 30rpx;
}
.link {
color: #007aff; // 蓝色链接
margin: 0 4rpx;
}
.modal-footer {
display: flex;
justify-content: space-between;
padding: 0 20rpx;
}
.btn {
flex: 1;
height: 80rpx;
line-height: 80rpx;
border-radius: 40rpx;
font-size: 30rpx;
text-align: center;
margin: 0 15rpx;
}
.btn-disagree {
background-color: #f5f5f5;
color: #333;
}
.btn-agree {
background-color: #07c160; // 微信绿
color: #fff;
}
</style> </style>
<style scoped> <style scoped>
.swiper ::v-deep .uni-swiper-dots-horizontal { .swiper ::v-deep .uni-swiper-dots-horizontal {
@@ -426,4 +245,14 @@ export default {
bottom: 180rpx !important; bottom: 180rpx !important;
/* #endif */ /* #endif */
} }
.version-trigger {
position: fixed;
right: 0;
bottom: 50rpx;
width: 100rpx;
height: 100rpx;
z-index: 999;
background: transparent;
}
</style> </style>

View File

@@ -1,95 +1,129 @@
export default { export default {
data() { data() {
return { return {
minScrollTop: 100, // 设置回到顶端按钮显示要求,最小页面滚动距离 minScrollTop: 100, // 设置回到顶端按钮显示要求,最小页面滚动距离
wechatQrcode: "", // 公众号二维码 wechatQrcode: '', // 公众号二维码
diyRoute: "/pages/index/index", diyRoute: '/pages/index/index',
}; shopInfo: null // 店铺信息
}, };
onLoad(option) { },
// #ifdef H5 onLoad(option) {
// H5地图选择位置回调数据 // #ifdef H5
if (option.module && option.module == "locationPicker") { // H5地图选择位置回调数据
option.name = ""; // 清空地址 if (option.module && option.module == 'locationPicker') {
} option.name = ''; // 清空地址
// #endif }
this.name = option.name || "DIY_VIEW_INDEX"; // 根据店铺运营模式,打开平台(shop)或者连锁门店(stroe)页面,接口会自行判断 // #endif
}, this.name = option.name || 'DIY_VIEW_INDEX'; // 根据店铺运营模式,打开平台(shop)或者连锁门店(stroe)页面,接口会自行判断
onShow() {
// 获取关注公众号二维码
this.getFollowQrcode();
// 检查隐私设置并显示弹窗
this.checkPrivacySetting();
},
mounted() {
// 监听图片、文字、商品列表等组件的点击事件
this.unsubscribe = this.$eventBus?.onMany(
[
"rubik-cube-tap",
"picture-tap",
"text-tap",
"goods-list-tap",
"presale-tap",
"notes-tap",
"merch-list-tap",
"map-tap",
"img-ads-tap",
"many-goods-list-tap",
"search-tap",
],
this._handleDiyGroupInteractionEvent,
);
},
beforeDestroy() {
// 移除图片点击事件监听
if (this.unsubscribe) this.unsubscribe();
},
methods: {
// 检查隐私设置
checkPrivacySetting() {
// 延迟执行,确保组件已经挂载
setTimeout(() => {
if (this.$refs.privacyPopup) {
this.$refs.privacyPopup.proactive();
}
}, 100);
},
// 关注公众号
getFollowQrcode() {
if (!this.$util.isWeiXin()) return;
this.$api.sendRequest({
url: "/wechat/api/wechat/followqrcode",
success: (res) => {
if (res.code >= 0 && res.data) {
this.wechatQrcode = res.data.qrcode;
}
},
});
},
officialAccountsOpen() {
this.$refs.officialAccountsPopup.open();
},
officialAccountsClose() {
this.$refs.officialAccountsPopup.close();
},
// 统一处理点击及触摸事件
_handleDiyGroupInteractionEvent(payload) {
// #ifdef H5
// 如果是 H5 环境,直接返回 true 继续传播
return true;
// #endif
// 如果已登录,直接返回 true 继续传播 // 获取店铺信息
if (this.storeToken) { this.shopInfo = uni.getStorageSync('shopInfo');
return true; },
} onShow() {
// 获取关注公众号二维码
this.getFollowQrcode();
// 重新获取店铺信息
this.shopInfo = uni.getStorageSync('shopInfo');
},
mounted() {
// 监听图片、文字、商品列表等组件的点击事件
this.unsubscribe = this.$eventBus?.onMany([
'rubik-cube-tap',
'picture-tap',
'text-tap',
'goods-list-tap',
'presale-tap',
'notes-tap',
'merch-list-tap',
'map-tap',
'img-ads-tap',
'many-goods-list-tap',
'search-tap',
], this._handleDiyGroupInteractionEvent);
},
beforeDestroy() {
// 移除图片点击事件监听
if (this.unsubscribe) this.unsubscribe();
},
methods: {
// 关注公众号
getFollowQrcode() {
if (!this.$util.isWeiXin()) return;
this.$api.sendRequest({
url: '/wechat/api/wechat/followqrcode',
success: res => {
if (res.code >= 0 && res.data) {
this.wechatQrcode = res.data.qrcode;
}
}
});
},
officialAccountsOpen() {
this.$refs.officialAccountsPopup.open();
},
officialAccountsClose() {
this.$refs.officialAccountsPopup.close();
},
// 判断是否需要登录授权
_needLoginAuth() {
// 检查 index_login_auth 都开启时才需要登录授权
return this.shopInfo?.index_login_auth == 1;
},
// 统一处理点击及触摸事件
_handleDiyGroupInteractionEvent(payload) {
// #ifdef H5
// 如果是 H5 环境,直接返回 true 继续传播
return true;
// #endif
// 打开登录弹窗 // 如果不需要登录授权,直接返回 true 继续传播
// console.log('==> _handleDiyGroupInteractionEvent, 未登录,打开登录弹窗', { payload }) if (!this._needLoginAuth()) {
this.$refs.login?.open(); return true;
}
// 阻止事件继续传播 // 如果已登录,直接返回 true 继续传播
return false; if (this.storeToken) {
}, return true;
}, }
};
this.$refs.login?.open();
// 阻止事件继续传播
return false;
},
/**
* 标题连击 5 次显示构建版本信息(供测试人员使用)
*/
onTitleTap() {
this._titleTapCount = (this._titleTapCount || 0) + 1;
if (this._titleTapTimer) {
clearTimeout(this._titleTapTimer);
}
if (this._titleTapCount >= 5) {
this._titleTapCount = 0;
this._showVersionInfo();
return;
}
// 2 秒内未达到 5 次则重置计数
this._titleTapTimer = setTimeout(() => {
this._titleTapCount = 0;
}, 2000);
},
_showVersionInfo() {
let v = null;
try {
v = typeof __app_version !== 'undefined' ? __app_version : null;
} catch (e) {}
if (v && v.commitId) {
uni.showModal({
title: '构建版本信息',
content: `提交 ID: ${v.commitId}\n构建时间: ${v.buildTime}`,
showCancel: false
});
} else {
console.log('未获取到构建版本信息');
}
}
}
}

View File

@@ -413,10 +413,8 @@ export default {
} }
}, },
success: function (res) { success: function (res) {
console.log('success', res);
}, },
fail: function (res) { fail: function (res) {
console.log('fail', res);
} }
}) })
} }

View File

@@ -2,6 +2,11 @@
<view> <view>
<view scroll-y="true" class="goods-detail" :class="isIphoneX ? 'active' : ''"> <view scroll-y="true" class="goods-detail" :class="isIphoneX ? 'active' : ''">
<view class="goods-container"> <view class="goods-container">
<!-- AI客服悬浮按钮 -->
<view class="ai-chat-float-btn" @tap.stop="$emit('aiChatClick')" v-if="showAIChatBtn">
<image :src="aiAvatarUrl" mode="aspectFill" class="ai-avatar-icon" />
</view>
<!-- 弹幕 --> <!-- 弹幕 -->
<pengpai-fadein-out v-if="goodsSkuDetail.barrage_show && goodsSkuDetail.barrageData" ref="pengpai" <pengpai-fadein-out v-if="goodsSkuDetail.barrage_show && goodsSkuDetail.barrageData" ref="pengpai"
:duration="1600" :wait="1900" :top="200" :left="0" :radius="60" :loop="true" :duration="1600" :wait="1900" :top="200" :left="0" :radius="60" :loop="true"
@@ -17,7 +22,7 @@
:item-id="'goods_id_' + index"> :item-id="'goods_id_' + index">
<view class="item" @click="previewMedia(index)"> <view class="item" @click="previewMedia(index)">
<image :src="$util.img(item, { size: 'big' })" @error="swiperImageError(index)" <image :src="$util.img(item, { size: 'big' })" @error="swiperImageError(index)"
mode="aspectFit" /> mode="aspectFit" show-menu-by-longpress />
</view> </view>
</swiper-item> </swiper-item>
</swiper> </swiper>
@@ -130,7 +135,7 @@
<view class="list-wrap" style="display: flex;"> <view class="list-wrap" style="display: flex;">
<view class="name-wrap"> <view class="name-wrap">
<image :src="$util.img(goodsSkuDetail.merchinfo.merch_image)" mode="widthFix" <image :src="$util.img(goodsSkuDetail.merchinfo.merch_image)" mode="widthFix"
style="width: 100rpx;height: 100rpx;border-radius: 50rpx;"></image> style="width: 100rpx;height: 100rpx;border-radius: 50rpx;" show-menu-by-longpress ></image>
</view> </view>
<view class="other-wrap"> <view class="other-wrap">
<view class="address" style="margin-left: 30rpx;"> <view class="address" style="margin-left: 30rpx;">
@@ -214,8 +219,8 @@
@click="selectStore(item)"> @click="selectStore(item)">
<view class="item-box"> <view class="item-box">
<view class="item-image"> <view class="item-image">
<image :src="$util.img(item.store_image)" v-if="item.store_image" /> <image :src="$util.img(item.store_image)" v-if="item.store_image" show-menu-by-longpress />
<image :src="$util.getDefaultImage().store" v-else /> <image :src="$util.getDefaultImage().store" v-else show-menu-by-longpress />
</view> </view>
<view class="item-info"> <view class="item-info">
<view class="item-title"> <view class="item-title">
@@ -243,7 +248,7 @@
<view class="detail-community" v-if="goodsSkuDetail.qr_data && goodsSkuDetail.qr_data.qr_state == 1"> <view class="detail-community" v-if="goodsSkuDetail.qr_data && goodsSkuDetail.qr_data.qr_state == 1">
<view class="community-box"> <view class="community-box">
<image :src="$util.img('public/uniapp/goods/detail_erweiImage.png')" mode="aspectFill"></image> <image :src="$util.img('public/uniapp/goods/detail_erweiImage.png')" mode="aspectFill" show-menu-by-longpress ></image>
<view class="community-content"> <view class="community-content">
<view class="community-title">{{ goodsSkuDetail.qr_data.qr_name }}</view> <view class="community-title">{{ goodsSkuDetail.qr_data.qr_name }}</view>
<view class="community-txt">{{ goodsSkuDetail.qr_data.community_describe }}</view> <view class="community-txt">{{ goodsSkuDetail.qr_data.community_describe }}</view>
@@ -259,7 +264,7 @@
<view>添加社群</view> <view>添加社群</view>
</view> </view>
<view class="community-model-content-draw" v-if="goodsSkuDetail.qr_data && goodsSkuDetail.qr_data.qr_img"> <view class="community-model-content-draw" v-if="goodsSkuDetail.qr_data && goodsSkuDetail.qr_data.qr_img">
<image :src="goodsSkuDetail.qr_data.qr_img != '' && goodsSkuDetail.qr_data.qr_state == 1 ? $util.img(goodsSkuDetail.qr_data.qr_img) : $util.img('public/uniapp/goods/detail_erweiImage.png') " mode="aspectFill" show-menu-by-longpress="true"/> <image :src="goodsSkuDetail.qr_data.qr_img != '' && goodsSkuDetail.qr_data.qr_state == 1 ? $util.img(goodsSkuDetail.qr_data.qr_img) : $util.img('public/uniapp/goods/detail_erweiImage.png') " mode="aspectFill" show-menu-by-longpress/>
</view> </view>
<view class="community-model-content-text">长按识别二维码,添加社群</view> <view class="community-model-content-text">长按识别二维码,添加社群</view>
</view> </view>
@@ -296,10 +301,10 @@
<view class="evaluator-face"> <view class="evaluator-face">
<image v-if="item.member_headimg" :src="$util.img(item.member_headimg)" <image v-if="item.member_headimg" :src="$util.img(item.member_headimg)"
@error="item.member_headimg = $util.getDefaultImage().head" @error="item.member_headimg = $util.getDefaultImage().head"
mode="aspectFill" /> mode="aspectFill" show-menu-by-longpress />
<image v-else :src="$util.getDefaultImage().head" <image v-else :src="$util.getDefaultImage().head"
@error="item.member_headimg = $util.getDefaultImage().head" @error="item.member_headimg = $util.getDefaultImage().head"
mode="aspectFill" /> mode="aspectFill" show-menu-by-longpress />
</view> </view>
<view class="evaluator-name-wrap"> <view class="evaluator-name-wrap">
<text class="evaluator-name using-hidden" <text class="evaluator-name using-hidden"
@@ -320,7 +325,7 @@
<view class="evaluate-img" v-if="item.images"> <view class="evaluate-img" v-if="item.images">
<view class="img-box" v-for="(img, img_index) in item.images" :key="img_index" <view class="img-box" v-for="(img, img_index) in item.images" :key="img_index"
@click="previewEvaluate(index, img_index, 'images')"> @click="previewEvaluate(index, img_index, 'images')">
<image :src="$util.img(img)" mode="aspectFill" /> <image :src="$util.img(img)" mode="aspectFill" show-menu-by-longpress />
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
@@ -385,7 +390,7 @@
<template v-if="poster != '-1'"> <template v-if="poster != '-1'">
<view class="poster-wrap"> <view class="poster-wrap">
<view class="image-wrap"> <view class="image-wrap">
<image :src="$util.img(poster)" :show-menu-by-longpress="true" mode="widthFix" /> <image :src="$util.img(poster)" show-menu-by-longpress mode="widthFix" />
<view class="close iconfont icon-close" @click="closePosterPopup()"></view> <view class="close iconfont icon-close" @click="closePosterPopup()"></view>
</view> </view>
<!-- #ifdef MP || APP-PLUS --> <!-- #ifdef MP || APP-PLUS -->
@@ -458,6 +463,8 @@
// 商品详情视图 // 商品详情视图
import scroll from '@/common/js/scroll-view.js'; import scroll from '@/common/js/scroll-view.js';
import detail from './detail.js'; import detail from './detail.js';
import IMAGE_CONFIG from '@/common/js/image-config.js';
import { createCustomerService } from '@/common/js/customer-service.js';
import pengpaiFadeinOut from '../pengpai-fadein-out/pengpai-fadein-out.vue'; import pengpaiFadeinOut from '../pengpai-fadein-out/pengpai-fadein-out.vue';
@@ -474,6 +481,15 @@ export default {
components: { components: {
pengpaiFadeinOut pengpaiFadeinOut
}, },
computed: {
aiAvatarUrl() {
return this.$util.img(IMAGE_CONFIG.aiAvatar);
},
showAIChatBtn() {
const customerService = createCustomerService(this);
return customerService.hasValidKefuConfig() && customerService.isAIKefu();
}
},
mixins: [scroll, detail] mixins: [scroll, detail]
}; };
</script> </script>
@@ -481,4 +497,36 @@ export default {
<style lang="scss"> <style lang="scss">
@import '@/common/css/goods_detail.scss'; @import '@/common/css/goods_detail.scss';
</style> </style>
<style scoped></style> <style scoped>
.ai-chat-float-btn {
position: fixed;
right: 20rpx;
top: 100rpx;
width: 80rpx;
height: 80rpx;
border-radius: 50%;
background: #ffffff;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.15);
z-index: 9999;
transition: all 0.3s ease;
overflow: hidden;
}
.ai-chat-float-btn:active {
transform: scale(0.9);
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
}
.ai-chat-float-btn .iconfont {
font-size: 40rpx;
}
.ai-chat-float-btn .ai-avatar-icon {
width: 100%;
height: 100%;
border-radius: 50%;
}
</style>

View File

@@ -6,38 +6,38 @@
<text class="promotion-mark ">限时折扣</text> <text class="promotion-mark ">限时折扣</text>
<text class="title">当前商品正在参加{{ item.promotion_name }}</text> <text class="title">当前商品正在参加{{ item.promotion_name }}</text>
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
<!-- <view class="img-wrap"><image :src="$util.img('public/uniapp/goods/detail_more.png')" mode="aspectFit" /></view> --> <!-- <view class="img-wrap"><image :src="$util.img('public/uniapp/goods/detail_more.png')" mode="aspectFit" show-menu-by-longpress/></view> -->
</view> </view>
<view v-else-if="item.promotion_type == 'groupbuy'" class="item" @click="redirectTo('/pages_promotion/groupbuy/detail', { groupbuy_id: item.groupbuy_id })"> <view v-else-if="item.promotion_type == 'groupbuy'" class="item" @click="redirectTo('/pages_promotion/groupbuy/detail', { groupbuy_id: item.groupbuy_id })">
<!-- <view v-else-if="item.promotion_type == 'groupbuy'" class="item" @click="redirectTo('/pages_promotion/groupbuy/detail', { id: item.groupbuy_id })"> --> <!-- <view v-else-if="item.promotion_type == 'groupbuy'" class="item" @click="redirectTo('/pages_promotion/groupbuy/detail', { id: item.groupbuy_id })"> -->
<text class="promotion-mark ">团购</text> <text class="promotion-mark ">团购</text>
<text class="title">当前商品正在参加{{ item.promotion_name }}</text> <text class="title">当前商品正在参加{{ item.promotion_name }}</text>
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
<!-- <view class="img-wrap"><image :src="$util.img('public/uniapp/goods/detail_more.png')" mode="aspectFit" /></view> --> <!-- <view class="img-wrap"><image :src="$util.img('public/uniapp/goods/detail_more.png')" mode="aspectFit" show-menu-by-longpress/></view> -->
</view> </view>
<view v-else-if="item.promotion_type == 'pintuan'" class="item" @click="redirectTo('/pages_promotion/pintuan/detail', { pintuan_id: item.pintuan_id })"> <view v-else-if="item.promotion_type == 'pintuan'" class="item" @click="redirectTo('/pages_promotion/pintuan/detail', { pintuan_id: item.pintuan_id })">
<text class="promotion-mark ">拼团</text> <text class="promotion-mark ">拼团</text>
<text class="title">当前商品正在参加{{ item.promotion_name }}</text> <text class="title">当前商品正在参加{{ item.promotion_name }}</text>
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
<!-- <view class="img-wrap"><image :src="$util.img('public/uniapp/goods/detail_more.png')" mode="aspectFit" /></view> --> <!-- <view class="img-wrap"><image :src="$util.img('public/uniapp/goods/detail_more.png')" mode="aspectFit" show-menu-by-longpress/></view> -->
</view> </view>
<view v-else-if="item.promotion_type == 'seckill'" class="item" @click="redirectTo('/pages_promotion/seckill/detail', { seckill_id: item.id })"> <view v-else-if="item.promotion_type == 'seckill'" class="item" @click="redirectTo('/pages_promotion/seckill/detail', { seckill_id: item.id })">
<text class="promotion-mark ">秒杀</text> <text class="promotion-mark ">秒杀</text>
<text class="title">当前商品正在参加{{ item.promotion_name }}</text> <text class="title">当前商品正在参加{{ item.promotion_name }}</text>
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
<!-- <view class="img-wrap"><image :src="$util.img('public/uniapp/goods/detail_more.png')" mode="aspectFit" /></view> --> <!-- <view class="img-wrap"><image :src="$util.img('public/uniapp/goods/detail_more.png')" mode="aspectFit" show-menu-by-longpress/></view> -->
</view> </view>
<view v-else-if="item.promotion_type == 'topic'" class="item" @click="redirectTo('/pages_promotion/topics/goods_detail', { id: item.id })"> <view v-else-if="item.promotion_type == 'topic'" class="item" @click="redirectTo('/pages_promotion/topics/goods_detail', { id: item.id })">
<text class="promotion-mark ">专题活动</text> <text class="promotion-mark ">专题活动</text>
<text class="title">当前商品正在参加{{ item.promotion_name }}</text> <text class="title">当前商品正在参加{{ item.promotion_name }}</text>
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
<!-- <view class="img-wrap"><image :src="$util.img('public/uniapp/goods/detail_more.png')" mode="aspectFit" /></view> --> <!-- <view class="img-wrap"><image :src="$util.img('public/uniapp/goods/detail_more.png')" mode="aspectFit" show-menu-by-longpress/></view> -->
</view> </view>
<view v-else-if="item.promotion_type == 'bargain'" class="item" @click="redirectTo('/pages_promotion/bargain/detail', { b_id: item.bargain_id })"> <view v-else-if="item.promotion_type == 'bargain'" class="item" @click="redirectTo('/pages_promotion/bargain/detail', { b_id: item.bargain_id })">
<text class="promotion-mark ">砍价</text> <text class="promotion-mark ">砍价</text>
<text class="title">当前商品正在参加{{ item.promotion_name }}</text> <text class="title">当前商品正在参加{{ item.promotion_name }}</text>
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
<!-- <view class="img-wrap"><image :src="$util.img('public/uniapp/goods/detail_more.png')" mode="aspectFit" /></view> --> <!-- <view class="img-wrap"><image :src="$util.img('public/uniapp/goods/detail_more.png')" mode="aspectFit" show-menu-by-longpress/></view> -->
</view> </view>
<view v-else-if="item.promotion_type == 'pinfan'" class="item" @click="redirectTo('/pages_promotion/pinfan/detail', { pinfan_id: item.pintuan_id })"> <view v-else-if="item.promotion_type == 'pinfan'" class="item" @click="redirectTo('/pages_promotion/pinfan/detail', { pinfan_id: item.pintuan_id })">
<text class="promotion-mark ">拼团返利</text> <text class="promotion-mark ">拼团返利</text>

View File

@@ -4,7 +4,7 @@
<view class="round bg-gradual-orange flex justify-start shadow" style="padding: 3px;"> <view class="round bg-gradual-orange flex justify-start shadow" style="padding: 3px;">
<view class="cu-avatar cu-a-sm round" :style="{ backgroundImage: 'url(' + $util.img(penpaiData.img) + ')' }"> <view class="cu-avatar cu-a-sm round" :style="{ backgroundImage: 'url(' + $util.img(penpaiData.img) + ')' }">
<!-- #ifdef APP-NVUE --> <!-- #ifdef APP-NVUE -->
<!-- <image :src="penpaiData.img" class="avatarimg"></image> --> <!-- <image :src="penpaiData.img" class="avatarimg" show-menu-by-longpress></image> -->
<!-- #endif --> <!-- #endif -->
</view> </view>
<view class="padding-lr-sm flex align-center"> <view class="padding-lr-sm flex align-center">
@@ -151,8 +151,7 @@ export default {
// #endif // #endif
}, this.wait); }, this.wait);
// console.log('this.top', this.top);
// console.log('this.radius', this.radius);
setTimeout(() => { setTimeout(() => {
this.animationData = uni this.animationData = uni

View File

@@ -34,7 +34,7 @@
@click="singleElection(siteIndex, cartIndex)"></view> @click="singleElection(siteIndex, cartIndex)"></view>
<view @click="toGoodsDetail(item)" class="goods-img"> <view @click="toGoodsDetail(item)" class="goods-img">
<image :src="$util.img(item.sku_image, { size: 'mid' })" <image :src="$util.img(item.sku_image, { size: 'mid' })"
@error="imageError(siteIndex, cartIndex)" mode="aspectFill" /> @error="imageError(siteIndex, cartIndex)" mode="aspectFill" show-menu-by-longpress/>
</view> </view>
<view class="goods-info"> <view class="goods-info">
<view> <view>
@@ -66,7 +66,7 @@
<text class="unit price-style small">.{{ <text class="unit price-style small">.{{
parseFloat(item.member_price).toFixed(2).split('.')[1] parseFloat(item.member_price).toFixed(2).split('.')[1]
}}</text> }}</text>
<image :src="$util.img('public/uniapp/index/VIP.png')" /> <image :src="$util.img('public/uniapp/index/VIP.png')" show-menu-by-longpress/>
</view> </view>
</view> </view>
</block> </block>
@@ -81,7 +81,7 @@
parseFloat(item.discount_price).toFixed(2).split('.')[1] parseFloat(item.discount_price).toFixed(2).split('.')[1]
}}</text> }}</text>
<image <image
:src="$util.img('public/uniapp/index/discount.png')" /> :src="$util.img('public/uniapp/index/discount.png')" show-menu-by-longpress/>
</view> </view>
</view> </view>
</block> </block>
@@ -96,7 +96,7 @@
<text class="unit price-style small">.{{ <text class="unit price-style small">.{{
parseFloat(item.member_price).toFixed(2).split('.')[1] parseFloat(item.member_price).toFixed(2).split('.')[1]
}}</text> }}</text>
<image :src="$util.img('public/uniapp/index/VIP.png')" /> <image :src="$util.img('public/uniapp/index/VIP.png')" show-menu-by-longpress/>
</view> </view>
</view> </view>
</block> </block>
@@ -150,7 +150,7 @@
<view class="iconfont icon-yuan_checked color-tip"></view> <view class="iconfont icon-yuan_checked color-tip"></view>
<view class="goods-img"> <view class="goods-img">
<image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" <image :src="$util.img(goodsItem.sku_image, { size: 'mid' })"
mode="aspectFill" /> mode="aspectFill" show-menu-by-longpress/>
</view> </view>
<view class="goods-info"> <view class="goods-info">
<view class="goods-name">{{ goodsItem.sku_name }}</view> <view class="goods-name">{{ goodsItem.sku_name }}</view>
@@ -176,7 +176,7 @@
<text class="unit price-style small">.{{ <text class="unit price-style small">.{{
parseFloat(goodsItem.member_price).toFixed(2).split('.')[1] parseFloat(goodsItem.member_price).toFixed(2).split('.')[1]
}}</text> }}</text>
<image :src="$util.img('public/uniapp/index/VIP.png')" /> <image :src="$util.img('public/uniapp/index/VIP.png')" show-menu-by-longpress/>
</template> </template>
<template v-else> <template v-else>
<text class="unit price-style small">{{ <text class="unit price-style small">{{
@@ -256,7 +256,7 @@
:style="{ backgroundColor: discount.coupon_info.receive_type != 'wait' ? '#F2F2F2' : 'var(--main-color-shallow)' }"> :style="{ backgroundColor: discount.coupon_info.receive_type != 'wait' ? '#F2F2F2' : 'var(--main-color-shallow)' }">
<view class="info-wrap"> <view class="info-wrap">
<image class="coupon-line" mode="heightFix" <image class="coupon-line" mode="heightFix"
:src="$util.img('public/uniapp/coupon/coupon_line.png')" /> :src="$util.img('public/uniapp/coupon/coupon_line.png')" show-menu-by-longpress/>
<view class="coupon-money"> <view class="coupon-money">
<template v-if="discount.coupon_info.type == 'reward'"> <template v-if="discount.coupon_info.type == 'reward'">
<text class="unit">{{ $lang('common.currencySymbol') }}</text> <text class="unit">{{ $lang('common.currencySymbol') }}</text>

View File

@@ -26,7 +26,8 @@
export default { export default {
data() { data() {
return { return {
diyData: null diyData: null,
mpShareData: null //小程序分享数据
}; };
}, },
onLoad() { onLoad() {
@@ -38,6 +39,25 @@ export default {
onShow() { onShow() {
this.$util.hideHomeButton(); this.$util.hideHomeButton();
if (this.$refs.category) this.$refs.category[0].pageShow(); if (this.$refs.category) this.$refs.category[0].pageShow();
//小程序分享
// #ifdef MP-WEIXIN
this.$util.getMpShare('/pages_goods/category').then(res => {
this.mpShareData = res;
}).catch(err => {
// 如果后台没配置,用默认值
this.mpShareData = {
appMessage: {
title: '发现超多好物,快来看看',
path: '/pages_goods/category'
},
timeLine: {
title: '发现超多好物,快来看看',
query: '/pages_goods/category'
}
};
});
// #endif
}, },
onUnload() { onUnload() {
if (!this.storeToken && this.$refs.login) this.$refs.login.cancelCompleteInfo(); if (!this.storeToken && this.$refs.login) this.$refs.login.cancelCompleteInfo();
@@ -69,6 +89,24 @@ export default {
onPullDownRefresh() { onPullDownRefresh() {
uni.hideTabBar(); uni.hideTabBar();
this.getDiyInfo(); this.getDiyInfo();
},
onShareAppMessage() {
return this.mpShareData?.appMessage || {
title: '发现超多好物,快来看看',
path: '/pages_goods/category'
};
},
onShareTimeline() {
return this.mpShareData?.timeLine || {
title: '发现超多好物,快来看看',
query: '/pages_goods/category'
};
},
onAddToFavorites() {
return {
title: '发现超多好物,快来看看',
path: '/pages_goods/category'
};
} }
}; };
</script> </script>

View File

@@ -6,7 +6,7 @@
</view> --> </view> -->
<!-- #endif --> <!-- #endif -->
<goods-detail-view :goodsSkuDetail="goodsSkuDetail" ref="goodsDetailView"> <goods-detail-view :goodsSkuDetail="goodsSkuDetail" ref="goodsDetailView" @aiChatClick="sendToAIChat(goodsSkuDetail)">
<!-- 价格区域 --> <!-- 价格区域 -->
<template v-slot:price> <template v-slot:price>
<!-- 限时折扣 --> <!-- 限时折扣 -->
@@ -49,7 +49,7 @@
<text class="price price-font">{{ parseFloat(goodsSkuDetail.member_price).toFixed(2).split('.')[0] }}</text> <text class="price price-font">{{ parseFloat(goodsSkuDetail.member_price).toFixed(2).split('.')[0] }}</text>
<text class="price-symbol price-font">.{{ parseFloat(goodsSkuDetail.member_price).toFixed(2).split('.')[1] }}</text> <text class="price-symbol price-font">.{{ parseFloat(goodsSkuDetail.member_price).toFixed(2).split('.')[1] }}</text>
<view class="member-vip-wrap"> <view class="member-vip-wrap">
<image :src="$util.img('public/uniapp/goods/member_vip.png')" mode="aspectFit"/> <image :src="$util.img('public/uniapp/goods/member_vip.png')" mode="aspectFit" show-menu-by-longpress/>
</view> </view>
<view class="member-price-wrap" v-if="!goodsSkuDetail.market_price_show"> <view class="member-price-wrap" v-if="!goodsSkuDetail.market_price_show">
<text class="unit price-font">原价</text> <text class="unit price-font">原价</text>
@@ -77,7 +77,6 @@
</block> </block>
<block v-else> <block v-else>
<template> <template>
<text class="price price-font" style="font-weight: 600;">{{$lang('makebtn')}}</text>
</template> </template>
</block> </block>
</view> </view>
@@ -141,7 +140,7 @@
v-for="(item, index) in goodsSkuDetail.card_info.relation_goods" v-for="(item, index) in goodsSkuDetail.card_info.relation_goods"
@click="$util.redirectTo('/pages_goods/detail', { goods_id: item.goods_id })" @click="$util.redirectTo('/pages_goods/detail', { goods_id: item.goods_id })"
> >
<image :src="$util.img(item.sku_image)" mode="aspectFill"/> <image :src="$util.img(item.sku_image)" mode="aspectFill" show-menu-by-longpress/>
<view class="content"> <view class="content">
<view class="name multi-hidden">{{ item.sku_name }}</view> <view class="name multi-hidden">{{ item.sku_name }}</view>
<view class="price">¥{{ item.price }}</view> <view class="price">¥{{ item.price }}</view>
@@ -222,13 +221,13 @@
<text>{{ bundling[0].bl_name }}</text> <text>{{ bundling[0].bl_name }}</text>
</view> </view>
<text class="iconfont icon-right"></text> <text class="iconfont icon-right"></text>
<!-- <view class="more-img-wrap"><image :src="$util.img('public/uniapp/goods/detail_more.png')" mode="aspectFit" /></view> --> <!-- <view class="more-img-wrap"><image :src="$util.img('public/uniapp/goods/detail_more.png')" mode="aspectFit" show-menu-by-longpress/></view> -->
</view> </view>
<scroll-view class="combo-goods-wrap color-tip" scroll-x="true"> <scroll-view class="combo-goods-wrap color-tip" scroll-x="true">
<view class="goods-wrap"> <view class="goods-wrap">
<view class="goods-item" @click="toGoodsDetail(skuId)" v-if="bundlingType == true"> <view class="goods-item" @click="toGoodsDetail(skuId)" v-if="bundlingType == true">
<view class="combo-img"> <view class="combo-img">
<image :src="$util.img(goodsSkuDetail.sku_image, { size: 'mid' })" @error="imageError()" /> <image :src="$util.img(goodsSkuDetail.sku_image, { size: 'mid' })" @error="imageError()" show-menu-by-longpress/>
<view class="price-wrap"> <view class="price-wrap">
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text> <text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="price price-font">{{ goodsSkuDetail.price }}</text> <text class="price price-font">{{ goodsSkuDetail.price }}</text>
@@ -240,7 +239,7 @@
<template v-if="index < 3"> <template v-if="index < 3">
<view class="goods-item" @click="toGoodsDetail(item.sku_id)"> <view class="goods-item" @click="toGoodsDetail(item.sku_id)">
<view class="combo-img"> <view class="combo-img">
<image :src="$util.img(item.sku_image, { size: 'mid' })" @error="bundlingImageError(0, index)" /> <image :src="$util.img(item.sku_image, { size: 'mid' })" @error="bundlingImageError(0, index)" show-menu-by-longpress/>
<view class="price-wrap"> <view class="price-wrap">
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text> <text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="price price-font">{{ item.price }}</text> <text class="price price-font">{{ item.price }}</text>
@@ -273,7 +272,7 @@
<view class="goods-wrap"> <view class="goods-wrap">
<view class="goods-item" @click="toGoodsDetail(skuId)"> <view class="goods-item" @click="toGoodsDetail(skuId)">
<view class="combo-img"> <view class="combo-img">
<image :src="$util.img(goodsSkuDetail.sku_image, { size: 'mid' })" @error="imageError()" /> <image :src="$util.img(goodsSkuDetail.sku_image, { size: 'mid' })" @error="imageError()" show-menu-by-longpress/>
<view class="price-wrap"> <view class="price-wrap">
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text> <text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="price price-font">{{ goodsSkuDetail.price }}</text> <text class="price price-font">{{ goodsSkuDetail.price }}</text>
@@ -285,7 +284,7 @@
<template v-if="goods_index < 3"> <template v-if="goods_index < 3">
<view class="goods-item" @click="toGoodsDetail(goods.sku_id)"> <view class="goods-item" @click="toGoodsDetail(goods.sku_id)">
<view class="combo-img"> <view class="combo-img">
<image :src="$util.img(goods.sku_image, { size: 'mid' })" @error="bundlingImageError(index, goods_index)" /> <image :src="$util.img(goods.sku_image, { size: 'mid' })" @error="bundlingImageError(index, goods_index)" show-menu-by-longpress/>
<view class="price-wrap"> <view class="price-wrap">
<text class="unit price-font">{{ $lang('common.currencySymbol') }}</text> <text class="unit price-font">{{ $lang('common.currencySymbol') }}</text>
<text class="price price-font">{{ goods.price }}</text> <text class="price price-font">{{ goods.price }}</text>
@@ -324,7 +323,7 @@
<view class="coupon-item ns-gradient-diy-goods-list" v-for="(item, index) in couponList" :key="index" v-if="hackReset"> <view class="coupon-item ns-gradient-diy-goods-list" v-for="(item, index) in couponList" :key="index" v-if="hackReset">
<view class="coupon-info" :style="{ backgroundColor: item.useState == 2 ? '#F2F2F2' : 'var(--main-color-shallow)' }"> <view class="coupon-info" :style="{ backgroundColor: item.useState == 2 ? '#F2F2F2' : 'var(--main-color-shallow)' }">
<view class="info-wrap" :class="{ disabled: item.useState == 2 }"> <view class="info-wrap" :class="{ disabled: item.useState == 2 }">
<image class="coupon-line" mode="heightFix" :src="$util.img('public/uniapp/coupon/coupon_line.png')"></image> <image class="coupon-line" mode="heightFix" :src="$util.img('public/uniapp/coupon/coupon_line.png')" show-menu-by-longpress></image>
<view class="coupon-money"> <view class="coupon-money">
<template v-if="item.type == 'reward'"> <template v-if="item.type == 'reward'">
<text class="unit">{{ $lang('common.currencySymbol') }}</text> <text class="unit">{{ $lang('common.currencySymbol') }}</text>
@@ -461,11 +460,12 @@
<ns-goods-action-icon :text="$lang('follow')" :icon="whetherCollection == 1 ? 'icon-likefill color-base-text' : 'icon-guanzhu'" @click="editCollection" /> <ns-goods-action-icon :text="$lang('follow')" :icon="whetherCollection == 1 ? 'icon-likefill color-base-text' : 'icon-guanzhu'" @click="editCollection" />
<!-- #endif --> <!-- #endif -->
<block v-if="goodsSkuDetail.isinformation >= 1"> <block v-if="goodsSkuDetail.isinformation >= 1">
<ns-goods-action-button v-if="goodsSkuDetail.isinformation == 1" class="goods-action-button active3" disabled-text="" backgroundColor="#54c952" @click="phoneClick(goodsSkuDetail.goods_mobile)" :text="$lang('make')" :disabled="false" /> <ns-goods-action-button v-if="goodsSkuDetail.isinformation == 1" class="goods-action-button active3" disabled-text="" backgroundColor="#54c952" @click="phoneClick(goodsSkuDetail.goods_mobile)" :text="$lang('make')" :disabled="false" />
<ns-goods-action-button v-if="goodsSkuDetail.isinformation == 2" class="goods-action-button active3" disabled-text="" backgroundColor="#54c952" @click="showinformation" :text="$lang('leave')" :disabled="false" /> <ns-goods-action-button v-if="goodsSkuDetail.isinformation == 2" class="goods-action-button active3" disabled-text="" backgroundColor="#54c952" @click="showinformation" :text="$lang('leave')" :disabled="false" />
<!-- <ns-goods-action-button v-if="goodsSkuDetail.isinformation == 2" class="goods-action-button active3" disabled-text="" backgroundColor="#54c952" @click="buyNow" text="商品留言" :disabled="false" /> --> <ns-goods-action-button v-if="goodsSkuDetail.isinformation == 3" class="goods-action-button active3" disabled-text="" backgroundColor="#54c952" @click="goToAIChat" text="智能客服" :disabled="false" />
<!-- <ns-goods-action-button v-if="goodsSkuDetail.isinformation == 2" class="goods-action-button active3" disabled-text="" backgroundColor="#54c952" @click="buyNow" text="商品留言" :disabled="false" /> -->
</block> </block>
<block v-else> <block v-else>
<block v-if="goodsSkuDetail.stock == 0 && !goodsSkuDetail.sku_spec_format"> <block v-if="goodsSkuDetail.stock == 0 && !goodsSkuDetail.sku_spec_format">
@@ -515,6 +515,19 @@
<!-- 隐私弹窗 --> <!-- 隐私弹窗 -->
<privacy-popup ref="privacyPopup"></privacy-popup> <privacy-popup ref="privacyPopup"></privacy-popup>
<!-- 联系电话弹窗 -->
<uni-popup ref="contactPopup" type="center">
<view class="contact-popup">
<view class="contact-content">
<text class="contact-text">可在手机端拨打 021-51815181</text>
</view>
<view class="contact-buttons">
<button class="contact-btn cancel-btn" @click="closeContactPopup">取消</button>
<button class="contact-btn copy-btn" @click="copyPhoneNumber">复制到剪切板</button>
</view>
</view>
</uni-popup>
</view> </view>
</template> </template>
@@ -531,9 +544,61 @@ export default {
goodsDetailView, goodsDetailView,
nsGoodsPromotion nsGoodsPromotion
}, },
mixins: [base, detail, scroll] mixins: [base, detail, scroll],
methods: {
/**
* 发送商品信息到智能客服
* @param {Object} item 商品信息
*/
sendToAIChat(item) {
this.$refs.contactPopup.open();
},
/**
* 跳转到智能客服页面
*/
goToAIChat() {
const productInfo = {
goods_id: this.goodsSkuDetail.goods_id || '',
goods_name: this.goodsSkuDetail.goods_name || '',
price: this.goodsSkuDetail.discount_price || this.goodsSkuDetail.member_price || this.goodsSkuDetail.price || '',
image: this.goodsSkuDetail.sku_image || '',
category_id: this.goodsSkuDetail.category_id || ''
};
uni.setStorageSync('selectedProduct', productInfo);
uni.navigateTo({
url: '/pages_tool/ai-chat/index'
});
},
/**
* 关闭联系电话弹窗
*/
closeContactPopup() {
this.$refs.contactPopup.close();
},
/**
* 复制电话号码到剪切板
*/
copyPhoneNumber() {
uni.setClipboardData({
data: '021-51815181',
success: () => {
uni.showToast({
title: '复制成功',
icon: 'success'
});
this.closeContactPopup();
}
});
}
}
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
@import '@/common/css/goods_detail.scss'; @import '@/common/css/goods_detail.scss';
@import './public/css/detail.scss'; @import './public/css/detail.scss';
@@ -545,6 +610,57 @@ export default {
z-index: 999; z-index: 999;
} }
.contact-popup {
width: 600rpx;
background: #ffffff;
border-radius: 16rpx;
overflow: hidden;
}
.contact-content {
padding: 60rpx 40rpx;
text-align: center;
}
.contact-text {
font-size: 32rpx;
color: #333333;
line-height: 1.5;
}
.contact-buttons {
display: flex;
border-top: 1px solid #e5e5e5;
}
.contact-btn {
flex: 1;
height: 90rpx;
line-height: 90rpx;
text-align: center;
font-size: 32rpx;
border: none;
background: transparent;
margin: 0;
padding: 0;
border-radius: 0;
}
.contact-btn::after {
border: none;
}
.cancel-btn {
color: #333333;
background: #ffffff;
border-right: 1px solid #e5e5e5;
}
.copy-btn {
color: #ffffff;
background: #54c952;
}
</style> </style>
<style scoped> <style scoped>
::v-deep .action-icon-wrap .iconfont.icon-shouye1 { ::v-deep .action-icon-wrap .iconfont.icon-shouye1 {
@@ -640,4 +756,5 @@ export default {
height: 72rpx; height: 72rpx;
line-height: 72rpx; line-height: 72rpx;
} }
</style> </style>

View File

@@ -51,7 +51,7 @@
<view class="goods-item margin-bottom" v-for="(item, index) in goodsList" :key="index" <view class="goods-item margin-bottom" v-for="(item, index) in goodsList" :key="index"
@click="toDetail(item)"> @click="toDetail(item)">
<view class="goods-img"> <view class="goods-img">
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"></image> <image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)" show-menu-by-longpress ></image>
<view class="color-base-bg goods-tag" v-if="goodsTag(item) != ''">{{ goodsTag(item) }} <view class="color-base-bg goods-tag" v-if="goodsTag(item) != ''">{{ goodsTag(item) }}
</view> </view>
<view class="sell-out" v-if="item.goods_stock <= 0"> <view class="sell-out" v-if="item.goods_stock <= 0">
@@ -75,68 +75,23 @@
<text class="unit price-style small">.{{ <text class="unit price-style small">.{{
parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text> parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text>
</view> </view>
<view class="discount-price" v-else>
<text class="price price-style large">{{ langstatus ? $lang('Make') : '询底价' }}</text>
</view>
<view class="member-price-tag"
v-if="item.member_price && item.member_price == showPrice(item)">
<image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix"></image>
</view>
<view class="member-price-tag" v-else-if="item.promotion_type == 1">
<image :src="$util.img('public/uniapp/index/discount.png')" mode="widthFix"></image>
</view>
</view> </view>
<view class="pro-info" v-if="item.isinformation == 0"> <view class="pro-info" v-if="item.isinformation == 0">
<view class="delete-price color-tip price-font" v-if="showMarketPrice(item)">
<text class="unit">{{ $lang('common.currencySymbol') }}</text>
<text>{{ showMarketPrice(item) }}</text>
</view>
<view class="block-wrap"> <view class="block-wrap">
<view class="sale color-tip" v-if="item.sale_show">已售{{ item.sale_num }}{{ item.unit <view class="sale" v-if="item.sale_show">已售{{ item.sale_num }}{{ item.unit
? item.unit : '件' }}</view> ? item.unit : '件' }}</view>
</view> </view>
<view class="cart-action-wrap" v-if="config.control && item.is_virtual == 0"> <view class="cart-action-wrap" v-if="config.control && item.is_virtual == 0">
<!-- 购物车图标 --> <view class="cart buy-btn click-wrap" :id="'goods-' + item.id"
<view v-if="config.style == 'icon-cart'" :style="{
color: config.theme == 'diy' ? config.textColor : '',
borderColor: config.theme == 'diy' ? config.textColor : ''
}" class="cart shopping-cart-btn iconfont icon-gouwuche click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)"> @click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
购买
<view class="click-event"></view> <view class="click-event"></view>
</view> </view>
</view>
<!--加号图标 --> </view>
<view v-else-if="config.style == 'icon-add'" :style="{ <view class="ai-chat-btn-wrap" v-if="item.isinformation == 1">
color: config.theme == 'diy' ? config.textColor : '', <view class="ai-chat-btn" @click.stop="sendToAIChat(item)">
borderColor: config.theme == 'diy' ? config.textColor : '' 立即咨询
}" class="cart plus-sign-btn iconfont icon-add1 click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
<view class="click-event"></view>
</view>
<!-- 按钮 -->
<view v-else-if="config.style == 'button'" :style="{
backgroundColor: config.theme == 'diy' ? config.bgColor : '',
color: config.theme == 'diy' ? config.textColor : '',
fontWeight: config.theme == 'diy' ? (config.fontWeight ? 'bold' : 'normal') : '',
padding: config.theme == 'diy' ? '12rpx ' + config.padding * 2 + 'rpx' : ''
}" class="cart buy-btn click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
{{ config.text }}
<view class="click-event"></view>
</view>
<!--自定义图标 -->
<view v-else-if="config.style == 'icon-diy'" :style="{
color: config.theme == 'diy' ? config.textColor : ''
}" class="icon-diy click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
<view class="click-event"></view>
<diy-icon :icon="config.iconDiy.icon"
:value="config.iconDiy.style ? config.iconDiy.style : null"></diy-icon>
</view>
</view> </view>
</view> </view>
</view> </view>
@@ -147,7 +102,7 @@
@click="toDetail(item)" @click="toDetail(item)"
:style="{ left: listPosition[index] ? listPosition[index].left : '', top: listPosition[index] ? listPosition[index].top : '' }"> :style="{ left: listPosition[index] ? listPosition[index].left : '', top: listPosition[index] ? listPosition[index].top : '' }">
<view class="goods-img"> <view class="goods-img">
<image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)"></image> <image :src="goodsImg(item.goods_image)" mode="widthFix" @error="imgError(index)" show-menu-by-longpress ></image>
<view class="color-base-bg goods-tag" v-if="goodsTag(item) != ''">{{ goodsTag(item) }} <view class="color-base-bg goods-tag" v-if="goodsTag(item) != ''">{{ goodsTag(item) }}
</view> </view>
<view class="sell-out" v-if="item.stock <= 0"> <view class="sell-out" v-if="item.stock <= 0">
@@ -168,66 +123,23 @@
<text class="unit price-style small">.{{ <text class="unit price-style small">.{{
parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text> parseFloat(showPrice(item)).toFixed(2).split('.')[1] }}</text>
</view> </view>
<view class="discount-price" v-else>
<text class="price price-style large">{{ langstatus ? $lang('Make') : '询底价' }}</text>
</view>
<view class="member-price-tag"
v-if="item.member_price && item.member_price == showPrice(item)">
<image :src="$util.img('public/uniapp/index/VIP.png')" mode="widthFix"></image>
</view>
<view class="member-price-tag" v-else-if="item.promotion_type == 1">
<image :src="$util.img('public/uniapp/index/discount.png')" mode="widthFix"></image>
</view>
<view class="delete-price color-tip price-font" v-if="showMarketPrice(item)">
<text class="unit">{{ $lang('common.currencySymbol') }}</text>
<text>{{ showMarketPrice(item) }}</text>
</view>
</view> </view>
<view class="pro-info" v-if="item.isinformation == 0"> <view class="pro-info" v-if="item.isinformation == 0">
<view class="block-wrap"> <view class="block-wrap">
<view class="sale color-tip" v-if="item.sale_show">已售{{ item.sale_num }}{{ item.unit <view class="sale" v-if="item.sale_show">已售{{ item.sale_num }}{{ item.unit
? item.unit : '件' }}</view> ? item.unit : '件' }}</view>
</view> </view>
<view class="cart-action-wrap" v-if="config.control && item.is_virtual == 0"> <view class="cart-action-wrap" v-if="config.control && item.is_virtual == 0">
<!-- 购物车图标 --> <view class="cart buy-btn click-wrap" :id="'goods-' + item.id"
<view v-if="config.style == 'icon-cart'" :style="{
color: config.theme == 'diy' ? config.textColor : '',
borderColor: config.theme == 'diy' ? config.textColor : ''
}" class="cart shopping-cart-btn iconfont icon-gouwuche click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)"> @click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
购买
<view class="click-event"></view> <view class="click-event"></view>
</view> </view>
</view>
<!--加号图标 --> </view>
<view v-else-if="config.style == 'icon-add'" :style="{ <view class="ai-chat-btn-wrap" v-if="item.isinformation == 1">
color: config.theme == 'diy' ? config.textColor : '', <view class="ai-chat-btn" @click.stop="sendToAIChat(item)">
borderColor: config.theme == 'diy' ? config.textColor : '' 立即咨询
}" class="cart plus-sign-btn iconfont icon-add1 click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
<view class="click-event"></view>
</view>
<!-- 按钮 -->
<view v-else-if="config.style == 'button'" :style="{
backgroundColor: config.theme == 'diy' ? config.bgColor : '',
color: config.theme == 'diy' ? config.textColor : '',
fontWeight: config.theme == 'diy' ? (config.fontWeight ? 'bold' : 'normal') : '',
padding: config.theme == 'diy' ? '12rpx ' + config.padding * 2 + 'rpx' : ''
}" class="cart buy-btn click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
{{ config.text }}
<view class="click-event"></view>
</view>
<!--自定义图标 -->
<view v-else-if="config.style == 'icon-diy'" :style="{
color: config.theme == 'diy' ? config.textColor : ''
}" class="icon-diy click-wrap" :id="'goods-' + item.id"
@click.stop="$refs.goodsSkuIndex.addCart(config.cartEvent, item, $event)">
<view class="click-event"></view>
<diy-icon :icon="config.iconDiy.icon"
:value="config.iconDiy.style ? config.iconDiy.style : null"></diy-icon>
</view>
</view> </view>
</view> </view>
</view> </view>
@@ -311,7 +223,14 @@ export default {
data() { data() {
return {}; return {};
}, },
mixins: [list] mixins: [list],
methods: {
sendToAIChat(item) {
this.$util.redirectTo('/pages_goods/detail', {
goods_id: item.goods_id
});
}
}
}; };
</script> </script>
@@ -327,4 +246,24 @@ export default {
::v-deep .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box { ::v-deep .sku-layer .uni-popup__wrapper.uni-custom .uni-popup__wrapper-box {
max-height: unset !important; max-height: unset !important;
} }
.ai-chat-btn-wrap {
display: flex;
justify-content: flex-end;
margin-top: auto;
padding-top: 10rpx;
}
.ai-chat-btn {
background-color: #ff0000;
color: #fff;
padding: 12rpx 30rpx;
border-radius: 40rpx;
font-size: 26rpx;
font-weight: 500;
line-height: 1.2;
text-align: center;
white-space: nowrap;
display: inline-block;
}
</style> </style>

View File

@@ -295,7 +295,8 @@
.lineheight-clear { .lineheight-clear {
display: flex; display: flex;
justify-content: flex-end; justify-content: space-between;
align-items: center;
} }
// 商品列表单列样式 // 商品列表单列样式
@@ -386,46 +387,30 @@
display: inline-block; display: inline-block;
font-weight: bold; font-weight: bold;
line-height: 1; line-height: 1;
margin-top: 16rpx; margin-top: 0;
background-color: var(--main-color);
border-radius: 35rpx;
padding: 12rpx 24rpx;
box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);
.unit { .unit {
margin-right: 6rpx; margin-right: 6rpx;
color: var(--price-color); color: #ff4444;
} }
.price { .price {
color: var(--price-color); color: #ff4444;
color: #fff !important; font-size: 32rpx !important;
font-size: 27rpx !important;
font-weight: bold !important; font-weight: bold !important;
} }
} }
.pro-info { .pro-info {
margin-top: 10rpx;
display: flex; display: flex;
margin-top: auto; justify-content: space-between;
align-items: center; align-items: center;
position: relative;
.delete-price {
text-decoration: line-through;
font-size: $font-size-tag !important;
flex: 1;
.unit {
margin-right: 0;
}
}
.block-wrap { .block-wrap {
flex: 1;
line-height: 1; line-height: 1;
margin-right: 20rpx;
.sale { .sale {
font-size: $font-size-tag !important; font-size: $font-size-tag !important;
color: #999;
} }
} }
} }
@@ -543,6 +528,9 @@
.lineheight-clear { .lineheight-clear {
margin-top: 16rpx; margin-top: 16rpx;
display: flex;
justify-content: space-between;
align-items: center;
} }
.discount-price { .discount-price {
@@ -552,24 +540,26 @@
.unit { .unit {
margin-right: 6rpx; margin-right: 6rpx;
color: var(--price-color); color: #ff4444;
} }
.price { .price {
color: var(--price-color); color: #ff4444;
font-size: 32rpx !important;
font-weight: bold !important;
} }
} }
.pro-info { .pro-info {
margin-top: 10rpx;
display: flex; display: flex;
margin-top: auto; justify-content: space-between;
align-items: center; align-items: center;
.block-wrap { .block-wrap {
flex: 1;
line-height: 1; line-height: 1;
margin-right: 20rpx;
.sale { .sale {
font-size: $font-size-tag !important; font-size: $font-size-tag !important;
color: #999;
} }
} }
} }
@@ -644,9 +634,9 @@
} }
.buy-btn { .buy-btn {
background-color: $base-color; background-color: #ff4444;
color: var(--btn-text-color); color: #fff;
border-radius: 50rpx; border-radius: 30rpx;
font-size: $font-size-tag; font-size: $font-size-tag;
padding: 12rpx 30rpx; padding: 12rpx 30rpx;
line-height: 1; line-height: 1;

View File

@@ -566,7 +566,6 @@ export default {
// 手指触摸事件 用于菜单左滑 // 手指触摸事件 用于菜单左滑
touchS(e) { touchS(e) {
this.startX = e.touches[0].clientX; this.startX = e.touches[0].clientX;
// console.log('开始' + e.touches[0].clientX);
}, },
touchE(e, cartIndex) { touchE(e, cartIndex) {
this.endX = e.changedTouches[0].clientX; this.endX = e.changedTouches[0].clientX;

View File

@@ -72,7 +72,6 @@ export default {
url: '/api/lucky/status', url: '/api/lucky/status',
data: {}, data: {},
success: res => { success: res => {
console.log(res)
this.langstatus = res.status this.langstatus = res.status
if(this.langstatus == 1){ if(this.langstatus == 1){
// this.$langConfig.refresh(); // this.$langConfig.refresh();

View File

@@ -59,7 +59,7 @@
<view class="iconfont icon-right"></view> <view class="iconfont icon-right"></view>
</view> </view>
</view> </view>
<image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image> <image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')" show-menu-by-longpress></image>
</view> </view>
<view class="address-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'local'"> <view class="address-box" :class="{ 'not-delivery-type': goodsData.delivery.express_type.length <= 1 }" v-if="orderCreateData.delivery.delivery_type == 'local'">
@@ -112,7 +112,7 @@
</view> </view>
</view> </view>
<image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image> <image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')" show-menu-by-longpress></image>
</view> </view>
<!-- 门店信息 --> <!-- 门店信息 -->
@@ -154,7 +154,7 @@
</view> </view>
</block> </block>
<view v-else class="empty">当前无自提门店,请选择其它配送方式</view> <view v-else class="empty">当前无自提门店,请选择其它配送方式</view>
<image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')"></image> <image class="address-line" :src="$util.img('public/uniapp/order/address-line.png')" show-menu-by-longpress></image>
</view> </view>
</template> </template>
@@ -170,7 +170,7 @@
<view class="goods-item" v-for="(goodsItem, goodsIndex) in goodsSpecFormat(calculateGoodsData.goods_list)" :key="goodsIndex"> <view class="goods-item" v-for="(goodsItem, goodsIndex) in goodsSpecFormat(calculateGoodsData.goods_list)" :key="goodsIndex">
<view class="goods-wrap"> <view class="goods-wrap">
<view class="goods-img" @click="$util.redirectTo('/pages_goods/detail', { goods_id: goodsItem.goods_id })"> <view class="goods-img" @click="$util.redirectTo('/pages_goods/detail', { goods_id: goodsItem.goods_id })">
<image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" mode="aspectFill"/> <image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" @error="imageError(goodsIndex)" mode="aspectFill" show-menu-by-longpress/>
</view> </view>
<view class="goods-info"> <view class="goods-info">
<view class="top-wrap"> <view class="top-wrap">
@@ -521,7 +521,7 @@
<view class="coupon-item" v-for="(couponItem, couponIndex) in merchCoupon.data" :key="couponIndex" @click="selectCoupon(couponItem,merchCoupon.merch_id)"> <view class="coupon-item" v-for="(couponItem, couponIndex) in merchCoupon.data" :key="couponIndex" @click="selectCoupon(couponItem,merchCoupon.merch_id)">
<view class="coupon-info" :style="{ backgroundColor: 'var(--main-color-shallow)' }"> <view class="coupon-info" :style="{ backgroundColor: 'var(--main-color-shallow)' }">
<view class="info-wrap"> <view class="info-wrap">
<image class="coupon-line" mode="heightFix" :src="$util.img('public/uniapp/coupon/coupon_line.png')"/> <image class="coupon-line" mode="heightFix" :src="$util.img('public/uniapp/coupon/coupon_line.png')" show-menu-by-longpress/>
<view class="coupon-money"> <view class="coupon-money">
<template v-if="couponItem.type == 'divideticket'"> <template v-if="couponItem.type == 'divideticket'">
<text class="unit">{{ $lang('common.currencySymbol') }}</text> <text class="unit">{{ $lang('common.currencySymbol') }}</text>

View File

@@ -762,13 +762,10 @@ export default {
} }
this.$forceUpdate(); this.$forceUpdate();
// this.orderCreateData.coupon[merch_id].coupon_id = data.coupon_id // this.orderCreateData.coupon[merch_id].coupon_id = data.coupon_id
console.log(this.selectCouponId)
}, },
//确定使用优惠券 //确定使用优惠券
useCpopon() { useCpopon() {
console.log(this.merchCoupon.merch_id)
this.orderCreateData.coupon[this.merchCoupon.merch_id].coupon_id = this.selectCouponId; this.orderCreateData.coupon[this.merchCoupon.merch_id].coupon_id = this.selectCouponId;
console.log(this.orderCreateData.coupon)
this.$refs.couponPopup.close(); this.$refs.couponPopup.close();
this.calculate(); this.calculate();
}, },

View File

@@ -111,9 +111,9 @@
<view class="code"> <view class="code">
<image :src="$util.img(orderData.pickup_barcode)" <image :src="$util.img(orderData.pickup_barcode)"
@click="previewMedia($util.img(orderData.pickup_barcode))" class="barcode" @click="previewMedia($util.img(orderData.pickup_barcode))" class="barcode"
mode="widthFix" /> mode="widthFix" show-menu-by-longpress/>
<image :src="$util.img(orderData.pickup)" @click="previewMedia($util.img(orderData.pickup))" <image :src="$util.img(orderData.pickup)" @click="previewMedia($util.img(orderData.pickup))"
class="qrcode" mode="widthFix" /> class="qrcode" mode="widthFix" show-menu-by-longpress/>
</view> </view>
</view> </view>
</view> </view>
@@ -126,7 +126,7 @@
<view class="goods-wrap"> <view class="goods-wrap">
<view class="goods-img" @click="goDetail(goodsItem)"> <view class="goods-img" @click="goDetail(goodsItem)">
<image :src="$util.img(goodsItem.sku_image, { size: 'mid' })" <image :src="$util.img(goodsItem.sku_image, { size: 'mid' })"
@error="imageError(goodsIndex)" mode="aspectFill" /> @error="imageError(goodsIndex)" mode="aspectFill" show-menu-by-longpress/>
</view> </view>
<view class="goods-info" @click="goDetail(goodsItem)"> <view class="goods-info" @click="goDetail(goodsItem)">
<view class="goods-name">{{ goodsItem.sku_name }}</view> <view class="goods-name">{{ goodsItem.sku_name }}</view>
@@ -174,7 +174,7 @@
<view class="box img-box" v-if="item.controller == 'Img'"> <view class="box img-box" v-if="item.controller == 'Img'">
<view class="img" v-for="(img, imgIndex) in item.img_lists" :key="imgIndex"> <view class="img" v-for="(img, imgIndex) in item.img_lists" :key="imgIndex">
<image :src="$util.img(img)" mode="widthFix" <image :src="$util.img(img)" mode="widthFix"
@click="previewMedia($util.img(img))" /> @click="previewMedia($util.img(img))" show-menu-by-longpress/>
</view> </view>
</view> </view>
<view class="box" v-else> <view class="box" v-else>
@@ -314,7 +314,7 @@
<text class="tit">{{ item.value.title }}:</text> <text class="tit">{{ item.value.title }}:</text>
<view class="box img-box" v-if="item.controller == 'Img'"> <view class="box img-box" v-if="item.controller == 'Img'">
<view class="img" v-for="(img, imgIndex) in item.img_lists" :key="imgIndex"> <view class="img" v-for="(img, imgIndex) in item.img_lists" :key="imgIndex">
<image :src="$util.img(img)" mode="widthFix" @click="previewMedia($util.img(img))"></image> <image :src="$util.img(img)" mode="widthFix" @click="previewMedia($util.img(img))" show-menu-by-longpress></image>
</view> </view>
</view> </view>
<view class="box" v-else> <view class="box" v-else>
@@ -345,8 +345,8 @@
<block v-if="orderData.virtual_goods && orderData.goods_class == 2 && orderData.virtual_goods.is_veirfy == 0"> <block v-if="orderData.virtual_goods && orderData.goods_class == 2 && orderData.virtual_goods.is_veirfy == 0">
<view class="verify-code-wrap"> <view class="verify-code-wrap">
<view class="code"> <view class="code">
<image :src="$util.img(orderData.virtualgoods_barcode)" class="barcode" mode="widthFix"></image> <image :src="$util.img(orderData.virtualgoods_barcode)" class="barcode" mode="widthFix" show-menu-by-longpress></image>
<image :src="$util.img(orderData.virtualgoods)" class="qrcode" mode="widthFix"></image> <image :src="$util.img(orderData.virtualgoods)" class="qrcode" mode="widthFix" show-menu-by-longpress></image>
<text>请将条形码或二维码出示给核销员</text> <text>请将条形码或二维码出示给核销员</text>
</view> </view>
<view class="hr"></view> <view class="hr"></view>
@@ -426,8 +426,8 @@
<block v-if="orderData.virtual_goods && orderData.goods_class == 4"> <block v-if="orderData.virtual_goods && orderData.goods_class == 4">
<view class="verify-code-wrap" v-if="orderData.virtual_goods.is_veirfy == 0"> <view class="verify-code-wrap" v-if="orderData.virtual_goods.is_veirfy == 0">
<view class="code"> <view class="code">
<image :src="$util.img(orderData.virtualgoods_barcode)" class="barcode" mode="widthFix"></image> <image :src="$util.img(orderData.virtualgoods_barcode)" class="barcode" mode="widthFix" show-menu-by-longpress></image>
<image :src="$util.img(orderData.virtualgoods)" class="qrcode" mode="widthFix"></image> <image :src="$util.img(orderData.virtualgoods)" class="qrcode" mode="widthFix" show-menu-by-longpress></image>
<text>请将条形码或二维码出示给核销员</text> <text>请将条形码或二维码出示给核销员</text>
</view> </view>
<view class="hr"></view> <view class="hr"></view>

Some files were not shown because too many files have changed in this diff Show More