Commit 0196e2d6 authored by 贾慧斌's avatar 贾慧斌

feat: 羊小咩h5代码测试

parent ff619225
.DS_Store
node_modules/
unpackage/
dist/
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.project
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*
# my-project2
## Project setup
```
yarn install
```
### Compiles and hot-reloads for development
```
yarn serve
```
### Compiles and minifies for production
```
yarn build
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
const webpack = require('webpack')
const plugins = []
if (process.env.UNI_OPT_TREESHAKINGNG) {
plugins.push(require('@dcloudio/vue-cli-plugin-uni-optimize/packages/babel-plugin-uni-api/index.js'))
}
if (
(
process.env.UNI_PLATFORM === 'app-plus' &&
process.env.UNI_USING_V8
) ||
(
process.env.UNI_PLATFORM === 'h5' &&
process.env.UNI_H5_BROWSER === 'builtin'
)
) {
const path = require('path')
const isWin = /^win/.test(process.platform)
const normalizePath = path => (isWin ? path.replace(/\\/g, '/') : path)
const input = normalizePath(process.env.UNI_INPUT_DIR)
try {
plugins.push([
require('@dcloudio/vue-cli-plugin-hbuilderx/packages/babel-plugin-console'),
{
file (file) {
file = normalizePath(file)
if (file.indexOf(input) === 0) {
return path.relative(input, file)
}
return false
}
}
])
} catch (e) { }
}
process.UNI_LIBRARIES = process.UNI_LIBRARIES || ['@dcloudio/uni-ui']
process.UNI_LIBRARIES.forEach(libraryName => {
plugins.push([
'import',
{
'libraryName': libraryName,
'customName': (name) => {
return `${libraryName}/lib/${name}/${name}`
}
}
])
})
if (process.env.UNI_PLATFORM !== 'h5') {
plugins.push('@babel/plugin-transform-runtime')
}
const config = {
presets: [
[
'@vue/app',
{
modules: webpack.version[0] > 4 ? 'auto' : 'commonjs',
useBuiltIns: process.env.UNI_PLATFORM === 'h5' ? 'usage' : 'entry'
}
]
],
plugins
}
const UNI_H5_TEST = '**/@dcloudio/uni-h5/dist/index.umd.min.js'
if (process.env.NODE_ENV === 'production') {
config.overrides = [{
test: UNI_H5_TEST,
compact: true,
}]
} else {
config.ignore = [UNI_H5_TEST]
}
module.exports = config
const { execSync } = require("child_process");
const path = require("path");
const fs = require("fs");
const cmd = `curl -s https://doraemon.quantgroups.cn/ack/namespace/list?env=all`;
const filePath = path.resolve("src/components/qaTool/", "qa.api.js");
function getEnvList() {
const result = JSON.parse(execSync(cmd).toString());
if (result && result.data) {
const esTxt = `/* eslint-disable */\nexport default ${JSON.stringify(result.data)};`;
fs.writeFileSync(filePath, esTxt);
console.log("inject [qaEnvInfo] to src/components/qaTool/qa.api.js");
}
}
module.exports = getEnvList;
const fs = require("fs");
const path = require("path");
const { spawn } = require("child_process");
const inquirer = require("inquirer");
const { createManifestConfig } = require("./manifest");
const getEnvList = require("./getQaInfo");
const CUSTOM_FILE_ROOT = path.join("./customization");
console.log("jhb", path, CUSTOM_FILE_ROOT);
const ENV_MAP = {
dev: "测试",
prod: "生产",
};
const ENV_MENT = {
dev: "dev",
prod: "build",
};
const appIdMap = [];
let optionMap = [];
let envMap = [
{
key: "development",
value: "development",
name: "测试环境",
},
{
key: "pre",
value: "pre",
name: "预发布环境",
},
{
key: "production",
value: "production",
name: "生产环境",
},
];
let currentData = {};
// 选择appid
const getOption = async () => {
const optionInfo = [
{
type: "list",
name: "projectIndex",
default: "",
message: "请选择小程序",
choices: optionMap,
filter(val) {
return val;
},
},
];
return inquirer.prompt(optionInfo);
};
// 选择api env
const setApiEnv = async () => {
const envMapInfo = [
{
type: "list",
name: "projectIndex",
default: "",
message: "请选择接口运行环境",
choices: envMap,
filter(val) {
return val;
},
},
];
return inquirer.prompt(envMapInfo);
};
// 写入配置信息
const setAppConfig = async (config) => {
const configData = config.config || {};
const filePath = path.resolve(process.cwd(), "./src/config/config.json");
let configStr = `${JSON.stringify(configData)}`;
try {
fs.statSync(filePath).isFile();
} catch (err) {
fs.appendFileSync(filePath, configStr);
}
fs.writeFileSync(filePath, configStr, {});
createManifestConfig(
config.config.tenantName,
config.appId,
config.config.mp
);
return config.env;
};
// 获取配置信息
const getAllConfig = async () => {
const dirs = fs.readdirSync(CUSTOM_FILE_ROOT);
dirs.forEach((node) => {
const childrenNode = fs.readdirSync(`${CUSTOM_FILE_ROOT}/${node}`);
if (!childrenNode) return;
childrenNode.forEach((childNode) => {
const basename = path.basename(childNode, ".js").split("-");
appIdMap.push({
appId: basename[1],
env: basename[0],
config: require(path.resolve(
`${CUSTOM_FILE_ROOT}/${node}/${childNode}`
)),
// config: fs.readFileSync(`${CUSTOM_FILE_ROOT}/${node}/${childNode}`, 'utf-8')
});
});
});
optionMap = appIdMap.map((item, index) => {
return {
name: `【${ENV_MAP[item.env]}${item.config.appName}-${
item.config.tenantName
}-${item.appId}`,
value: index,
key: index,
};
});
};
// 执行编译命令
const execShell = (env, apiEnv, mpConfig) => {
process.env.VUE_APP_API_ENV = apiEnv;
const cmdStr = `${process.platform === "win32" ? "npm.cmd" : "npm"} run ${
ENV_MENT[env]
}:${mpConfig.mp}`;
const cmdArr = cmdStr.split(" ");
spawn(cmdArr[0], [cmdArr[1], cmdArr[2]], {
stdio: [2, 2, 2],
});
};
const run = async () => {
await getAllConfig();
const { projectIndex } = await getOption();
currentData = appIdMap;
const selectEnv = await setApiEnv();
const mpConfig = currentData[projectIndex];
const env = await setAppConfig(mpConfig);
getEnvList();
execShell(env, selectEnv.projectIndex, mpConfig.config);
};
run();
const fs = require('fs');
const path = require('path');
const defaultConfig = {
"name" : "羊小咩plus",
"appid" : "wxb3e6270e1b1e0bc7",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
"usingComponents" : true,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"modules" : {},
"distribute" : {
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios" : {},
"sdkConfigs" : {}
}
},
"quickapp" : {},
"mp-weixin" : {
"appid" : "wxb3e6270e1b1e0bc7",
"setting" : {
"urlCheck" : true,
"postcss" : true,
"minified" : true
},
"usingComponents" : true,
"optimization": {
"subPackages": true
},
"permission" : {
"scope.userLocation" : {
"desc" : "授权位置,为您提供更好的服务"
}
},
"requiredPrivateInfos" : [ "getLocation"],
},
"mp-alipay" : {
"usingComponents" : true,
"appid": "2021003126632272",
"enableAppxNg": true
},
"mp-baidu" : {
"usingComponents" : true,
"appid": "25998612",
"optimization": {
"subPackages": true
}
},
"mp-toutiao" : {
"usingComponents" : true
},
"mp-qq" : {
"usingComponents" : true
}
}
const createManifestConfig = function(name = '', appId = '', mp = "mp-weixin") {
const config = Object.assign(defaultConfig, {});
if (name) {
config.name = name;
}
if (appId) {
config.appid = appId;
config[mp].appid = appId;
}
const configStr = JSON.stringify(config);
const filePath = path.resolve(process.cwd(), './src/manifest.json');
try {
fs.statSync(filePath).isFile();
} catch (err) {
fs.appendFileSync(filePath, configStr);
}
fs.writeFileSync(filePath, configStr, {});
}
module.exports = {
createManifestConfig
}
const config = {
mp: "mp-weixin",
qinghai: true,
tenantId: 560867,
tenantName: "青海移动",
vccChannel: 560867002,
appName: "狗大旺",
defaultTitle: "花一得二优选",
logoImg: "https://img.lkbang.net/xcx/logo-qinghai.21de2b.png",
yinSiUrl: "https://page.q-gp.com/hua-yi-de-er-shang-cheng-yin-si-zheng-ce/",
yinSiText: "隐私政策",
zhuCeUrl: "https://page.q-gp.com/hua-yi-de-er-shang-cheng-yong-hu-fu-wu-xie-yi",
zhuCeText: "用户服务协议",
similarList: false,
order: {
cancel: false,
refund: false,
afterSale: false
},
virtualMsg: "请选择虚拟支付!",
templateList: {
SELLER_SHIP: "Y3uSrtVIpm72lk0MoAnAxX5I8rPuVYZZsev82iEkAG4", // 商家发货通知
ORDER_RECEIPT: "gwV9SmC1xLDj7i4FdjK8-nyjVYFh_YIEgjnqz5Lkjco", // 订单签收通知
COUPON_RECEIPT: "CJy2ltIrkoi7X9Jdk7moV6IGCOEgQztuE7EPbXWJ5BU", // 优惠券到账通知
// 以下是新增的团购消息模板
GROUP_BUY_REFUND: "", // 退款通知
GROUP_SUCCESS: "", // 拼团成功
ACTIVITY_START: "", // 活动开始提醒
// 新增订阅节点
PAY_SUCCESS: "", //支付成功
RESULT_NOTICE: "", //审核结果通知
RECEIPT_OPEN_SUCCESS: "" // 发票开具成功提醒
// NEWPRODUCT_NOTICE: "36c1LKstbzyrC1W1mknnnRtNq7_AffQf0-vOMrWANiU" // 新品上架通知
}
};
module.exports = config;
const config = {
mp: "mp-weixin",
qinghai: true,
tenantId: 560867,
tenantName: "青海移动",
appName: "花一得二优选",
vccChannel: 560867002,
defaultTitle: "花一得二优选",
logoImg: "https://img.lkbang.net/xcx/logo-qinghai.21de2b.png",
yinSiUrl: "https://page.q-gp.com/hua-yi-de-er-shang-cheng-yin-si-zheng-ce/",
yinSiText: "隐私政策",
zhuCeUrl: "https://page.q-gp.com/hua-yi-de-er-shang-cheng-yong-hu-fu-wu-xie-yi",
zhuCeText: "用户服务协议",
similarList: false,
order: {
cancel: false,
refund: false,
afterSale: false
},
virtualMsg: "请选择虚拟支付!",
templateList: {
SELLER_SHIP: "q-8zIk5LQF4YcjDqoHRvS10VuGW02tulp7Xa8P_zNpU", // 商家发货通知
ORDER_RECEIPT: "Wz-trJALbJA5f0Wxkq9OgsfESYhHPWg5psVWYV23o2g", // 订单签收通知
COUPON_RECEIPT: "MC2ohZOlhDAHVC3DS5M2LQtToQ4AhatH13E4AcBc6d4", // 优惠券到账通知
// 以下是新增的团购消息模板
GROUP_BUY_REFUND: "", // 退款通知
GROUP_SUCCESS: "", // 拼团成功
ACTIVITY_START: "", // 活动开始提醒
// 新增订阅节点
PAY_SUCCESS: "", //支付成功
RESULT_NOTICE: "", //审核结果通知
RECEIPT_OPEN_SUCCESS: "" // 发票开具成功提醒
}
};
module.exports = config;
const config = require("./dev-wxe16bf9293671506c");
module.exports = Object.assign({}, config, { appName: "支付宝", mp: "mp-alipay" });
const config = require("./dev-wxe16bf9293671506c");
module.exports = Object.assign({}, config, { appName: "百度", mp: "mp-baidu" });
const config = {
mp: "mp-weixin",
yxm: true,
tenantId: 560761,
tenantName: "羊小咩",
appName: "狼大呜",
defaultTitle: "羊小咩",
logoImg: "https://img.lkbang.net/xcx/login-logo2.png",
yinSiUrl: "https://page.q-gp.com/he-tong-yu-lan/?contractTemplateId=8",
yinSiText: "羊小咩用户隐私协议",
zhuCeUrl: "https://page.q-gp.com/he-tong-yu-lan/?contractTemplateId=280",
zhuCeText: "羊小咩注册协议",
tuiJianUrl: "https://mall-qa.liangkebang.net/recommend?vccToken={token}",
tuiJianText: "个性化推荐管理",
similarList: true,
order: {
cancel: true,
refund: true,
afterSale: true
},
virtualMsg: "请选择现金券支付!",
templateList: {
SELLER_SHIP: "1JhEINnMkdCLfEKkBu_g4kBYBwZ5ttdc8wJCHM3rptQ", // 商家发货通知
ORDER_RECEIPT: "yuTVWlf5mfMJ1OdVepV4lNGNlC0ODsuPRKznTQxPUIY", // 订单签收通知
COUPON_RECEIPT: "7O1W4EdNo1CDe7xLCzV7bzzqX57RCjZoibUkwWHx-BE", // 优惠券到账通知
// 以下是新增的团购消息模板
GROUP_BUY_REFUND: "BsS1di1gz_fxCrXYYPjQSw9juezCEhklyuJFwrr81EA", // 退款通知
GROUP_SUCCESS: "jjQDF-xjFGWif1ePik6NsTnHHLYERMvCUjvgUWhZ2iM", // 拼团成功
ACTIVITY_START: "YCLxz0TtrymAOOW74pIEht5dMLBlyI84dHgu-RdVjVw", // 活动开始提醒
// 新增订阅节点
PAY_SUCCESS: "mqriYSvLJO-4QLrQi4h7A00VXp16i1Uyr_1bmkA7POo", //支付成功
RESULT_NOTICE: "GfvGAKzYBotsosAmGF90g_qndPPg_s8X7y31raPDUu4", //审核结果通知
RECEIPT_OPEN_SUCCESS: "zx4AIHgLWV4Ge-ssmrbMsqpj9Ijha7fQREeX5J48lVc" // 发票开具成功提醒
// NEWPRODUCT_NOTICE: "36c1LKstbzyrC1W1mknnnRtNq7_AffQf0-vOMrWANiU" // 新品上架通知
}
};
module.exports = Object.assign({}, config);
const config = require("./prod-wxb3e6270e1b1e0bc7");
module.exports = Object.assign({}, config, { appName: "支付宝", mp: "mp-alipay" });
const config = require("./prod-wxb3e6270e1b1e0bc7");
module.exports = Object.assign({}, config, { appName: "百度", mp: "mp-baidu" });
const config = {
mp: "mp-weixin",
yxm: true,
tenantId: 560761,
tenantName: "羊小咩",
appName: "羊小咩",
defaultTitle: "羊小咩",
logoImg: "https://img.lkbang.net/xcx/login-logo2.png",
yinSiUrl: "https://page.q-gp.com/he-tong-yu-lan/?contractTemplateId=8",
yinSiText: "羊小咩用户隐私协议",
zhuCeUrl: "https://page.q-gp.com/he-tong-yu-lan/?contractTemplateId=280",
zhuCeText: "羊小咩注册协议",
tuiJianUrl: "https://mall.q-gp.com/recommend?vccToken={token}",
tuiJianText: "个性化推荐管理",
similarList: true,
order: {
cancel: true,
refund: true,
afterSale: true
},
virtualMsg: "请选择现金券支付!",
templateList: {
SELLER_SHIP: "_RJyydfzZXkL-Js8oOe592SS6MwDqgl01V60l6Ky-vg", // 商家发货通知
ORDER_RECEIPT: "7FD59HKMBa6y8AP61N9I-ui4Pm7EWy401_Ar_9hlpAw", // 订单签收通知
COUPON_RECEIPT: "6WP-LpbuJ_guHZsdU6nAnIDyf1h6VG5B66FWZPsZW18", // 优惠券到账通知
// 以下是新增的团购消息模板
GROUP_BUY_REFUND: "oF9UpxhnhRTWwmLTODHfXNou8uYZoB6tNRFLsYcdO10", // 退款通知
GROUP_SUCCESS: "vvsh-X1hqHOYvvKd-xE3YAXHt_62_he59iM-6n1Y91s", // 拼团成功
ACTIVITY_START: "eAx92dW4gcm-ZKnm9r_faz3ADopCvq65H5Zm6e615ZU", // 活动开始提醒
// 新增订阅节点
PAY_SUCCESS: "4tO9I3tRhIidvRd-E1i8Nh_r4ykz_NFWCSBP0oV_C8o", //支付成功
RESULT_NOTICE: "I3gcq3_jxn0Jvin_tnhwtVgRhzU2Q9cjqwBbejGMcJI", //审核结果通知
RECEIPT_OPEN_SUCCESS: "k9zsVBbSEmfBPcjN3TxcpDg_sesLnOm9zqROERicOJU" // 发票开具成功提醒
// NEWPRODUCT_NOTICE: "w-nI_Ycw2G36GfLBa0qe-11YAy3mpHNb79X_FwK-U8Y" // 新品上架通知
}
};
module.exports = Object.assign({}, config);
{
"compilerOptions": {
"types": [
"@dcloudio/types",
"miniprogram-api-typings",
"mini-types"
]
}
}
{
"name": "my-project",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "npm run dev:h5",
"build": "npm run build:h5",
"build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build",
"build:custom": "cross-env NODE_ENV=production uniapp-cli custom",
"build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
"build:mp-360": "cross-env NODE_ENV=production UNI_PLATFORM=mp-360 vue-cli-service uni-build",
"build:mp-alipay": "cross-env NODE_ENV=production UNI_PLATFORM=mp-alipay vue-cli-service uni-build",
"build:mp-baidu": "cross-env NODE_ENV=production UNI_PLATFORM=mp-baidu vue-cli-service uni-build",
"build:mp-jd": "cross-env NODE_ENV=production UNI_PLATFORM=mp-jd vue-cli-service uni-build",
"build:mp-kuaishou": "cross-env NODE_ENV=production UNI_PLATFORM=mp-kuaishou vue-cli-service uni-build",
"build:mp-lark": "cross-env NODE_ENV=production UNI_PLATFORM=mp-lark vue-cli-service uni-build",
"build:mp-qq": "cross-env NODE_ENV=production UNI_PLATFORM=mp-qq vue-cli-service uni-build",
"build:mp-toutiao": "cross-env NODE_ENV=production UNI_PLATFORM=mp-toutiao vue-cli-service uni-build",
"build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",
"build:mp-xhs": "cross-env NODE_ENV=production UNI_PLATFORM=mp-xhs vue-cli-service uni-build",
"build:quickapp-native": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-native vue-cli-service uni-build",
"build:quickapp-webview": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview vue-cli-service uni-build",
"build:quickapp-webview-huawei": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build",
"build:quickapp-webview-union": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build",
"dev:app-plus": "cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch",
"dev:custom": "cross-env NODE_ENV=development uniapp-cli custom",
"dev:h5": "cross-env VUE_APP_API_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-serve",
"dev:mp-360": "cross-env NODE_ENV=development UNI_PLATFORM=mp-360 vue-cli-service uni-build --watch",
"dev:mp-alipay": "cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch",
"dev:mp-baidu": "cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch",
"dev:mp-jd": "cross-env NODE_ENV=development UNI_PLATFORM=mp-jd vue-cli-service uni-build --watch",
"dev:mp-kuaishou": "cross-env NODE_ENV=development UNI_PLATFORM=mp-kuaishou vue-cli-service uni-build --watch",
"dev:mp-lark": "cross-env NODE_ENV=development UNI_PLATFORM=mp-lark vue-cli-service uni-build --watch",
"dev:mp-qq": "cross-env NODE_ENV=development UNI_PLATFORM=mp-qq vue-cli-service uni-build --watch",
"dev:mp-toutiao": "cross-env NODE_ENV=development UNI_PLATFORM=mp-toutiao vue-cli-service uni-build --watch",
"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch",
"dev:mp-xhs": "cross-env NODE_ENV=development UNI_PLATFORM=mp-xhs vue-cli-service uni-build --watch",
"dev:quickapp-native": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-native vue-cli-service uni-build --watch",
"dev:quickapp-webview": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview vue-cli-service uni-build --watch",
"dev:quickapp-webview-huawei": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build --watch",
"dev:quickapp-webview-union": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build --watch",
"info": "node node_modules/@dcloudio/vue-cli-plugin-uni/commands/info.js",
"serve:quickapp-native": "node node_modules/@dcloudio/uni-quickapp-native/bin/serve.js",
"test:android": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=android jest -i",
"test:h5": "cross-env UNI_PLATFORM=h5 jest -i",
"test:ios": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=ios jest -i",
"test:mp-baidu": "cross-env UNI_PLATFORM=mp-baidu jest -i",
"test:mp-weixin": "cross-env UNI_PLATFORM=mp-weixin jest -i",
"start": "node build/index.js"
},
"dependencies": {
"@dcloudio/uni-app": "^2.0.2-3061820230117002",
"@dcloudio/uni-app-plus": "^2.0.2-3061820230117002",
"@dcloudio/uni-h5": "^2.0.2-3061820230117002",
"@dcloudio/uni-i18n": "^2.0.2-3061820230117002",
"@dcloudio/uni-mp-360": "^2.0.2-3061820230117002",
"@dcloudio/uni-mp-alipay": "^2.0.2-3061820230117002",
"@dcloudio/uni-mp-baidu": "^2.0.2-3061820230117002",
"@dcloudio/uni-mp-jd": "^2.0.2-3061820230117002",
"@dcloudio/uni-mp-kuaishou": "^2.0.2-3061820230117002",
"@dcloudio/uni-mp-lark": "^2.0.2-3061820230117002",
"@dcloudio/uni-mp-qq": "^2.0.2-3061820230117002",
"@dcloudio/uni-mp-toutiao": "^2.0.2-3061820230117002",
"@dcloudio/uni-mp-vue": "^2.0.2-3061820230117002",
"@dcloudio/uni-mp-weixin": "^2.0.2-3061820230117002",
"@dcloudio/uni-mp-xhs": "^2.0.2-3061820230117002",
"@dcloudio/uni-quickapp-native": "^2.0.2-3061820230117002",
"@dcloudio/uni-quickapp-webview": "^2.0.2-3061820230117002",
"@dcloudio/uni-stacktracey": "^2.0.2-3061820230117002",
"@dcloudio/uni-stat": "^2.0.2-3061820230117002",
"@dcloudio/uni-ui": "^1.4.26",
"sa-sdk-alipaymini": "^1.2.0",
"sa-sdk-miniprogram": "^1.14.5",
"sa-sdk-javascript": "^1.14.5",
"sa-sdk-smartprogram": "0.4.0-rc",
"uuid": "3.4.0",
"@vue/shared": "^3.0.0",
"core-js": "^3.8.3",
"flyio": "^0.6.2",
"vue": ">= 2.6.14 < 2.7",
"vuex": "^3.2.0"
},
"devDependencies": {
"@dcloudio/types": "^3.3.2",
"@dcloudio/uni-automator": "^2.0.2-3061820230117002",
"@dcloudio/uni-cli-i18n": "^2.0.2-3061820230117002",
"@dcloudio/uni-cli-shared": "^2.0.2-3061820230117002",
"@dcloudio/uni-helper-json": "*",
"@dcloudio/uni-migration": "^2.0.2-3061820230117002",
"@dcloudio/uni-template-compiler": "^2.0.2-3061820230117002",
"@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.2-3061820230117002",
"@dcloudio/vue-cli-plugin-uni": "^2.0.2-3061820230117002",
"@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.2-3061820230117002",
"@dcloudio/webpack-uni-mp-loader": "^2.0.2-3061820230117002",
"@vue/cli-plugin-babel": "~5.0.0",
"@dcloudio/webpack-uni-pages-loader": "^2.0.2-3061820230117002",
"@vue/cli-service": "~5.0.0",
"babel-plugin-import": "^1.11.0",
"cross-env": "^7.0.2",
"jest": "^25.4.0",
"mini-types": "*",
"miniprogram-api-typings": "*",
"postcss-comment": "^2.0.0",
"sass": "^1.49.8",
"sass-loader": "^8.0.2",
"vue-template-compiler": ">= 2.6.14 < 2.7",
"inquirer": "^8.2.0"
},
"browserslist": [
"Android >= 4.4",
"ios >= 9"
],
"uni-app": {
"scripts": {}
}
}
const path = require('path')
const webpack = require('webpack')
const config = {
parser: require('postcss-comment'),
plugins: [
require('postcss-import')({
resolve (id, basedir, importOptions) {
if (id.startsWith('~@/')) {
return path.resolve(process.env.UNI_INPUT_DIR, id.substr(3))
} else if (id.startsWith('@/')) {
return path.resolve(process.env.UNI_INPUT_DIR, id.substr(2))
} else if (id.startsWith('/') && !id.startsWith('//')) {
return path.resolve(process.env.UNI_INPUT_DIR, id.substr(1))
}
return id
}
}),
require('autoprefixer')({
remove: process.env.UNI_PLATFORM !== 'h5'
}),
require('@dcloudio/vue-cli-plugin-uni/packages/postcss')
]
}
if (webpack.version[0] > 4) {
delete config.parser
}
module.exports = config
import Vue from 'vue'
declare module "vue/types/options" {
type Hooks = App.AppInstance & Page.PageInstance;
interface ComponentOptions<V extends Vue> extends Hooks {
/**
* 组件类型
*/
mpType?: string;
}
}
\ No newline at end of file
declare module "*.vue" {
import Vue from 'vue'
export default Vue
}
\ No newline at end of file
<script>
/**
* vuex管理登陆状态,具体可以参考官方登陆模板示例
*/
import { mapMutations, mapActions } from "vuex";
import request from "./utils/request";
// #ifdef MP-WEIXIN
import SMSdk from "./utils/shumei";
// #endif
import { onLaunchSubmit } from "@/utils/subscribe";
import cfg from "@/config/index";
import appIdMap from "@/config/appId.config";
import config from "@/config/config.json";
import { saTrackEvent } from "@/utils/sa.js";
import { param2Obj } from "@/utils/index";
import { uploadSMDeviceID } from "@/api/home.api";
export default {
globalData: {
...config
},
methods: {
...mapMutations(["login"]),
...mapActions({
setGDTVID: "setGDTVID"
})
},
// #ifdef MP-WEIXIN
SMSdk,
// #endif
onLaunch: async function() {
let appId;
let smDeviceId=""
// #ifdef MP-WEIXIN
smDeviceId = await SMSdk.SMSdk.getDeviceId();
// #endif
console.log("smDeviceId = ", smDeviceId);
uni.setStorageSync("smDeviceId", smDeviceId || "");
if (smDeviceId) {
const [shumeiKey] = await uploadSMDeviceID({
shumeiDeviceId: smDeviceId
});
console.log("shumeiKey after kdsp redis = ", shumeiKey);
if (shumeiKey) {
uni.setStorageSync("shumeiKey", shumeiKey);
}
}
// #ifdef MP-ALIPAY
appId = uni.getAppIdSync().appId;
// #endif
// #ifndef MP-ALIPAY || H5
const accountInfo = uni.getAccountInfoSync();
appId = accountInfo.miniProgram.appId;
// #endif
const tenantBasicInfo = appIdMap[appId] || {};
uni.setStorageSync("appId", appId);
uni.setStorageSync("tenantId", tenantBasicInfo.tenantId || 560761);
uni.setStorageSync("tenantBasicInfo", tenantBasicInfo);
tenantBasicInfo.vccChannel && uni.setStorageSync("vccChannel", tenantBasicInfo.vccChannel);
console.log("jhb cfg",cfg)
this.$ry?.init(cfg.REYUN_APP_KEY);
// todo
if (appId === "wxe16bf9293671506c" && process.env.NODE_ENV === "production") {
//wxe16bf9293671506c 测试环境appid
let [data] = await request.get("https://talos.xyqb.com/api/kdsp/miniapp/getData");
uni.setStorageSync("url", data);
} else {
uni.removeStorageSync("url");
}
let userInfo = uni.getStorageSync("userInfo") || "";
if (userInfo?.id) {
//更新登陆状态
uni.getStorage({
key: "userInfo",
success: res => {
this.login(res.data);
}
});
}
// #ifdef MP-WEIXIN
onLaunchSubmit();
// #endif
},
onShow: function(option) {
// #ifdef MP-WEIXIN
// 存储腾讯广告id
const { query } = option;
if (query && query.gdt_vid) {
// store存储gdt_vid以便后续登录拿到openid后使用
this.setGDTVID(query.gdt_vid);
}
//新版本更新
if (uni.canIUse("getUpdateManager")) {
//判断当前微信版本是否支持版本更新
const updateManager = uni.getUpdateManager();
updateManager.onCheckForUpdate(function(res) {
if (res.hasUpdate) {
// 请求完新版本信息的回调
updateManager.onUpdateReady(function() {
uni.showModal({
title: "更新提示",
content: "新版本已经准备好,是否重启应用?",
success: function(res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
}
}
});
});
updateManager.onUpdateFailed(function() {
uni.showModal({
// 新的版本下载失败
title: "已经有新版本了哟~",
content: "新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~"
});
});
}
});
} else {
uni.showModal({
// 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
title: "提示",
content: "当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。"
});
}
// #endif
// #ifndef MP-ALIPAY || H5
uni.onAppShow(obj => {
const TPL_TITLE = "tplTitle";
const tplTitle = param2Obj(obj.path)[TPL_TITLE] || obj.query[TPL_TITLE];
if ((obj.scene === 1014 || obj.scene === 1107) && tplTitle) {
saTrackEvent("MINI_SubscribeMessageCardBtnClick", {
cards_name: tplTitle
});
}
});
// #endif
},
onHide: function() {
console.log("App Hide");
}
};
</script>
<style lang="scss">
@import "@/style/icon.scss";
@import "@/style/uni-ui.scss";
page {
background: $page-color-base;
height: 100%;
/* #ifdef MP-ALIPAY */
/* width: 100%;
position: fixed;
top: 0;
bottom: 0; */
/* #endif */
}
view,
scroll-view,
swiper,
swiper-item,
cover-view,
cover-image,
icon,
text,
rich-text,
progress,
button,
checkbox,
form,
input,
label,
radio,
slider,
switch,
textarea,
navigator,
audio,
camera,
image,
video {
box-sizing: border-box;
}
/* 骨架屏替代方案 */
.Skeleton {
background: #f3f3f3;
padding: 20rpx 0;
border-radius: 8rpx;
}
/* 图片载入替代方案 */
.image-wrapper {
font-size: 0;
background: #f3f3f3;
border-radius: 4px;
image {
width: 100%;
height: 100%;
transition: 0.6s;
opacity: 0;
&.loaded {
opacity: 1;
}
}
}
.clamp {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: block;
}
.common-hover {
background: #f5f5f5;
}
/*边框*/
.b-b:after,
.b-t:after {
position: absolute;
z-index: 3;
left: 0;
right: 0;
height: 0;
content: "";
transform: scaleY(0.5);
border-bottom: 1px solid $border-color-base;
}
.b-b:after {
bottom: 0;
}
.b-t:after {
top: 0;
}
/* button样式改写 */
uni-button,
button {
height: 80rpx;
line-height: 80rpx;
font-size: $font-lg + 2rpx;
font-weight: normal;
&.no-border:before,
&.no-border:after {
border: 0;
}
}
uni-button[type="default"],
button[type="default"] {
color: $font-color-dark;
}
/* input 样式 */
.placeholder {
font-size: 28rpx;
line-height: 40rpx;
color: #999999;
}
button::after {
display: none;
}
/* requestRevokeTest test */
</style>
import request from "../utils/request";
import config from "@/config";
const { kdspApi } = config;
export default {
saveGDTVID(data) {
return request.post(`${kdspApi}/api/kdsp/minipro/setRedisClick`, data);
},
getGDTVID(data) {
return request.get(`${kdspApi}/api/kdsp/minipro/getRedisClick?wechatOpenId=${data}`);
},
uploadAdData(data) {
return request.post(`${kdspApi}/api/kdsp/minipro/addUserAction`, data);
},
createOrderRecord(data) {
return request.post(`${kdspApi}/api/kdsp/minipro/addClickRequest`, data);
}
};
import request from "../utils/request";
import config from "@/config";
const { yxmGateway } = config;
export default {
addProduct(data) {
return request.post(`${yxmGateway}/api/kdsp/shop-cart/add-update`, data);
}
};
import request from "../utils/request";
import config from "@/config";
import { mpConfig } from "@/utils/mpConfig/types";
const { talosApi, yxmGateway } = config;
export default {
// 提现
cashOut(data) {
return request.get(`${talosApi}/vcc/xyqb/mineMini`, data);
},
// 物流信息
orderLogistics(data) {
return request.get(`${yxmGateway}/api/kdsp/logistics/list`, data);
},
// 用户订单确认收货接口
orderConfirm(data) {
return request.post(`${yxmGateway}/api/kdsp/order-info/receipt/confirm`, data);
},
// 用户订单取消接口【未付款】
orderCancel(data) {
return request.post(`${yxmGateway}/api/kdsp/order-info/cancel`, data);
},
// 用户订单取消接口【已付款】
orderUnfilledCancel(data) {
return request.get(`${yxmGateway}/api/kdsp/order-info/unfilled/cancel`, data);
},
// 用户订单取消接口【已付款】
orderUnfilledCancelV2(data) {
return request.get(`${yxmGateway}/api/kdsp/order-info/unfilled/cancel/v2`, data);
},
// 订单取消原因查询接口
orderCancelList(data) {
return request.get(`${yxmGateway}/api/kdsp/order-info/cancel-reason/query`, data);
},
// 订单取消原因查询接口
orderCancelListV2(data) {
return request.get(`${yxmGateway}/api/kdsp/order-info/paid-cancel-props/query`, data, {
hideToast: true
});
},
// 已发货申请退款催办接口
orderRemindCancel(data) {
return request.get(`${yxmGateway}/api/kdsp/order-info/remindCancel`, data);
},
// 撤销取消订单申请
cancelRevoke(data) {
return request.get(`${yxmGateway}/api/kdsp/order-info/unfilled/cancel-revoke`, data);
},
// 取消/售后,获取是否需要签订合同
orderQueryNote(data) {
return request.get(`${yxmGateway}/api/kdsp/order-info/queryNote`, data);
},
// 订单详情查询接口
orderDetail(data) {
return request.get(`${yxmGateway}/api/kdsp/order-info/detail/query`, data);
},
// 用户订单列表查询接口
orderList(data) {
return request.get(`${yxmGateway}/api/kdsp/order-info/list/query`, data, {
hideLoading: true
});
},
// 获取信用钱包用户信息
xhkInfo(data) {
return request.get(`${yxmGateway}/api/kdsp/profile/vcc/user-account`, data);
},
// 我的 查询各状态订单数量
orderInfo(data) {
return request.get(`${yxmGateway}/api/kdsp/order-info/status-number`, data);
},
// 微信小程序登录
login(data) {
return request.post(`${yxmGateway}${mpConfig.loginUrl}`, data, {
emulateFormData: true
});
},
// 注册
register(data) {
// 登录接口添加utm_source
getCurrentPages().forEach(item => {
if (item.options?.utm_source) {
data.utm_source = item.options?.utm_source;
}
});
return request.post(`${yxmGateway}${mpConfig.registerUrl}`, data);
},
getAvatar(data) {
return request.post(`${yxmGateway}/api/kdsp/wx/mini-app/avatar`, data);
},
loadArea(id = "") {
return request.get(`${yxmGateway}/api/kdsp/addr/query?addrId=${id}`);
},
saveAddress(data) {
return request.post(`${yxmGateway}/api/kdsp/addr/receiver/add_edit`, data);
},
getAddressList() {
return request.get(`${yxmGateway}/api/kdsp/addr/receiver/list`);
},
deleteAddress(addrReceiverId) {
return request.post(`${yxmGateway}/api/kdsp/addr/receiver/delete`, {
addrReceiverId
});
},
apiTest(data) {
return request.get(`${talosApi}/activity/commonly/free-goods/list`, data);
},
// 获取首页活动弹窗
getUserPopup() {
return request.get(
`${yxmGateway}/api/kdsp/app-config-push/profile/popup`,
{
page: "profile"
},
{
hideLoading: true
}
);
},
// 注销登录
logout(data) {
return request.post(`${yxmGateway}/api/kdsp/user/user-logged-off`, data);
},
// 退出登录
logoutUser(data) {
return request.post(`${yxmGateway}/api/kdsp/logout/user`, data);
}
};
import request from "../utils/request";
import config from "@/config";
const { yxmGateway } = config;
const submit = function(data) {
return request.post(`${yxmGateway}/api/kdsp/order-info/apply-refund`, data);
};
export { submit };
import request from "../utils/request";
import config from "@/config";
const { yxmGateway } = config;
export const getCouponList = params => {
return request.get(`${yxmGateway}/api/kdsp/coupon/user-coupons`, params, {
hideLoading: true
});
};
// // 我的礼品卡
export const getGiftCardList = function(data) {
return request.post(`${yxmGateway}/api/kdsp/card/list`, data, {
hideLoading: true
});
};
export const exchange = params => {
return request.post(`${yxmGateway}/api/kdsp/coupon/pickup-code`, params, {
reportDeviceId: true
});
};
export const getCouponDesc = () => {
return request.get(`${yxmGateway}/api/kdsp/coupon/getDescriptionOfExchangeCode`);
};
import request from "../utils/request";
import config from "@/config";
const { vccHost, yxmGateway } = config;
// 查询活体认证url
const getFaceUrl = function(token, from, orderNo) {
const callBackUrl = orderNo
? vccHost + token + "&fromXcxPage=" + from + "&orderNo=" + orderNo
: vccHost + token + "&fromXcxPage=" + from;
return request.get(`${yxmGateway}/api/kdsp/face/h5/face-url`, {
callBackUrl: callBackUrl
});
};
// const getNextUrl = function() {
// return request.get(`${talosApi}/vcc/xyqb_mall/credit_url`);
// };
// const getNextUrlKa = function(data) {
// return request.get(`${yxmGateway}/api/kdsp/ka/process/get-next-url`, data);
// };
export { getFaceUrl };
/* eslint-disable space-before-function-paren */
/* eslint-disable prettier/prettier */
import request from "../utils/request";
import config from "@/config";
const { yxmGateway } = config;
// 获取banner
const getBanner = function (data) {
///appconfig/home/topinfo
const page = "home";
return request.get(`${yxmGateway}/api/kdsp/appconfig/${page}/topinfo`, data, {
hideLoading: true
});
};
//获取动态内容【金刚区、运营专区等】【金刚区、运营专区-横向,运营专区-竖向, 通栏】
const getContent = function (data) {
//页面:home-精选,discovery-发现,profile-我的
const page = "home";
return request.get(`${yxmGateway}/api/kdsp/appconfig/${page}/content`, data, {
hideLoading: true
});
};
// 主页底纹词
const getSearchBorderTxt = function (data) {
const page = "home";
return request.get(`${yxmGateway}/api/kdsp/appconfig/${page}/border`, data, {
hideLoading: true
});
};
// 主页猜你喜欢列表
const getGoodsList = function (data) {
const tenantId = +uni.getStorageSync("tenantId");
if (tenantId === 560867) {
// 青海移动
return request.get(`${yxmGateway}/api/kdsp/recommend/goods-list`, data, {
needScDeviceId: true,
hideLoading: true
});
} else {
// 羊小咩
// return request.get(`${talosApi}/vcc/xyqb/recommend/goods-list`, data, {
return request.get(`${yxmGateway}/api/kdsp/recommend/goods-list`, data, {
needScDeviceId: true,
hideLoading: true
});
}
};
const homeSearch = function (data, loading = true) {
return request.post(`${yxmGateway}/api/kdsp/search/result`, data, {
needScDeviceId: true,
hideLoading: loading
});
};
const getActivityInfo = function (data) {
return request.post(`${yxmGateway}/api/kdsp/search/result/fee/calc`, data, {
needScDeviceId: true,
hideLoading: true
});
};
const landingSearch = function (data) {
return request.post(`${yxmGateway}/api/kdsp/search/result`, data, {
needScDeviceId: true,
hideLoading: true
});
};
// 搜索--大家都在搜的关键词
const getTerms = function (data) {
// return request.get(`${talosApi}/vcc/app/mall/search/page`, data);
return request.get(`${yxmGateway}/api/kdsp/search/page`, data);
};
// 商品详情页是否放开立即购买
///api/kdsp/order-info/miniOrder/hasOrder
const hasOrder = function (data) {
return request.get(`${yxmGateway}/api/kdsp/order-info/miniOrder/hasOrder`, data);
};
// 详情页基本信息--/api/kdsp/sku-info/detail/query
const detailInfo = function (data) {
// return request.get('http://yapi.quantgroups.com/mock/351/api/kdsp/sku-info/detail/query')
return request.get(`${yxmGateway}/api/kdsp/sku-info/detail/query`, data);
};
// 详情页-猜你喜欢 /vcc/xyqb/recommend/like
const goodsLike = function (data) {
// return request.get(`${talosApi}/vcc/xyqb/jd/recommend/like`, data, {
return request.get(`${yxmGateway}/api/kdsp/recommend/goods-detail/similarity`, data, {
needScDeviceId: true,
hideLoading: true
});
};
const shopCartLike = function (data) {
// return request.get(`${talosApi}/vcc/xyqb/jd/recommend/like`, data, {
return request.get(`${yxmGateway}/api/kdsp/recommend/goods-list`, data, {
needScDeviceId: true,
hideLoading: true
});
};
// 商品详情地址列表
const addrList = function (data) {
return request.get(`${yxmGateway}/api/kdsp/addr/receiver/list`, data, {
hideLoading: true
});
};
// 商品详情优惠券列表
const getCouponList = function (data) {
return request.get(`${yxmGateway}/api/kdsp/coupon/user-pickup`, data);
};
// 查询用户优惠券选择查询接口
const getCouponChooseList = function (data) {
return request.post(`${yxmGateway}/api/kdsp/coupon/activity/choose-list`, data);
};
// 商品详情--领取优惠券 /api/kdsp/coupon/user-pickup
const userPickupCoupon = function (data) {
return request.post(`${yxmGateway}/api/kdsp/coupon/pickup`, data, {
hideLoading: true,
reportDeviceId: true
});
};
// 获取首页活动弹窗
const getHomePopup = function () {
return request.get(
`${yxmGateway}/api/kdsp/app-config-push/home/popup`,
{
page: "home"
},
{
hideLoading: true
}
);
};
// 上报活动弹窗
const uploadPopup = function (data) {
return request.post(`${yxmGateway}/api/kdsp/app-config-push/report/notice`, data, {
hideLoading: true
});
};
const getVaildSubTmplIds = async tmplIds => {
const res = await wx.getSetting({
withSubscriptions: true
});
let {
subscriptionsSetting: { mainSwitch, itemSettings }
} = res;
if (mainSwitch) {
itemSettings = itemSettings || {};
const vaildTmplIds = tmplIds.filter(
item => !itemSettings[item] || itemSettings[item] !== "ban"
);
return vaildTmplIds;
}
};
const subscribe = async data => {
return request.post(`${yxmGateway}/api/kdsp/group-msg/subscribe`, data, {
hideLoading: true
});
};
const addSkuToCart = function (data) {
return request.post(`${yxmGateway}/api/kdsp/shop-cart/add-update`, data, {
hideLoading: true
});
};
// 获取购物车商品数量
const getCartCount = function () {
return request.get(
`${yxmGateway}/api/kdsp/shop-cart/count`,
{},
{
hideLoading: true
}
);
};
// 无效商品列表
const getInvalidList = function (data) {
return request.post(`${yxmGateway}/api/kdsp/shop-cart/list/invalid`, data, {
hideLoading: true
});
};
// 青海获取礼品卡余额接口
const getGiftCard = () => {
return request.get(`${yxmGateway}/api/kdsp/user/card-coupon`);
};
// 上报数据
const importOpenId = function (data) {
return request.post(`${yxmGateway}/api/kdsp/miniapp/saveWechatAppletInfo`, data, {
hideLoading: true,
hideToast: true
});
};
// 获取卡包部分信息(羊小咩)
const getWalletInfo = function () {
return request.get(`${yxmGateway}/api/kdsp/user/mine/my-wallet`, {
hideLoading: true,
hideToast: true
});
};
const getFincialData = () => {
return request.get(`${yxmGateway}/api/kdsp/miniapp/jump/vcc/mini`,
{},
{
header: {
appChannel: 'miniapp',
appName: "xinyongqianbao",
userId: uni.getStorageSync("userAuthInfo").userId,
uuid: uni.getStorageSync("userAuthInfo").uuid
}
}
);
};
const getSchemaCode = params => {
return request.post(`${yxmGateway}/api/kdsp/miniapp/jump/vcc/mini/schema/code`, params,
{
header: {
appName: "xinyongqianbao",
userId: uni.getStorageSync("userAuthInfo").userId,
uuid: uni.getStorageSync("userAuthInfo").uuid
}
});
};
const getContract = () => {
return request.get(`${yxmGateway}/api/kdsp/contract/view`);
}
const smEvent = data => {
return request.post(`${yxmGateway}/api/kdsp/shumei/eventDataServer/report`, data);
};
// kdsp存数美设备id
const uploadSMDeviceID = data => {
return request.post(`${yxmGateway}/api/kdsp/fraud/borderColor`, data);
};
export {
getSearchBorderTxt,
getBanner,
getContent,
getGoodsList,
homeSearch,
getActivityInfo,
getTerms,
hasOrder,
detailInfo,
addrList,
getCouponList,
getCouponChooseList,
userPickupCoupon,
goodsLike,
landingSearch,
getCartCount,
addSkuToCart,
getInvalidList,
getHomePopup,
getVaildSubTmplIds,
uploadPopup,
subscribe,
shopCartLike,
getGiftCard,
importOpenId,
getWalletInfo,
getFincialData,
getSchemaCode,
getContract,
smEvent,
uploadSMDeviceID
};
import request from "../utils/request";
import config from "@/config";
const { yxmGateway } = config;
// 根据id查询优惠券列表
const couponList = function(data) {
return request.get(`${yxmGateway}/api/kdsp/coupon/h5-qb/list`, data);
};
// 用户领取优惠券接口-批量
const couponPickup = function(data) {
return request.post(`${yxmGateway}/api/kdsp/coupon/pickup-batch`, data, {
reportDeviceId: true
});
};
// 搜索接口_result
const searchGoodsList = function(data) {
return request.post(`${yxmGateway}/api/kdsp/search/result`, data);
};
// 用户领取优惠券状态查询
const searchCoupon = function(data) {
return request.get(`${yxmGateway}/api/kdsp/coupon/pickup-status`, data);
};
// KA流程节点
const kaGetNextUrl = function(data) {
let options = {
sonVccChannel: true
};
return request.get(`${yxmGateway}/api/kdsp/ka/process/get-next-url`, data, options);
};
// KA流程节点_查询流程是否走完
const kaFlow = function(data) {
let options = {
sonVccChannel: true
};
return request.get(`${yxmGateway}/api/kdsp/ka/process/get-status`, data, options);
};
// 流程节点_返回商品页面临时支持1个月(高价)
const lableInfoIdsExpensive = function(data) {
return request.get(`${yxmGateway}/api/kdsp/ka/process/get-landing-page-temp`, data);
};
// 获取ka配置
const getKaData = function(data) {
return request.get(`${yxmGateway}/api/kdsp/ka/info/getDetail`, data);
};
// 验证是否是白名单
const getWhiteUser = function(data) {
return request.get(`${yxmGateway}/api/kdsp/ka/user/getWhiteUser`, data);
};
// 根据md5获取百人团url
const getGroupBuyUrl = function(m) {
return request.get(`${yxmGateway}/api/kdsp/playBill/getPlayBillUrl?m=${m}`);
};
export {
searchCoupon,
couponList,
couponPickup,
searchGoodsList,
kaGetNextUrl,
kaFlow,
lableInfoIdsExpensive,
getKaData,
getWhiteUser,
getGroupBuyUrl
};
import request from "../utils/request";
import config from "@/config";
const { yxmGateway } = config;
// let kdspApi = "http://yapi.quantgroups.com/mock/351";
// 我的页面查询会员、优惠券信息
// 接口存在与app显示不一致情况,该接口提升version
const queryMemberAndCouponInfo = () => {
// return request.get(
// "http://yapi.quantgroups.com/mock/351/api/kdsp/userBenefits/getCurrentLevelInfo"
// );
return request.get(
`${yxmGateway}/api/kdsp/userBenefits/getCurrentLevelInfo`,
{},
{
header: {
version: "8.6.00"
}
}
);
};
// 会员中心查询
const queryMemberCenterInfo = () => {
return request.get(
`${yxmGateway}/api/kdsp/userBenefits/center/getUserCenterInfo`,
{},
{
header: {
version: "8.6.00"
}
}
);
};
// 获取用户会员权益明细
const queryMemberBenefitsDetail = () => {
return request.get(
`${yxmGateway}/api/kdsp/userBenefits/rewardDetail/getBenefitsDetail`,
{},
{
header: {
version: "8.6.00"
}
}
);
};
// 获取用户会员权益值列表
const queryBenefitsDiscountDetail = data => {
return request.get(
`${yxmGateway}/api/kdsp/userBenefitsDiscountDetail/getBenefitsDiscountDetail`,
data,
{
header: {
version: "8.6.00"
}
}
);
// return request.get(
// `http://yapi.quantgroups.com/mock/351/api/kdsp/userBenefitsDiscountDetail/getBenefitsDiscountDetail`,
// data
// );
};
// 获取成长值信息
const queryPointDetail = () => {
return request.get(`${yxmGateway}/api/kdsp/userBenefits/getPointDetail`);
};
// 成长值(积分)列表
const getBenefitsDetail = () => {
return request.get(`${yxmGateway}/api/kdsp/userBenefitsDetail/getBenefitsDetail`);
};
// 获取礼品卡消费记录
const getConsumptions = params => {
return request.post(`${yxmGateway}/api/kdsp/card/io`, params);
};
// 领取优惠券
const pickupCoupon = params => {
return request.post(`${yxmGateway}/api/kdsp/coupon/pickup-batch`, params, {
reportDeviceId: true
});
};
export {
queryMemberAndCouponInfo,
queryMemberBenefitsDetail,
queryPointDetail,
queryMemberCenterInfo,
getConsumptions,
pickupCoupon,
queryBenefitsDiscountDetail,
getBenefitsDetail
};
import request from "../utils/request";
import config from "@/config";
const { yxmGateway, SHARE_CHANNEL } = config;
export const confirmOrder = data => {
return request.post(`${yxmGateway}/api/kdsp/shop-cart/order-confirm/page/v2`, data);
};
export const orderSubmit = data => {
const options = {
encrypt: true
};
// #ifdef MP-WEIXIN
const sceneList = [1007, 1008, 1011, 1012, 1013, 1036, 1044, 1047, 1048, 1049, 1058];
const currentScene = wx.getEnterOptionsSync().scene;
if (sceneList.indexOf(currentScene) > -1) {
options.customizeChannel = SHARE_CHANNEL;
}
// #endif
return request.post(`${yxmGateway}/api/kdsp/order-info/e/submit`, data, options);
};
// 校验手机号是否为 推广员手机号
export const checkPromoterByMobile = phone => {
return request.get(`${yxmGateway}/api/kdsp/self-mention/checkPromoterByMobile?phoneNo=${phone}`);
};
import request from "../utils/request";
import config from "@/config";
const { talosApi, yxmGateway } = config;
// const yapiHost = "http://yapi.quantgroups.com/mock/499";
const queryPayInfo = function(data) {
// return request.post("http://yapi.quantgroups.com/mock/410/open/checkout", data);
return request.post(`${talosApi}/open/checkout`, data, {
hideToast: true
});
};
const prepay = function(data) {
const tenantId = +uni.getStorageSync("tenantId");
if (tenantId === 560761) {
return request.post(`${talosApi}/open/checkout/v2/prepay`, data);
} else {
return request.post(`${talosApi}/open/checkout/prepay`, data);
}
};
const pay = function(data) {
const tenantId = +uni.getStorageSync("tenantId");
if (tenantId === 560761) {
return request.post(`${talosApi}/open/checkout/v2/pay`, data, {
needScDeviceId: true
});
} else {
return request.post(`${talosApi}/open/checkout/pay`, data, {
needScDeviceId: true
});
}
};
const queryPayStatus = function(data) {
const tenantId = +uni.getStorageSync("tenantId");
if (tenantId === 560761) {
return request.post(`${talosApi}/open/checkout/v2/pay_status/query`, data);
} else {
return request.post(`${talosApi}/open/checkout/pay_status/query`, data);
}
};
const sendSms = function(data) {
return request.post(`${talosApi}/open/checkout/send_sms`, data);
};
const desSalt = function() {
return request.get(`${talosApi}/vcc/account/salt`);
};
const h5AppyUrl = function() {
return request.get(`${talosApi}/vcc/xyqb_mall/app_url`);
};
const getCoupon = function(params) {
// return request.post(`http://yapi.quantgroups.com/mock/499/x/checkout/pay_coupon_list`, params);
return request.post(`${talosApi}/open/checkout/pay_coupon_list`, params);
};
const reissueContract = function(params) {
return request.post(`${talosApi}/open/checkout/payReissueContract`, params);
};
const guideStream = function(data) {
return request.get(`${yxmGateway}/api/kdsp/appconfig/pay-succ-page/guide-stream`, data);
};
const getOrderType = function(data) {
return request.get(`${yxmGateway}/api/kdsp/checkIsHundredGroupOrder?orderNo=${data}`);
};
const getPrivDomain = function(data) {
return request.get(`${yxmGateway}/api/kdsp/appconfig/private-domain/detail?activityType=${data}`);
};
export {
pay,
prepay,
sendSms,
queryPayInfo,
queryPayStatus,
desSalt,
h5AppyUrl,
getCoupon,
reissueContract,
guideStream,
getOrderType,
getPrivDomain
};
import request from "../utils/request";
import config from "@/config";
const { yxmGateway } = config;
// const talosApi = "http://yapi.quantgroups.com/mock/351";
const query = function(data) {
return request.post(`${yxmGateway}/api/kdsp/shop-cart/list/valid`, data);
};
const goodSelected = function(data) {
return request.post(`${yxmGateway}/api/kdsp/shop-cart/selected`, data);
};
const goodAdd = function(data) {
return request.post(`${yxmGateway}/api/kdsp/shop-cart/add-update`, data);
};
const goodFee = function(data) {
return request.post(`${yxmGateway}/api/kdsp/shop-cart/fee`, data);
};
const orderConfirm = function(data) {
return request.post(`${yxmGateway}/api/kdsp/shop-cart/order-confirm/page/v2`, data);
};
const beforeConfirmCheck = function() {
return request.post(`${yxmGateway}/api/kdsp/shop-cart/before/order-confirm`);
};
export { query, goodSelected, goodAdd, goodFee, orderConfirm, beforeConfirmCheck };
<template>
<view class="tip-ul">
<view class="tip-li tip-li-bottom">
感谢您选择羊小咩小程序,我们非常重视您的个人信息安全和隐私保护。依据最新法律要求,使用我们的产品前,请仔细阅读并同意
<text class="tip-li-yellow" @click="navTo($config('zhuCeUrl'))"> 《用户注册协议》</text>
<text class="tip-li-yellow" @click="navTo($config('yinSiUrl'))"> 《隐私政策》 </text>
,以便我们向您提供更优质的服务!
</view>
</view>
</template>
<script>
export default {
methods: {
navTo(jumpUrl) {
uni.navigateTo({
url: `/pages/webview/webview?url=${encodeURIComponent(JSON.stringify(jumpUrl))}`
});
}
}
};
</script>
<style scoped lang="scss">
.tip-ul {
.tip-li {
font-size: 28rpx;
line-height: 48rpx;
color: #141414;
}
.tip-li-bottom {
margin-bottom: 12rpx;
}
.tip-li-yellow {
color: #ec1500;
}
}
</style>
<template>
<uni-popup
ref="popup"
:z-index="9999999"
:overlay-style="{ zIndex: 9999999 }"
type="bottom"
:mask-click="false"
@close="close"
@open="open"
>
<view class="Tip" :style="tipHeight">
<view class="Tip__title">{{ title }}</view>
<view class="Tip__content">
<slot name="default" />
</view>
<view class="Tip__button">
<button class="Tip__button--cancel" @click="confirmEvent()">
{{ cancelText }}
</button>
<button class="Tip__button--confirm" @click="confirmEvent()">
{{ confirmText }}
</button>
</view>
</view>
</uni-popup>
</template>
<script>
import uniPopup from "@/components/uni-popup/uni-popup";
const CONFIRM_EVENT = "confirm";
export default {
components: {
uniPopup
},
props: {
title: {
type: String,
default: "欢迎使用羊小咩"
},
round: {
type: [Number, String],
default: 10
},
confirmText: {
type: String,
default: "同意"
},
cancelText: {
type: String,
default: "不同意"
},
closeAble: {
type: Boolean,
default: true
},
closeOnClickOverlay: {
type: Boolean,
default: false
}
},
data() {
return {
show: false
};
},
methods: {
open() {
this.show = true;
this.$refs.popup.open();
},
close() {
this.show = false;
this.$refs.popup.close();
},
confirmEvent() {
this.close();
const timer = setTimeout(() => {
this.$emit(CONFIRM_EVENT);
clearTimeout(timer);
}, 200);
}
}
};
</script>
<style scoped lang="scss">
::v-deep .u-popup {
z-index: 9999999999;
}
.uni-popup {
z-index: 9999999;
background: #fff;
}
.Tip {
padding: 20rpx 48rpx;
width: 100%;
height: auto;
padding-bottom: env(safe-area-inset-bottom);
border-radius: 40rpx 40rpx 0px 0px;
box-sizing: border-box;
display: flex;
flex-direction: column;
background: #fff;
&__title {
text-align: center;
line-height: 88rpx;
font-size: 32rpx;
font-weight: 500;
color: #323233;
}
&__content {
flex: 1;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
padding-top: 16rpx;
}
&__button {
display: flex;
margin-bottom: 40rpx;
button {
font-size: 28rpx;
background-color: none;
width: 332rpx;
height: 80rpx;
line-height: 80rpx;
border-radius: 200rpx;
margin-top: 50rpx;
&::after {
border: none;
}
}
&--confirm {
color: $white;
background: linear-gradient(270deg, #ff5d00 0%, #ff1900 100%);
}
&--cancel {
background-color: transparent;
color: #141414;
border-radius: 4px;
border: 2rpx solid #999999;
margin-right: 24rpx;
}
}
}
</style>
<template>
<view>
<uni-popup
ref="popup"
type="bottom"
:title="title"
:mask-click="true"
closeable
@change="onChange"
>
<view class="action-sheet">
<!-- #ifdef MP-ALIPAY -->
<slot />
<!-- #endif -->
<!-- #ifndef MP-ALIPAY -->
<slot>
<view class="content" />
</slot>
<!-- #endif -->
<slot name="footer">
<view v-if="actionText" class="footer">
<button class="action-btn" type="default" @click="onConfirm">
{{ actionText }}
</button>
</view>
</slot>
</view>
</uni-popup>
</view>
</template>
<script>
import uniPopup from "@/components/uni-popup/uni-popup";
export default {
name: "ActionSheet",
components: {
uniPopup
},
props: {
title: {
type: String,
default: ""
},
showClose: {
type: Boolean,
default: true
},
closeIconSize: {
type: Number,
default: 18
},
actionText: {
type: String,
default: ""
}
},
methods: {
/**
* @exposed-api
*/
open() {
this.$refs.popup.open();
},
/**
* @exposed-api
*/
close() {
this.$refs.popup.close();
},
onChange(e) {
// 点击遮罩关闭时触发
if (e.show === false) {
this.$emit("close");
}
},
onConfirm() {
this.$emit("confirm");
this.close();
},
onClose() {
this.close();
this.$emit("close");
}
}
};
</script>
<style lang="scss" scoped>
.action-sheet {
background-color: $uni-bg-color;
// border-radius: 12rpx 12rpx 0 0;
display: flex;
flex-direction: column;
.header {
padding: 36rpx 36rpx 20rpx 36rpx;
display: flex;
flex: 1;
flex-direction: row;
justify-content: center;
align-items: center;
.title {
flex: 1;
text-align: center;
font-size: 32rpx;
line-height: 44rpx;
color: #333;
}
.close {
color: #dcdcdc;
}
}
.content {
padding: 0 30rpx;
}
.footer {
padding: 20rpx 30rpx;
.action-btn {
@include primary-bg;
color: white;
font-size: $uni-font-size-base;
font-weight: bold;
border-radius: $uni-border-radius-xl;
}
}
}
</style>
<template>
<view v-if="modalData.img" class="activityModal">
<view class="content">
<image :src="modalData.img" mode="widthFix" @click="goto" />
</view>
<view class="close">
<i class="iconfont icon-close-line" @click="$emit('close')" />
</view>
</view>
</template>
<script>
import { saTrackEvent } from "@/utils/sa.js";
export default {
props: {
modalData: {
type: Object,
default() {
return {};
}
},
pageName: String
},
mounted() {
saTrackEvent("MINI_PagePopupWindowExposure", {
popupwindow_id: this.modalData.uid,
popupwindow_name: this.modalData.componentName,
page_name: this.pageName
});
},
methods: {
goto() {
this.$emit("goto", this.modalData);
}
}
};
</script>
<style scoped lang="scss">
.activityModal {
z-index: 9999;
position: fixed;
top: 0;
left: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
.content {
max-width: 311px;
// max-height: 360px;
// background: $uni-bg-color;
border-radius: $uni-border-radius-sm * 4;
image {
max-width: 100%;
max-height: 100%;
border-radius: $uni-border-radius-sm * 4;
}
}
.close {
margin-top: $uni-spacing-col-md;
i {
font-size: 33px;
color: $white;
}
}
}
</style>
<template>
<view>
<view v-if="type === 'shoppingCar'" class="goods-bottom">
<!-- <navigator url="/pages/index/index" class="goods-bottom-icon" @click="goHome" hover-class="none">
<text class="iconfont icon-home"></text>
<text>首页</text>
</navigator> -->
<!-- <navigator v-if="type === 'shoppingCar'" url="/pages/cart/cart" class="goods-bottom-icon">
<text class="iconfont icon-cart-card" />
<text>购物车</text>
</navigator>
<button class="goods-bottom-car">加入购物车</button> -->
<button class="goods-bottom-buy" :class="{ disabled: disabled }" @click="buy">
{{ shopBtnName }}
</button>
</view>
<view v-if="type === 'settlement'" class="goods-bottom">
<radio-group class="goods-bottom-radio" @change="radioChange">
<label>
<radio />
<text>全选</text>
</label>
</radio-group>
<view class="goods-bottom-text">
<view class="Gb-text-top">
<text>合计:</text>
<text>¥</text>
<text>627.00</text>
</view>
<text class="Gb-text-bottom">免运费</text>
</view>
<button class="goods-bottom-buy" @click="buy">结算(5)</button>
</view>
<view v-if="type === 'submitOrder'" class="goods-bottom">
<view class="goods-bottom-text">
<view class="Gb-text-top">
<text>合计:</text>
<text>¥</text>
<text>{{ info.totalPayFee || "0.00" }}</text>
</view>
</view>
<button class="goods-bottom-buy confirm-order-btn" @click="buy">提交订单</button>
</view>
</view>
</template>
<script>
import { saTrackEvent } from "@/utils/sa.js";
export default {
name: "BottomNav",
props: {
type: {
type: String,
default: "shopCar" // shoppingCar 购物车;settlement 结算;submitOrder 确认订单
},
shopBtnName: {
type: String,
default: "立即购买" // shoppingCar 购物车;settlement 结算;submitOrder 确认订单
},
info: {
type: Object,
default() {
return {};
}
},
disabled: {
type: Boolean,
default: false
},
goodsId: {
type: String,
default: ""
}
},
methods: {
buy() {
this.$emit("buy");
},
goHome() {
const that = this;
// const currentPage = getCurrentPages();
saTrackEvent("PD_YXMMAEC_UserClickCommodityDetailHomePageBtn", {
commodity_id: that.goodsId
});
uni.reportAnalytics("c_commoditydetailhomepagebtn", {
commodity_id: that.goodsId
});
setTimeout(() => {
uni.switchTab({
url: "/pages/index/index"
});
}, 500);
}
}
};
</script>
<style lang="scss" scoped>
@import "@/style/icon.scss";
.goods-bottom {
position: fixed;
left: 0;
bottom: 0;
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 120rpx;
padding: 30rpx 15rpx 30rpx 30rpx;
background: $white;
border-top: $border-sm solid $bg-color-g1;
&-radio {
display: flex;
align-items: center;
justify-content: space-around;
padding-top: 8rpx;
width: 140rpx;
radio {
transform: scale(0.7);
}
text {
font-size: 24rpx;
color: #999999;
}
}
&-text {
display: flex;
flex-direction: column;
align-items: flex-end;
flex: 1;
margin: 0 20rpx;
.Gb-text-top {
display: flex;
align-items: center;
text {
&:nth-child(1) {
padding-top: 8rpx;
font-size: 24rpx;
color: #333333;
}
&:nth-child(2) {
padding-top: 8rpx;
font-size: 24rpx;
color: #ec3333;
}
&:nth-child(3) {
font-size: 38rpx;
font-weight: bold;
color: #ec3333;
}
}
}
.Gb-text-bottom {
font-size: 24rpx;
color: #999999;
}
}
&-icon {
display: flex;
align-items: center;
flex-direction: column;
text {
&:first-child {
font-size: $font-2;
}
&:last-child {
font-size: $font-sm;
color: $text-color-n1;
}
}
}
&-car {
border: $border-sm solid $border-color-search;
background: $white;
color: $font-color-search;
}
&-buy {
color: $white;
background-image: $background-primary;
}
button {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 80rpx;
font-size: 34rpx;
// font-weight: bold;
border-radius: $border-radius-2;
&.disabled {
opacity: 0.7;
}
}
}
.confirm-order-btn {
width: 200rpx !important;
}
</style>
<template>
<view class="home-list">
<!-- <view class="home-list-container"> -->
<view
v-for="(item, index) in goodList"
:key="index"
class="Hl-container-item"
@click="toDetail(item, index)"
>
<view class="Hl-container-item-img">
<image lazy-load class="Hlc-item-img" mode="aspectFit" :src="item.goods.goodsImage" />
</view>
<view class="Hlc-item-title">
<text>{{ item.goods.goodsName }}</text>
</view>
<!-- 猜你喜欢商品标签 -->
<view class="Hlc-item-tag">
<view v-for="(tag, i) in item.goods.tagList" :key="i" class="Hlc-item-tag-wrap">
<span v-if="tag.type == 2" :key="i" class="Hlc-item-tag-normal">{{ tag.name }}</span>
<img
v-if="tag.type == 1"
mode="heightFix"
class="Hlc-item-tag-icon"
:src="tag.icon"
alt=""
/>
</view>
<img
v-if="item.userBenefitsLabelImgUrl"
:src="item.userBenefitsLabelImgUrl"
class="memberImg"
/>
</view>
<!-- 猜你喜欢商品标签 -->
<view class="Hlc-item-info">
<view class="Hlcu-info-left">
<text>¥</text>
<text>{{ item.goods.goodsSalePrice }}</text>
<text v-if="item.goods.saleCount">已售{{ item.goods.saleCount }}</text>
</view>
<view v-if="!noShare" class="Hlcu-info-right" @click.stop="goodsMaskIdx = index">
<view class="Hlcui-right-dot" />
<view class="Hlcui-right-dot" />
<view class="Hlcui-right-dot" />
</view>
</view>
<view
v-if="goodsMaskIdx === index && !noShare"
class="Hlc-item-mask"
@click.stop="goodsMaskIdx = -1"
>
<button
class="Hlci-mask-button"
open-type="share"
:data-shareinfo="item"
:data-goods="item"
@click.stop="toShare(item, index)"
>
<image src="https://img.lkbang.net/xcx/goods_share@2x.png" />
<text>分享好友</text>
</button>
<button v-if="isDelete" class="Hlci-mask-button" @click="delGoods(item, index)">
<image src="https://img.lkbang.net/xcx/no@2x.png" />
<text>不感兴趣</text>
</button>
</view>
</view>
<!-- </view> -->
</view>
</template>
<script>
import { debounce } from "@/utils";
import { saTrackEvent } from "@/utils/sa.js";
export default {
name: "GoodsCard",
props: {
list: {
type: Array,
default: () => []
},
isDelete: {
type: Boolean,
default: true
},
noShare: {
type: Boolean,
default: false
}
},
data() {
return {
goodsMaskIdx: -1,
goodList: []
};
},
watch: {
list: {
deep: true,
immediate: true,
handler(v) {
this.goodList = v;
}
}
},
methods: {
toShare(item, index) {
const currentPage = getCurrentPages();
saTrackEvent("PD_YXMMAEC_UserClickSelectionPageViewMoreBtn", {
page_id: currentPage[currentPage.length - 1].route,
commodity_id: item.goods.goodsId,
view_more_selection: "分享好友",
position_number: index
});
uni.reportAnalytics("c_selectionpageviewmorebtn", {
page_id: currentPage[currentPage.length - 1].route,
commodity_id: item.goods.goodsId,
view_more_selection: "分享好友",
position_number: index
});
},
delGoods(item, index) {
const currentPage = getCurrentPages();
saTrackEvent("PD_YXMMAEC_UserClickSelectionPageViewMoreBtn", {
page_id: currentPage[currentPage.length - 1].route,
commodity_id: item.goods.goodsId,
view_more_selection: "不感兴趣",
position_number: index
});
uni.reportAnalytics("c_selectionpageviewmorebtn", {
page_id: currentPage[currentPage.length - 1].route,
commodity_id: item.goods.goodsId,
view_more_selection: "不感兴趣",
position_number: index
});
this.goodList.splice(index, 1);
// this.$emit("update:goodsList", this.goodsList);
this.$api.msg("已减少此类信息推荐");
},
toDetail(good, index) {
const currentPage = getCurrentPages();
uni.reportAnalytics("c_selectionpagecommoditycard", {
page_id: currentPage[currentPage.length - 1].route,
commodity_id: good.goods.goodsId,
position_number: index,
uuid: uni.getStorageSync("userAuthInfo").uuid || "",
channel_id: uni.getStorageSync("vccChannel") || ""
});
saTrackEvent("PD_YXMMAEC_UserClickSelectionPageCommodityCard", {
page_id: currentPage[currentPage.length - 1].route,
commodity_id: good.goods.goodsId,
position_number: index
});
debounce(
uni.navigateTo({
url: `/pages/product/goodDetail?skuNo=${
good.goods.goodsId
}&count=1&receiverId=&goodsName=${encodeURIComponent(good.goods.goodsName)}&goodsImage=${
good.goods.goodsImage
}`
// url: `/pages/product/goodDetail?skuNo=144652147824&count=1&receiverId=&goodsName=${good.goods.goodsName}`
}),
300
);
}
}
};
</script>
<style lang="scss" scoped>
.home-list {
// &-container {
// padding-top: 20rpx;
// display: flex;
// justify-content: space-between;
// flex-wrap: wrap;
.Hl-container-item {
position: relative;
margin-bottom: 25rpx;
width: 339rpx;
background: #fff;
border-radius: 12rpx;
&-img {
height: 340rpx;
display: flex;
align-items: center;
}
.Hlc-item-img {
width: 100%;
height: 346rpx;
border-radius: 12rpx;
}
.Hlc-item-title {
height: 76rpx;
margin: 10rpx 20rpx 0rpx 14rpx;
text {
font-size: 26rpx;
line-height: 36rpx;
color: #333333;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
}
.Hlc-item-tag {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
align-items: center;
margin: -12rpx 0rpx 0rpx 14rpx;
&-normal {
display: inline-block;
font-size: 10px;
box-sizing: border-box;
border: 1rpx solid #ff5a4b;
color: #ff5a4b;
padding: 0px 4px;
border-radius: 3px;
margin-right: 5px;
line-height: 14px;
}
&-icon {
height: 28rpx;
margin-right: 5px;
vertical-align: middle;
}
}
.Hlc-item-info {
margin: 16rpx 20rpx 14rpx;
padding-bottom: 16rpx;
display: flex;
align-items: center;
justify-content: space-between;
.Hlcu-info-left {
display: flex;
align-items: flex-end;
text {
&:nth-child(1) {
font-size: 20rpx;
color: #ec3333;
font-weight: bold;
}
&:nth-child(2) {
margin-right: 4rpx;
font-size: 30rpx;
line-height: 34rpx;
color: #ec3333;
font-weight: bold;
}
&:nth-child(3) {
font-size: 19rpx;
line-height: 26rpx;
color: #999999;
text-align: right;
}
}
}
.Hlcu-info-right {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 6rpx;
// width: 66rpx;
width: 40rpx;
height: 40rpx;
.Hlcui-right-dot {
width: 6rpx;
height: 6rpx;
background: #d8d8d8;
border-radius: 50%;
}
// font-size: 35rpx;
// line-height: 26rpx;
// letter-spacing: -6rpx;
// color: #D8D8D8;
}
}
.Hlc-item-mask {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.4);
border-radius: 12rpx;
.Hlci-mask-button {
padding: 0 60rpx;
display: flex;
justify-content: space-between;
align-items: center;
width: 266rpx;
height: 60rpx;
border-radius: 31rpx;
font-size: 24rpx;
color: #333333;
&:first-child {
margin-bottom: 40rpx;
}
image {
width: 36rpx;
height: 36rpx;
}
}
}
}
// }
}
.memberImg {
width: 132.68rpx;
height: 28rpx;
}
</style>
<template>
<view class="coupon-list">
<view class="coupon-title">选择{{ feeTitle }}</view>
<view class="coupon-list__list">
<template v-if="list.length">
<scroll-view :scroll-y="true" class="coupon-list__scroll">
<view v-for="(info, index) in list" :key="index" @click="handleSelectCoupon(info.id)">
<view v-if="couponType == 4" class="minus-list__item">
<view class="minus-list__left">
<view>{{ info.activityDesc }}</view>
<text>活动有效期:{{ info.startDate }}-{{ info.endDate }}</text>
</view>
<view class="minus-list__right">
<radio :value="index" color="#EC1500" :checked="info.isSelect" />
<view class="coupon-list__radio--cover" />
</view>
</view>
<view v-else class="coupon-list__item">
<image v-if="info.iconUrl" :src="info.iconUrl" class="coupon-list__tag" />
<view class="coupon-list__left">
<view class="coupon-list__amount">
<text>{{ currency }}</text>
{{ info.faceValue }}
</view>
<view class="coupon-list__limit">{{ info.limitDesc }}</view>
</view>
<view class="coupon-list__content">
<view class="coupon-list__desc">{{ info.name }}</view>
<view class="coupon-list__date">{{ info.couponValidTime }}</view>
</view>
<view class="coupon-list__right">
<radio :value="index" color="#EC1500" :checked="info.isSelect" />
<view class="coupon-list__radio--cover" />
</view>
</view>
</view>
</scroll-view>
</template>
<view v-else class="coupon-list__empty"><empty text="暂无优惠券"/></view>
</view>
<view v-if="list.length" class="coupon-list__bottom">
<button @click="handleRadioSubmit">确定</button>
</view>
</view>
</template>
<script>
import { getCouponChooseList } from "../api/home.api";
import Empty from "./empty";
import { TITLE_LIST } from "@/constants/order.js";
export default {
name: "CouponList",
components: {
Empty
},
props: {
couponId: {
type: [String, Number],
default: 0
},
couponType: [String, Number],
currency: {
type: String,
default: "¥"
},
goodsInfo: {
type: Array,
default: () => []
},
couponActivityInfoList: {
type: Array,
default: () => []
},
commonPopup: Number
},
data() {
return {
list: [],
selectedCouponIndex: null
};
},
computed: {
selectedCoupon() {
return this.list.filter(l => {
if (l.isSelect) return l;
});
},
feeTitle() {
return TITLE_LIST[this.couponType];
}
},
watch: {
couponActivityInfoList: {
handler() {
this.getCouponChooseList();
},
deep: true,
immediate: true
},
couponType: {
handler: function() {
this.getCouponChooseList();
},
deep: true,
immediate: true
},
couponId: {
handler: function() {
this.getCouponChooseList();
},
deep: true,
immediate: true
}
},
mounted() {
this.getCouponChooseList();
},
methods: {
handleSelectCoupon(num) {
this.list.map(item => {
if (item.id == num) {
item.isSelect = !item.isSelect;
} else {
item.isSelect = false;
}
});
},
handleRadioSubmit() {
this.$emit("select", this.selectedCoupon);
},
async getCouponChooseList() {
if (!this.goodsInfo.length) return;
this.list = [];
const selectedSkuList = this.goodsInfo.map(item => {
const { skuSource, count, skuId } = item;
return {
skuNo: skuId,
skuNum: count,
skuSource
};
});
const selectedCouponActivityList = [];
this.couponActivityInfoList.forEach(item => {
selectedCouponActivityList.push({
couponActivityType: item.couponActivityType,
couponActivityUseId: item.couponActivityUseId
});
});
const [res] = await getCouponChooseList({
selectedSkuList,
couponActivityType: this.couponType,
selectedCouponActivityList
});
if ((res && res.coupons) || (res && res.activityList)) {
const data = this.couponType == 4 ? res.activityList : res.coupons;
data.forEach(u => {
u.id = this.couponType == 4 ? u.activityId : u.pickupId;
u.couponCategory = this.couponType == 4 ? 4 : u.couponCategory;
if (u.id == this.couponId) u.isSelect = true;
else u.isSelect = false;
});
this.list = data;
}
}
}
};
</script>
<style lang="scss" scoped>
.coupon-title {
text-align: center;
margin: 0 auto;
padding-top: 30rpx;
width: 50%;
font-size: 36rpx;
}
.coupon-list {
&__bottom {
padding: 20rpx 40rpx 30rpx;
position: relative;
button {
background-image: linear-gradient(269deg, #ff5d00 12%, #ff1900 86%);
border-radius: 160rpx;
height: 80rpx;
font-size: 28rpx;
line-height: 80rpx;
color: #fff;
}
}
&__list {
padding: 20rpx 20rpx 0;
overflow-y: scroll;
overflow-x: hidden;
height: 50vh;
}
&__scroll {
height: 100%;
}
&__empty {
padding-top: 100rpx;
}
&__item {
position: relative;
display: flex;
align-items: center;
background: #ffece6;
border-radius: 12rpx;
padding: 37.5rpx 20rpx;
margin-bottom: 20rpx;
&--disabled {
-webkit-filter: grayscale(100%) opacity(0.8); /* Chrome, Safari, Opera */
filter: grayscale(100%) opacity(0.8);
.cr-coupon-list__right {
display: none;
}
}
}
&__radio--cover {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 1;
}
&__tag {
position: absolute;
top: 0;
left: 0;
width: 88rpx;
height: 32rpx;
}
&__left {
text-align: center;
color: #ec3333;
}
&__amount {
font-size: 60rpx;
font-weight: 500;
line-height: 72rpx;
margin: 0;
text {
font-size: 32rpx;
line-height: 44rpx;
}
}
&__limit {
font-size: 24rpx;
color: #ec3333;
line-height: 34rpx;
margin: 0;
}
&__content {
padding: 0 36rpx;
}
&__desc {
font-size: 28rpx;
line-height: 40rpx;
font-weight: 500;
color: #333;
margin-bottom: 6rpx;
}
&__date {
font-size: 24rpx;
color: #666666;
line-height: 34rpx;
}
&__right {
margin-left: auto;
position: relative;
&.wx-radio-input {
background-color: #ffece6 !important;
}
radio {
transform: scale(0.8);
}
}
}
.minus-list {
&__item {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 12rpx;
padding: 12rpx 20rpx;
margin-bottom: 20rpx;
}
&__left {
font-size: 28rpx;
span {
color: $font-color-base;
font-size: 24rpx;
}
}
&__right {
margin-left: auto;
position: relative;
&.wx-radio-input {
background-color: #ffece6 !important;
}
radio {
transform: scale(0.8);
}
}
}
</style>
<template>
<view class="goods-coupon">
<view v-for="(item, index) in list" :key="index" class="goods-coupon-item Gc-item_pink">
<view class="Gc-item-left">
<image class="Gci-left-type" :src="item.iconUrl" />
<view class="Gci-left-amount">
<view class="Gcil-amount-price"
><text>{{ item.faceValue }}</text></view
>
<view class="Gci-amount-desc">{{ item.limitDesc }}</view>
</view>
<view class="Gci-left-desc">
<text class="Gcil-desc-name">{{ item.name }}</text>
<!-- <text v-if="!item.pickupAble" class="Gcil-desc-time"
>{{ item.startDate }}-{{ item.endDate }}</text
> -->
<text class="Gcil-desc-time">{{ item.couponValidTime }}</text>
<view>
<text class="Gcil-desc-detail" />
<text />
</view>
</view>
</view>
<view class="Gc-item-right">
<image
v-if="item.pickupAble"
class="Gci-right-receive"
src="https://img.lkbang.net/xcx/coupon_received@2x.png"
/>
<button
class="Gci-right-button"
:class="{ 'Gci-right-button_received': item.pickupAble }"
@click="pickupCoupon(item)"
>
{{ item.pickupAble ? "已领取" : "立即领取" }}
</button>
</view>
</view>
</view>
</template>
<script>
export default {
name: "CouponCard",
props: {
couponList: {
type: Array,
default: () => []
}
},
data() {
return {
list: []
};
},
computed: {
// list() {
// const coupon = []
// this.couponList.map(el => {
// el.startDate = el.startDate && el.startDate.replace(/-/g, '.').slice(0,10) || ''
// el.endDate = el.endDate && el.endDate.replace(/-/g, '.').slice(0,10) || ''
// coupon.push(el)
// });
// return coupon
// }
},
watch: {
couponList: {
handler() {
this.list = [];
this.couponList.map(el => {
el.startDate = (el.startDate && el.startDate.replace(/-/g, ".").slice(0, 10)) || "";
el.endDate = (el.endDate && el.endDate.replace(/-/g, ".").slice(0, 10)) || "";
this.list.push(el);
});
},
immediate: true
}
},
methods: {
pickupCoupon(coupon) {
if (coupon.pickupAble) {
return;
}
this.$emit("pickupCoupon", coupon);
}
}
};
</script>
<style lang="scss" scoped>
.goods-coupon {
margin: 0 24rpx;
&-item {
position: relative;
margin-bottom: 20rpx;
width: 100%;
height: 180rpx;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 $padding-md;
border-radius: $border-radius-base;
.Gc-item-left {
display: flex;
flex: 1;
padding-right: 16rpx;
.Gci-left-type {
position: absolute;
top: 0;
left: 0;
width: 88rpx;
height: 32rpx;
}
.Gci-left-amount {
display: flex;
flex-direction: column;
width: 140rpx;
margin-right: $margin-1 - 4;
align-items: center;
.Gcil-amount-price {
font-size: $font-lg;
color: $font-color-red;
font-weight: bold;
text {
font-size: $font-1;
}
}
.Gci-amount-desc {
font-size: $font-sm;
color: $font-color-red;
width: 150rpx;
text-align: center;
}
}
.Gci-left-desc {
display: flex;
flex-direction: column;
justify-content: center;
.Gcil-desc-name {
font-weight: bold;
font-size: $font-base;
color: $text-color-n5;
}
.Gcil-desc-time {
font-size: $font-sm;
color: $text-color-n3;
}
}
}
.Gc-item-right {
.Gci-right-receive {
position: absolute;
top: 0;
right: 20rpx;
width: 120rpx;
height: 100rpx;
}
.Gci-right-button {
width: 164rpx;
height: 48rpx;
line-height: 48rpx;
text-align: center;
font-size: $font-sm;
color: $white;
background-image: $background-primary;
border-radius: $border-radius-2;
&_received {
opacity: 0.6;
// background-image: $background-primary;
}
}
}
}
.Gc-item_pink {
background: $bg-color-pink;
}
.Gc-item_white {
background: $white;
}
}
</style>
This diff is collapsed.
<template>
<view v-if="showPopup" class="uni-popup" :class="[popupstyle]" @touchmove.stop.prevent="clear">
<uni-transition
v-if="maskShow"
:mode-class="['fade']"
:styles="maskClass"
:duration="duration"
:show="showTrans"
@click="onTap"
/>
<uni-transition
:mode-class="ani"
:styles="transClass"
:duration="duration"
:show="showTrans"
@click="onTap"
>
<view class="uni-popup__wrapper-box" @click.stop="clear">
<text class="uni-popup-icon iconfont icon-close-plane" @click="onTap" />
<view v-if="title || desc" class="uni-popup-header">
<text v-if="title" class="uni-popup-title">{{ title }}</text>
<text v-if="desc" class="uni-popup-desc">{{ desc }}</text>
</view>
<slot />
</view>
</uni-transition>
</view>
</template>
<script>
import { uniTransition } from "@dcloudio/uni-ui";
const config = {
// 顶部弹出
top: "top",
// 底部弹出
bottom: "bottom",
// 居中弹出
center: "center",
// 消息提示
message: "top",
// 对话框
dialog: "center",
// 分享
share: "bottom"
};
export default {
name: "UniPopup",
components: {
uniTransition
},
provide() {
return {
popup: this
};
},
props: {
// 开启动画
animation: {
type: Boolean,
default: true
},
// 弹出层类型,可选值,top: 顶部弹出层;bottom:底部弹出层;center:全屏弹出层
// message: 消息提示 ; dialog : 对话框
type: {
type: String,
default: "bottom"
},
// maskClick
maskClick: {
type: Boolean,
default: true
},
title: {
type: String,
default: ""
},
desc: {
type: String,
default: ""
}
},
data() {
return {
duration: 300,
ani: [],
showPopup: false,
showTrans: false,
maskClass: {
position: "fixed",
bottom: 0,
top: 0,
left: 0,
right: 0,
backgroundColor: "rgba(0, 0, 0, 0.4)"
},
transClass: {
position: "fixed",
left: 0,
right: 0
},
maskShow: true,
mkclick: true,
popupstyle: "top",
config
};
},
watch: {
/**
* 监听type类型
*/
type: {
handler: function(newVal) {
this[this.config[newVal]]();
},
immediate: true
},
/**
* 监听遮罩是否可点击
* @param {Object} val
*/
maskClick(val) {
this.mkclick = val;
}
},
created() {
this.mkclick = this.maskClick;
if (this.animation) {
this.duration = 300;
} else {
this.duration = 0;
}
},
methods: {
clear(e) {
// TODO nvue 取消冒泡
e.stopPropagation();
},
open() {
this.showPopup = true;
this.$nextTick(() => {
new Promise(resolve => {
clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.showTrans = true;
// fixed by mehaotian 兼容 app 端
this.$nextTick(() => {
resolve();
});
}, 50);
}).then(() => {
// 自定义打开事件
clearTimeout(this.msgtimer);
this.msgtimer = setTimeout(() => {
this.customOpen && this.customOpen();
}, 100);
this.$emit("change", {
show: true,
type: this.type
});
});
});
},
close() {
this.showTrans = false;
this.$nextTick(() => {
this.$emit("change", {
show: false,
type: this.type
});
clearTimeout(this.timer);
// 自定义关闭事件
this.customOpen && this.customClose();
this.timer = setTimeout(() => {
this.showPopup = false;
}, 300);
});
},
onTap() {
if (!this.mkclick) return;
this.close();
},
/**
* 顶部弹出样式处理
*/
top() {
this.popupstyle = "top";
this.ani = ["slide-top"];
this.transClass = {
position: "fixed",
left: 0,
right: 0
};
},
/**
* 底部弹出样式处理
*/
bottom() {
this.popupstyle = "bottom";
this.ani = ["slide-bottom"];
this.transClass = {
position: "fixed",
left: 0,
right: 0,
bottom: 0
};
},
/**
* 中间弹出样式处理
*/
center() {
this.popupstyle = "center";
this.ani = ["zoom-out", "fade"];
this.transClass = {
position: "fixed",
/* #ifndef APP-NVUE */
display: "flex",
flexDirection: "column",
/* #endif */
bottom: 0,
left: 0,
right: 0,
top: 0,
justifyContent: "center",
alignItems: "center"
};
}
}
};
</script>
<style lang="scss" scoped>
.uni-popup {
position: fixed;
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.uni-popup__mask {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: $uni-bg-color-mask;
opacity: 0;
}
.mask-ani {
transition-property: opacity;
transition-duration: 0.2s;
}
.uni-top-mask {
opacity: 1;
}
.uni-bottom-mask {
opacity: 1;
}
.uni-center-mask {
opacity: 1;
}
.uni-popup__wrapper {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: absolute;
}
.top {
/* #ifdef H5 */
top: var(--window-top);
/* #endif */
/* #ifndef H5 */
top: 0;
/* #endif */
}
.bottom {
bottom: 0;
}
.uni-popup__wrapper-box {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: relative;
/* iphonex 等安全区设置,底部安全区适配 */
/* #ifndef APP-NVUE */
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
/* #endif */
padding: 40rpx 40rpx 0;
border-radius: 12rpx 12rpx 0 0;
background-color: #fff;
.uni-popup-icon {
position: absolute;
right: 40rpx;
top: 43rpx;
font-size: 36rpx;
color: #999999;
}
.uni-popup-header {
margin-bottom: 40rpx;
text {
display: inline-block;
width: 100%;
text-align: center;
}
.uni-popup-title {
font-size: 32rpx;
line-height: 44rpx;
font-weight: bold;
color: #333333;
}
.uni-popup-desc {
margin-top: 10rpx;
font-size: 26rpx;
color: #999999;
}
}
}
.content-ani {
// transition: transform 0.3s;
transition-property: transform, opacity;
transition-duration: 0.2s;
}
.uni-top-content {
transform: translateY(0);
}
.uni-bottom-content {
transform: translateY(0);
}
.uni-center-content {
transform: scale(1);
opacity: 1;
}
</style>
<template>
<view class="Hl-container-item">
<view class="Hlc-title">失效</view>
<image lazy-load class="Hlc-item-img" mode="aspectFit" :src="goods.skuImg" />
<view class="Hlc-item-info">
<view class="Hlc-item-info-title">
<text v-if="goods.textTag" class="Hlc-item-info-title-tag">{{ goods.textTag }}</text>
<text class="Hlc-item-info-title-name"
><text class="name"> {{ goods.skuName }}</text></text
>
</view>
<view class="Hlc-item-info-bottom">
<view class="Hlc-item-info-bottom-des">{{ goods.invalidStatusDesc }}</view>
<!-- 仅羊小咩展示看相似 2021.11.25 -->
<view v-if="$config('yxm')" class="Hlc-item-info-bottom-btn"
><button class="similar" @click="goSimilar">看相似</button></view
>
</view>
</view>
</view>
</template>
<script>
import { saTrackEvent } from "@/utils/sa.js";
export default {
name: "DisabledGoodsCard",
props: {
goods: {
type: Object,
default: () => {}
}
},
data() {
return {
options: [
{
text: "删除",
style: {
backgroundColor: "#F43530"
}
}
]
};
},
methods: {
delGood(goods) {
this.$emit("delGood", goods);
},
goSimilar() {
saTrackEvent("MINI_ShoppingCartPageViewSimilarityBtnClick", {
sku_no: this.goods.skuId
});
uni.navigateTo({
url: `/pages/product/similar?skuNo=${this.goods.skuId}&goodsName=${this.goods.skuName}&goodsImage=${this.goods.skuImg}&des=${this.goods.invalidStatusDesc}`
});
}
}
};
</script>
<style lang="scss" scoped>
.Hl-container-item {
display: flex;
// margin: 40rpx 0;
align-items: center;
justify-content: space-around;
width: 100%;
padding: 20rpx 0rpx;
.Hlc-title {
color: #fff;
background: #979797;
border-radius: 30rpx;
height: 30rpx;
line-height: 30rpx;
width: 64rpx;
text-align: center;
font-size: 20rpx;
}
.Hlc-item-img {
max-width: 200rpx;
height: 200rpx;
border-radius: 12rpx;
opacity: 0.5;
margin-left: 12rpx;
// background: #aaa;
}
.Hlc-item-info {
width: 365rpx;
height: 200rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
margin: 0 20rpx;
position: relative;
&-title {
position: relative;
opacity: 0.5;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
&-name {
.name {
font-size: 26rpx;
line-height: 36rpx;
color: #333333;
}
.blank {
width: 10rpx;
}
}
&-tag {
font-size: 20rpx;
color: #fff;
background: red;
border-radius: 6rpx;
padding: 0 6rpx;
margin-right: 10rpx;
}
}
&-bottom {
position: absolute;
bottom: 0rpx;
display: flex;
align-items: center;
justify-content: space-around;
width: 100%;
padding-right: 1px;
&-des {
font-size: 26rpx;
// line-height: 36rpx;
width: 60%;
color: #333333;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
}
&-btn {
width: 40%;
.similar {
height: 60rpx;
line-height: 60rpx;
font-size: 28rpx;
// font-weight: bold;
border-radius: $border-radius-2;
border: $border-sm solid $border-color-search;
// background: $white;
color: $font-color-search;
padding: 0 $padding-sm;
background: #fff;
}
}
}
}
}
</style>
<template>
<view v-if="!isClear && goodsList.length" class="disabledGoods">
<view v-if="goodsList.length" class="disabledGoods-header">
<view class="disabledGoods-header-title">失效商品</view>
<view class="disabledGoods-header-clear" @click="clearDisabledGoods">清空失效商品</view>
</view>
<view class="disabledGoods-list">
<uni-swipe-action>
<view v-for="item in goodsList" :key="item" class="disabledGoods-list-item">
<uni-swipe-action-item :right-options="options" auto-close @click="delGood(item)">
<cardList :goods="item" />
</uni-swipe-action-item>
</view>
</uni-swipe-action>
</view>
<uni-popup ref="confirmPop">
<uni-popup-dialog
type="base"
content="确定删除失效商品吗?"
message=""
title=" "
:duration="2000"
:before-close="true"
cancel-txt="再想想"
confirm-txt="删除"
warning-btn="cancel"
@confirm="confirm(goodsList, true)"
@cancle="cancel"
/>
</uni-popup>
</view>
</template>
<script>
import cardList from "./cardList";
import uniPopupDialog from "@/components/uni-popup/uni-popup-dialog";
import { getInvalidList, addSkuToCart } from "../../api/home.api.js";
import { mapActions } from "@/pages/shopcart/shopCartModules.js";
import uniSwipeAction from "@/components/uni-swipe-action";
import uniSwipeActionItem from "@/components/uni-swipe-action-item";
export default {
name: "DisabledGoodsCard",
components: {
cardList,
uniPopupDialog,
uniSwipeAction,
uniSwipeActionItem
},
data() {
return {
goodsList: [],
isClear: false,
options: [
{
text: "删除",
style: {
backgroundColor: "#F43530"
}
}
]
};
},
mounted() {
this.getList();
uni.$on("updateInvalid", () => this.getList());
},
beforeDestroy() {
uni.$off("updateInvalid");
},
methods: {
...mapActions({
querCartCount: "queryCartCount"
}),
async getList() {
const [data] = await getInvalidList({ pageNo: 1, pageSize: 120 });
this.goodsList = data.invalidSkuList || [];
},
clearDisabledGoods() {
this.$refs["confirmPop"].open();
},
async delGood(goods) {
this.confirm([goods]);
},
async confirm(goodsList, isClear) {
goodsList.forEach(item => {
item.type = 4;
});
const [data] = await addSkuToCart({ shopCartBaseList: goodsList });
if (data) {
if (isClear) {
this.isClear = true;
uni.showToast({
title: "无效商品已清空",
icon: "none"
});
}
if (!isClear) {
uni.showToast({
title: "商品已删除",
icon: "none"
});
}
this.getList();
this.querCartCount();
}
}
}
};
</script>
<style lang="scss" scoped>
.disabledGoods {
background: #fff;
padding: $padding-md;
border-radius: 10rpx;
// margin-top: 20px;
&-header {
display: flex;
justify-content: space-between;
align-items: center;
&-title {
font-weight: bold;
font-size: $uni-font-size-md;
}
&-clear {
color: $uni-color-error;
font-size: $uni-font-size-md;
}
}
&-list {
width: 100%;
&-item {
margin: 40rpx 0;
}
}
}
</style>
<template>
<view class="empty-content" :style="{ background: backColor }">
<image src="https://img.lkbang.net/xcx/empty@2x.png" mode="aspectFit" />
<text v-if="text">{{ text }}</text>
</view>
</template>
<script>
export default {
props: {
backColor: {
type: String,
default: "#fff"
},
src: {
type: String,
default: "empty"
},
text: {
type: String,
default: "暂无订单~"
}
},
data() {
return {
typeSrc: {
empty: ""
}
};
},
computed: {
setSrc() {
return this.typeSrc[this.src];
}
}
};
</script>
<style lang="scss">
.empty-content {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
margin: 0 20rpx 20rpx;
padding: 20rpx;
height: 422rpx;
border-radius: 12rpx;
image {
margin-bottom: 20rpx;
width: 300rpx;
height: 300rpx;
}
text {
font-size: 32rpx;
color: #666666;
}
}
</style>
This diff is collapsed.
<template>
<view class="home-list">
<view class="home-list-container">
<view v-for="(item, index) in goodsList" :key="index" class="Hl-container-item">
<image
lazy-load
class="Hlc-item-img"
mode="aspectFit"
:src="item.goods.goodsImage"
@click="goDetail(item)"
/>
<view class="Hlc-item-info">
<view class="Hlc-item-info-title" @click="goDetail(item)">
<text>{{ item.goods.goodsName }}</text>
</view>
<view class="Hlc-item-tag" @click="goDetail(item)">
<view v-for="(tag, i) in item.goods.tagList" :key="i" class="Hlc-item-tag-wrap">
<span v-if="tag.type == 2" :key="i" class="Hlc-item-tag-normal">{{ tag.name }}</span>
<img
v-if="tag.type == 1"
mode="heightFix"
class="Hlc-item-tag-icon"
:src="tag.icon"
alt=""
/>
</view>
</view>
<view class="Hlc-item-info-count">
<div @click="goDetail(item)">
<view class="Hlc-item-info-count-left">
<text>¥{{ item.goods.goodsSalePrice }}</text>
<!-- <text v-if="item.goods.goodsPrice">¥{{ item.goods.goodsPrice }}</text> -->
</view>
<view class="Hlc-item-info-count-right">
<text v-if="item.goods.saleCount">已售{{ item.goods.saleCount }}</text>
</view>
</div>
<view class="Hlc-item-info-count-icon">
<text class="iconfont icon-cart" @click="addProduct(item)" />
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import { debounce } from "@/utils";
import api from "../api/addProduct.api.js";
export default {
name: "GoodsCard",
props: {
goodsList: {
type: Array,
default: () => []
}
},
data() {
return {};
},
methods: {
goDetail(good) {
debounce(
uni.navigateTo({
url: `/pages/product/goodDetail?skuNo=${
good.goods.goodsId
}&count=1&receiverId=&goodsName=${encodeURIComponent(good.goods.goodsName)}&goodsImage=${
good.goods.goodsImage
}`
}),
300
);
},
async addProduct(good) {
const shopCartBaseList = [
{
skuId: good.goods.goodsId,
skuNum: 1,
skuSource: good.goods.goodsType,
type: 1
}
];
await api.addProduct({ shopCartBaseList, selected: true });
this.$emit("addProduct", good.goods.goodsSalePrice);
uni.showToast({
title: "购物车添加成功",
icon: "none"
});
}
}
};
</script>
<style lang="scss" scoped>
.home-list {
background: $white;
padding: 0 $space-md * 2;
&-container {
.Hl-container-item {
display: flex;
margin: 0 0 40rpx 0;
.Hlc-item-img {
width: 270rpx;
height: 270rpx;
border-radius: 12rpx;
// background: #aaa;
}
.Hlc-item-info {
width: 450rpx;
height: 260rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
margin-left: 20rpx;
&-title {
text {
font-size: 26rpx;
line-height: 36rpx;
color: #333333;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
}
&-count {
display: flex;
justify-content: space-between;
&-left {
color: #ec3333;
margin: 1px;
text {
&:nth-child(1) {
margin-right: 10rpx;
font-size: $uni-font-size-lg;
line-height: 34rpx;
color: #ec3333;
font-weight: bold;
}
&:nth-child(2) {
font-size: $uni-font-size-tiny;
line-height: 24rpx;
color: #999999;
text-align: right;
text-decoration: line-through;
}
}
}
&-right {
font-size: $uni-font-size-tiny;
line-height: 24rpx;
color: #999999;
}
&-icon {
align-items: center;
height: 28px;
width: 28px;
line-height: 28px;
padding-left: 4px;
border: 1px solid #f2f3f5;
background-color: #f2f3f5;
border-radius: 50%;
}
}
}
.Hlc-item-tag {
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
height: 60rpx;
margin-top: -40rpx;
&-normal {
// display: inline-block;
// font-size: 22rpx;
// box-sizing: border-box;
// border: 1px solid #ec1500;
// color: #ec1500;
// padding: 0px 4px;
// border-radius: 3px;
// margin-right: 5px;
// // line-height: 14px;
height: 32rpx;
/* #ifdef MP-ALIPAY */
line-height: 30rpx;
/* #endif */
display: flex-inline;
font-size: $uni-font-size-tiny;
justify-content: center;
align-items: center;
margin-top: 8rpx;
border-radius: $uni-border-radius-base;
color: $font-color-search;
padding: 0 $padding-sm;
margin-right: $padding-sm;
border: 1px solid $font-color-search;
::v-deep .uni-tag {
width: 10rpx;
}
}
&-icon {
height: 15px;
margin-right: 5px;
}
}
}
}
}
</style>
<template>
<div class="gfcard" :class="{ 'gfcard-disabled': isDisabled }" @click="bindGiftClick">
<div class="gfcard-header">
<div class="gfcard-header-top gfcard-flex">
<text class="gfcard-header-title">{{
cardItem.createModeDesc || cardItem.cardName || ""
}}</text>
<template v-if="showRecord">
<text
v-if="cardItem.giftStatus != 0"
class="gfcard-header-record"
@click.stop="bindRecordClick"
>消费记录</text
>
<text v-else>确认收货后即可激活</text>
</template>
</div>
<div class="gfcard-header-bottom gfcard-flex">
<text class="gfcard-header-amount">
面值:{{ (+cardItem.denomination || 0).toFixed(2) }}元
</text>
<text class="gfcard-header-time">
<template v-if="$config('qinghai') && cardItem.validTimeStart && cardItem.validTimeEnd">
{{ cardItem.validTimeStart | format }} - {{ cardItem.validTimeEnd | format }}
</template>
<template v-if="$config('yxm') && cardItem.validDateStart && cardItem.validDateEnd">
{{ cardItem.validDateStart }} - {{ cardItem.validDateEnd }}
</template>
</text>
</div>
</div>
<div class="gfcard-bottom">
<div class="gfcard-bottom-money">
<text class="gfcard-bottom-balance">余额</text>
<text class="gfcard-bottom-num">
¥<text class="gfcard-bottom-bold">{{ formatPrice[0] }}</text>
<text class="gfcard-bottom-zero">.{{ formatPrice[1] }}</text>
</text>
</div>
<p class="gfcard-bottom-describe">{{ cardItem.cardDesc || "" }}</p>
<!-- 1-未到期2-使用中3-已失效4-已使用 -->
<div v-if="cardItem.status !== 2" :class="['gfcard-bg', `bg-${cardItem.status}`]" />
<radio
v-if="showCheckbox"
class="gfcard-checkbox"
color="#EC1500"
style="transform: scale(0.7)"
:checked="selectChecked"
/>
</div>
</div>
</template>
<script>
const BINDRECORD_CLICK = "bind-record-click";
const BINDGIFT_CLICK = "bind-gift-click";
import { parseTime } from "@/utils";
export default {
filters: {
format(time) {
return parseTime(time, "{y}.{m}.{d}");
}
},
props: {
cardItem: {
type: Object,
default: () => {}
},
checked: undefined,
// 是否显示禁止使用
beOverdue: {
type: Boolean,
default: false
},
// 是否显示消费记录文案
showRecord: {
type: Boolean,
default: true
}
},
data() {
return {
selectChecked: false
};
},
computed: {
isDisabled() {
return this.beOverdue && this.cardItem.status !== 1;
},
formatPrice() {
const balance = this.cardItem.balance;
let price = !isNaN(balance) ? +balance : 0;
return price.toFixed(2).split(".");
},
showCheckbox() {
return typeof this.checked === "boolean";
}
},
watch: {
checked: {
handler(val) {
this.selectChecked = val;
},
immediate: true
}
},
methods: {
bindGiftClick() {
this.$emit(BINDGIFT_CLICK, this.cardItem);
},
bindRecordClick() {
this.$emit(BINDRECORD_CLICK, this.cardItem);
}
}
};
</script>
<style lang="scss">
.gfcard {
font-size: $uni-font-size-sm;
border-radius: 16rpx;
margin-bottom: 16rpx;
overflow: hidden;
position: relative;
margin-bottom: 16rpx;
&-checkbox {
position: absolute;
right: 20rpx;
}
&-flex {
display: flex;
justify-content: space-between;
align-items: center;
}
&-header {
color: $white;
height: 112rpx;
padding: 16rpx 24rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
background: url(https://img.lkbang.net/xcx/gift-header.png) no-repeat;
background-size: 101%;
border-radius: 16rpx 16rpx 0 0;
box-sizing: border-box;
&-title {
font-size: $uni-font-size-base;
}
&-record {
padding-left: 32rpx;
background: url(https://img.lkbang.net/xcx/gift-header-record.png) no-repeat left center;
background-size: 24rpx 28rpx;
}
&-time {
opacity: 0.7;
}
}
&-bottom {
height: 180rpx;
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
background: url(https://img.lkbang.net/xcx/gift-bottom.png) no-repeat;
background-size: 102%;
border: 1px solid #ebebeb;
border-top: 0;
box-sizing: border-box;
border-radius: 0 0 16rpx 16rpx;
position: relative;
overflow: hidden;
&-money {
font-size: $uni-font-size-base;
color: $font-color-red;
}
&-num {
font-weight: bold;
font-size: $font-lg;
margin-left: 10rpx;
}
&-bold {
font-size: 60rpx;
}
&-zero {
font-size: 40rpx;
}
&-describe {
font-size: $font-sm;
color: $uni-text-color-grey;
margin-top: 10rpx;
}
}
}
.gfcard-bg {
position: absolute;
width: 67px;
height: 77px;
right: 0;
top: -20px;
background-repeat: no-repeat;
background-size: 100%;
&.bg-1 {
background-image: url(https://img.lkbang.net/xcx/gift-use-v2.png);
}
&.bg-3 {
background-image: url(https://img.lkbang.net/xcx/gift-overdue-v2.png);
}
&.bg-4 {
background-image: url(https://img.lkbang.net/xcx/gift-used-v2.png);
}
}
.gfcard-disabled {
.gfcard-header {
background-image: url(https://img.lkbang.net/xcx/gift-header-dis.png);
}
.gfcard-bottom {
background-image: url(https://img.lkbang.net/xcx/gift-bottom-dis.png);
position: relative;
overflow: hidden;
&-money {
color: $text-color-n3;
}
}
}
</style>
<template>
<view class="member-tag">{{ text }}</view>
</template>
<script>
export default {
props: {
text: {
type: String,
default: "会员专享"
}
}
};
</script>
<style lang="scss" scoped>
.member-tag {
display: inline-flex;
justify-content: center;
align-items: center;
min-width: 128rpx;
height: 28rpx;
background: #ffe1b0 url(https://img.lkbang.net/xcx/memberCenter/member_tag_bg.png);
background-size: 124rpx 28rpx;
background-repeat: no-repeat;
border-top-right-radius: 6rpx;
border-bottom-right-radius: 6rpx;
padding-left: 46rpx;
padding-right: 6rpx;
font-size: 20rpx;
color: #252931;
}
</style>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<template>
<view class="uploader">
<view v-for="(item, index) in queue" :key="index" class="uploaded">
<image :src="item.url" />
<icon class="close" type="clear" :size="18" @click="remove(index)" />
</view>
<view v-if="!limited" class="upload" @click="upload">
<image src="https://img.lkbang.net/xcx/pic.png" mode="aspectFit" />
<view>
<text class="tips">最多{{ maxCount }}</text>
</view>
</view>
</view>
</template>
<script>
import qiniu from "./qiniu";
export default {
name: "ImageUploader",
props: {
maxCount: {
type: Number,
default: 3
}
},
data() {
return {
queue: [],
uploader: null
// cancelTask: function() {},
};
},
computed: {
limited() {
return this.queue.length >= this.maxCount;
}
},
created() {
this.initQiniu();
this.uploader = qiniu;
},
methods: {
upload() {
uni.chooseImage({
count: 1,
sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有
sourceType: ["album"], //从相册选择
success: res => {
uni.showLoading({
title: "上传中"
});
this.uploader.upload(
res.tempFilePaths[0],
this.uploadSuccess,
this.uploadFail,
null,
this.uploadProgress,
// eslint-disable-next-line no-unused-vars
cancelTask => {}
);
}
});
},
uploadSuccess(res) {
uni.hideLoading();
this.queue.push({
url: res.fileURL
});
this.onChange();
},
uploadFail(err) {
console.error(err);
uni.hideLoading();
},
uploadProgress() {},
remove(index) {
this.queue.splice(index, 1);
this.onChange();
},
onChange() {
this.$emit("change", JSON.parse(JSON.stringify(this.queue)));
},
initQiniu() {
const option = {
region: "ECN",
uptokenURL: "https://mapi.q-gp.com/upload/token",
domain: "https://appsync.lkbang.net",
shouldUseQiniuFileName: true
};
qiniu.init(option);
}
}
};
</script>
<style lang="scss" scoped>
.uploader {
display: flex;
flex-direction: row;
flex-wrap: wrap;
.upload {
width: 170rpx;
height: 170rpx;
border: 1px dashed #999;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
image {
width: 40rpx;
height: 36rpx;
}
.tips {
font-size: 24rpx;
color: #999;
}
}
.uploaded {
width: 170rpx;
height: 170rpx;
margin-right: 30rpx;
margin-bottom: 20rpx;
position: relative;
image {
width: 100%;
height: 100%;
}
.close {
position: absolute;
top: 0;
right: 0;
transform: translate(50%, -50%);
}
}
}
</style>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<template>
<view class="maxMemberInstallment">
<view class="content">
<image v-if="iconUrl" class="icon" mode="heightFix" :src="iconUrl" />
<text>小程序暂不支持MAX会员免息分期,请移步APP操作</text>
</view>
</view>
</template>
<script>
export default {
props: {
displayInfo: {
type: Object,
default: () => {}
}
},
computed: {
iconUrl() {
let url = "";
try {
url = this.displayInfo.installmentInfo.cancelInterestExplainImgUrl;
} catch (e) {
url = "";
}
return url;
}
}
};
</script>
<style lang="scss" scoped>
.maxMemberInstallment {
width: 100%;
padding: 16rpx;
.content {
display: flex;
width: 100%;
height: 48rpx;
background: #e8f6ff;
font-size: 22rpx;
color: #001746;
border-radius: 8rpx;
padding: 0 4px;
align-items: center;
.icon {
width: auto;
margin-right: 8rpx;
height: 32rpx;
}
}
}
</style>
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* eslint-disable */
export default [{"name":"bd","env":"dev","owner":"jinhua.yang","type":null,"status":"Active","createdAt":"2022-10-21 19:39:01"},{"name":"ds","env":"dev","owner":"feng.tang","type":"toc","status":"Active","createdAt":"2022-10-21 19:38:29"},{"name":"saas3","env":"dev","owner":"yulong.zhao","type":"tob","status":"Active","createdAt":"2022-10-21 19:38:11"},{"name":"saas4","env":"test","owner":"liang1.chen","type":"tob","status":"Active","createdAt":"2022-10-21 19:38:07"},{"name":"saas5","env":"dev","owner":"yulong.zhao","type":"tob","status":"Active","createdAt":"2022-10-21 19:38:21"},{"name":"saas6","env":"dev","owner":"yulong.zhao","type":"tob","status":"Active","createdAt":"2022-10-21 19:38:47"},{"name":"sc","env":"dev","owner":"nan.sun","type":"toc","status":"Active","createdAt":"2022-10-21 19:38:17"},{"name":"sc1","env":"dev","owner":"nan.sun","type":"toc","status":"Active","createdAt":"2022-10-27 18:16:00"},{"name":"td","env":"test","owner":"bo.li","type":"qa","status":"Active","createdAt":"2022-10-21 19:38:15"},{"name":"tob1","env":"test","owner":"liang.chen","type":"tob","status":"Active","createdAt":"2022-10-20 19:26:20"},{"name":"tob2","env":"test","owner":"liang.chen","type":"tob","status":"Active","createdAt":"2022-10-20 19:26:55"},{"name":"tob3","env":"test","owner":"liang1.chen","type":"tob","status":"Active","createdAt":"2022-10-22 16:31:47"},{"name":"toc","env":"test","owner":"qiaoling.yu","type":"toc","status":"Active","createdAt":"2022-10-21 19:38:31"},{"name":"xyqb","env":"test","owner":"xiaoqiang.wang","type":"toc","status":"Active","createdAt":"2022-10-21 19:38:41"},{"name":"yxm","env":"test","owner":"qiaoling.yu","type":"toc","status":"Active","createdAt":"2022-10-21 19:38:03"},{"name":"yxm2","env":"test","owner":"qiaoling.yu","type":"toc","status":"Active","createdAt":"2022-10-21 19:38:09"},{"name":"yxm6","env":"test","owner":"qiaoling.yu","type":null,"status":"Active","createdAt":"2023-02-22 14:28:04"}];
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment