mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
synced 2026-08-06 02:47:25 +08:00
refactor: 移动端升级 Vue3 + uView Plus
将 lilishop-uniapp 从 Vue2/uView 1.6 迁移到 Vue3/uview-plus,优先支持 H5/微商城与微信小程序;移除 vendored uview-ui,改用 npm 依赖、Vuex4 与迁移脚本/补丁,并补充 VUE3_MIGRATION.md 回归清单。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -229,6 +229,38 @@ function navigationToBack(type) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析商品相册/图片项,兼容上传组件的 JSON 字符串与纯 URL。
|
||||
* 后端 goodsGalleryList 可能同时存在两种格式:
|
||||
* - '{"url":"https://...jpg","name":"x.jpg","status":"finished"}'
|
||||
* - 'https://...jpg'
|
||||
* @param {String} item 单个相册项
|
||||
* @returns {String} 解析出的图片地址,无法解析时返回空字符串
|
||||
*/
|
||||
export function parseGoodsImageUrl(item) {
|
||||
if (item === null || item === undefined) return "";
|
||||
if (typeof item !== "string") return "";
|
||||
const trimmed = item.trim();
|
||||
if (!trimmed) return "";
|
||||
// 纯 URL 直接返回
|
||||
if (/^https?:\/\//.test(trimmed)) return trimmed;
|
||||
// JSON 字符串,尝试解析取 url 字段
|
||||
if (trimmed.charAt(0) === "{") {
|
||||
try {
|
||||
const parsed = JSON.parse(trimmed);
|
||||
const url = parsed && (parsed.url || parsed.path || parsed.link);
|
||||
if (typeof url === "string" && /^https?:\/\//.test(url.trim())) {
|
||||
return url.trim();
|
||||
}
|
||||
} catch (e) {
|
||||
// 解析失败时退化为正则提取
|
||||
}
|
||||
const match = trimmed.match(/https?:\/\/[^\s"'\\}]+/);
|
||||
if (match) return match[0];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算当前时间到第二天0点的倒计时[秒]
|
||||
* @returns {number}
|
||||
@@ -246,7 +278,7 @@ export function theNextDayTime() {
|
||||
).getTime() - nowDate.getTime();
|
||||
return parseInt(time / 1000);
|
||||
}
|
||||
module.exports = {
|
||||
export default {
|
||||
unixToDate,
|
||||
dateToUnix,
|
||||
formatPrice,
|
||||
@@ -256,4 +288,5 @@ module.exports = {
|
||||
theNextDayTime,
|
||||
whetherNavigate,
|
||||
checkBankno,
|
||||
parseGoodsImageUrl,
|
||||
};
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
import { logout, logoffConfirm } from "@/api/login";
|
||||
import { getUserInfo } from "@/api/members";
|
||||
import storage from "@/utils/storage.js";
|
||||
import Vue from "vue";
|
||||
import config from "@/config/config";
|
||||
import Foundation from "./Foundation.js";
|
||||
|
||||
/**
|
||||
* 解析商品图片地址,兼容上传 JSON 与纯 URL,非法时返回占位图
|
||||
*/
|
||||
export function parseGoodsImageUrl(item, fallback = config.logo) {
|
||||
const url = Foundation.parseGoodsImageUrl(item);
|
||||
return url || fallback || "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 金钱单位置换 2999 --> 2,999.00
|
||||
* @param val
|
||||
@@ -347,7 +356,7 @@ export function quiteLoginOut () {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "是否退出登录?",
|
||||
confirmColor: Vue.prototype.$mainColor,
|
||||
confirmColor: config.mainColor,
|
||||
async success (res) {
|
||||
if (res.confirm) {
|
||||
storage.setAccessToken("");
|
||||
@@ -369,7 +378,7 @@ export function logoff () {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "确认注销用户么?注销用户将无法再次登录并失去当前数据。",
|
||||
confirmColor: Vue.prototype.$mainColor,
|
||||
confirmColor: config.mainColor,
|
||||
async success (res) {
|
||||
if (res.confirm) {
|
||||
await logoffConfirm();
|
||||
@@ -406,7 +415,7 @@ export function tipsToLogin (type) {
|
||||
content: "当前用户未登录是否登录?",
|
||||
confirmText: "确定",
|
||||
cancelText: "取消",
|
||||
confirmColor: Vue.prototype.$mainColor,
|
||||
confirmColor: config.mainColor,
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
navigateToLogin();
|
||||
@@ -426,7 +435,7 @@ export function tipsToLogin (type) {
|
||||
/**
|
||||
* 获取用户信息并重新添加到缓存里面
|
||||
*/
|
||||
export async function userInfo () {
|
||||
export async function refreshUserInfo () {
|
||||
let res = await getUserInfo();
|
||||
if (res.data.success) {
|
||||
storage.setUserInfo(res.data.result);
|
||||
|
||||
@@ -216,8 +216,9 @@ function b64MD5w(str) {
|
||||
/* Backward compatibility */
|
||||
function calcMD5(str) {
|
||||
return binl2hex(coreMD5(str2binl(str)))
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
export const md5 = hexMD5
|
||||
export default {
|
||||
md5: hexMD5
|
||||
}
|
||||
}
|
||||
|
||||
16
utils/mpShare.js
Normal file
16
utils/mpShare.js
Normal file
@@ -0,0 +1,16 @@
|
||||
export default {
|
||||
onLoad() {
|
||||
if (!uni.$u) {
|
||||
uni.$u = {}
|
||||
}
|
||||
uni.$u.mpShare = {
|
||||
title: '',
|
||||
path: '',
|
||||
imageUrl: ''
|
||||
}
|
||||
this.$u.mpShare = uni.$u.mpShare
|
||||
},
|
||||
onShareAppMessage() {
|
||||
return this.$u.mpShare || uni.$u.mpShare
|
||||
}
|
||||
}
|
||||
61
utils/uploadHelper.js
Normal file
61
utils/uploadHelper.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import storage from "@/utils/storage.js";
|
||||
import { upload as uploadUrl } from "@/api/common.js";
|
||||
|
||||
export function getUploadHeader() {
|
||||
return { accessToken: storage.getAccessToken() };
|
||||
}
|
||||
|
||||
export function getUploadedUrls(fileList) {
|
||||
return fileList
|
||||
.filter((item) => item.status === "success" && item.url)
|
||||
.map((item) => item.url);
|
||||
}
|
||||
|
||||
/**
|
||||
* uView Plus u-upload @afterRead handler for lilishop upload API.
|
||||
* Backend returns { result: "fileUrl", ... }.
|
||||
*/
|
||||
export function handleUploadAfterRead(event, fileList, onSuccess) {
|
||||
const files = [].concat(event.file);
|
||||
files.forEach((file) => {
|
||||
const index = fileList.length;
|
||||
fileList.push({
|
||||
...file,
|
||||
status: "uploading",
|
||||
message: "上传中",
|
||||
});
|
||||
uni.uploadFile({
|
||||
url: uploadUrl,
|
||||
filePath: file.url,
|
||||
name: "file",
|
||||
header: getUploadHeader(),
|
||||
success: (res) => {
|
||||
try {
|
||||
const data = JSON.parse(res.data);
|
||||
fileList.splice(index, 1, {
|
||||
...fileList[index],
|
||||
status: "success",
|
||||
message: "",
|
||||
url: data.result,
|
||||
});
|
||||
if (onSuccess) {
|
||||
onSuccess(getUploadedUrls(fileList));
|
||||
}
|
||||
} catch (e) {
|
||||
fileList.splice(index, 1, {
|
||||
...fileList[index],
|
||||
status: "failed",
|
||||
message: "上传失败",
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
fileList.splice(index, 1, {
|
||||
...fileList[index],
|
||||
status: "failed",
|
||||
message: "上传失败",
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -4,7 +4,7 @@
|
||||
// MIT License - http://opensource.org/licenses/mit-license.php
|
||||
|
||||
/*global window, require, define */
|
||||
(function(_window) {
|
||||
var uuid = (function(_window) {
|
||||
'use strict';
|
||||
|
||||
|
||||
@@ -241,22 +241,7 @@
|
||||
uuid._whatwgRNG = _whatwgRNG;
|
||||
|
||||
|
||||
if (('undefined' !== typeof module) && module.exports) {
|
||||
// Publish as node.js module
|
||||
module.exports = uuid;
|
||||
} else if (typeof define === 'function' && define.amd) {
|
||||
// Publish as AMD module
|
||||
define(function() { return uuid; });
|
||||
} else {
|
||||
// Publish as global (in browsers)
|
||||
_previousRoot = _window.uuid;
|
||||
return uuid;
|
||||
})('undefined' !== typeof window ? window : (typeof globalThis !== 'undefined' ? globalThis : {}));
|
||||
|
||||
// **`noConflict()` - (browser only) to reset global 'uuid' var**
|
||||
uuid.noConflict = function() {
|
||||
_window.uuid = _previousRoot;
|
||||
return uuid;
|
||||
};
|
||||
|
||||
_window.uuid = uuid;
|
||||
}
|
||||
})('undefined' !== typeof window ? window : null);
|
||||
export default uuid;
|
||||
Reference in New Issue
Block a user