feat(order): 优化订单流程
- 新增获取微信openid和生成支付订单的API接口 - 修改登录逻辑,保存公众号appid - 优化AiDrama页面,接入新的AI生成接口 - 屏蔽商品tabbar - 完善素材编辑页面,增加修改意见展示
This commit is contained in:
parent
7946d4995d
commit
c45996fdd8
2
App.vue
2
App.vue
|
@ -9,6 +9,7 @@
|
|||
export default {
|
||||
onLaunch: function() {
|
||||
console.log('App Launch');
|
||||
// #ifdef MP-WEIXIN
|
||||
const updateManager = uni.getUpdateManager();
|
||||
|
||||
updateManager.onCheckForUpdate(function (res) {
|
||||
|
@ -33,6 +34,7 @@
|
|||
updateManager.onUpdateFailed(function (res) {
|
||||
// 新的版本下载失败
|
||||
});
|
||||
// #endif
|
||||
},
|
||||
onShow: function() {
|
||||
console.log('App Show');
|
||||
|
|
|
@ -1,51 +1,14 @@
|
|||
export default{
|
||||
cdnImgUrl:'http://static.drgyen.com/app/hc-app-power/images',
|
||||
// 正式
|
||||
// baseUrl: 'https://ny-core.dieruen-iot.com',
|
||||
// imgUrl: 'https://ny-core.dieruen-iot.com',
|
||||
// baseUrl: 'https://platform-core.059000.xyz',
|
||||
// imgUrl: 'https://platform-core.059000.xyz',
|
||||
// wsUrl: 'wss://ny-core.dieruen-iot.com',
|
||||
// 弃用
|
||||
// iotOsBaseUrl:"https://iot.gkiiot.com/prod-api",
|
||||
// 德润正式
|
||||
// baseUrl: 'https://digital-core.dieruen-iot.com',
|
||||
// imgUrl: 'https://digital-core.dieruen-iot.com',
|
||||
// wsUrl: 'wss://digital-core.dieruen-iot.com',
|
||||
// 谷云正式
|
||||
// baseUrl: 'https://digital-core.drgyen.com',
|
||||
// imgUrl: 'https://digital-core.drgyen.com',
|
||||
// wsUrl: 'wss://digital-core.drgyen.com',
|
||||
|
||||
// 商城本地测试环境
|
||||
baseUrl: 'http://192.168.1.17:8080',
|
||||
imgUrl: 'http://192.168.1.17:8080',
|
||||
wsUrl: 'wss://digital-core.drgyen.com',
|
||||
// 长城
|
||||
// baseUrl: 'https://zhny.snc.cn/prod-api/',
|
||||
// imgUrl: 'https://zhny.snc.cn/prod-api/',
|
||||
// wsUrl: 'wss://zhny.snc.cn/prod-api/',
|
||||
// 线下
|
||||
// baseUrl: 'http://192.168.1.17:8899',
|
||||
// imgUrl: 'http://192.168.1.17:8899',
|
||||
// wsUrl: 'ws://192.168.1.17:8899',
|
||||
// iotOsBaseUrl:"http://192.168.18.139:8080",
|
||||
|
||||
// 本地
|
||||
// baseUrl: 'http://192.168.18.134:9988/dev-api',
|
||||
// imgUrl: 'http://192.168.18.134:9988/dev-api',
|
||||
// iotOsBaseUrl:"http://iot.gkiiot.com:8080",
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
// mqttUrl:'wx://iot.gkiiot.com:8083/mqtt',
|
||||
// mqttUrl:'wxs://iot.gkiiot.com/mqtt-ws/mqtt',
|
||||
// mqttUrl:'wx://192.168.18.139:8083/mqtt',
|
||||
// mqttUrl:'wx://iot.gkiiot.com:8083/mqtt',
|
||||
//#endif
|
||||
|
||||
// #ifndef MP-WEIXIN
|
||||
// mqttUrl:'ws://iot.gkiiot.com:8083/mqtt',
|
||||
// mqttUrl:'ws://192.168.18.139:8083/mqtt',
|
||||
// mqttUrl:'wx://iot.gkiiot.com:8083/mqtt',
|
||||
// #endif
|
||||
|
||||
// 客户端id
|
||||
clientId: 'e5cd7e4891bf95d1d19206ce24a7b32e',
|
||||
}
|
|
@ -166,4 +166,26 @@ export default {
|
|||
})
|
||||
})
|
||||
},
|
||||
// 获取openid
|
||||
getWxOpenid(data){
|
||||
return new Promise((resolve, reject) => {
|
||||
request.get('/wx/offiaccount/getAccessToken',data)
|
||||
.then((res) =>{
|
||||
resolve(res);
|
||||
}).catch(err =>{
|
||||
reject(err);
|
||||
})
|
||||
})
|
||||
},
|
||||
// 生成支付订单
|
||||
addPayOrder(data){
|
||||
return new Promise((resolve, reject) => {
|
||||
request.post('/mall/order/pay',data)
|
||||
.then((res) =>{
|
||||
resolve(res);
|
||||
}).catch(err =>{
|
||||
reject(err);
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
|
@ -122,17 +122,22 @@
|
|||
"h5" : {
|
||||
"devServer" : {
|
||||
"https" : false,
|
||||
"port" : 8055,
|
||||
"disableHostCheck" : true // 禁用 Host 检查 打包时改成false
|
||||
"port" : 8055
|
||||
},
|
||||
"disableHostCheck" : true, // 禁用 Host 检查 打包时改成false
|
||||
"router" : {
|
||||
"mode" : "hash",
|
||||
"base" : ""
|
||||
"mode" : "hash"
|
||||
},
|
||||
"base" : "",
|
||||
// "base" : "/app/",
|
||||
"optimization" : {
|
||||
"treeShaking" : {
|
||||
"enable" : false
|
||||
"enable" : true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// "port" : 8055
|
||||
// "disableHostCheck" : true, // 禁用 Host 检查 打包时改成false
|
||||
// "base" : "/app/"
|
||||
|
||||
|
|
21
package.json
21
package.json
|
@ -1,20 +1 @@
|
|||
{
|
||||
"name": "hc-zhyd-app",
|
||||
"version": "1.0.0",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"flyio": "^0.6.14",
|
||||
"mqtt": "^3.0.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://e.coding.net/fengsl/zhihuiyongdian/hc-app-power.git"
|
||||
},
|
||||
"description": ""
|
||||
}
|
||||
{}
|
||||
|
|
14
pages.json
14
pages.json
|
@ -120,12 +120,14 @@
|
|||
"text": "消息",
|
||||
"iconPath": "static/images/toolbar/new.png",
|
||||
"selectedIconPath": "static/images/toolbar/new-active.png"
|
||||
}, {
|
||||
"pagePath": "pages/tabBar/product",
|
||||
"text": "商品",
|
||||
"iconPath": "static/images/toolbar/product.png",
|
||||
"selectedIconPath": "static/images/toolbar/product-active.png"
|
||||
}, {
|
||||
},
|
||||
// {
|
||||
// "pagePath": "pages/tabBar/product",
|
||||
// "text": "商品",
|
||||
// "iconPath": "static/images/toolbar/product.png",
|
||||
// "selectedIconPath": "static/images/toolbar/product-active.png"
|
||||
// },
|
||||
{
|
||||
"pagePath": "pages/tabBar/order",
|
||||
"text": "订单",
|
||||
"iconPath": "static/images/toolbar/order.png",
|
||||
|
|
|
@ -124,6 +124,7 @@
|
|||
smsLoading:false,
|
||||
loading:false,
|
||||
icpLicense:'',
|
||||
homePage:"/pages/tabBar/order"
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -161,7 +162,7 @@
|
|||
console.log("userToken", userToken)
|
||||
if (userToken) {
|
||||
uni.switchTab({
|
||||
url: "../tabBar/product"
|
||||
url: this.homePage
|
||||
})
|
||||
} else {
|
||||
// this.getCode();
|
||||
|
@ -368,7 +369,7 @@
|
|||
smsCode: this.form.smsCode,
|
||||
},
|
||||
header: {
|
||||
UserType: this.usetTypeValue == "普通用户" ? "PERSONAL" : "TENANT",
|
||||
// UserType: this.usetTypeValue == "普通用户" ? "PERSONAL" : "TENANT",
|
||||
},
|
||||
success: (res) => {
|
||||
console.log(res);
|
||||
|
@ -379,29 +380,29 @@
|
|||
})
|
||||
this.$store.dispatch('setLogin', res.data.token);
|
||||
uni.setStorage({
|
||||
key: 'userType',
|
||||
data: this.usetTypeValue,
|
||||
key: 'appIdPublic',
|
||||
data: this.appConfig.appIdPublic,
|
||||
}).then(res => {
|
||||
return uni.setStorage({
|
||||
key: 'tenantId',
|
||||
data: this.form.tenantId,
|
||||
})
|
||||
}).then(res => {
|
||||
return uni.setStorage({
|
||||
key: 'phonenumber',
|
||||
data: this.form.phonenumber,
|
||||
})
|
||||
}).then(res => {
|
||||
return uni.setStorage({
|
||||
key: 'smsCode',
|
||||
data: this.form.smsCode,
|
||||
})
|
||||
}).then(res => {
|
||||
setTimeout(() => {
|
||||
if (this.usetTypeValue == "普通用户") {
|
||||
uni.reLaunch({
|
||||
url: "../oneselfUser/index"
|
||||
})
|
||||
} else {
|
||||
// if (this.usetTypeValue == "普通用户") {
|
||||
// uni.reLaunch({
|
||||
// url: "../oneselfUser/index"
|
||||
// })
|
||||
// } else {
|
||||
uni.switchTab({
|
||||
url: "../tabBar/product"
|
||||
url: this.homePage
|
||||
})
|
||||
}
|
||||
// }
|
||||
}, 1000)
|
||||
})
|
||||
} else {
|
||||
|
@ -440,8 +441,13 @@
|
|||
})
|
||||
this.$store.dispatch('setLogin', res.data.data.access_token);
|
||||
uni.setStorage({
|
||||
key: 'userType',
|
||||
data: this.usetTypeValue,
|
||||
key: 'appIdPublic',
|
||||
data: this.appConfig.appIdPublic,
|
||||
}).then(res => {
|
||||
return uni.setStorage({
|
||||
key: 'tenantId',
|
||||
data: this.form.tenantId,
|
||||
})
|
||||
}).then(res => {
|
||||
return uni.setStorage({
|
||||
key: 'phonenumber',
|
||||
|
@ -449,15 +455,16 @@
|
|||
})
|
||||
}).then(res => {
|
||||
setTimeout(() => {
|
||||
if (this.usetTypeValue == "普通用户") {
|
||||
uni.reLaunch({
|
||||
url: "../oneselfUser/index"
|
||||
})
|
||||
} else {
|
||||
// if (this.usetTypeValue == "普通用户") {
|
||||
// uni.reLaunch({
|
||||
// url: "../oneselfUser/index"
|
||||
// })
|
||||
// } else {
|
||||
console.log("this.homePage",this.homePage)
|
||||
uni.switchTab({
|
||||
url: "../tabBar/product"
|
||||
url: this.homePage
|
||||
})
|
||||
}
|
||||
// }
|
||||
}, 1000)
|
||||
})
|
||||
} else {
|
||||
|
|
|
@ -127,6 +127,7 @@
|
|||
isTenant: true,
|
||||
appIdMini:'',
|
||||
icpLicense:'',
|
||||
homePage:"/pages/tabBar/order"
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -159,20 +160,20 @@
|
|||
if(e.mode == '1'){ //mode:1 带密码参数直接登录
|
||||
this.form.username = e.user || '';
|
||||
this.form.password = e.pwd || '';
|
||||
this.autoLogin()
|
||||
// this.autoLogin()
|
||||
}else{
|
||||
userToken = uni.getStorageSync('userToken');
|
||||
console.log("userToken", userToken)
|
||||
if (userToken) {
|
||||
uni.switchTab({
|
||||
url: "../tabBar/product"
|
||||
url: this.homePage
|
||||
})
|
||||
} else {
|
||||
// this.getCodeImageFn();
|
||||
}
|
||||
}
|
||||
|
||||
this.usetTypeValue = e.userType == "user" ? "普通用户" : "企业用户";
|
||||
// this.usetTypeValue = e.userType == "user" ? "普通用户" : "企业用户";
|
||||
|
||||
},
|
||||
onShow() {
|
||||
|
@ -339,11 +340,11 @@
|
|||
url: '/pages/tabBar/my/userPolicy'
|
||||
})
|
||||
},
|
||||
goForgotPasswordFn() {
|
||||
uni.navigateTo({
|
||||
url: `./forgotPassword?userType=${this.usetTypeValue=="普通用户"?"user":"company"}`
|
||||
})
|
||||
},
|
||||
// goForgotPasswordFn() {
|
||||
// uni.navigateTo({
|
||||
// url: `./forgotPassword?userType=${this.usetTypeValue=="普通用户"?"user":"company"}`
|
||||
// })
|
||||
// },
|
||||
// 获取验证码
|
||||
getCodeImageFn() {
|
||||
this.$get("/captchaImage").then((res) => {
|
||||
|
@ -361,7 +362,7 @@
|
|||
password: this.form.password,
|
||||
},
|
||||
header: {
|
||||
UserType: this.usetTypeValue == "普通用户" ? "PERSONAL" : "TENANT",
|
||||
// UserType: this.usetTypeValue == "普通用户" ? "PERSONAL" : "TENANT",
|
||||
},
|
||||
success: (res) => {
|
||||
console.log(res);
|
||||
|
@ -372,8 +373,8 @@
|
|||
})
|
||||
this.$store.dispatch('setLogin', res.data.token);
|
||||
uni.setStorage({
|
||||
key: 'userType',
|
||||
data: this.usetTypeValue,
|
||||
key: 'appIdPublic',
|
||||
data: this.appConfig.appIdPublic,
|
||||
}).then(res => {
|
||||
return uni.setStorage({
|
||||
key: 'username',
|
||||
|
@ -386,15 +387,15 @@
|
|||
})
|
||||
}).then(res => {
|
||||
setTimeout(() => {
|
||||
if (this.usetTypeValue == "普通用户") {
|
||||
uni.reLaunch({
|
||||
url: "../oneselfUser/index"
|
||||
})
|
||||
} else {
|
||||
// if (this.usetTypeValue == "普通用户") {
|
||||
// uni.reLaunch({
|
||||
// url: "../oneselfUser/index"
|
||||
// })
|
||||
// } else {
|
||||
uni.switchTab({
|
||||
url: "../tabBar/product"
|
||||
url: this.homePage
|
||||
})
|
||||
}
|
||||
// }
|
||||
}, 1000)
|
||||
})
|
||||
} else {
|
||||
|
@ -425,6 +426,7 @@
|
|||
},
|
||||
success: (res) => {
|
||||
console.log(res);
|
||||
|
||||
if (res.data.code == 200 && res.data.data.access_token) {
|
||||
this.$refs.uToast.show({
|
||||
title: '登录成功',
|
||||
|
@ -432,8 +434,13 @@
|
|||
})
|
||||
this.$store.dispatch('setLogin', res.data.data.access_token);
|
||||
uni.setStorage({
|
||||
key: 'tenantId',
|
||||
data: this.form.tenantId,
|
||||
key: 'appIdPublic',
|
||||
data: this.appConfig.appIdPublic,
|
||||
}).then(res => {
|
||||
return uni.setStorage({
|
||||
key: 'tenantId',
|
||||
data: this.form.tenantId,
|
||||
})
|
||||
}).then(res => {
|
||||
return uni.setStorage({
|
||||
key: 'username',
|
||||
|
@ -445,16 +452,17 @@
|
|||
data: this.form.password,
|
||||
})
|
||||
}).then(res => {
|
||||
|
||||
setTimeout(() => {
|
||||
if (this.usetTypeValue == "普通用户") {
|
||||
uni.reLaunch({
|
||||
url: "../oneselfUser/index"
|
||||
})
|
||||
} else {
|
||||
// if (this.usetTypeValue == "普通用户") {
|
||||
// uni.reLaunch({
|
||||
// url: "../oneselfUser/index"
|
||||
// })
|
||||
// } else {
|
||||
uni.switchTab({
|
||||
url: "../tabBar/product"
|
||||
url: this.homePage
|
||||
})
|
||||
}
|
||||
// }
|
||||
}, 1000)
|
||||
})
|
||||
} else {
|
||||
|
|
|
@ -87,6 +87,7 @@
|
|||
|
||||
<script>
|
||||
import { renderMarkdown } from './markdown.js';
|
||||
import config from "@/common/api/config.js"
|
||||
|
||||
export default {
|
||||
data() {
|
||||
|
@ -118,13 +119,14 @@ export default {
|
|||
// 是否需要滚动到底部
|
||||
needScrollToBottom: true,
|
||||
// 滚动计时器
|
||||
scrollTimer: null
|
||||
scrollTimer: null,
|
||||
token:''
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
// 从URL获取参数
|
||||
this.orderId = options.orderId || '';
|
||||
|
||||
this.token = uni.getStorageSync('userToken');
|
||||
// 检测是否是H5环境
|
||||
// #ifdef H5
|
||||
this.isH5 = true;
|
||||
|
@ -242,115 +244,230 @@ export default {
|
|||
|
||||
// 使用fetch API进行流式请求(仅H5环境)
|
||||
async fetchStreamResponse(apiMessages) {
|
||||
try {
|
||||
// 添加一个空的AI回复,用于流式更新
|
||||
this.currentAiMessageIndex = this.messages.length;
|
||||
this.messages.push({
|
||||
role: 'assistant',
|
||||
content: '',
|
||||
renderedContent: '',
|
||||
time: this.formatTime(new Date()),
|
||||
endStatus: false
|
||||
});
|
||||
try {
|
||||
// 添加一个空的AI回复,用于流式更新
|
||||
this.currentAiMessageIndex = this.messages.length;
|
||||
this.messages.push({
|
||||
role: 'assistant',
|
||||
content: '',
|
||||
renderedContent: '',
|
||||
time: this.formatTime(new Date()),
|
||||
endStatus: false
|
||||
});
|
||||
|
||||
const response = await fetch(`${config.baseUrl}/ai/generateStream`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.token}`,
|
||||
'clientid': config.clientId,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
redirect: 'follow',
|
||||
body: JSON.stringify(apiMessages)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API请求失败: ${response.status}`);
|
||||
}
|
||||
|
||||
if (!response.body) {
|
||||
throw new Error('响应体为空');
|
||||
}
|
||||
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
let result = '';
|
||||
let buffer = ''; // 用于存储未完整的数据
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
|
||||
const chunk = decoder.decode(value);
|
||||
buffer += chunk; // 将新的chunk添加到buffer中
|
||||
console.log("buffer",buffer)
|
||||
// 按换行符分割,但保留buffer中可能不完整的最后一行
|
||||
const lines = buffer.split('\n');
|
||||
buffer = lines.pop() || ''; // 保存最后一行到buffer,如果是空行则置空
|
||||
console.log("lines",lines)
|
||||
for (const line of lines.filter(l => l.trim())) {
|
||||
// debugger
|
||||
console.log('处理行:', line);
|
||||
let data = line;
|
||||
|
||||
if (line.startsWith('data:')) {
|
||||
data = line.substring(5).trim();
|
||||
}
|
||||
console.log("data",data)
|
||||
if (data === '[DONE]') {
|
||||
// 设置消息已完成状态
|
||||
if (this.currentAiMessageIndex >= 0 && this.currentAiMessageIndex < this.messages.length) {
|
||||
this.messages[this.currentAiMessageIndex].endStatus = true;
|
||||
// 最后一次滚动到底部
|
||||
this.throttledScrollToBottom();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// debugger
|
||||
try {
|
||||
result += data;
|
||||
console.log("result",result)
|
||||
if (this.messages && this.currentAiMessageIndex < this.messages.length) {
|
||||
this.messages[this.currentAiMessageIndex].content = result;
|
||||
this.messages[this.currentAiMessageIndex].renderedContent = renderMarkdown(result);
|
||||
console.log("messages1",this.messages)
|
||||
// 最后一次滚动到底部
|
||||
this.throttledScrollToBottom();
|
||||
} else {
|
||||
console.warn('无法更新消息,索引无效:', aiMessageIndex);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('解析流数据失败:', e, line);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理buffer中剩余的数据
|
||||
if (buffer) {
|
||||
try {
|
||||
let data = buffer;
|
||||
if (buffer.startsWith('data:')) {
|
||||
data = buffer.substring(5).trim();
|
||||
}
|
||||
if (data && data !== '[DONE]') {
|
||||
result += data;
|
||||
this.messages[this.currentAiMessageIndex].content = result;
|
||||
this.messages[this.currentAiMessageIndex].renderedContent = renderMarkdown(result);
|
||||
this.throttledScrollToBottom();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('处理剩余数据失败:', e, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error('调用DeepSeek流式API失败:', error);
|
||||
// 如果出错,确保移除空的AI消息
|
||||
if (this.messages.length > 0 && this.messages[this.messages.length - 1].content === '') {
|
||||
this.messages.pop();
|
||||
this.currentAiMessageIndex = -1;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// try {
|
||||
// // 添加一个空的AI回复,用于流式更新
|
||||
// this.currentAiMessageIndex = this.messages.length;
|
||||
// this.messages.push({
|
||||
// role: 'assistant',
|
||||
// content: '',
|
||||
// renderedContent: '',
|
||||
// time: this.formatTime(new Date()),
|
||||
// endStatus: false
|
||||
// });
|
||||
|
||||
const response = await fetch('https://api.siliconflow.cn/v1/chat/completions', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${this.apiKey}`,
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
model: 'deepseek-ai/DeepSeek-R1-Distill-Qwen-7B',
|
||||
messages: apiMessages,
|
||||
stream: true,
|
||||
max_tokens: 8192,
|
||||
stop: '',
|
||||
temperature: 0.6,
|
||||
top_p: 0.7,
|
||||
top_k: 50,
|
||||
frequency_penalty: 0
|
||||
})
|
||||
});
|
||||
// const response = await fetch('https://api.siliconflow.cn/v1/chat/completions', {
|
||||
// method: 'POST',
|
||||
// headers: {
|
||||
// 'Authorization': `Bearer ${this.apiKey}`,
|
||||
// 'Content-Type': 'application/json'
|
||||
// },
|
||||
// body: JSON.stringify({
|
||||
// model: 'deepseek-ai/DeepSeek-R1-Distill-Qwen-7B',
|
||||
// messages: apiMessages,
|
||||
// stream: true,
|
||||
// max_tokens: 8192,
|
||||
// stop: '',
|
||||
// temperature: 0.6,
|
||||
// top_p: 0.7,
|
||||
// top_k: 50,
|
||||
// frequency_penalty: 0
|
||||
// })
|
||||
// });
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`API请求失败: ${response.status}`);
|
||||
}
|
||||
// if (!response.ok) {
|
||||
// throw new Error(`API请求失败: ${response.status}`);
|
||||
// }
|
||||
|
||||
if (!response.body) {
|
||||
throw new Error('响应体为空');
|
||||
}
|
||||
// if (!response.body) {
|
||||
// throw new Error('响应体为空');
|
||||
// }
|
||||
|
||||
const reader = response.body.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
let result = '';
|
||||
// const reader = response.body.getReader();
|
||||
// const decoder = new TextDecoder();
|
||||
// let result = '';
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
// while (true) {
|
||||
// const { done, value } = await reader.read();
|
||||
// if (done) break;
|
||||
|
||||
const chunk = decoder.decode(value);
|
||||
const lines = chunk.split('\n').filter(line => line.trim() !== '');
|
||||
// const chunk = decoder.decode(value);
|
||||
// const lines = chunk.split('\n').filter(line => line.trim() !== '');
|
||||
|
||||
for (const line of lines) {
|
||||
if (line.startsWith('data: ')) {
|
||||
const data = line.substring(6).trim();
|
||||
if (data === '[DONE]') {
|
||||
// 设置消息已完成状态
|
||||
if (this.currentAiMessageIndex >= 0 && this.currentAiMessageIndex < this.messages.length) {
|
||||
this.messages[this.currentAiMessageIndex].endStatus = true;
|
||||
// 最后一次滚动到底部
|
||||
this.throttledScrollToBottom();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// for (const line of lines) {
|
||||
// if (line.startsWith('data: ')) {
|
||||
// const data = line.substring(6).trim();
|
||||
// if (data === '[DONE]') {
|
||||
// // 设置消息已完成状态
|
||||
// if (this.currentAiMessageIndex >= 0 && this.currentAiMessageIndex < this.messages.length) {
|
||||
// this.messages[this.currentAiMessageIndex].endStatus = true;
|
||||
// // 最后一次滚动到底部
|
||||
// this.throttledScrollToBottom();
|
||||
// }
|
||||
// continue;
|
||||
// }
|
||||
|
||||
try {
|
||||
const parsed = JSON.parse(data);
|
||||
// 检查parsed和choices是否存在
|
||||
if (!parsed || !parsed.choices || !Array.isArray(parsed.choices) || parsed.choices.length === 0) {
|
||||
console.warn('无效的响应格式:', data);
|
||||
continue;
|
||||
}
|
||||
// try {
|
||||
// const parsed = JSON.parse(data);
|
||||
// // 检查parsed和choices是否存在
|
||||
// if (!parsed || !parsed.choices || !Array.isArray(parsed.choices) || parsed.choices.length === 0) {
|
||||
// console.warn('无效的响应格式:', data);
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// 安全地访问delta属性
|
||||
const delta = parsed.choices[0].delta || {};
|
||||
// // 安全地访问delta属性
|
||||
// const delta = parsed.choices[0].delta || {};
|
||||
|
||||
// 根据您提供的格式解析内容
|
||||
const content = delta.content;
|
||||
// 有些响应可能包含reasoning_content而不是content
|
||||
const reasoningContent = delta.reasoning_content || '';
|
||||
// // 根据您提供的格式解析内容
|
||||
// const content = delta.content;
|
||||
// // 有些响应可能包含reasoning_content而不是content
|
||||
// const reasoningContent = delta.reasoning_content || '';
|
||||
|
||||
// 只有当content不是null且有值,或者reasoningContent有值时才添加
|
||||
const textToAdd = (content !== null && content !== undefined) ? content : reasoningContent;
|
||||
// // 只有当content不是null且有值,或者reasoningContent有值时才添加
|
||||
// const textToAdd = (content !== null && content !== undefined) ? content : reasoningContent;
|
||||
|
||||
if (textToAdd) {
|
||||
result += textToAdd;
|
||||
// 确保messages[currentAiMessageIndex]存在
|
||||
if (this.currentAiMessageIndex >= 0 && this.currentAiMessageIndex < this.messages.length) {
|
||||
this.messages[this.currentAiMessageIndex].content = result;
|
||||
this.messages[this.currentAiMessageIndex].renderedContent = renderMarkdown(result);
|
||||
// if (textToAdd) {
|
||||
// result += textToAdd;
|
||||
// // 确保messages[currentAiMessageIndex]存在
|
||||
// if (this.currentAiMessageIndex >= 0 && this.currentAiMessageIndex < this.messages.length) {
|
||||
// this.messages[this.currentAiMessageIndex].content = result;
|
||||
// this.messages[this.currentAiMessageIndex].renderedContent = renderMarkdown(result);
|
||||
|
||||
// 滚动到底部,但限制频率以提高性能
|
||||
this.throttledScrollToBottom();
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('解析流数据失败:', e, line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// // 滚动到底部,但限制频率以提高性能
|
||||
// this.throttledScrollToBottom();
|
||||
// }
|
||||
// }
|
||||
// } catch (e) {
|
||||
// console.error('解析流数据失败:', e, line);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error('调用DeepSeek流式API失败:', error);
|
||||
// 如果出错,确保移除空的AI消息
|
||||
if (this.messages.length > 0 && this.messages[this.messages.length - 1].content === '') {
|
||||
this.messages.pop();
|
||||
this.currentAiMessageIndex = -1;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
// return result;
|
||||
// } catch (error) {
|
||||
// console.error('调用DeepSeek流式API失败:', error);
|
||||
// // 如果出错,确保移除空的AI消息
|
||||
// if (this.messages.length > 0 && this.messages[this.messages.length - 1].content === '') {
|
||||
// this.messages.pop();
|
||||
// this.currentAiMessageIndex = -1;
|
||||
// }
|
||||
// throw error;
|
||||
// }
|
||||
},
|
||||
|
||||
// 使用普通请求(非H5环境)
|
||||
|
|
|
@ -9,6 +9,15 @@
|
|||
</view>
|
||||
</view>
|
||||
|
||||
<view class="form-item" v-if="commitState === 'back'">
|
||||
<text class="form-label">修改意见</text>
|
||||
<template>
|
||||
<view class="comment-box">
|
||||
{{ comment }}
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<view class="form-item">
|
||||
<text class="form-label">剧本 <text class="form-hint">视频的剧本</text> </text>
|
||||
<!-- 文本输入 -->
|
||||
|
@ -92,6 +101,7 @@
|
|||
orderItemId: "",
|
||||
// 素材提交状态
|
||||
commitState:'add',
|
||||
comment:'',
|
||||
materialfrom:{
|
||||
id: undefined,
|
||||
dictId: undefined,
|
||||
|
@ -159,26 +169,17 @@
|
|||
});
|
||||
},
|
||||
async getProductDetail(){
|
||||
// let res = await this.$api.orderApi.getMallclientOrderProductList({ orderId: this.orderId, productId: this.productId })
|
||||
let res = await this.$api.orderApi.getOrderMaterialList({ orderItemId: this.orderItemId })
|
||||
console.log("res",res)
|
||||
// this.materialfrom.productSn = res.rows[0].productSn;
|
||||
// this.commitState = res.rows[0].commitState;
|
||||
// if (this.commitState === 0) {
|
||||
// this.getMaterialDictList();
|
||||
// } else {
|
||||
// this.getMaterialList();
|
||||
// }
|
||||
if(res.rows.length!=0){
|
||||
this.materialfrom.flowId = res.rows[0].id;
|
||||
this.commitState = res.rows[0].status;
|
||||
this.comment = res.rows[0].comment || '';
|
||||
this.scriptContent = res.rows[0].script || '';
|
||||
this.materialTemplateList = res.rows[0].materialItems || [];
|
||||
res.rows[0].materialItems.forEach(async (item,index)=>{
|
||||
if(item.attrType !== 0 && item.attrValue !== ''){
|
||||
let {fileUrl,fileName} = await this.getFileDetail(item.attrValue);
|
||||
console.log("fileUrl,fileName",fileUrl,fileName)
|
||||
// this.materialTemplateList[index].fileUrl = fileUrl;
|
||||
// this.materialTemplateList[index].fileName = fileName;
|
||||
this.$nextTick(()=>{
|
||||
this.$set(this.materialTemplateList[index],'fileUrl',fileUrl)
|
||||
this.$set(this.materialTemplateList[index],'fileName',fileName)
|
||||
|
@ -440,13 +441,21 @@
|
|||
orderId: this.orderId,
|
||||
productId: this.productId,
|
||||
orderItemId: this.orderItemId,
|
||||
materialItems: this.materialTemplateList
|
||||
materialItems: this.materialTemplateList,
|
||||
script: this.scriptContent
|
||||
});
|
||||
this.buttonLoading = false;
|
||||
this.materialfrom.flowId = res.data.id;
|
||||
this.getProductDetail();
|
||||
}else{
|
||||
res = await this.$api.orderApi.mallMaterialUpdateBatch(this.materialTemplateList);
|
||||
res = await this.$api.orderApi.EditOrderMaterial({
|
||||
orderId: this.orderId,
|
||||
productId: this.productId,
|
||||
orderItemId: this.orderItemId,
|
||||
materialItems: this.materialTemplateList,
|
||||
script: this.scriptContent,
|
||||
id: this.materialfrom.flowId
|
||||
});
|
||||
this.buttonLoading = false;
|
||||
}
|
||||
|
||||
|
@ -514,6 +523,15 @@
|
|||
align-items: center;
|
||||
}
|
||||
}
|
||||
.comment-box{
|
||||
background-color: rgb(254,242,242);
|
||||
border: 1px solid rgb(254,226,226);
|
||||
border-radius: 0.5rem;
|
||||
padding: 1rem;
|
||||
width: 100%;
|
||||
color: red;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
margin-bottom: 20rpx;
|
||||
|
@ -527,9 +545,9 @@
|
|||
margin-bottom: 10rpx;
|
||||
font-weight: bold;
|
||||
.form-hint{
|
||||
font-size: 22rpx;
|
||||
color: #666;
|
||||
margin-left: 10rpx;
|
||||
font-size: 20rpx;
|
||||
color: #999;
|
||||
margin-left: 6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,394 +1,556 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<!-- 订单信息 -->
|
||||
<view class="info-card">
|
||||
<view class="info-item">
|
||||
<text class="label">订单编号</text>
|
||||
<text class="value">{{ orderInfo.orderSn }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">创建时间</text>
|
||||
<text class="value">{{ orderInfo.createTime }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">客户姓名</text>
|
||||
<text class="value">{{ orderInfo.memberName }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">客户手机</text>
|
||||
<text class="value">{{ orderInfo.memberPhone }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品信息 -->
|
||||
<view class="info-card">
|
||||
<view class="card-title">商品信息</view>
|
||||
<view class="">
|
||||
<view v-for="(item, index) in orderInfo.orderItems" :key="index" class="product-item">
|
||||
<image :src="item.productPic" mode="aspectFill" class="product-image" @click="lookPic(item.productPic)"></image>
|
||||
<view class="product-info">
|
||||
<text class="product-name">{{ item.productName }}</text>
|
||||
<view class="product-bottom">
|
||||
<text class="product-quantity">x{{ item.productQuantity }}</text>
|
||||
<text class="product-price">¥{{ (item.productPrice / 100).toFixed(2) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="container">
|
||||
<!-- 订单信息 -->
|
||||
<view class="info-card">
|
||||
<view class="info-item">
|
||||
<text class="label">订单编号</text>
|
||||
<text class="value">{{ orderInfo.orderSn }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">创建时间</text>
|
||||
<text class="value">{{ orderInfo.createTime }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">客户姓名</text>
|
||||
<text class="value">{{ orderInfo.memberName }}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">客户手机</text>
|
||||
<text class="value">{{ orderInfo.memberPhone }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 商品信息 -->
|
||||
<view class="info-card">
|
||||
<view class="card-title">商品信息</view>
|
||||
<view class="">
|
||||
<view v-for="(item, index) in orderInfo.orderItems" :key="index" class="product-item">
|
||||
<image :src="item.productPic" mode="aspectFill" class="product-image" @click="lookPic(item.productPic)">
|
||||
</image>
|
||||
<view class="product-info">
|
||||
<text class="product-name">{{ item.productName }}</text>
|
||||
<view class="product-bottom">
|
||||
<text class="product-quantity">x{{ item.productQuantity }}</text>
|
||||
<text class="product-price">¥{{ (item.productPrice / 100).toFixed(2) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 订单金额信息 -->
|
||||
<view class="amount-info">
|
||||
<view class="amount-item">
|
||||
<text>总金额</text>
|
||||
<text class="price">¥{{ (orderInfo.totalAmount / 100).toFixed(2) }}</text>
|
||||
</view>
|
||||
<view class="amount-item">
|
||||
<text>已付额</text>
|
||||
<text class="price paid">¥{{ orderInfo.payAmount ? (orderInfo.payAmount / 100).toFixed(2) : '0.00' }}</text>
|
||||
</view>
|
||||
<view class="amount-item">
|
||||
<text>支付方式</text>
|
||||
<view class="payment-method">
|
||||
<!-- <u-icon name="weixin-fill" color="#07c160" size="28"></u-icon> -->
|
||||
<text>{{getDictName('mall_pay_type',orderInfo.payType,'dictLabel')}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单其他信息 -->
|
||||
<view class="info-card">
|
||||
<view class="info-item">
|
||||
<text class="label">订单来源</text>
|
||||
<view class="value source">
|
||||
<u-icon name="shopping-mall" size="24"></u-icon>
|
||||
<text>{{getDictName('mall_source_type',orderInfo.sourceType,'dictLabel')}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">订单状态</text>
|
||||
<text class="value status" :class="['dict-item',getDictName('mall_order_status',orderInfo.orderStatus,'listClass')]">{{getDictName('mall_order_status',orderInfo.orderStatus,'dictLabel')}}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">订单备注</text>
|
||||
<text class="value">{{ orderInfo.orderNote || '无' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 底部购买按钮 -->
|
||||
<view class="btn-box">
|
||||
<u-button type="primary" style="width: 680rpx;" :loading="buttonLoading" @click="handlePay">去支付</u-button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 订单金额信息 -->
|
||||
<view class="amount-info">
|
||||
<view class="amount-item">
|
||||
<text>总金额</text>
|
||||
<text class="price">¥{{ (orderInfo.totalAmount / 100).toFixed(2) }}</text>
|
||||
</view>
|
||||
<view class="amount-item">
|
||||
<text>已付额</text>
|
||||
<text class="price paid">¥{{ orderInfo.payAmount ? (orderInfo.payAmount / 100).toFixed(2) : '0.00' }}</text>
|
||||
</view>
|
||||
<view class="amount-item">
|
||||
<text>支付方式</text>
|
||||
<view class="payment-method">
|
||||
<!-- <u-icon name="weixin-fill" color="#07c160" size="28"></u-icon> -->
|
||||
<text>{{getDictName('mall_pay_type',orderInfo.payType,'dictLabel')}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 订单其他信息 -->
|
||||
<view class="info-card">
|
||||
<view class="info-item">
|
||||
<text class="label">订单来源</text>
|
||||
<view class="value source">
|
||||
<u-icon name="shopping-mall" size="24"></u-icon>
|
||||
<text>{{getDictName('mall_source_type',orderInfo.sourceType,'dictLabel')}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">订单状态</text>
|
||||
<text class="value status"
|
||||
:class="['dict-item',getDictName('mall_order_status',orderInfo.orderStatus,'listClass')]">{{getDictName('mall_order_status',orderInfo.orderStatus,'dictLabel')}}</text>
|
||||
</view>
|
||||
<view class="info-item">
|
||||
<text class="label">订单备注</text>
|
||||
<text class="value">{{ orderInfo.orderNote || '无' }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 底部购买按钮 -->
|
||||
<view class="btn-box">
|
||||
<u-button type="primary" style="width: 680rpx;" :loading="buttonLoading" @click="handlePay">去支付</u-button>
|
||||
</view>
|
||||
<u-toast ref="uToast" />
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
orderId:'',
|
||||
orderInfo:{
|
||||
"billContent": null,
|
||||
"billHeader": null,
|
||||
"billReceiverEmail": null,
|
||||
"billReceiverPhone": null,
|
||||
"billType": 0,
|
||||
"confirmStatus": 0,
|
||||
"createBy": "",
|
||||
"createTime": "",
|
||||
"deliveryTime": null,
|
||||
"finishTime": null,
|
||||
"freightAmount": null,
|
||||
"id": "",
|
||||
"memberName": "",
|
||||
"memberPhone": "",
|
||||
"memberUsername": "",
|
||||
"orderItems": [],
|
||||
"orderNote": null,
|
||||
"orderSn": "",
|
||||
"orderStatus": 0,
|
||||
"orderType": 0,
|
||||
"payAmount": null,
|
||||
"payTime": null,
|
||||
"payType": 0,
|
||||
"receiverCity": null,
|
||||
"receiverDetailAddress": null,
|
||||
"receiverName": null,
|
||||
"receiverPhone": null,
|
||||
"receiverPostCode": null,
|
||||
"receiverProvince": null,
|
||||
"receiverRegion": null,
|
||||
"sourceType": 0,
|
||||
"totalAmount": 0,
|
||||
"updateBy": "",
|
||||
"updateTime": ""
|
||||
},
|
||||
mall_order_status:[],
|
||||
mall_source_type:[],
|
||||
mall_pay_type:[],
|
||||
buttonLoading:false,
|
||||
officialAccount:{
|
||||
appid:'',
|
||||
appsecret:'ca307cfb6c94e8ac015e26cfd717a91c',
|
||||
},
|
||||
code:'',
|
||||
openId:'',
|
||||
}
|
||||
},
|
||||
onLoad(option) {
|
||||
this.officialAccount.appid = this.$store.state.app.appConfig.appIdPublic;
|
||||
this.getDictDataList('mall_order_status');
|
||||
this.getDictDataList('mall_source_type');
|
||||
this.getDictDataList('mall_pay_type');
|
||||
console.log("option",option)
|
||||
this.orderId = option.id;
|
||||
this.getOrderDetail(option.id);
|
||||
let res = uni.getStorageSync('openid');
|
||||
if (res.length == 2) {
|
||||
this.openid = res[1].data;
|
||||
}else{
|
||||
// #ifdef H5
|
||||
let code = this.getUrlCode('code')
|
||||
if(code || this.code){
|
||||
this.code = code;
|
||||
this.getOpenidAndUserinfo(code)
|
||||
}else{
|
||||
console.log("当前网址",window.location.href)
|
||||
this.getH5Code()
|
||||
// import WeixinJSBridge from '../../utils/jweixin-1.6.0.js';
|
||||
var jweixin = require('jweixin-module');
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
orderId: '',
|
||||
orderInfo: {
|
||||
"billContent": null,
|
||||
"billHeader": null,
|
||||
"billReceiverEmail": null,
|
||||
"billReceiverPhone": null,
|
||||
"billType": 0,
|
||||
"confirmStatus": 0,
|
||||
"createBy": "",
|
||||
"createTime": "",
|
||||
"deliveryTime": null,
|
||||
"finishTime": null,
|
||||
"freightAmount": null,
|
||||
"id": "",
|
||||
"memberName": "",
|
||||
"memberPhone": "",
|
||||
"memberUsername": "",
|
||||
"orderItems": [],
|
||||
"orderNote": null,
|
||||
"orderSn": "",
|
||||
"orderStatus": 0,
|
||||
"orderType": 0,
|
||||
"payAmount": null,
|
||||
"payTime": null,
|
||||
"payType": 0,
|
||||
"receiverCity": null,
|
||||
"receiverDetailAddress": null,
|
||||
"receiverName": null,
|
||||
"receiverPhone": null,
|
||||
"receiverPostCode": null,
|
||||
"receiverProvince": null,
|
||||
"receiverRegion": null,
|
||||
"sourceType": 0,
|
||||
"totalAmount": 0,
|
||||
"updateBy": "",
|
||||
"updateTime": ""
|
||||
},
|
||||
mall_order_status: [],
|
||||
mall_source_type: [],
|
||||
mall_pay_type: [],
|
||||
buttonLoading: false,
|
||||
officialAccount: {
|
||||
appid: '',
|
||||
appsecret: 'ca307cfb6c94e8ac015e26cfd717a91c',
|
||||
},
|
||||
code: '',
|
||||
openId: '',
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
methods:{
|
||||
// 获取订单详情
|
||||
getOrderDetail(id){
|
||||
this.$api.orderApi.getOrderDetail(id).then((res)=>{
|
||||
console.log("获取订单详情",res)
|
||||
if(res.code == 200){
|
||||
this.orderInfo = res.data;
|
||||
}
|
||||
}).catch(()=>{
|
||||
})
|
||||
},
|
||||
getDictDataList(type){
|
||||
this.$api.getDictList(type).then((res)=>{
|
||||
if(res.code===200){
|
||||
this[type] = res.data || [];
|
||||
}
|
||||
})
|
||||
},
|
||||
getDictName(list,value,key){
|
||||
let name = ''
|
||||
if(this[list]){
|
||||
this[list].forEach((item)=>{
|
||||
if(item.dictValue == value){
|
||||
name = item[key];
|
||||
onLoad(option) {
|
||||
let appIdPublic = uni.getStorageSync('appIdPublic');
|
||||
console.log("this.$store.state.app.appConfig.appIdPublic",this.$store.state.app.appConfig.appIdPublic)
|
||||
this.officialAccount.appid = appIdPublic || '';
|
||||
this.getDictDataList('mall_order_status');
|
||||
this.getDictDataList('mall_source_type');
|
||||
this.getDictDataList('mall_pay_type');
|
||||
console.log("option", option)
|
||||
this.orderId = option.id;
|
||||
this.getOrderDetail(option.id);
|
||||
let res = uni.getStorageSync('openId');
|
||||
if (res) {
|
||||
this.openId = res;
|
||||
} else {
|
||||
// #ifdef H5
|
||||
let code = this.getUrlCode('code')
|
||||
if (code || this.code) {
|
||||
this.code = code;
|
||||
this.getOpenidAndUserinfo(code)
|
||||
// // 清除URL中的code参数
|
||||
// const url = window.location.href;
|
||||
// const newUrl = url.split('?')[0]; // 去掉参数部分
|
||||
// history.replaceState({}, '', newUrl+'');
|
||||
} else {
|
||||
console.log("当前网址", window.location.href)
|
||||
this.getH5Code()
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 获取订单详情
|
||||
getOrderDetail(id) {
|
||||
this.$api.orderApi.getOrderDetail(id).then((res) => {
|
||||
console.log("获取订单详情", res)
|
||||
if (res.code == 200) {
|
||||
this.orderInfo = res.data;
|
||||
}
|
||||
}).catch(() => {})
|
||||
},
|
||||
getDictDataList(type) {
|
||||
this.$api.getDictList(type).then((res) => {
|
||||
if (res.code === 200) {
|
||||
this[type] = res.data || [];
|
||||
}
|
||||
})
|
||||
return name;
|
||||
}
|
||||
},
|
||||
lookPic(url){
|
||||
uni.previewImage({
|
||||
current: '', // 当前显示图片的 http 链接
|
||||
urls: [url] // 需要预览的图片 http 链接列表
|
||||
});
|
||||
},
|
||||
handlePay() {
|
||||
// 处理购买逻辑
|
||||
uni.showToast({
|
||||
title: '正在开发中...',
|
||||
icon: 'none'
|
||||
})
|
||||
// openid获取支付参数、调用支付
|
||||
|
||||
},
|
||||
getH5Code(){
|
||||
if(this.isWechat()) {
|
||||
// 截取地址中的code,如果没有code就去微信授权,如果已经获取到code了就直接把code传给后台获取openId
|
||||
window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='+this.officialAccount.appid+'&redirect_uri=' + encodeURIComponent(window.location.href) + '&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect'
|
||||
console.log("跳转授权页面")
|
||||
// redirect_uri是授权成功后,跳转的url地址,微信会帮我们跳转到该链接,并且通过?的形式拼接code,这里需要用encodeURIComponent对链接进行处理。
|
||||
// 如果配置参数一一对应,那么此时已经通过回调地址刷新页面后,你就会再地址栏中看到code了。
|
||||
// http://127.0.0.1/pages/views/profile/login/login?code=001BWV4J1lRzz00H4J1J1vRE4J1BWV4q&state=1
|
||||
}
|
||||
},
|
||||
getUrlCode(name){
|
||||
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ''])[1].replace(/\+/g, '%20')) || null
|
||||
},
|
||||
isWechat(){
|
||||
return String(navigator.userAgent.toLowerCase().match(/MicroMessenger/i)) === "micromessenger";
|
||||
},
|
||||
getOpenidAndUserinfo(code){
|
||||
console.log("code换openid")
|
||||
uni.request({
|
||||
url: 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='+this.officialAccount.appid+'&secret='+this.officialAccount.secret +'&grant_type=authorization_code&code='+code,
|
||||
success: (res) => {
|
||||
console.log('通过code获取openid和accessToken', res)
|
||||
// if(res.data.code === 200) {
|
||||
// // 登录成功,可以将用户信息和token保存到缓存中
|
||||
// uni.setStorageSync('userInfo', res.data.result.userInfo)
|
||||
// uni.setStorageSync('token', res.data.result.token)
|
||||
// }
|
||||
},
|
||||
getDictName(list, value, key) {
|
||||
let name = ''
|
||||
if (this[list]) {
|
||||
this[list].forEach((item) => {
|
||||
if (item.dictValue == value) {
|
||||
name = item[key];
|
||||
}
|
||||
})
|
||||
return name;
|
||||
}
|
||||
},
|
||||
lookPic(url) {
|
||||
uni.previewImage({
|
||||
current: '', // 当前显示图片的 http 链接
|
||||
urls: [url] // 需要预览的图片 http 链接列表
|
||||
});
|
||||
},
|
||||
handlePay() {
|
||||
// 处理购买逻辑
|
||||
// uni.showToast({
|
||||
// title: '正在开发中...',
|
||||
// icon: 'none'
|
||||
// })
|
||||
// openid获取支付参数、调用支付
|
||||
console.log("支付")
|
||||
if(this.openId){
|
||||
this.$api.orderApi.addPayOrder({
|
||||
orderId: this.orderInfo.id,
|
||||
//拉卡拉这个参数无用,后面换类型在添加其他参数如:openid
|
||||
channelExtra: JSON.stringify({'openid': this.openId}),
|
||||
wayCode: 'LKL_WX_JSAPI'
|
||||
}).then((res) => {
|
||||
console.log("获取支付详情", res)
|
||||
if (res.code == 200) {
|
||||
// this.orderInfo = res.data;
|
||||
}
|
||||
}).catch(() => {})
|
||||
// this.wxpay({
|
||||
// "appId": this.officialAccount.appid, //公众号
|
||||
// "timeStamp": 'a1sd12as1d23sa1d231as2d1asd', //时间戳
|
||||
// "nonceStr": 'a1sd12as1d23sa1d231as2d1asd', //随机串
|
||||
// "package": 'a1sd12as1d23sa1d231as2d1asd', //prepay_id
|
||||
// "signType": 'a1sd12as1d23sa1d231as2d1asd', //微信签名方式RSA
|
||||
// "paySign": 'a1sd12as1d23sa1d231as2d1asd', //微信签名
|
||||
// "signature": 'a1sd12as1d23sa1d231as2d1asd' //微信签名
|
||||
// })
|
||||
}else{
|
||||
this.clearUrlCode()
|
||||
this.getH5Code()
|
||||
this.$refs.uToast.show({
|
||||
title: '获取支付信息失败,请重试',
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
clearUrlCode(){
|
||||
// 清除URL中的code参数
|
||||
const url = window.location.href;
|
||||
const newUrl = url.split('?')[0]; // 去掉参数部分
|
||||
history.replaceState({}, '', newUrl+'/pages/order/detail?id='+this.orderId);
|
||||
},
|
||||
getH5Code() {
|
||||
if (this.isWechat()) {
|
||||
// 截取地址中的code,如果没有code就去微信授权,如果已经获取到code了就直接把code传给后台获取openId
|
||||
window.location.href = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + this.officialAccount
|
||||
.appid + '&redirect_uri=' + encodeURIComponent(window.location.href) +
|
||||
'&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect'
|
||||
console.log("跳转授权页面",'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' + this.officialAccount
|
||||
.appid + '&redirect_uri=' + encodeURIComponent(window.location.href) +
|
||||
'&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect')
|
||||
// redirect_uri是授权成功后,跳转的url地址,微信会帮我们跳转到该链接,并且通过?的形式拼接code,这里需要用encodeURIComponent对链接进行处理。
|
||||
// 如果配置参数一一对应,那么此时已经通过回调地址刷新页面后,你就会再地址栏中看到code了。
|
||||
// http://127.0.0.1/pages/views/profile/login/login?code=001BWV4J1lRzz00H4J1J1vRE4J1BWV4q&state=1
|
||||
}
|
||||
},
|
||||
getUrlCode(name) {
|
||||
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [,
|
||||
''])[1].replace(/\+/g, '%20')) || null
|
||||
},
|
||||
isWechat() {
|
||||
return String(navigator.userAgent.toLowerCase().match(/MicroMessenger/i)) === "micromessenger";
|
||||
},
|
||||
getOpenidAndUserinfo(code) {
|
||||
console.log("code换openid")
|
||||
this.$api.orderApi.getWxOpenid({
|
||||
code: code
|
||||
}).then((res) => {
|
||||
console.log("获取openid", res)
|
||||
if (res.code == 200) {
|
||||
if(res.data.openid){
|
||||
this.openId = res.data.openid;
|
||||
uni.setStorageSync('openId', res.data.openid)
|
||||
this.clearUrlCode();
|
||||
}else{
|
||||
this.clearUrlCode();
|
||||
this.getUrlCode();
|
||||
}
|
||||
// 1、调用后端获取支付参数
|
||||
// 2、调起支付
|
||||
}else{
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}).catch(() => {
|
||||
|
||||
})
|
||||
// uni.request({
|
||||
// url: 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='+this.officialAccount.appid+'&secret='+this.officialAccount.secret +'&grant_type=authorization_code&code='+code,
|
||||
// success: (res) => {
|
||||
// console.log('通过code获取openid和accessToken', res)
|
||||
// // if(res.data.code === 200) {
|
||||
// // // 登录成功,可以将用户信息和token保存到缓存中
|
||||
// // uni.setStorageSync('userInfo', res.data.result.userInfo)
|
||||
// // uni.setStorageSync('token', res.data.result.token)
|
||||
// // }
|
||||
// }
|
||||
// })
|
||||
},
|
||||
wxpay(data) {
|
||||
// if (typeof WeixinJSBridge == "undefined") {
|
||||
// if (document.addEventListener) {
|
||||
// document.addEventListener('WeixinJSBridgeReady', this.onBridgeReady(data), false);
|
||||
// } else if (document.attachEvent) {
|
||||
// document.attachEvent('WeixinJSBridgeReady', this.onBridgeReady(data));
|
||||
// document.attachEvent('onWeixinJSBridgeReady', this.onBridgeReady(data));
|
||||
// }
|
||||
// } else {
|
||||
// this.onBridgeReady(data);
|
||||
// }
|
||||
jweixin.config({
|
||||
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。(测试记得关掉)
|
||||
appId: data.appId, // 公众号的唯一标识
|
||||
timestamp: data.timestamp, // 生成签名的时间戳
|
||||
nonceStr: data.nonceStr, // 生成签名的随机串
|
||||
signature: data.signature, // 签名
|
||||
jsApiList: ['chooseWXPay'], // JS接口列表
|
||||
})
|
||||
this.onBridgeReady(data);
|
||||
},
|
||||
|
||||
onBridgeReady(data) {
|
||||
// jweixin.ready(()=>{
|
||||
// // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
|
||||
// jweixin.chooseWXPay({
|
||||
// timestamp: data.timeStamp,
|
||||
// package: data.package,
|
||||
// nonceStr: data.nonceStr,
|
||||
// signType: data.signType,
|
||||
// paySign: data.paySign,
|
||||
// success: (res) => {
|
||||
// if (res.errMsg == "chooseWXPay:ok") {
|
||||
// console.log('支付成功')
|
||||
// } else {
|
||||
// console.log('支付失败')}
|
||||
// },
|
||||
// fail: (res) => {
|
||||
// console.log('支付失败')
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
|
||||
jweixin.invoke(
|
||||
'getBrandWCPayRequest', {
|
||||
// 传入第一步后端接口返回的核心参数
|
||||
"appId": data.appId, //公众号
|
||||
"timeStamp": data.timeStamp, //时间戳
|
||||
"nonceStr": data.nonceStr, //随机串
|
||||
"package": data.package, //prepay_id
|
||||
"signType": data.signType, //微信签名方式RSA
|
||||
"paySign": data.paySign //微信签名
|
||||
},
|
||||
(res)=>{
|
||||
// 支付成功
|
||||
if (res.err_msg == "get_brand_wcpay_request:ok") {
|
||||
// 使用以上方式判断前端返回,微信团队郑重提示:
|
||||
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
|
||||
this.$refs.uToast.show({
|
||||
title: '支付成功',
|
||||
type: 'success',
|
||||
})
|
||||
}
|
||||
// 支付过程中用户取消
|
||||
if (res.err_msg == "get_brand_wcpay_request:cancel") {
|
||||
this.$refs.uToast.show({
|
||||
title: '用户取消',
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
// 支付失败
|
||||
if (res.err_msg == "get_brand_wcpay_request:fail") {
|
||||
this.$refs.uToast.show({
|
||||
title: '支付失败',
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 其它
|
||||
* 1、请检查预支付会话标识prepay_id是否已失效
|
||||
* 2、请求的appid与下单接口的appid是否一致
|
||||
* */
|
||||
if (res.err_msg == "调用支付JSAPI缺少参数:total_fee") {
|
||||
this.$refs.uToast.show({
|
||||
title: '缺少参数',
|
||||
type: 'error',
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20rpx;
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background-color: #f5f5f5;
|
||||
padding: 20rpx;
|
||||
padding-bottom: 120rpx;
|
||||
}
|
||||
|
||||
.info-card {
|
||||
background-color: #fff;
|
||||
border-radius: 12rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.info-card {
|
||||
background-color: #fff;
|
||||
border-radius: 12rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
.label {
|
||||
color: #666;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #333;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
.info-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
.label {
|
||||
color: #666;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.value {
|
||||
color: #333;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.product-item {
|
||||
display: flex;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
|
||||
display: flex;
|
||||
padding: 20rpx 0;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.product-image {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
border-radius: 8rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
.product-image {
|
||||
width: 160rpx;
|
||||
height: 160rpx;
|
||||
border-radius: 8rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.product-bottom {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.product-quantity {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.product-price {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.amount-info {
|
||||
margin-top: 30rpx;
|
||||
padding-top: 30rpx;
|
||||
border-top: 1rpx solid #eee;
|
||||
}
|
||||
|
||||
.amount-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 28rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-weight: 500;
|
||||
|
||||
&.paid {
|
||||
color: #19be6b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.payment-method {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.source {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.status {
|
||||
color: #19be6b;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
height: 120rpx;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #fff;
|
||||
z-index: 999;
|
||||
button{
|
||||
width: 680rpx;
|
||||
height: 85rpx;
|
||||
border-radius: 10rpx;
|
||||
.product-info {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.product-name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.product-bottom {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
.product-quantity {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.product-price {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.amount-info {
|
||||
margin-top: 30rpx;
|
||||
padding-top: 30rpx;
|
||||
border-top: 1rpx solid #eee;
|
||||
}
|
||||
|
||||
.amount-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
font-size: 28rpx;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.price {
|
||||
font-weight: 500;
|
||||
|
||||
&.paid {
|
||||
color: #19be6b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.payment-method {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.source {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rpx;
|
||||
}
|
||||
|
||||
.status {
|
||||
color: #19be6b;
|
||||
}
|
||||
|
||||
.btn-box {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
height: 120rpx;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: #fff;
|
||||
z-index: 999;
|
||||
|
||||
button {
|
||||
width: 680rpx;
|
||||
height: 85rpx;
|
||||
border-radius: 10rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue