Compare commits

...

No commits in common. "v1.9.0" and "master" have entirely different histories.

922 changed files with 89164 additions and 56700 deletions

35
.env Normal file
View File

@ -0,0 +1,35 @@
# 版本号
SHOPRO_VERSION=v2.4.1
# 后端接口 - 正式环境(通过 process.env.NODE_ENV 非 development
SHOPRO_BASE_URL=http://api-dashboard.yudao.iocoder.cn
# 后端接口 - 测试环境(通过 process.env.NODE_ENV = development
SHOPRO_DEV_BASE_URL=http://127.0.0.1:48080
### SHOPRO_DEV_BASE_URL=http://10.171.1.188:48080
### SHOPRO_DEV_BASE_URL = http://yunai.natapp1.cc
# 文件上传类型server - 后端上传, client - 前端直连上传,仅支持 S3 服务
SHOPRO_UPLOAD_TYPE=server
# 后端接口前缀(一般不建议调整)
SHOPRO_API_PATH=/app-api
# 后端 websocket 接口前缀
SHOPRO_WEBSOCKET_PATH=/infra/ws
# 开发环境运行端口
SHOPRO_DEV_PORT=3000
# 客户端静态资源地址 空=默认使用服务端指定的CDN资源地址前缀 | local=本地 | http(s)://xxx.xxx=自定义静态资源地址前缀
SHOPRO_STATIC_URL=http://test.yudao.iocoder.cn
### SHOPRO_STATIC_URL = https://file.sheepjs.com
# 前端 H5 访问域名
SHOPRO_H5_URL=http://127.0.0.1:3000
# 是否开启直播 1 开启直播 | 0 关闭直播
SHOPRO_MPLIVE_ON=0
# 租户ID 默认 1
SHOPRO_TENANT_ID=1

35
.gitignore vendored
View File

@ -1,24 +1,11 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
build.sh
.idea
unpackage
unpackage/*
node_modules/*
.idea/*
deploy.sh
.hbuilderx/
.vscode/
**/.DS_Store
yarn.lock
package-lock.json
*.keystore
pnpm-lock.yaml

View File

@ -1,20 +0,0 @@
{ // launch.json configurations app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtypelocalremote, localremote
"version": "0.0",
"configurations": [{
"default" :
{
"launchtype" : "remote"
},
"h5" :
{
"launchtype" : "remote"
},
"mp-weixin" :
{
"launchtype" : "remote"
},
"type" : "uniCloud"
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 KiB

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

6
.prettierignore Normal file
View File

@ -0,0 +1,6 @@
/unpackage/*
/node_modules/**
/uni_modules/**
/public/*
**/*.svg
**/*.sh

10
.prettierrc Normal file
View File

@ -0,0 +1,10 @@
{
"printWidth": 100,
"semi": true,
"vueIndentScriptAndStyle": true,
"singleQuote": true,
"trailingComma": "all",
"proseWrap": "never",
"htmlWhitespaceSensitivity": "strict",
"endOfLine": "auto"
}

212
App.vue
View File

@ -1,194 +1,32 @@
<script>
import { HTTP_REQUEST_URL } from './config/app';
import Auth from './libs/wechat.js';
import Routine from './libs/routine.js';
export default {
globalData: {
spid: 0,
code: 0,
isLogin: false,
userInfo: {},
MyMenus: [],
windowHeight: 0,
id: 0
},
onLaunch: function(option) {
let that = this;
// window
// #ifdef H5
uni.getSystemInfo({
success: function(res) {
// title
// 44px
let height = res.windowHeight - res.statusBarHeight - 44
// #ifdef H5
that.globalData.windowHeight = res.windowHeight + 'px'
// #endif
}
});
// #endif
<script setup>
import { onLaunch, onShow, onError } from '@dcloudio/uni-app';
import { ShoproInit } from './sheep';
//
uni.getSystemInfo({
success: function(res) {
that.globalData.navHeight = res.statusBarHeight * (750 / res.windowWidth) + 91;
}
});
// #ifdef MP
let menuButtonInfo = uni.getMenuButtonBoundingClientRect();
that.globalData.navH = menuButtonInfo.top * 2 + menuButtonInfo.height / 2;
// #endif
onLaunch(() => {
// 使
uni.hideTabBar({
fail: () => {},
});
// #ifdef MP
if (HTTP_REQUEST_URL === '') {
console.error(
"请配置根目录下的config.js文件中的 'HTTP_REQUEST_URL'\n\n请修改开发者工具中【详情】->【AppID】改为自己的Appid\n\n请前往后台【小程序】->【小程序配置】填写自己的 appId and AppSecret"
);
return false;
}
// TODO :
if (option.query.hasOwnProperty('scene')) {
switch(option.scene){
case 1047: //
case 1048: //
case 1049: //
case 1001: //
let value = this.$util.getUrlParams(decodeURIComponent(option.query.scene));
let values = value.split(',');
if(values.length === 2){
let v1 = values[0].split(":");
if (v1[0] === 'pid') {
that.globalData.spid = v1[1];
} else{
that.globalData.id = v1[1];
}
let v2 = values[1].split(":");
if (v2[0] === 'pid') {
that.globalData.spid = v2[1];
}else{
that.globalData.id = v2[1];
}
}else{
that.globalData.spid = values[0].split(":")[1];
}
break;
}
}
// #endif
// Shopro
ShoproInit();
});
// #ifdef H5
//
let snsapiBase = 'snsapi_base';
let urlData = location.pathname + location.search;
if (!that.$store.getters.isLogin && Auth.isWeixin()) {
const { code, state } = option.query;
if (code && code !== uni.getStorageSync('snsapiCode')
&& location.pathname.indexOf('/pages/users/wechat_login/index') === -1) {
// code
uni.setStorageSync('snsapiCode', code);
Auth.auth(code, state, that.$Cache.get('spread')).then(res => {
// TODO snRouter
uni.setStorageSync('snRouter', decodeURIComponent(decodeURIComponent(option.query.back_url)));
//
location.replace(decodeURIComponent(decodeURIComponent(option.query.back_url)));
}).catch(error => {
this.$Cache.set('snsapiKey', code);
// TODO snsapiKey
// if (!this.$Cache.has('snsapiKey')) {
// if (location.pathname.indexOf('/pages/users/wechat_login/index') === -1) {
// Auth.oAuth(snsapiBase, option.query.back_url);
// }
// }
});
} else {
if (!this.$Cache.has('snsapiKey')) {
if (location.pathname.indexOf('/pages/users/wechat_login/index') === -1) {
Auth.oAuth(snsapiBase, urlData);
}
}
}
} else {
if (option.query.back_url) {
location.replace(uni.getStorageSync('snRouter'));
}
}
// #endif
onShow(() => {
// #ifdef APP-PLUS
// urlSchemes
const args = plus.runtime.arguments;
if (args) {
}
// #ifdef MP
//
if (!this.$store.getters.isLogin) {
let spread = that.globalData.spid ? that.globalData.spid : 0;
Routine.getCode().then(code => {
Routine.authUserInfo(code, spread)
.then(res => {})
}).catch(res => {
uni.hideLoading();
});
}
// #endif
},
async mounted() {
//
if (this.$store.getters.isLogin && !this.$Cache.get('USER_INFO')) {
await this.$store.dispatch('USERINFO');
}
},
onShow: function() {
// #ifdef H5
uni.getSystemInfo({
success(e) {
// TODO
/* 窗口宽度大于420px且不在PC页面且不在移动设备时跳转至 PC.html 页面 */
if (e.windowWidth > 420 && !window.top.isPC && !/iOS|Android/i.test(e.system)) {
// window.location.pathname = 'https://java.crmeb.net/';
/* 若你的项目未设置根目录(默认为 / 时),则使用下方代码 */
window.location.pathname = '/static/html/pc.html';
}
}
})
// #endif
}
}
//
uni.getClipboardData({
success: (res) => {},
});
// #endif
});
</script>
<style>
@import url("@/plugin/animate/animate.min.css");
@import 'static/css/base.css';
@import 'static/iconfont/iconfont.css';
@import 'static/css/guildford.css';
@import 'static/css/style.scss';
/* 条件编译仅在H5平台生效 */
// #ifdef H5
body::-webkit-scrollbar,
html::-webkit-scrollbar {
display: none;
}
// #endif
view {
box-sizing: border-box;
}
.bg-color-red {
background-color: #E93323 !important;
}
.syspadding {
padding-top: var(--status-bar-height);
}
.flex {
display: flex;
}
.uni-scroll-view::-webkit-scrollbar {
/* 隐藏滚动条,但依旧具备可以滚动的功能 */
display: none
}
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
}
<style lang="scss">
@import '@/sheep/scss/index.scss';
</style>

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 lidongtony
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -23,18 +23,18 @@
![功能图](/.image/common/mall-feature.png)
* 基于 uniapp 开发支持微信小程序、微信公众号、H5 移动端,未来会支持支付宝小程序、抖音小程序等
* 基于 uni-app + Vue3 开发支持微信小程序、微信公众号、H5 移动端,未来会支持支付宝小程序、抖音小程序等
* 支持 SaaS 多租户,可满足商品、订单、支付、会员、优惠券、秒杀、拼团、砍价、分销、积分等多种经营需求
## 🔥 后端架构
支持 Spring Boot、Spring Cloud 两种架构:
① Spring Boot 单体架构:<https://github.com/YunaiV/ruoyi-vue-pro>
① Spring Boot 单体架构:<https://doc.iocoder.cn>
![架构图](/.image/common/ruoyi-vue-pro-architecture.png)
② Spring Cloud 微服务架构:<https://github.com/YunaiV/yudao-cloud>
② Spring Cloud 微服务架构:<https://cloud.iocoder.cn>
![架构图](/.image/common/yudao-cloud-architecture.png)
@ -42,10 +42,10 @@
![移动端预览](/.image/common/mall-preview.png)
_前端基于 crmeb uniapp 经过授权重构优化代码实现_
## 🐶 管理端预览
![店铺装修](/.image/mall/店铺装修.png)
![会员详情](/.image/mall/会员详情.png)
![商品详情](/.image/mall/商品详情.png)
@ -53,3 +53,4 @@ _前端基于 crmeb uniapp 经过授权重构优化代码实现_
![订单详情](/.image/mall/订单详情.png)
![营销中心](/.image/mall/营销中心.png)

3
androidPrivacy.json Normal file
View File

@ -0,0 +1,3 @@
{
"prompt" : "template"
}

View File

@ -1,143 +0,0 @@
import request from "@/utils/request.js";
/**
*
* 所有活动接口 包括拼团砍价秒杀
*
*/
/**
* 拼团列表
*
*/
export function getCombinationList(data) {
return request.get('combination/list', data,{noAuth:true});
}
/**
* 拼团 开团
*/
export function getCombinationPink(id) {
return request.get("combination/pink/" + id);
}
/**
* 拼团 取消开团
*/
export function postCombinationRemove(data) {
return request.post("combination/remove",data);
}
/**
* 砍价列表
*/
export function getBargainList(data) {
return request.get("bargain/list", data,{noAuth:true});
}
/**
*
* 砍价列表(已参与)
* @param object data
*/
export function getBargainUserList(data){
return request.get('bargain/record',data);
}
/**
*
* 取消砍价
* @param int bargainId
*/
export function bargainUserCancel(bargainId){
return request.post('bargain/user/cancel', { bargainId: bargainId})
}
/**
* 砍价产品详情
*/
export function getBargainDetail(id) {
return request.get("bargain/detail/" + id);
}
/**
* 用户砍价信息,注意自己的活动和别人的活动的区别
*/
export function getBargainUser(data) {
return request.get("bargain/user", data);
}
/**
* 砍价开启
*/
export function postBargainStart(bargainId) {
return request.post("bargain/start", { bargainId: bargainId});
}
/**
* 砍价 帮助好友砍价
*/
export function postBargainHelp(data) {
return request.post("bargain/help", data);
}
/**
* 砍价 砍掉金额
*/
export function postBargainHelpPrice(data) {
return request.post("bargain/help/price", data);
}
/**
* 砍价 砍价帮
*/
export function postBargainHelpList(params,data) {
return request.get("bargain/help/list?limit="+params.limit+"&page="+params.page, data,{});
}
/**
* 砍价海报
* @param object data
*
*/
export function getBargainPoster(data){
return request.post('bargain/poster',data)
}
/**
* 拼团海报
* @param object data
*
*/
export function getCombinationPoster(data){
return request.post('combination/poster',data)
}
/**
* 砍价取消
*/
export function getBargainUserCancel(data) {
return request.post("/bargain/user/cancel", data);
}
/**
* 获取秒杀小程序二维码
*/
export function seckillCode(id,data) {
return request.get("seckill/code/"+id,data);
}
/**
* 获取拼团小程序二维码
*/
export function scombinationCode(id) {
return request.get("combination/code/"+id);
}
/**
* 首页砍价产品列表
*/
export function bargainHeaderApi(){
return request.get('bargain/header');
}

View File

@ -1,164 +0,0 @@
import request from "@/utils/request.js";
/**
* 公共接口 优惠券接口 , 行业此讯 , 手机号码注册
*
*/
/**
* 获取主页数据 无需授权
*
*/
export function getIndexData()
{
return request.get("index",{},{ noAuth : true});
}
/**
* 获取登录授权login
*
*/
export function getLogo()
{
return request.get('wechat/getLogo', {}, { noAuth : true});
}
/**
* 保存form_id
* @param string formId
*/
export function setFormId(formId) {
return request.post("wechat/set_form_id", { formId: formId});
}
/**
* 领取优惠券
* @param int couponId
*
*/
export function setCouponReceive(couponId){
return request.post('coupon/receive', { couponId: couponId});
}
/**
* 优惠券列表
* @param object data
*/
export function getCoupons(data){
return request.get('coupons',data,{noAuth:true})
}
/**
* 手机号+验证码登录接口
* @param object data
*/
export function loginMobile(data){
return request.post('login/mobile',data,{noAuth:true})
}
/**
* 获取短信KEY
* @param object phone
*/
export function verifyCode(){
return request.get('verify_code', {},{noAuth:true})
}
/**
* 验证码发送
* @param object phone
*/
export function registerVerify(phone){
return request.post('sendCode', { phone: phone },{noAuth:true},1)
}
/**
* 手机号注册
* @param object data
*
*/
export function phoneRegister(data){
return request.post('register',data,{noAuth:true});
}
/**
* 手机号修改密码
* @param object data
*
*/
export function phoneRegisterReset(data){
return request.post('register/reset',data,{noAuth:true})
}
/**
* 手机号+密码登录
* @param object data
*
*/
export function phoneLogin(data){
return request.post('login',data,{noAuth:true})
}
/**
* 切换H5登录
* @param object data
*/
// #ifdef MP
export function switchH5Login(){
return request.post('switch_h5', { 'from':'routine'});
}
// #endif
/*
* h5切换公众号登录
* */
// #ifdef H5
export function switchH5Login() {
return request.post("switch_h5", { 'from': "wechat" });
}
// #endif
/**
* 换绑手机号
*
*/
export function bindingPhone(data){
return request.post('update/binding',data);
}
/**
* 换绑手机号校验
*
*/
export function bindingVerify(data){
return request.post('update/binding/verify',data);
}
/**
* 退出登錄
*
*/
export function logout(){
return request.get('logout');
}
/**
* 获取订阅消息id
*/
export function getTemlIds(data)
{
return request.get('wechat/program/my/temp/list', data , { noAuth:true});
}
/**
* 获取小程序直播列表
*/
export function getLiveList(page,limit) {
return request.get('wechat/live', { page, limit}, { noAuth: true });
}
/**
* 获取小程序二维码
*/
export function getQrcode(data) {
return request.post('qrcode/get',data,{ noAuth: true });
}

View File

@ -1,33 +0,0 @@
import request from "@/utils/request.js";
// 获得用户收件地址
export function getAddress(id) {
return request.get('app-api/member/address/get', {
id
});
}
// 获得默认的用户收件地址
export function getDefaultUserAddress() {
return request.get('app-api/member/address/get-default', {});
}
// 获得用户收件地址列表
export function getAddressList() {
return request.get('app-api/member/address/list', {});
}
// 创建用户收件地址
export function createAddress(data) {
return request.post('app-api/member/address/create', data);
}
// 更新用户收件地址
export function updateAddress(data) {
return request.put('app-api/member/address/update', data);
}
// 删除用户收件地址
export function deleteAddress(id) {
return request.delete('app-api/member/address/delete?id=' + id, {});
}

View File

@ -1,67 +0,0 @@
import request from "@/utils/request.js";
// 发送手机验证码
export function sendSmsCode(mobile, scene) {
return request.post('app-api/member/auth/send-sms-code', {
mobile,
scene
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 校验手机验证码
export function validateSmsCode(mobile, scene, code) {
return request.post('app-api/member/auth/validate-sms-code', {
mobile,
scene,
code
});
}
// 登出系统
export function logout() {
return request.post('app-api/member/auth/logout');
}
// 使用手机 + 密码登录
export function login(data) {
return request.post('app-api/member/auth/login', data, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 使用手机 + 验证码登录
export function smsLogin(data) {
return request.post('app-api/member/auth/sms-login', data, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 社交快捷登录
export function socialLogin(type, code, state) {
return request.post('app-api/member/auth/social-login', {
type,
code,
state
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 微信小程序的一键登录登录
export function weixinMiniAppLogin(phoneCode, loginCode) {
return request.post('app-api/member/auth/weixin-mini-app-login', {
phoneCode,
loginCode
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 创建微信 JS SDK 初始化所需的签名
export function createWeixinMpJsapiSignature(url) {
return request.post("app-api/member/auth/create-weixin-jsapi-signature?url=" + url, {}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}

View File

@ -1,11 +0,0 @@
import request from "@/utils/request.js";
// 获得会员等级列表
export function getLevelList() {
return request.get('app-api/member/level/list');
}
// 获得会员经验记录分页
export function getExperienceRecordPage() {
return request.get('app-api/member/experience-record/page');
}

View File

@ -1,6 +0,0 @@
import request from "@/utils/request.js";
// 获得用户积分记录分页
export function getPointRecordPage() {
return request.get('app-api/member/point/record/page');
}

View File

@ -1,21 +0,0 @@
import request from "@/utils/request.js";
// 获得签到规则列表
export function getSignInConfigList() {
return request.get('app-api/member/sign-in/config/list');
}
// 获得个人签到统计
export function getSignInRecordSummary() {
return request.get('app-api/member/sign-in/record/get-summary')
}
// 签到
export function createSignInRecord() {
return request.post('app-api/member/sign-in/record/create')
}
// 获得签到记录分页
export function getSignRecordPage() {
return request.get('app-api/member/sign-in/record/page');
}

View File

@ -1,28 +0,0 @@
import request from "@/utils/request.js";
// 获得基本信息
export function getUserInfo() {
return request.get('app-api/member/user/get');
}
// 修改基本信息
export function updateUser(data) {
return request.put('app-api/member/user/update', data);
}
// 修改用户手机
export function updateUserMobile(data) {
return request.put('app-api/member/user/update-mobile', data);
}
// 修改用户密码
export function updateUserPassword(data) {
return request.put('app-api/member/user/update-password', data);
}
// 重置密码
export function resetUserPassword(data) {
return request.put('app-api/member/user/reset-password', data, {
noAuth: true // TODO 芋艿:后续要做调整
});
}

View File

@ -1,247 +0,0 @@
import request from "@/utils/request.js";
/**
* 获取购物车列表
* @param numType boolean true 购物车数量,false=购物车产品数量
*/
export function getCartCounts(numType,type) {
return request.get("cart/count?numType=" + numType + "&type=" + type);
}
/**
* 获取购物车列表
*
*/
export function getCartList(data) {
return request.get("cart/list", data);
}
/**
* 修改购物车数量
* @param int cartId 购物车id
* @param int number 修改数量
*/
export function changeCartNum(cartId, number) {
return request.post("cart/num", {
id: cartId,
number: number
}, {}, 1);
}
/**
* 清除购物车
* @param object ids join(',') 切割成字符串
*/
export function cartDel(ids) {
if (typeof ids === 'object')
ids = ids.join(',');
return request.post('cart/delete', {
ids: ids
}, {}, 1);
}
/**
* 购物车重选提交
*
*/
export function getResetCart(data) {
return request.post('cart/resetcart', data);
}
/**
* 订单列表
* @param object data
*/
export function getOrderList(data) {
return request.get('order/list', data);
}
/**
* 订单产品信息
* @param string unique
*/
export function orderProduct(data) {
return request.post('order/product', data);
}
/**
* 订单评价
* @param object data
*
*/
export function orderComment(data) {
return request.post('order/comment', data);
}
/**
* 订单支付
* @param object data
*/
export function orderPay(data) {
return request.post('order/pay', data);
}
/**
* 订单统计数据
*/
export function orderData() {
return request.get('order/data')
}
/**
* 订单取消
* @param string id
*
*/
export function orderCancel(id) {
return request.post('order/cancel', {
id: id
}, {}, 1);
}
/**
* 删除已完成订单
* @param string uni
*
*/
export function orderDel(uni) {
return request.post('order/del', {
id: uni
}, {}, 1);
}
/**
* 订单详情
* @param string uni
*/
export function getOrderDetail(uni) {
return request.get('order/detail/' + uni);
}
/**
* 再次下单
* @param string uni
*
*/
export function orderAgain(uni) {
return request.post('order/again', {
orderNo: uni
});
}
/**
* 订单收货
* @param string uni
*
*/
export function orderTake(uni) {
return request.post('order/take', {
id: uni
}, {}, 1);
}
/**
* 订单查询物流信息
* @returns {*}
*/
export function express(uni) {
return request.get("order/express/" + uni);
}
/**
* 获取退款理由
*
*/
export function ordeRefundReason() {
return request.get('order/refund/reason');
}
/**
* 订单退款审核
* @param object data
*/
export function orderRefundVerify(data) {
return request.post('order/refund', data);
}
/**
* 订单确认获取订单详细信息
* @param string cartId
*/
export function orderConfirm(cartId, isNew, addAgain,secKill,combination,bargain) {
return request.post('order/confirm', {
cartIds: cartId,
isNew: isNew,
addAgain: addAgain,
secKill: secKill,
combination:combination,
bargain:bargain
});
}
/**
* 获取当前金额能使用的优惠券
* @param string price
*
*/
export function getCouponsOrderPrice(preOrderNo) {
return request.get(`coupons/order/${preOrderNo}`)
}
/**
* 订单创建
* @param string key
* @param object data
*
*/
export function orderCreate(data) {
return request.post('order/create', data);
}
/**
* 计算订单金额
* @param key
* @param data
* @returns {*}
*/
export function postOrderComputed(data) {
return request.post("order/computed/price", data);
}
/**
* 微信订单支付
* @param object data
*/
export function wechatOrderPay(data) {
return request.post('pay/payment', data);
}
/**
* 微信查询支付结果
* @param object data
*/
export function wechatQueryPayResult(data) {
return request.get('pay/queryPayResult?orderNo=' + data);
}
/**
* 申请退款商品详情
* @param object data
*/
export function applyRefund(orderId) {
return request.get(`order/apply/refund/${orderId}`);
}
/**
* 预下单
* @param object data
*/
export function preOrderApi(data) {
return request.post(`order/pre/order`, data);
}
/**
* 加载预下单
* @param object preOrderNo
*/
export function loadPreOrderApi(preOrderNo) {
return request.get(`order/load/pre/${preOrderNo}`);
}

View File

@ -1,8 +0,0 @@
import request from "@/utils/request.js";
// 获得指定应用的开启的支付渠道编码列表
export function getEnableChannelCodeList(appId) {
return request.get("app-api/pay/channel/get-enable-code-list", {
appId
});
}

View File

@ -1,11 +0,0 @@
import request from "@/utils/request.js";
export function getOrder(id) {
return request.get("app-api/pay/order/get", {
id
});
}
export function submitOrder(data) {
return request.post("app-api/pay/order/submit", data);
}

View File

@ -1,21 +0,0 @@
import request from "@/utils/request.js";
// 获取钱包
export function getPayWallet() {
return request.get("app-api/pay/wallet/get");
}
// 获得钱包流水分页
export function getWalletTransactionPage(data) {
return request.get("app-api/pay/wallet-transaction/page", data);
}
// 获得钱包充值套餐列表
export function getWalletRechargePackageList() {
return request.get("app-api/pay/wallet-recharge-package/list");
}
// 创建钱包充值记录(发起充值)
export function createWalletRecharge(data) {
return request.post("app-api/pay/wallet-recharge/create", data);
}

View File

@ -1,8 +0,0 @@
import request from "@/utils/request.js";
// 查询分类列表
export function getCategoryList() {
return request.get('app-api/product/category/list', {}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}

View File

@ -1,27 +0,0 @@
import request from "@/utils/request.js";
// 获得商品的评价统计
export function getCommentStatistics(spuId) {
return request.get('app-api/product/comment/statistics', {
spuId
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得最近的 n 条商品评价
export function getCommentList(spuId, count) {
return request.get('app-api/product/comment/list', {
spuId,
count
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得商品评价分页
export function getCommentPage(data) {
return request.get('app-api/product/comment/page', data, {
noAuth: true // TODO 芋艿:后续要做调整
});
}

View File

@ -1,46 +0,0 @@
import request from "@/utils/request.js";
// 检查是否收藏过商品
export function isFavoriteExists(spuId) {
return request.get('app-api/product/favorite/exits', {
spuId
});
}
// 获得商品收藏数量
export function getFavoriteCount() {
return request.get('app-api/product/favorite/get-count');
}
// 添加商品收藏
export function createFavorite(spuId) {
return request.post('app-api/product/favorite/create', {
spuId
});
}
// 添加多个商品收藏
export function createFavoriteList(spuIds) {
return request.post('app-api/product/favorite/create-list', {
spuIds
});
}
// 取消商品收藏
export function deleteFavorite(spuId) {
return request.delete('app-api/product/favorite/delete', {
spuId
});
}
// 获得商品收藏分页
export function getFavoritePage(data) {
return request.get('app-api/product/favorite/page', data);
}
// 取消多个商品收藏
export function deleteFavoriteList(spuIds) {
return request.delete('app-api/product/favorite/delete-list', {
spuIds
});
}

View File

@ -1,24 +0,0 @@
import request from "@/utils/request.js";
// 获得商品 SPU 列表
export function getSpuList(recommendType) {
return request.get('app-api/product/spu/list', {
recommendType
});
}
// 获得商品 SPU 分页
export function getSpuPage(data) {
return request.get('app-api/product/spu/page', data, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 查询商品
export function getSpuDetail(id) {
return request.get('app-api/product/spu/get-detail', {
id
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}

View File

@ -1,19 +0,0 @@
import request from "@/utils/request.js";
// 获得单个商品,近期参与的每个活动
export function getActivityListBySpuId(spuId) {
return request.get("app-api/promotion/activity/list-by-spu-id", {
spuId
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得多个商品,近期参与的每个活动
export function getActivityListBySpuIds(spuIds) {
return request.get("app-api/promotion/activity/list-by-spu-ids", {
spuIds: spuIds && spuIds.length > 0 ? spuIds.join(',') : undefined
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}

View File

@ -1,38 +0,0 @@
import request from "@/utils/request.js";
// 获得文章分类列表
export function getArticleCategoryList() {
return request.get("app-api/promotion/article-category/list", {}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得文章列表
export function getArticleList(data) {
return request.get("app-api/promotion/article/list", data, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得文章分页
export function getArticlePage(data) {
return request.get("app-api/promotion/article/page", data, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得文章
export function getArticle(id) {
return request.get("app-api/promotion/article/get", {
id
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 增加文章浏览量
export function addArticleBrowseCount(id) {
return request.put("app-api/promotion/article/add-browse-count?id=" + id, {}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}

View File

@ -1,7 +0,0 @@
import request from "@/utils/request.js";
export function getBannerList(position) {
return request.get("app-api/promotion/banner/list", {
position
});
}

View File

@ -1,75 +0,0 @@
import request from "@/utils/request.js";
// 获得砍价活动列表
export function getBargainActivityList(count) {
return request.get("app-api/promotion/bargain-activity/list", {
count
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得砍价活动详情
export function getBargainActivityDetail(id) {
return request.get("app-api/promotion/bargain-activity/get-detail", {
id
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得砍价活动分页
export function getBargainActivityPage(count) {
return request.get("app-api/promotion/bargain-activity/page", {
count
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得砍价记录的概要信息
export function getBargainRecordSummary() {
return request.get("app-api/promotion/bargain-record/get-summary", {}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得砍价记录的分页
export function getBargainRecordPage(data) {
return request.get("app-api/promotion/bargain-record/page", data, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得砍价活动详情
export function getBargainRecordDetail(id, activityId) {
return request.get("app-api/promotion/bargain-record/get-detail", {
id: id > 0 ? id : undefined,
activityId: activityId > 0 ? activityId : undefined
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 创建砍价记录(参与拼团活动)
export function createBargainRecord(activityId) {
return request.post("app-api/promotion/bargain-record/create", {
activityId
});
}
// 创建砍价助力(给拼团记录砍一刀)
export function createBargainHelp(recordId) {
return request.post("app-api/promotion/bargain-help/create", {
recordId: recordId
});
}
// 获得砍价助力列表
export function getBargainHelpList(recordId) {
return request.get("app-api/promotion/bargain-help/list", {
recordId: recordId
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}

View File

@ -1,53 +0,0 @@
import request from "@/utils/request.js";
// 获得拼团活动列表
export function getCombinationActivityList(count) {
return request.get("app-api/promotion/combination-activity/list", {
count
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得拼团活动分页
export function getCombinationActivityPage(data) {
return request.get("app-api/promotion/combination-activity/page", data, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得拼团活动明细
export function getCombinationActivity(id) {
return request.get("app-api/promotion/combination-activity/get-detail", {
id
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得最近 n 条拼团记录(团长发起的)
export function getHeadCombinationRecordList(activityId, status, count) {
return request.get("app-api/promotion/combination-record/get-head-list", {
activityId,
status,
count
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得拼团记录明细
export function getCombinationRecordDetail(id) {
return request.get("app-api/promotion/combination-record/get-detail", {
id
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得拼团记录的概要信息
export function getCombinationRecordSummary() {
return request.get("app-api/promotion/combination-record/get-summary", {}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}

View File

@ -1,37 +0,0 @@
import request from "@/utils/request.js";
// 领取优惠券
export function takeCoupon(templateId) {
return request.post("app-api/promotion/coupon/take", {
templateId
});
}
// 获得匹配指定商品的优惠劵列表
export function getMatchCouponList(data) {
return request.get("app-api/promotion/coupon/match-list", data);
}
// 获得用户优惠劵列表
export function getCouponPage(data) {
return request.get("app-api/promotion/coupon/page", data);
}
// 获得优惠劵模板分页
export function getCouponTemplatePage(data) {
return request.get("app-api/promotion/coupon-template/page", data, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得优惠劵模板列表
export function getCouponTemplateList(data) {
return request.get("app-api/promotion/coupon-template/list", data, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得未使用的优惠劵数量
export function getUnusedCouponCount() {
return request.get("app-api/promotion/coupon/get-unused-count");
}

View File

@ -1,9 +0,0 @@
import request from "@/utils/request.js";
export function getDecorateComponentListByPage(page) {
return request.get("app-api/promotion/decorate/list", {
page
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}

View File

@ -1,31 +0,0 @@
import request from "@/utils/request.js";
// 获得秒杀时间段列表
export function getSeckillConfigList() {
return request.get("app-api/promotion/seckill-config/list", {}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得当前秒杀活动
export function getNowSeckillActivity() {
return request.get("app-api/promotion/seckill-activity/get-now", {}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得秒杀活动分页
export function getSeckillActivityPage(data) {
return request.get("app-api/promotion/seckill-activity/page", data, {
noAuth: true // TODO 芋艿:后续要做调整
});
}
// 获得秒杀活动明细
export function getSeckillActivity(id) {
return request.get("app-api/promotion/seckill-activity/get-detail", {
id
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}

View File

@ -1,116 +0,0 @@
import request from "@/utils/request.js";
import wechat from "@/libs/wechat.js";
import {
toLogin,
checkLogin
} from '../libs/login';
/**
* 获取微信公众号js配置
* @returns {*}
*/
export function getWechatConfig() {
return request.get("wechat/config",{ url: encodeURIComponent(wechat.signLink()) },{ noAuth: true });
}
/**
* 获取微信sdk配置
* @returns {*}
*/
export function wechatAuth(code, spread) {
var reg=/^[0-9]+.?[0-9]*$/; //判断字符串是否为数字 ,判断正整数用/^[1-9]+[0-9]*]*$/
spread = reg.test(spread) ? spread : 0;
return request.get(
"wechat/authorize/login?code=" + code + "&spread_spid=" + spread, {},
{ noAuth: true }
);
}
/**
* 获取登录授权login
*
*/
export function getLogo()
{
// wechat/get_logo
return request.get('wechat/getLogo', {}, { noAuth : true});
}
/**
* 小程序用户登录
* @param data object 小程序用户登录信息
*/
export function login(code,data) {
return request.post("wechat/authorize/program/login?code="+code, data, { noAuth : true });
}
/**
* 分享
* @returns {*}
*/
export function getShare() {
return request.get("share", {}, { noAuth: true });
}
/**
* 获取关注海报
* @returns {*}
*/
export function follow() {
return request.get("wechat/follow", {}, { noAuth: true });
}
/**
* 获取图片base64
* @retins {*}
* */
export function imageBase64(image) {
return request.post("qrcode/base64",image,{ noAuth: true },1);
}
/**
* 自动复制口令功能
* @returns {*}
*/
export function copyWords() {
return request.get("copy_words", {}, { noAuth: true });
}
/**
* 首页 获取客服地址
* @returns {*}
*/
export function kefuConfig() {
return request.get("config", {}, { noAuth: true });
}
/**
* 微信公众号小程序绑定手机号
* @param {Object} data
*/
export function getUserPhone(data){
return request.post('wechat/register/binding/phone',data,{noAuth : true});
}
/**
* APP微信登录
* @param {Object} data
*/
export function appAuth(data) {
return request.post("wechat/authorize/app/login", data, { noAuth : true });
}
/**
* 苹果登录
* @param {Object} data
*/
export function appleLogin(data) {
return request.post("ios/login", data, { noAuth : true });
}
/**
* 苹果绑定手机号
* @param {Object} data
*/
export function iosBinding(data) {
return request.post("ios/binding/phone", data, { noAuth : true });
}

View File

@ -1,191 +0,0 @@
import request from "@/utils/request.js";
/**
* 获取产品详情
* @param int id
*
*/
export function getProductDetail(id, type) {
return request.get('product/detail/' + id + '?type=' + type, {}, {
noAuth: true
});
}
/**
* 产品分享二维码 推广员
* @param int id
*/
// #ifndef MP
export function getProductCode(id) {
return request.get('product/code/' + id, {});
}
// #endif
// #ifdef MP
export function getProductCode(id) {
return request.get('product/code/' + id, {
user_type: 'routine'
});
}
// #endif
/**
* 添加收藏
* @param int id
* @param string category product=普通产品,product_seckill=秒杀产品
*/
export function collectAdd(id, category) {
return request.post('collect/add', {
id: id,
'category': category === undefined ? 'product' : category
});
}
/**
* 取消收藏产品
* @param int id
*/
export function collectDel(proId) {
return request.post(`collect/cancel/${proId}`);
}
/**
* 删除收藏产品
* @param string id
*/
export function collectDelete(ids) {
return request.post(`collect/delete`,ids);
}
/**
* 购车添加
*
*/
export function postCartAdd(data) {
return request.post('cart/save', data, {});
}
/**
* 获取分类列表
*
*/
export function getCategoryList() {
return request.get('category', {}, {
noAuth: true
});
}
/**
* 获取产品列表
* @param object data
*/
export function getProductslist(data) {
return request.get('products', data, {
noAuth: true
});
}
/**
* 获取推荐产品
*
*/
export function getProductHot(page, limit) {
return request.get("product/hot", {
page: page === undefined ? 1 : page,
limit: limit === undefined ? 4 : limit
}, {
noAuth: true
});
}
/**
* 批量收藏
*
* @param object id 产品编号 join(',') 切割成字符串
* @param string category
*/
export function collectAll(id, category) {
return request.post('collect/all', {
id: id,
category: category === undefined ? 'product' : category
});
}
/**
* 首页产品的轮播图和产品信息
* @param int type
*
*/
export function getGroomList(type, data) {
return request.get('index/product/' + type, data, {
noAuth: true
});
}
/**
* 获取收藏列表
* @param object data
*/
export function getCollectUserList(data) {
return request.get('collect/user', data)
}
/**
* 获取产品评论
* @param int id
* @param object data
*
*/
export function getReplyList(id, data) {
return request.get('reply/list/' + id, data,{
noAuth: true
})
}
/**
* 产品评价数量和好评度
* @param int id
*/
export function getReplyConfig(id) {
return request.get('reply/config/' + id,{},{
noAuth: true
});
}
/**
* 获取搜索关键字获取
*
*/
export function getSearchKeyword() {
return request.get('search/keyword', {}, {
noAuth: true
});
}
/**
* 门店列表
* @returns {*}
*/
export function storeListApi(data) {
return request.post("store/list", data, {}, 1);
}
/**
* 优品推荐
* @param object data
*/
export function getProductGood() {
return request.get('product/good');
}
/**
* 详情页产品评论
* @param int id
* @param object data
*
*/
export function getReplyProduct(id) {
return request.get('reply/product/' + id, {
noAuth: true
})
}

View File

@ -1,8 +0,0 @@
import request from "@/utils/request.js";
// 获得地区树
export function getAreaTree() {
return request.get("app-api/system/area/tree", {}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}

View File

@ -1,6 +0,0 @@
import request from "@/utils/request.js";
// 根据字典类型查询字典数据信息
export function getDicts(dictType) {
return request.get('app-api/system/dict-data/type?type=' + dictType);
}

View File

@ -1,27 +0,0 @@
import request from "@/utils/request.js";
export function getAfterSale(id) {
return request.get("app-api/trade/after-sale/get", {
id
});
}
export function getApplyingAfterSaleCount() {
return request.get("app-api/trade/after-sale/get-applying-count");
}
export function getAfterSalePage(data) {
return request.get("app-api/trade/after-sale/page", data);
}
export function createAfterSale(data) {
return request.post("app-api/trade/after-sale/create", data);
}
export function cancelAfterSale(id) {
return request.delete("app-api/trade/after-sale/cancel?id=" + id);
}
export function deliveryAfterSale(data) {
return request.put("app-api/trade/after-sale/delivery", data);
}

View File

@ -1,62 +0,0 @@
import request from "@/utils/request.js";
// 获得个人分销信息
export function getBrokerageUser() {
return request.get('app-api/trade/brokerage-user/get');
}
// 获得个人分销信息
export function bindBrokerageUser(bindUserId) {
return request.put('app-api/trade/brokerage-user/bind', {
bindUserId
});
}
// 获得个人分销统计
export function getBrokerageUserSummary() {
return request.get('app-api/trade/brokerage-user/get-summary');
}
// 获得下级分销统计分页
export function getBrokerageUserChildSummaryPage(data) {
return request.get('app-api/trade/brokerage-user/child-summary-page', data);
}
// 获得分销用户排行分页(基于用户量)
export function getBrokerageUserRankPageByUserCount(data) {
return request.get('app-api/trade/brokerage-user/rank-page-by-user-count', data);
}
// 获得分销用户排行(基于佣金)
export function getBrokerageUserRankByPrice(data) {
return request.get('app-api/trade/brokerage-user/get-rank-by-price', data);
}
// 获得分销用户排行分页(基于佣金)
export function getBrokerageUserRankPageByPrice(data) {
return request.get('app-api/trade/brokerage-user/rank-page-by-price', data);
}
// 获得分销提现分页记录
export function getBrokerageWithdrawPage(data) {
return request.get('app-api/trade/brokerage-withdraw/page', data);
}
// 创建分销提现
export function createBrokerageWithdraw(data) {
return request.post('app-api/trade/brokerage-withdraw/create', data);
}
// 获得分销记录分页
export function getBrokerageRecordPage(data) {
return request.get('app-api/trade/brokerage-record/page', data);
}
// 获得商品的分销金额
export function getProductBrokeragePrice(spuId) {
return request.get('app-api/trade/brokerage-record/get-product-brokerage-price', {
spuId
}, {
noAuth: true // TODO 芋艿:后续要做调整
});
}

View File

@ -1,33 +0,0 @@
import request from "@/utils/request.js";
export function addCart(data) {
return request.post("app-api/trade/cart/add", data);
}
export function updateCartCount(data) {
return request.put("app-api/trade/cart/update-count", data);
}
export function updateCartSelected(data) {
return request.put("app-api/trade/cart/update-selected", data);
}
export function resetCart(data) {
return request.put("app-api/trade/cart/reset", data);
}
export function getCartCount() {
return request.get("app-api/trade/cart/get-count");
}
export function getCartCountMap() {
return request.get("app-api/trade/cart/get-count-map");
}
export function getCartList() {
return request.get("app-api/trade/cart/list");
}
export function deleteCart(ids) {
return request.delete("app-api/trade/cart/delete?ids=" + ids.join(','));
}

View File

@ -1,6 +0,0 @@
import request from "@/utils/request.js";
// 获得交易配置
export function getTradeConfig() {
return request.get("app-api/trade/config/get");
}

View File

@ -1,23 +0,0 @@
import request from "@/utils/request.js";
// 获得配送配置
export function getDeliveryConfig() {
return request.get("app-api/trade/delivery/config/get", {});
}
// 获得自提门店列表
export function getDeliveryPickUpStoreList(data) {
return request.get("app-api/trade/delivery/pick-up-store/list", data);
}
// 获得自提门店
export function getDeliveryPickUpStore(id) {
return request.get("app-api/trade/delivery/pick-up-store/get", {
id
});
}
// 获得快递公司列表
export function getDeliveryExpressList() {
return request.get("app-api/trade/delivery/express/list");
}

View File

@ -1,61 +0,0 @@
import request from "@/utils/request.js";
export function settlementOrder(data) {
const data2 = {
...data,
}
// 解决 SpringMVC 接受 List<Item> 参数的问题
delete data2.items
for (let i = 0; i < data.items.length; i++) {
data2['items[' + i + '].skuId'] = data.items[i].skuId;
data2['items[' + i + '].count'] = data.items[i].count;
data2['items[' + i + '].cartId'] = data.items[i].cartId;
}
return request.get("app-api/trade/order/settlement", data2);
}
export function createOrder(data) {
return request.post("app-api/trade/order/create", data);
}
export function getOrderDetail(id) {
return request.get("app-api/trade/order/get-detail", {
id
});
}
export function getOrderCount() {
return request.get("app-api/trade/order/get-count");
}
export function getOrderPage(data) {
return request.get("app-api/trade/order/page", data);
}
export function receiveOrder(id) {
return request.put("app-api/trade/order/receive?id=" + id, {});
}
export function cancelOrder(id) {
return request.delete("app-api/trade/order/cancel?id=" + id, {});
}
export function deleteOrder(id) {
return request.delete("app-api/trade/order/delete?id=" + id, {});
}
export function getOrderItem(id) {
return request.get("app-api/trade/order/item/get", {
id
});
}
export function createOrderItemComment(data) {
return request.post("app-api/trade/order/item/create-comment", data);
}
export function getOrderExpressTrackList(id) {
return request.get("app-api/trade/order/get-express-track-list", {
id
});
}

View File

@ -1,396 +0,0 @@
import request from "@/utils/request.js";
/**
* 获取用户信息
*/
export function getUserInfo(){
return request.get('user');
}
/**
* 设置用户分享
*/
export function userShare(){
return request.post('user/share');
}
/**
* h5用户登录
* @param data object 用户账号密码
*/
export function loginH5(data) {
return request.post("login", data, { noAuth : true });
}
/**
* h5用户手机号登录
* @param data object 用户手机号 也只能
*/
export function loginMobile(data) {
return request.post("login/mobile", data, { noAuth : true });
}
/**
* 验证码key
*/
export function getCodeApi() {
return request.get("verify_code", {}, { noAuth: true });
}
/**
* h5用户发送验证码
* @param data object 用户手机号
*/
export function registerVerify(phone){
return request.post('sendCode', { phone: phone },{noAuth:true},1)
}
/**
* h5用户手机号注册
* @param data object 用户手机号 验证码 密码
*/
export function register(data) {
return request.post("register", data, { noAuth : true });
}
/**
* 用户手机号修改密码
* @param data object 用户手机号 验证码 密码
*/
export function registerReset(data) {
return request.post("register/reset", data, { noAuth: true });
}
/**
* 获取用户中心菜单
*
*/
export function getMenuList() {
return request.get("menu/user");
}
/*
* 签到用户信息
* */
export function postSignUser(sign) {
return request.post("user/sign/user", sign);
}
/**
* 获取签到配置
*
*/
export function getSignConfig(){
return request.get('user/sign/config')
}
/**
* 获取签到列表
* @param object data
*/
export function getSignList(data){
return request.get('user/sign/list',data);
}
/**
* 用户签到
*/
export function setSignIntegral(){
return request.get('user/sign/integral')
}
/**
* 签到列表(年月)
* @param object data
*
*/
export function getSignMonthList(data){
return request.get('user/sign/month',data)
}
/**
* 活动状态
*
*/
export function userActivity(){
return request.get('user/activity');
}
/*
* 余额明细types|2=全部,1=支出,2=收入
* */
export function getCommissionInfo(data) {
return request.get("spread/commission/detail", data);
}
/*
* 提现记录 getCountApi
* */
export function getRecordApi(q) {
return request.get("extract/record", q);
}
/*
* 提现总金额
* */
export function getCountApi() {
return request.get("extract/totalMoney");
}
/*
* 积分记录
* */
export function getIntegralList(q) {
return request.get("integral/list", q);
}
/**
* 获取分销海报图片
*
*/
export function spreadBanner(data){
return request.get('user/spread/banner',data);
}
/**
*
* 获取推广用户一级和二级
* @param object data
*/
export function spreadPeople(data){
return request.get('spread/people',data);
}
/**
*
* 推广佣金/提现总和
* @param int type
*/
export function spreadCount(type){
return request.get('spread/count/'+type);
}
/*
* 推广数据 当前佣金 提现总金额
* */
export function getSpreadInfo() {
return request.get("commission");
}
/**
*
* 推广订单
* @param object data
*/
export function spreadOrder(data){
return request.get('spread/order',data);
}
/*
* 获取推广人排行
* */
export function getRankList(q) {
return request.get("rank", q);
}
/*
* 获取佣金排名
* */
export function getBrokerageRank(q) {
return request.get("brokerage_rank", q);
}
/**
* 提现申请
* @param object data
*/
export function extractCash(data){
return request.post('extract/cash',data)
}
/**
* 会员等级列表
*
*/
export function userLevelGrade(){
return request.get('user/level/grade');
}
/**
* 获取某个等级任务
* @param int id 任务id
*/
export function userLevelTask(id){
return request.get('user/level/task/'+id);
}
/**
* 检查用户是否可以成为会员
*
*/
export function userLevelDetection(){
return request.get('user/level/detection');
}
/**
* 获取单个地址
* @param int id
*/
export function getAddressDetail(id){
return request.get('address/detail/'+id);
}
/**
* 修改用户信息
* @param object
*/
export function userEdit(data){
return request.post('user/edit',data);
}
/*
* 退出登录
* */
export function getLogout() {
return request.get("logout");
}
/**
* 小程序充值
*
*/
export function rechargeRoutine(data){
return request.post('recharge/routine',data)
}
/*
* 公众号充值
* */
export function rechargeWechat(data) {
return request.post("recharge/wechat", data);
}
/*
* app微信充值
* */
export function appWechat(data) {
return request.post("recharge/wechat/app", data);
}
/*
* 余额充值
* */
export function transferIn(data) {
return request.post("recharge/transferIn", data,{},1);
}
/**
* 获取默认地址
*
*/
export function getAddressDefault(){
return request.get('address/default');
}
/**
* 充值金额选择
*/
export function getRechargeApi() {
return request.get("recharge/index");
}
/**
* 登录记录
*/
export function setVisit(data)
{
return request.post('user/set_visit', {...data}, { noAuth:true});
}
/**
* 客服列表
*/
export function serviceList() {
return request.get("user/service/lst");
}
/**
* 客服详情
*/
export function getChatRecord(to_uid, data) {
return request.get("user/service/record/" + to_uid, data);
}
/**
* 静默绑定推广人
* @param {Object} puid
*/
export function spread(puid)
{
return request.get("user/bindSpread?spreadPid="+ puid);
}
/**
* 当前用户在佣金排行第几名
*
*/
export function brokerageRankNumber(data)
{
return request.get("user/brokerageRankNumber",data);
}
/**
* 会员等级经验值
*
*/
export function getlevelInfo()
{
return request.get("user/level/grade");
}
/**
* 经验值明细
*
*/
export function getlevelExpList(data)
{
return request.get("user/expList",data);
}
/**
* 经验值明细
*
*/
export function getuserDalance()
{
return request.get("user/balance");
}
/**
* 账单记录
*
*/
export function getBillList(data)
{
return request.get("recharge/bill/record",data);
}
/*
* 积分中心详情
* */
export function postIntegralUser() {
return request.get("integral/user");
}
/*
* 立即提现 冻结期冻结佣金可提现佣金最低可提现金额
* */
export function extractUser() {
return request.get("extract/user");
}
/*
* 推广人统计页 推广人数一级+二级一级人数二级人数
* */
export function spreadPeoCount() {
return request.get("spread/people/count");
}

View File

@ -1,145 +0,0 @@
<template>
<view>
<view class='Popup' v-if='isShowAuth'>
<image :src='logoUrl'></image>
<view class='title'>授权提醒</view>
<view class='tip'>请授权头像等信息以便为您提供更好的服务</view>
<view class='bottom flex'>
<view class='item' @click='close'>随便逛逛</view>
<!-- #ifdef APP-PLUS -->
<button class='item grant' @click="setUserInfo"></button>
<!-- #endif -->
<!-- #ifdef MP -->
<button class='item grant' type="primary" open-type="getUserInfo" lang="zh_CN" @getuserinfo="setUserInfo"></button>
<!-- #endif -->
</view>
</view>
<view class='mask' v-if='isShowAuth' @click='close'></view>
</view>
</template>
<script>
const app = getApp();
import Cache from '../utils/cache';
import { getLogo } from '../api/public';
import { LOGO_URL } from '../config/cache';
import { mapGetters } from 'vuex';
import Routine from '../libs/routine';
export default {
name:'Authorize',
props:{
isAuto:{
type:Boolean,
default:true
},
isGoIndex:{
type:Boolean,
default:true
},
isShowAuth:{
type:Boolean,
default:false
}
},
data(){
return {
logoUrl:''
}
},
computed:mapGetters(['isLogin','userInfo']),
watch:{
isLogin(n){
n === true && this.$emit('onLoadFun',this.userInfo);
}
},
created() {
this.getLogoUrl();
this.setAuthStatus();
},
methods:{
setAuthStatus(){
Routine.authorize().then(res=>{
if(res.islogin === false)
this.setUserInfo();
else
this.$emit('onLoadFun',this.userInfo);
}).catch(res=>{
if (this.isAuto)
this.$emit('authColse',true);
})
},
getUserInfo(code){
Routine.getUserInfo().then(res=>{
let userInfo = res.userInfo
userInfo.code = code;
userInfo.spread_spid = app.globalData.spid;//广ID
userInfo.spread_code = app.globalData.code;//广ID
userInfo.avatar = userInfo.userInfo.avatarUrl;
userInfo.city = userInfo.userInfo.city;
userInfo.country = userInfo.userInfo.country;
userInfo.nickName = userInfo.userInfo.nickName;
userInfo.province = userInfo.userInfo.province;
userInfo.sex = userInfo.userInfo.gender;
Routine.authUserInfo(code,userInfo).then(res=>{
uni.hideLoading();
this.$emit('authColse',false);
this.$emit('onLoadFun',this.userInfo);
}).catch(res=>{
uni.hideLoading();
uni.showToast({
title:res.message,
icon:'none',
duration:2000
});
})
}).catch(res =>{
uni.hideLoading();
})
},
setUserInfo(){
uni.showLoading({title:'正在登录中'});
Routine.getCode().then(code=>{
this.getUserInfo(code);
}).catch(res=>{
uni.hideLoading();
})
},
getLogoUrl(){
let that = this;
if (Cache.has(LOGO_URL)) {
this.logoUrl = Cache.get(LOGO_URL);
return;
}
getLogo().then(res=>{
that.logoUrl = res.data.logoUrl
Cache.set(LOGO_URL,that.logoUrl);
})
},
close(){
let pages = getCurrentPages(), currPage = pages[pages.length - 1];
if(this.isGoIndex){
uni.switchTab({url:'/pages/index/index'});
} else {
this.$emit('authColse',false);
}
// if (currPage && currPage.isShowAuth != undefined){
// currPage.isShowAuth = true;
// }
},
}
}
</script>
<style scoped lang='scss'>
.Popup{width:500rpx;background-color:#fff;position:fixed;top:50%;left:50%;margin-left:-250rpx;transform:translateY(-50%);z-index:320;}
.Popup image{width:150rpx;height:150rpx;margin:-67rpx auto 0 auto;display:block;border: 8rpx solid #fff;border-radius: 50%}
.Popup .title{font-size:28rpx;color:#000;text-align:center;margin-top: 30rpx}
.Popup .tip{font-size:22rpx;color:#555;padding:0 24rpx;margin-top:25rpx;}
.Popup .bottom .item{width:50%;height:80rpx;background-color:#eeeeee;text-align:center;line-height:80rpx;font-size:24rpx;color:#666;margin-top:54rpx;}
.Popup .bottom .item.on{width: 100%}
.flex{display:flex;}
.Popup .bottom .item.grant{font-size:28rpx;color:#fff;font-weight:bold;background-color:$theme-color;border-radius:0;padding:0;}
.mask{position:fixed;top:0;right:0;left:0;bottom:0;background-color:rgba(0,0,0,0.65);z-index:310;}
</style>

View File

@ -1,57 +0,0 @@
<template>
<view>
<view class="Loads acea-row row-center-wrapper" v-if="loading && !loaded" style="margin-top: .2rem;">
<view v-if="loading">
<view class="iconfont icon-jiazai loading acea-row row-center-wrapper"></view>
正在加载中
</view>
<view v-else>
上拉加载更多
</view>
</view>
</view>
</template>
<script>
export default {
name: "Loading",
props: {
loaded: {
type: Boolean,
default: false
},
loading: {
type: Boolean,
default: false
}
}
};
</script>
<style>
.Loads {
height: 80upx;
font-size: 25upx;
color: #000;
}
.Loads .iconfont {
font-size: 30upx;
margin-right: 10upx;
height: 32upx;
line-height: 32upx;
}
/*加载动画*/
@keyframes load {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.loadingpic {
animation: load 3s linear 1s infinite;
}
.loading {
animation: load linear 1s infinite;
}
</style>

View File

@ -1,189 +0,0 @@
<template>
<view>
<view class="address-window" :class="address.address ? 'on' : ''">
<view class='title'>选择地址<text class='iconfont icon-guanbi' @tap='close'></text></view>
<view class='list'>
<view class='item acea-row row-between-wrapper' :class='active === index?"font-color":""'
v-for="(item,index) in addressList" @tap='tapAddress(index,item.id)' :key='index'>
<text class='iconfont icon-ditu' :class='active===index?"font-color":""' />
<view class='address'>
<view class='name' :class='active==index?"font-color":""'>
{{ item.name }}
<text class='phone'>{{ item.mobile }}</text>
</view>
<view class='line1'>{{ item.areaName }} {{ item.detailAddress }}</view>
</view>
<text class='iconfont icon-complete' :class='active === index?"font-color":""' />
</view>
</view>
<!-- 无地址 -->
<view class='pictrue' v-if="!is_loading && !addressList.length">
<image src='../../static/images/noAddress.png'></image>
</view>
<view class='addressBnt bg-color' @tap='goAddressPages'>选择其地址</view>
</view>
<view class='mask' catchtouchmove="true" :hidden='!address.address' @tap='close' />
</view>
</template>
<script>
import * as AddressApi from '@/api/member/address.js';
export default {
props: {
pagesUrl: {
type: String,
default: '',
},
address: {
type: Object,
default: function() {
return {
address: true, //
addressId: 0,
};
}
},
isLog: {
type: Boolean,
default: false,
}
},
data() {
return {
active: 0, // addressList
is_loading: true,
addressList: []
};
},
methods: {
/**
* 选中某个地址
*/
tapAddress: function(e, addressid) {
this.active = e;
for (let i = 0; i < this.addressList.length; i++) {
if (this.addressList[i].id === addressid) {
this.$emit('OnChangeAddress', this.addressList[i]);
break
}
}
},
close: function() {
this.$emit('changeClose');
},
goAddressPages: function() {
this.$emit('changeClose');
uni.navigateTo({
url: this.pagesUrl
});
},
getAddressList: function() {
AddressApi.getAddressList().then(res => {
const addressList = res.data;
this.$set(this, 'addressList', addressList);
this.is_loading = false;
//
if (!this.address.addressId) {
return;
}
let defaultAddress = {};
for (let i = 0; i < addressList.length; i++) {
if (addressList[i].id === this.address.addressId) {
this.active = i;
defaultAddress = this.addressList[i];
}
}
})
}
}
}
</script>
<style scoped lang="scss">
.address-window {
background-color: #fff;
position: fixed;
bottom: 0;
left: 0;
width: 100%;
z-index: 101;
transform: translate3d(0, 100%, 0);
transition: all .3s cubic-bezier(.25, .5, .5, .9);
}
.address-window.on {
transform: translate3d(0, 0, 0);
}
.address-window .title {
font-size: 32rpx;
font-weight: bold;
text-align: center;
height: 123rpx;
line-height: 123rpx;
position: relative;
}
.address-window .title .iconfont {
position: absolute;
right: 30rpx;
color: #8a8a8a;
font-size: 35rpx;
}
.address-window .list .item {
margin-left: 30rpx;
padding-right: 30rpx;
border-bottom: 1px solid #eee;
height: 129rpx;
font-size: 25rpx;
color: #333;
}
.address-window .list .item .iconfont {
font-size: 37rpx;
color: #2c2c2c;
}
.address-window .list .item .iconfont.icon-complete {
font-size: 30rpx;
color: #fff;
}
.address-window .list .item .address {
width: 560rpx;
}
.address-window .list .item .address .name {
font-size: 28rpx;
font-weight: bold;
color: #282828;
margin-bottom: 4rpx;
}
.address-window .list .item .address .name .phone {
margin-left: 18rpx;
}
.address-window .addressBnt {
font-size: 30rpx;
font-weight: bold;
color: #fff;
width: 690rpx;
height: 86rpx;
border-radius: 43rpx;
text-align: center;
line-height: 86rpx;
margin: 85rpx auto;
}
.address-window .pictrue {
width: 414rpx;
height: 336rpx;
margin: 0 auto;
}
.address-window .pictrue image {
width: 100%;
height: 100%;
}
</style>

View File

@ -1,247 +0,0 @@
<template>
<view>
<view class='coupon-list-window' :class='coupon.coupon === true?"on":""'>
<view v-if="!orderShow" class="nav acea-row row-around">
<view :class="['acea-row', 'row-middle', type === 1 ? 'on' : '']" @click="setType(1)"></view>
<view :class="['acea-row', 'row-middle', type === 2 ? 'on' : '']" @click="setType(2)"></view>
<view :class="['acea-row', 'row-middle', type === 3 ? 'on' : '']" @click="setType(3)"></view>
</view>
<view class='coupon-list' :style="{'margin-top':!orderShow?'0':'50rpx'}">
<block v-if="coupon.list.length">
<view class='item acea-row row-center-wrapper' v-for="(item,index) in coupon.list"
@click="getCouponUser(index, item.id)" :key='index'>
<!-- 金额 -->
<view class='money acea-row row-column row-center-wrapper' :class='item.canTake ? "" : "moneyGray"'>
<view>
<text v-if="item.discountType === 1" class='num'>{{ fen2yuan(item.discountPrice) }}</text>
<text v-else class='num'>{{ (item.discountPercent / 10.0).toFixed(1) }} </text>
</view>
<view class="pic-num"> {{ fen2yuan(item.usePrice) }} 元可用</view>
</view>
<view class='text'>
<!-- 类型 -->
<view class='condition line2'>
<span class='line-title' :class='item.isUse?"gray":""' v-if='type === 1'>通用</span>
<span class='line-title' :class='item.isUse?"gray":""'
v-else-if='type === 3'>品类</span>
<span class='line-title' :class='item.isUse?"gray":""' v-else></span>
<span>{{item.name}}</span>
</view>
<!-- 领取类型 -->
<view class='data acea-row row-between-wrapper'>
<view v-if="item.validityType > 1"> {{ item.fixedEndTerm }} </view>
<view v-else>
{{ formatDate(item.validStartTime) + " - " + formatDate(item.validEndTime) }}
</view>
<view class='bnt bg-color' v-if="item.canTake">{{coupon.statusTile || ''}}</view>
<view class='bnt gray' v-else>{{item.use_title || ''}}</view>
</view>
</view>
</view>
</block>
<!-- 无优惠券 -->
<view class='pictrue' v-else>
<image src='../../static/images/noCoupon.png'></image>
</view>
</view>
</view>
<view class='mask' catchtouchmove="true" :hidden='!coupon.coupon' @click='close'></view>
</view>
</template>
<script>
import * as Util from '@/utils/util.js';
import dayjs from "@/plugin/dayjs/dayjs.min.js";
import * as CouponApi from '@/api/promotion/coupon.js';
export default {
props: {
openType: {
type: Number, // 0=, 1=使
default: 0,
},
coupon: {
type: Object,
default: function() {
return {};
}
},
orderShow: {
type: String, // 使 tab
default: function() {
return '';
}
}
},
data() {
return {
type: 1 // 使
};
},
methods: {
close: function() {
this.type = 1
this.$emit('ChangCouponsClose');
},
/**
* 选择优惠劵
*/
getCouponUser: function(index, id) {
//
let list = this.coupon.list;
switch (this.openType) {
case 0: //
if (!list[index].canTake) {
return;
}
CouponApi.takeCoupon(id).then(res => {
this.$util.Tips({
title: "领取成功"
});
this.$emit('ChangCoupons', list[index]);
})
break;
case 1: // 使
// TODO
if (list[index].match === false) {
alert('该优惠劵无法使用,原因:' + list[index].description);
return;
}
this.$emit('ChangCoupons', index);
break;
}
},
setType: function(type) {
this.type = type;
this.$emit('tabCouponType', type);
},
fen2yuan(price) {
return Util.fen2yuan(price)
},
formatDate: function(date) {
return dayjs(date).format("YYYY-MM-DD");
}
}
}
</script>
<style scoped lang="scss">
.coupon-list-window {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
background-color: #f5f5f5;
border-radius: 16rpx 16rpx 0 0;
z-index: 555;
transform: translate3d(0, 100%, 0);
transition: all .3s cubic-bezier(.25, .5, .5, .9);
}
.coupon-list-window.on {
transform: translate3d(0, 0, 0);
}
.coupon-list-window .title {
height: 124rpx;
width: 100%;
text-align: center;
line-height: 124rpx;
font-size: 32rpx;
font-weight: bold;
position: relative;
}
.coupon-list-window .title .iconfont {
position: absolute;
right: 30rpx;
top: 50%;
transform: translateY(-50%);
font-size: 35rpx;
color: #8a8a8a;
font-weight: normal;
}
.coupon-list-window .coupon-list {
margin: 0 0 30rpx 0;
height: 823rpx;
overflow: auto;
padding-top: 30rpx;
}
.coupon-list-window .pictrue {
width: 414rpx;
height: 336rpx;
margin: 208rpx auto;
}
.coupon-list-window .pictrue image {
width: 100%;
height: 100%;
}
.pic-num {
color: #fff;
font-size: 24rpx;
}
.line-title {
width: 90rpx;
padding: 0 10rpx;
box-sizing: border-box;
background: rgba(255, 247, 247, 1);
border: 1px solid rgba(232, 51, 35, 1);
opacity: 1;
border-radius: 20rpx;
font-size: 20rpx;
color: #E83323;
margin-right: 12rpx;
}
.line-title.gray {
border-color: #BBB;
color: #bbb;
background-color: #F5F5F5;
}
.nav {
// position: absolute;
// top: 0;
// left: 0;
width: 100%;
height: 96rpx;
border-bottom: 2rpx solid #F5F5F5;
border-top-left-radius: 16rpx;
border-top-right-radius: 16rpx;
background-color: #FFFFFF;
font-size: 30rpx;
color: #999999;
}
.nav .acea-row {
border-top: 5rpx solid transparent;
border-bottom: 5rpx solid transparent;
}
.nav .acea-row.on {
border-bottom-color: #E93323;
color: #282828;
}
.nav .acea-row:only-child {
border-bottom-color: transparent;
}
.occupy {
height: 106rpx;
}
.coupon-list .item {
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.06);
}
.coupon-list .item .money {
font-weight: normal;
}
</style>

File diff suppressed because one or more lines are too long

View File

@ -1,260 +0,0 @@
<template>
<view>
<view class="upload">
<block v-for="(upload,index) in uploads" :key="index">
<view class="uplode-file">
<image v-if="types == 'image'" class="uploade-img" :src="upload" :data-src="upload" @tap="previewImage"></image>
<image v-if="types == 'image'" class="clear-one-icon" :src="clearIcon" @tap="delImage(index)"></image>
<video v-if="types == 'video'" class="uploade-img" :src="upload" controls>
<cover-image v-if="types == 'video'" class="clear-one-icon" :src="clearIcon" @tap="delImage(index)"></cover-image>
</video>
</view>
</block>
<view class="uploader-input-box" v-if="uploads.length < uploadCount">
<view class="uploader-input" @tap="chooseUploads"></view>
</view>
</view>
<button type="primary" v-if="types == 'image'" @tap="upload"></button>
</view>
</template>
<script>
export default{
props: {
types: {
type: String,
default: 'image'
},
dataList: {
type: Array,
default: function() {
return []
}
},
clearIcon: {
type: String,
default: 'http://img1.imgtn.bdimg.com/it/u=451604666,2295832001&fm=26&gp=0.jpg'
},
uploadUrl: {
type: String,
default: ''
},
deleteUrl: {
type: String,
default: ''
},
uploadCount: {
type: Number,
default: 1
},
// 3M
upload_max: {
type: Number,
default: 3
}
},
data(){
return {
//
uploadImages: [],
//
uploads: [],
//
exceeded_list: [],
}
},
watch:{
dataList() {
this.uploads = this.dataList
}
},
methods:{
previewImage (e) {
var current = e.target.dataset.src
uni.previewImage({
current: current,
urls: this.dataList
})
},
chooseUploads(){
switch (this.types){
case 'image':
uni.chooseImage({
count: this.uploadCount - this.uploads.length, //9
sizeType: ['original', 'compressed'], //
sourceType: ['album', 'camera'], //
success: (res) => {
for(let i = 0; i< res.tempFiles.length; i++){
if(Math.ceil(res.tempFiles[i].size / 1024) < this.upload_max * 1024){
this.uploads.push(res.tempFiles[i].path)
this.uploadImages.push(res.tempFiles[i].path)
}else {
this.exceeded_list.push(i === 0 ? 1 : i + 1);
uni.showModal({
title: '提示',
content: `${[...new Set(this.exceeded_list)].join(',')}张图片超出限制${this.upload_max}MB,已过滤`
});
}
}
},
fail: (err) => {
uni.showModal({
content: JSON.stringify(err)
});
}
});
break;
case 'video' :
uni.chooseVideo({
sourceType: ['camera', 'album'],
success: (res) => {
if(Math.ceil(res.size / 1024) < this.upload_max * 1024){
this.uploads.push(res.tempFilePath)
uni.uploadFile({
url: this.uploadUrl, //
filePath: res.tempFilePath,
name: 'file',
//
formData: {
'user': 'test'
},
success: (uploadFileRes) => {
this.$emit('successVideo',uploadFileRes)
}
});
}else {
uni.showModal({
title: '提示',
content: `${[...new Set(this.exceeded_list)].join(',')}张视频超出限制${this.upload_max}MB,已过滤`
});
}
},
fail: (err) => {
uni.showModal({
content: JSON.stringify(err)
});
}
});
break;
}
},
delImage(index){
if(this.uploads[index].substring(0,4) !== 'http'){
this.uploads.splice(index,1)
return;
};
if(!this.deleteUrl) {
uni.showModal({
content: '请填写删除接口'
});
return;
};
uni.request({
url: this.deleteUrl,
method: 'DELETE',
data: {
image: this.dataList[index]
},
success: res => {
this.uploads.splice(index,1)
},
});
},
upload(){
if(!this.uploadUrl) {
uni.showModal({
content: '请填写上传接口'
});
return;
};
for (let i of this.uploadImages) {
uni.uploadFile({
url: this.uploadUrl, //
filePath: i,
name: 'file',
//
formData: {
'user': 'test'
},
success: (uploadFileRes) => {
this.$emit('successImage',uploadFileRes)
}
});
}
}
}
}
</script>
<style scoped>
.upload {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.uplode-file {
margin: 10upx;
width: 210upx;
height: 210upx;
position: relative;
}
.uploade-img {
display: block;
width: 210upx;
height: 210upx;
}
.clear-one{
position: absolute;
top: -10rpx;
right: 0;
}
.clear-one-icon{
position: absolute;
width: 20px;
height: 20px;
top: 0;
right: 0;
z-index: 9;
}
.uploader-input-box {
position: relative;
margin:10upx;
width: 208upx;
height: 208upx;
border: 2upx solid #D9D9D9;
}
.uploader-input-box:before,
.uploader-input-box:after {
content: " ";
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
background-color: #D9D9D9;
}
.uploader-input-box:before {
width: 4upx;
height: 79upx;
}
.uploader-input-box:after {
width: 79upx;
height: 4upx;
}
.uploader-input-box:active {
border-color: #999999;
}
.uploader-input-box:active:before,
.uploader-input-box:active:after {
background-color: #999999;
}
.uploader-input {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
}
</style>

View File

@ -1,40 +0,0 @@
### easy-upload 组件
使用方法
```js
<easy-upload
:dataList="imageList" uploadUrl="http://localhost:3000/upload" :types="category"
deleteUrl='http://localhost:3000/upload' :uploadCount="6"
@successImage="successImage" @successVideo="successvideo"
></easy-upload>
//先引入组件
import easyUpload from '@/components/easy-upload/easy-upload.vue'
//注册组件
components:{
easyUpload
}
//使用 easycom 可以直接使用
```
| 参数 | 类型 | 是否必填 | 参数描述
| ---- | ---- | ---- | ----
| types | String | 否 | 上传类型 image/video
| dataList | Array | 否 | 图片/视频数据展示
| clearIcon | String | 否 | 删除图标(可以换成自己本地图片)
| uploadUrl | String | 否 | 上传的接口
| deleteUrl | String | 否 | 删除的接口
| uploadCount | Number | 否 | 上传图片最大个数(默认为一张)
| upload_max | Number | 否 | 上传大小(默认为3M)
| upload_max | Number | 否 | 上传大小(默认为3M)
| upload_max | Number | 否 | 上传大小(默认为3M)
| 事件 | 是否必填 | 参数描述
| ---- | ---- | ----
| successImage | 否 | 上传图片成功事件
| successVideo | 否 | 上传视频成功回调
示例项目中有服务端代码 (node.js)

View File

@ -1,37 +0,0 @@
<template>
<view class="empty-box">
<image src="../static/images/empty-box.png"></image>
<view class="txt">{{title}}</view>
</view>
</template>
<script>
export default{
props: {
title: {
type: String,
default: '暂无记录',
},
},
}
</script>
<style lang="scss">
.empty-box{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin-top: 200rpx;
padding-bottom: 60rpx;
image{
width: 414rpx;
height: 240rpx;
}
.txt{
font-size: 26rpx;
color: #999;
}
}
</style>

View File

@ -1,140 +0,0 @@
<template>
<view class='goodList'>
<block v-for="(item,index) in bastList" :key="index">
<view @click="goDetail(item)" class='item acea-row row-between-wrapper' hover-class="none">
<view class='pictrue'>
<image :src='item.picUrl'></image>
<span class="pictrue_log pictrue_log_class" v-if="item.activityList && item.activityList[0] && item.activityList[0].type === 1"></span>
<span class="pictrue_log pictrue_log_class" v-if="item.activityList && item.activityList[0] && item.activityList[0].type === 2"></span>
<span class="pictrue_log pictrue_log_class" v-if="item.activityList && item.activityList[0] && item.activityList[0].type === 3"></span>
</view>
<view class='underline'>
<view class='text'>
<view class='line1'>{{ item.name }}</view>
<view class='money font-color'><text class='num'>{{ fen2yuan(item.price) }}</text></view>
<view class='vip-money acea-row row-middle' v-if="item.vipPrice > 0">{{ fen2yuan(item.price - item.vipPrice) }}
<image src='../../static/images/vip.png'></image><text class='num'>已售{{ item.salesCount }}{{item.unitName}}</text>
</view>
<view class='vip-money acea-row row-middle' v-else><text class='num'>已售{{ item.salesCount }}{{item.unitName}}</text></view>
</view>
</view>
<view class='iconfont icon-gouwuche cart-color acea-row row-center-wrapper'></view>
</view>
</block>
</view>
</template>
<script>
import {mapGetters} from "vuex";
import { goShopDetail } from '@/libs/order.js'
import * as Util from '@/utils/util.js';
export default {
computed: mapGetters(['uid']),
props: {
status: {
type: Number,
default: 0,
},
bastList: {
type: Array,
default: function() {
return [];
}
}
},
methods: {
goDetail(item) {
goShopDetail(item,this.uid).then(() =>{
uni.navigateTo({
url:`/pages/goods_details/index?id=${item.id}`
})
})
},
fen2yuan(price) {
return Util.fen2yuan(price)
}
}
}
</script>
<style scoped lang='scss'>
.goodList .item {
position: relative;
padding-left: 30rpx;
}
.goodList .item .pictrue {
width: 180rpx;
height: 180rpx;
position: relative;
}
.goodList .item .pictrue image {
width: 100%;
height: 100%;
border-radius: 6rpx;
}
.goodList .item .pictrue .numPic {
position: absolute;
left: 7rpx;
top: 7rpx;
width: 50rpx;
height: 50rpx;
border-radius: 50%;
}
.goodList .item .underline {
padding: 30rpx 30rpx 30rpx 0;
border-bottom: 1px solid #f5f5f5;
}
.goodList .item:nth-last-child(1) .underline {
border-bottom: 0;
}
.goodList .item .text {
font-size: 30rpx;
color: #222;
width: 489rpx;
}
.goodList .item .text .money {
font-size: 26rpx;
font-weight: bold;
margin-top: 50rpx;
}
.goodList .item .text .money .num {
font-size: 34rpx;
}
.goodList .item .text .vip-money {
font-size: 24rpx;
color: #282828;
font-weight: bold;
margin-top: 15rpx;
}
.goodList .item .text .vip-money image {
width: 46rpx;
height: 21rpx;
margin: 0 22rpx 0 5rpx;
}
.goodList .item .text .vip-money .num {
font-size: 22rpx;
color: #aaa;
font-weight: normal;
margin: -2rpx 0 0 0;
}
.goodList .item .iconfont {
position: absolute;
right: 30rpx;
width: 50rpx;
height: 50rpx;
border-radius: 50%;
font-size: 30rpx;
bottom: 38rpx;
}
</style>

View File

@ -1,107 +0,0 @@
<template>
<view style="touch-action: none;">
<view class="home" style="position:fixed;" :style="{ top: top + 'px'}" id="right-nav" @touchmove.stop.prevent="setTouchMove">
<view class="homeCon bg-color-red" :class="homeActive === true ? 'on' : ''" v-if="homeActive">
<navigator hover-class='none' url='/pages/index/index' open-type='switchTab'
class='iconfont icon-shouye-xianxing' />
<navigator hover-class='none' url='/pages/order_addcart/order_addcart' open-type='switchTab'
class='iconfont icon-caigou-xianxing' />
<navigator hover-class='none' url='/pages/user/index' open-type='switchTab'
class='iconfont icon-yonghu1' />
</view>
<view @click="open" class="pictrueBox">
<view class="pictrue">
<image :src="homeActive === true ? '/static/images/close.gif' : '/static/images/open.gif'" class="image" />
</view>
</view>
</view>
</view>
</template>
<script>
import {
mapGetters
} from "vuex";
export default {
name: "Home",
props: {},
data: function() {
return {
top: "500"
};
},
computed: mapGetters(["homeActive"]),
methods: {
setTouchMove(e) {
if (e.touches[0].clientY < 545 && e.touches[0].clientY > 66) {
this.top = e.touches[0].clientY
}
},
open: function() {
this.homeActive ?
this.$store.commit("CLOSE_HOME") :
this.$store.commit("OPEN_HOME");
}
}
};
</script>
<style scoped>
.pictrueBox {
width: 130rpx;
height: 120rpx;
}
/*返回主页按钮*/
.home {
position: fixed;
color: white;
text-align: center;
z-index: 9999;
right: 15rpx;
display: flex;
}
.home .homeCon {
border-radius: 50rpx;
opacity: 0;
height: 0;
color: $theme-color;
width: 0;
}
.home .homeCon.on {
opacity: 1;
animation: bounceInRight 0.5s cubic-bezier(0.215, 0.610, 0.355, 1.000);
width: 300rpx;
height: 86rpx;
margin-bottom: 20rpx;
display: flex;
justify-content: center;
align-items: center;
background: #f44939 !important;
}
.home .homeCon .iconfont {
font-size: 48rpx;
color: #fff;
display: inline-block;
margin: 0 auto;
}
.home .pictrue {
width: 86rpx;
height: 86rpx;
border-radius: 50%;
margin: 0 auto;
}
.home .pictrue .image {
width: 100%;
height: 100%;
border-radius: 50%;
transform: rotate(90deg);
ms-transform: rotate(90deg);
moz-transform: rotate(90deg);
webkit-transform: rotate(90deg);
o-transform: rotate(90deg);
}
</style>

View File

@ -1,814 +0,0 @@
<!--
parser 主模块组件
githubhttps://github.com/jin-yufeng/Parser
docshttps://jin-yufeng.github.io/Parser
插件市场https://ext.dcloud.net.cn/plugin?id=805
authorJinYufeng
update2020/04/14
-->
<template>
<view>
<slot v-if="!nodes.length" />
<!--#ifdef APP-PLUS-NVUE-->
<web-view id="top" ref="web" :src="src" :style="'margin-top:-2px;height:'+height+'px'" @onPostMessage="_message" />
<!--#endif-->
<!--#ifndef APP-PLUS-NVUE-->
<view id="top" :style="showAm+(selectable?';user-select:text;-webkit-user-select:text':'')" :animation="scaleAm" @tap="_tap"
@touchstart="_touchstart" @touchmove="_touchmove">
<!--#ifdef H5-->
<div :id="'rtf'+uid"></div>
<!--#endif-->
<!--#ifndef H5-->
<trees :nodes="nodes" :lazy-load="lazyLoad" :loadVideo="loadVideo" />
<image v-for="(item, index) in imgs" v-bind:key="index" :id="index" :src="item" hidden @load="_load" />
<!--#endif-->
</view>
<!--#endif-->
</view>
</template>
<script>
// #ifndef H5 || APP-PLUS-NVUE
import trees from './libs/trees';
var cache = {},
// #ifdef MP-WEIXIN || MP-TOUTIAO
fs = uni.getFileSystemManager ? uni.getFileSystemManager() : null,
// #endif
Parser = require('./libs/MpHtmlParser.js');
var document; // document https://jin-yufeng.github.io/Parser/#/instructions?id=document
// cache key
function hash(str) {
for (var i = str.length, val = 5381; i--;)
val += (val << 5) + str.charCodeAt(i);
return val;
}
// #endif
// #ifdef H5 || APP-PLUS-NVUE
var rpx = uni.getSystemInfoSync().screenWidth / 750,
cfg = require('./libs/config.js');
// #endif
// #ifdef APP-PLUS-NVUE
var dom = weex.requireModule('dom');
// #endif
export default {
name: 'parser',
data() {
return {
// #ifdef APP-PLUS
loadVideo: false,
// #endif
// #ifdef H5
uid: this._uid,
// #endif
// #ifdef APP-PLUS-NVUE
src: '',
height: 1,
// #endif
// #ifndef APP-PLUS-NVUE
scaleAm: '',
showAm: '',
imgs: [],
// #endif
nodes: []
}
},
// #ifndef H5 || APP-PLUS-NVUE
components: {
trees
},
// #endif
props: {
'html': null,
// #ifndef MP-ALIPAY
'autopause': {
type: Boolean,
default: true
},
// #endif
'autosetTitle': {
type: Boolean,
default: true
},
// #ifndef H5 || APP-PLUS-NVUE
'compress': Number,
'useCache': Boolean,
'xml': Boolean,
// #endif
'domain': String,
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
'gestureZoom': Boolean,
// #endif
// #ifdef MP-WEIXIN || MP-QQ || H5 || APP-PLUS
'lazyLoad': Boolean,
// #endif
'selectable': Boolean,
'tagStyle': Object,
'showWithAnimation': Boolean,
'useAnchor': Boolean
},
watch: {
html(html) {
this.setContent(html);
}
},
mounted() {
//
this.imgList = [];
this.imgList.each = function(f) {
for (var i = 0, len = this.length; i < len; i++)
this.setItem(i, f(this[i], i, this));
}
this.imgList.setItem = function(i, src) {
if (i == void 0 || !src) return;
// #ifndef MP-ALIPAY || APP-PLUS
//
if (src.indexOf('http') == 0 && this.includes(src)) {
var newSrc = '';
for (var j = 0, c; c = src[j]; j++) {
if (c == '/' && src[j - 1] != '/' && src[j + 1] != '/') break;
newSrc += Math.random() > 0.5 ? c.toUpperCase() : c;
}
newSrc += src.substr(j);
return this[i] = newSrc;
}
// #endif
this[i] = src;
// data src
if (src.includes('data:image')) {
var filePath, info = src.match(/data:image\/(\S+?);(\S+?),(.+)/);
if (!info) return;
// #ifdef MP-WEIXIN || MP-TOUTIAO
filePath = `${wx.env.USER_DATA_PATH}/${Date.now()}.${info[1]}`;
fs && fs.writeFile({
filePath,
data: info[3],
encoding: info[2],
success: () => this[i] = filePath
})
// #endif
// #ifdef APP-PLUS
filePath = `_doc/parser_tmp/${Date.now()}.${info[1]}`;
var bitmap = new plus.nativeObj.Bitmap();
bitmap.loadBase64Data(src, () => {
bitmap.save(filePath, {}, () => {
bitmap.clear()
this[i] = filePath;
})
})
// #endif
}
}
if (this.html) this.setContent(this.html);
},
beforeDestroy() {
// #ifdef H5
if (this._observer) this._observer.disconnect();
// #endif
this.imgList.each(src => {
// #ifdef APP-PLUS
if (src && src.includes('_doc')) {
plus.io.resolveLocalFileSystemURL(src, entry => {
entry.remove();
});
}
// #endif
// #ifdef MP-WEIXIN || MP-TOUTIAO
if (src && src.includes(uni.env.USER_DATA_PATH))
fs && fs.unlink({
filePath: src
})
// #endif
})
clearInterval(this._timer);
},
methods: {
// #ifdef H5 || APP-PLUS-NVUE
_Dom2Str(nodes) {
var str = '';
for (var node of nodes) {
if (node.type == 'text')
str += node.text;
else {
str += ('<' + node.name);
for (var attr in node.attrs || {})
str += (' ' + attr + '="' + node.attrs[attr] + '"');
if (!node.children || !node.children.length) str += '>';
else str += ('>' + this._Dom2Str(node.children) + '</' + node.name + '>');
}
}
return str;
},
_handleHtml(html, append) {
if (typeof html != 'string') html = this._Dom2Str(html.nodes || html);
// rpx
if (html.includes('rpx'))
html = html.replace(/[0-9.]+\s*rpx/g, $ => parseFloat($) * rpx + 'px');
if (!append) {
// tag-style userAgentStyles
var style = '<style>@keyframes show{0%{opacity:0}100%{opacity:1}}';
for (var item in cfg.userAgentStyles)
style += `${item}{${cfg.userAgentStyles[item]}}`;
for (item in this.tagStyle)
style += `${item}{${this.tagStyle[item]}}`;
style += '</style>';
html = style + html;
}
return html;
},
// #endif
setContent(html, append) {
// #ifdef APP-PLUS-NVUE
if (!html) {
this.src = '';
this.height = 1;
return;
}
if (append) return;
plus.io.resolveLocalFileSystemURL('_doc', entry => {
entry.getDirectory('parser_tmp', {
create: true
}, entry => {
var fileName = Date.now() + '.html';
entry.getFile(fileName, {
create: true
}, entry => {
entry.createWriter(writer => {
writer.onwriteend = () => {
this.nodes = [1];
this.src = '_doc/parser_tmp/' + fileName;
this.$nextTick(function() {
entry.remove();
})
}
html =
'<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1' +
(this.selectable ? '' : ',user-scalable=no') +
'"><script type="text/javascript" src="https://js.cdn.aliyun.dcloud.net.cn/dev/uni-app/uni.webview.1.5.2.js"></' +
'script><base href="' + this.domain + '">' + this._handleHtml(html) +
'<script>"use strict";function post(t){uni.postMessage({data:t})}' +
(this.showWithAnimation ? 'document.body.style.animation="show .5s",' : '') +
'document.addEventListener("UniAppJSBridgeReady",function(){post({action:"load",text:document.body.innerText});var t=document.getElementsByTagName("title");t.length&&post({action:"getTitle",title:t[0].innerText});for(var e,o=document.getElementsByTagName("img"),n=[],i=0,r=0;e=o[i];i++)e.onerror=function(){post({action:"error",source:"img",target:this})},e.hasAttribute("ignore")||"A"==e.parentElement.nodeName||(e.i=r++,n.push(e.src),e.onclick=function(){post({action:"preview",img:{i:this.i,src:this.src}})});post({action:"getImgList",imgList:n});for(var a,s=document.getElementsByTagName("a"),c=0;a=s[c];c++)a.onclick=function(){var t,e=this.getAttribute("href");if("#"==e[0]){var r=document.getElementById(e.substr(1));r&&(t=r.offsetTop)}return post({action:"linkpress",href:e,offset:t}),!1};;for(var u,m=document.getElementsByTagName("video"),d=0;u=m[d];d++)u.style.maxWidth="100%",u.onerror=function(){post({action:"error",source:"video",target:this})}' +
(this.autopause ? ',u.onplay=function(){for(var t,e=0;t=m[e];e++)t!=this&&t.pause()}' : '') +
';for(var g,l=document.getElementsByTagName("audio"),p=0;g=l[p];p++)g.onerror=function(){post({action:"error",source:"audio",target:this})};window.onload=function(){post({action:"ready",height:document.body.scrollHeight})}});</' +
'script>';
writer.write(html);
});
})
})
})
// #endif
// #ifdef H5
if (!html) {
if (this.rtf && !append) this.rtf.parentNode.removeChild(this.rtf);
return;
}
var div = document.createElement('div');
if (!append) {
if (this.rtf) this.rtf.parentNode.removeChild(this.rtf);
this.rtf = div;
} else {
if (!this.rtf) this.rtf = div;
else this.rtf.appendChild(div);
}
div.innerHTML = this._handleHtml(html, append);
for (var styles = this.rtf.getElementsByTagName('style'), i = 0, style; style = styles[i++];) {
style.innerHTML = style.innerHTML.replace(/body/g, '#rtf' + this._uid);
style.setAttribute('scoped', 'true');
}
//
if (!this._observer && this.lazyLoad && IntersectionObserver) {
this._observer = new IntersectionObserver(changes => {
for (let item, i = 0; item = changes[i++];) {
if (item.isIntersecting) {
item.target.src = item.target.getAttribute('data-src');
item.target.removeAttribute('data-src');
this._observer.unobserve(item.target);
}
}
}, {
rootMargin: '900px 0px 900px 0px'
})
}
var _ts = this;
//
var title = this.rtf.getElementsByTagName('title');
if (title.length && this.autosetTitle)
uni.setNavigationBarTitle({
title: title[0].innerText
})
//
this.imgList.length = 0;
var imgs = this.rtf.getElementsByTagName('img');
for (let i = 0, j = 0, img; img = imgs[i]; i++) {
img.style.maxWidth = '100%';
var src = img.getAttribute('src');
if (this.domain && src) {
if (src[0] == '/') {
if (src[1] == '/')
img.src = (this.domain.includes('://') ? this.domain.split('://')[0] : '') + ':' + src;
else img.src = this.domain + src;
} else if (!src.includes('://')) img.src = this.domain + '/' + src;
}
if (!img.hasAttribute('ignore') && img.parentElement.nodeName != 'A') {
img.i = j++;
_ts.imgList.push(img.src || img.getAttribute('data-src'));
img.onclick = function() {
var preview = true;
this.ignore = () => preview = false;
_ts.$emit('imgtap', this);
if (preview) {
uni.previewImage({
current: this.i,
urls: _ts.imgList
});
}
}
}
img.onerror = function() {
_ts.$emit('error', {
source: 'img',
target: this
});
}
if (_ts.lazyLoad && this._observer && img.src && img.i != 0) {
img.setAttribute('data-src', img.src);
img.removeAttribute('src');
this._observer.observe(img);
}
}
//
var links = this.rtf.getElementsByTagName('a');
for (var link of links) {
link.onclick = function() {
var jump = true,
href = this.getAttribute('href');
_ts.$emit('linkpress', {
href,
ignore: () => jump = false
});
if (jump && href) {
if (href[0] == '#') {
if (_ts.useAnchor) {
_ts.navigateTo({
id: href.substr(1)
})
}
} else if (href.indexOf('http') == 0 || href.indexOf('//') == 0)
return true;
else {
uni.navigateTo({
url: href
})
}
}
return false;
}
}
//
var videos = this.rtf.getElementsByTagName('video');
_ts.videoContexts = videos;
for (let video, i = 0; video = videos[i++];) {
video.style.maxWidth = '100%';
video.onerror = function() {
_ts.$emit('error', {
source: 'video',
target: this
});
}
video.onplay = function() {
if (_ts.autopause)
for (let item, i = 0; item = _ts.videoContexts[i++];)
if (item != this) item.pause();
}
}
//
var audios = this.rtf.getElementsByTagName('audios');
for (var audio of audios)
audio.onerror = function() {
_ts.$emit('error', {
source: 'audio',
target: this
});
}
this.document = this.rtf;
if (!append) document.getElementById('rtf' + this._uid).appendChild(this.rtf);
this.$nextTick(() => {
this.nodes = [1];
this.$emit('load');
})
setTimeout(() => this.showAm = '', 500);
// #endif
// #ifndef H5 || APP-PLUS-NVUE
var nodes;
if (!html)
return this.nodes = [];
else if (typeof html == 'string') {
let parser = new Parser(html, this);
//
if (this.useCache) {
var hashVal = hash(html);
if (cache[hashVal])
nodes = cache[hashVal];
else {
nodes = parser.parse();
cache[hashVal] = nodes;
}
} else nodes = parser.parse();
this.$emit('parse', nodes);
} else if (Object.prototype.toString.call(html) == '[object Array]') {
// array
if (html.length && html[0].PoweredBy != 'Parser') {
let parser = new Parser(html, this);
(function f(ns) {
for (var i = 0, n; n = ns[i]; i++) {
if (n.type == 'text') continue;
n.attrs = n.attrs || {};
for (var item in n.attrs)
if (typeof n.attrs[item] != 'string') n.attrs[item] = n.attrs[item].toString();
parser.matchAttr(n, parser);
if (n.children && n.children.length) {
parser.STACK.push(n);
f(n.children);
parser.popNode(parser.STACK.pop());
} else n.children = void 0;
}
})(html);
}
nodes = html;
} else if (typeof html == 'object' && html.nodes) {
nodes = html.nodes;
console.warn('错误的 html 类型object 类型已废弃');
} else
return console.warn('错误的 html 类型:' + typeof html);
// #ifdef APP-PLUS
this.loadVideo = false;
// #endif
if (document) this.document = new document(this.nodes, 'nodes', this);
if (append) this.nodes = this.nodes.concat(nodes);
else this.nodes = nodes;
if (nodes.length && nodes[0].title && this.autosetTitle)
uni.setNavigationBarTitle({
title: nodes[0].title
})
this.$nextTick(() => {
this.imgList.length = 0;
this.videoContexts = [];
// #ifdef MP-TOUTIAO
setTimeout(() => {
// #endif
var f = (cs) => {
for (let i = 0, c; c = cs[i++];) {
if (c.$options.name == 'trees') {
for (var j = c.nodes.length, item; item = c.nodes[--j];) {
if (item.c) continue;
if (item.name == 'img') {
this.imgList.setItem(item.attrs.i, item.attrs.src);
// #ifndef MP-ALIPAY
if (!c.observer && !c.imgLoad && item.attrs.i != '0') {
if (this.lazyLoad && uni.createIntersectionObserver) {
c.observer = uni.createIntersectionObserver(c);
c.observer.relativeToViewport({
top: 900,
bottom: 900
}).observe('._img', () => {
c.imgLoad = true;
c.observer.disconnect();
})
} else
c.imgLoad = true;
}
// #endif
}
// #ifndef MP-ALIPAY
else if (item.name == 'video') {
var ctx = uni.createVideoContext(item.attrs.id, c);
ctx.id = item.attrs.id;
this.videoContexts.push(ctx);
}
// #endif
// #ifdef MP-BAIDU || MP-ALIPAY || APP-PLUS
if (item.attrs && item.attrs.id) {
this.anchors = this.anchors || [];
this.anchors.push({
id: item.attrs.id,
node: c
})
}
// #endif
}
}
if (c.$children.length)
f(c.$children)
}
}
f(this.$children);
// #ifdef MP-TOUTIAO
}, 200)
this.$emit('load');
// #endif
// #ifdef APP-PLUS
setTimeout(() => {
this.loadVideo = true;
}, 3000);
// #endif
})
// #endif
// #ifndef APP-PLUS-NVUE
var height;
clearInterval(this._timer);
this._timer = setInterval(() => {
// #ifdef H5
var res = [this.rtf.getBoundingClientRect()];
// #endif
// #ifndef H5
// #ifdef APP-PLUS
uni.createSelectorQuery().in(this)
// #endif
// #ifndef APP-PLUS
this.createSelectorQuery()
// #endif
.select('#top').boundingClientRect().exec(res => {
// #endif
this.width = res[0].width;
if (res[0].height == height) {
this.$emit('ready', res[0])
clearInterval(this._timer);
}
height = res[0].height;
// #ifndef H5
});
// #endif
}, 350)
if (this.showWithAnimation && !append) this.showAm = 'animation:show .5s';
// #endif
},
getText(ns = this.nodes) {
// #ifdef APP-PLUS-NVUE
return this._text;
// #endif
// #ifdef H5
return this.rtf.innerText;
// #endif
// #ifndef H5 || APP-PLUS-NVUE
var txt = '';
for (var i = 0, n; n = ns[i++];) {
if (n.type == 'text') txt += n.text.replace(/&nbsp;/g, '\u00A0').replace(/&lt;/g, '<').replace(/&gt;/g, '>')
.replace(/&amp;/g, '&');
else if (n.type == 'br') txt += '\n';
else {
//
var block = n.name == 'p' || n.name == 'div' || n.name == 'tr' || n.name == 'li' || (n.name[0] == 'h' && n.name[1] >
'0' && n.name[1] < '7');
if (block && txt && txt[txt.length - 1] != '\n') txt += '\n';
if (n.children) txt += this.getText(n.children);
if (block && txt[txt.length - 1] != '\n') txt += '\n';
else if (n.name == 'td' || n.name == 'th') txt += '\t';
}
}
return txt;
// #endif
},
navigateTo(obj) {
if (!this.useAnchor)
return obj.fail && obj.fail({
errMsg: 'Anchor is disabled'
})
// #ifdef APP-PLUS-NVUE
if (!obj.id)
dom.scrollToElement(this.$refs.web);
else
this.$refs.web.evalJs('var pos=document.getElementById("' + obj.id +
'");if(pos)post({action:"linkpress",href:"#",offset:pos.offsetTop})');
return obj.success && obj.success({
errMsg: 'pageScrollTo:ok'
});
// #endif
// #ifdef H5
if (!obj.id) {
window.scrollTo(0, this.rtf.offsetTop);
return obj.success && obj.success({
errMsg: 'pageScrollTo:ok'
});
}
var target = document.getElementById(obj.id);
if (!target) return obj.fail && obj.fail({
errMsg: 'Label not found'
});
obj.scrollTop = this.rtf.offsetTop + target.offsetTop;
uni.pageScrollTo(obj);
// #endif
// #ifndef H5
var Scroll = (selector, component) => {
uni.createSelectorQuery().in(component ? component : this).select(selector).boundingClientRect().selectViewport()
.scrollOffset()
.exec(res => {
if (!res || !res[0])
return obj.fail && obj.fail({
errMsg: 'Label not found'
});
obj.scrollTop = res[1].scrollTop + res[0].top;
uni.pageScrollTo(obj);
})
}
if (!obj.id) Scroll('#top');
else {
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
Scroll('#top >>> #' + obj.id + ', #top >>> .' + obj.id);
// #endif
// #ifdef MP-BAIDU || MP-ALIPAY || APP-PLUS
for (var anchor of this.anchors)
if (anchor.id == obj.id)
Scroll('#' + obj.id + ', .' + obj.id, anchor.node);
// #endif
}
// #endif
},
getVideoContext(id) {
// #ifndef APP-PLUS-NVUE
if (!id) return this.videoContexts;
else
for (var i = this.videoContexts.length; i--;)
if (this.videoContexts[i].id == id) return this.videoContexts[i];
// #endif
},
//
preLoad(html, num) {
// #ifdef H5 || APP-PLUS-NVUE
if (html.constructor == Array)
html = this._Dom2Str(html);
var script = "var contain=document.createElement('div');contain.innerHTML='" + html.replace(/'/g, "\\'") +
"';for(var imgs=contain.querySelectorAll('img'),i=imgs.length-1;i>=" + num +
";i--)imgs[i].removeAttribute('src');";
// #endif
// #ifdef APP-PLUS-NVUE
this.$refs.web.evalJs(script);
// #endif
// #ifdef H5
eval(script);
// #endif
// #ifndef H5 || APP-PLUS-NVUE
if (typeof html == 'string') {
var id = hash(html);
html = new Parser(html, this).parse();
cache[id] = html;
}
var wait = [];
(function f(ns) {
for (var i = 0, n; n = ns[i++];) {
if (n.name == 'img' && n.attrs.src && !wait.includes(n.attrs.src))
wait.push(n.attrs.src);
f(n.children || []);
}
})(html);
if (num) wait = wait.slice(0, num);
this._wait = (this._wait || []).concat(wait);
if (!this.imgs) this.imgs = this._wait.splice(0, 15);
else if (this.imgs.length < 15)
this.imgs = this.imgs.concat(this._wait.splice(0, 15 - this.imgs.length));
// #endif
},
// #ifdef APP-PLUS-NVUE
_message(e) {
// web-view
var data = e.detail.data[0];
if (data.action == 'load') {
this.$emit('load');
this._text = data.text;
} else if (data.action == 'getTitle') {
if (this.autosetTitle)
uni.setNavigationBarTitle({
title: data.title
})
} else if (data.action == 'getImgList') {
this.imgList.length = 0;
for (var i = data.imgList.length; i--;)
this.imgList.setItem(i, data.imgList[i]);
} else if (data.action == 'preview') {
var preview = true;
data.img.ignore = () => preview = false;
this.$emit('imgtap', data.img);
if (preview)
uni.previewImage({
current: data.img.i,
urls: this.imgList
})
} else if (data.action == 'linkpress') {
var jump = true,
href = data.href;
this.$emit('linkpress', {
href,
ignore: () => jump = false
})
if (jump && href) {
if (href[0] == '#') {
if (this.useAnchor)
dom.scrollToElement(this.$refs.web, {
offset: data.offset
})
} else if (href.includes('://'))
plus.runtime.openWeb(href);
else
uni.navigateTo({
url: href
})
}
} else if (data.action == 'error')
this.$emit('error', {
source: data.source,
target: data.target
})
else if (data.action == 'ready') {
this.height = data.height;
this.$nextTick(() => {
uni.createSelectorQuery().in(this).select('#top').boundingClientRect().exec(res => {
this.rect = res[0];
this.$emit('ready', res[0]);
})
})
}
},
// #endif
// #ifndef APP-PLUS-NVUE
// #ifndef H5
_load(e) {
if (this._wait.length)
this.$set(this.imgs, e.target.id, this._wait.shift());
},
// #endif
_tap(e) {
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
if (this.gestureZoom && e.timeStamp - this._lastT < 300) {
var initY = e.touches[0].pageY - e.currentTarget.offsetTop;
if (this._zoom) {
this._scaleAm.translateX(0).scale(1).step();
uni.pageScrollTo({
scrollTop: (initY + this._initY) / 2 - e.touches[0].clientY,
duration: 400
})
} else {
var initX = e.touches[0].pageX - e.currentTarget.offsetLeft;
this._initY = initY;
this._scaleAm = uni.createAnimation({
transformOrigin: `${initX}px ${this._initY}px 0`,
timingFunction: 'ease-in-out'
});
// #ifdef MP-TOUTIAO
this._scaleAm.opacity(1);
// #endif
this._scaleAm.scale(2).step();
this._tMax = initX / 2;
this._tMin = (initX - this.width) / 2;
this._tX = 0;
}
this._zoom = !this._zoom;
this.scaleAm = this._scaleAm.export();
}
this._lastT = e.timeStamp;
// #endif
},
_touchstart(e) {
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
if (e.touches.length == 1)
this._initX = this._lastX = e.touches[0].pageX;
// #endif
},
_touchmove(e) {
// #ifndef MP-BAIDU || MP-ALIPAY || APP-PLUS
var diff = e.touches[0].pageX - this._lastX;
if (this._zoom && e.touches.length == 1 && Math.abs(diff) > 20) {
this._lastX = e.touches[0].pageX;
if ((this._tX <= this._tMin && diff < 0) || (this._tX >= this._tMax && diff > 0))
return;
this._tX += (diff * Math.abs(this._lastX - this._initX) * 0.05);
if (this._tX < this._tMin) this._tX = this._tMin;
if (this._tX > this._tMax) this._tX = this._tMax;
this._scaleAm.translateX(this._tX).step();
this.scaleAm = this._scaleAm.export();
}
// #endif
}
// #endif
}
}
</script>
<style>
@keyframes show {
0% {
opacity: 0
}
100% {
opacity: 1;
}
}
/* #ifdef MP-WEIXIN */
:host {
display: block;
overflow: scroll;
-webkit-overflow-scrolling: touch;
}
/* #endif */
</style>

View File

@ -1,102 +0,0 @@
/*
解析和匹配 Css 的选择器
githubhttps://github.com/jin-yufeng/Parser
docshttps://jin-yufeng.github.io/Parser
authorJinYufeng
update2020/03/15
*/
var cfg = require('./config.js');
class CssHandler {
constructor(tagStyle) {
var styles = Object.assign({}, cfg.userAgentStyles);
for (var item in tagStyle)
styles[item] = (styles[item] ? styles[item] + ';' : '') + tagStyle[item];
this.styles = styles;
}
getStyle = data => this.styles = new CssParser(data, this.styles).parse();
match(name, attrs) {
var tmp, matched = (tmp = this.styles[name]) ? tmp + ';' : '';
if (attrs.class) {
var items = attrs.class.split(' ');
for (var i = 0, item; item = items[i]; i++)
if (tmp = this.styles['.' + item])
matched += tmp + ';';
}
if (tmp = this.styles['#' + attrs.id])
matched += tmp + ';';
return matched;
}
}
module.exports = CssHandler;
class CssParser {
constructor(data, init) {
this.data = data;
this.floor = 0;
this.i = 0;
this.list = [];
this.res = init;
this.state = this.Space;
}
parse() {
for (var c; c = this.data[this.i]; this.i++)
this.state(c);
return this.res;
}
section = () => this.data.substring(this.start, this.i);
isLetter = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
// 状态机
Space(c) {
if (c == '.' || c == '#' || this.isLetter(c)) {
this.start = this.i;
this.state = this.Name;
} else if (c == '/' && this.data[this.i + 1] == '*')
this.Comment();
else if (!cfg.blankChar[c] && c != ';')
this.state = this.Ignore;
}
Comment() {
this.i = this.data.indexOf('*/', this.i) + 1;
if (!this.i) this.i = this.data.length;
this.state = this.Space;
}
Ignore(c) {
if (c == '{') this.floor++;
else if (c == '}' && !--this.floor) this.state = this.Space;
}
Name(c) {
if (cfg.blankChar[c]) {
this.list.push(this.section());
this.state = this.NameSpace;
} else if (c == '{') {
this.list.push(this.section());
this.Content();
} else if (c == ',') {
this.list.push(this.section());
this.Comma();
} else if (!this.isLetter(c) && (c < '0' || c > '9') && c != '-' && c != '_')
this.state = this.Ignore;
}
NameSpace(c) {
if (c == '{') this.Content();
else if (c == ',') this.Comma();
else if (!cfg.blankChar[c]) this.state = this.Ignore;
}
Comma() {
while (cfg.blankChar[this.data[++this.i]]);
if (this.data[this.i] == '{') this.Content();
else {
this.start = this.i--;
this.state = this.Name;
}
}
Content() {
this.start = ++this.i;
if ((this.i = this.data.indexOf('}', this.i)) == -1) this.i = this.data.length;
var content = this.section();
for (var i = 0, item; item = this.list[i++];)
if (this.res[item]) this.res[item] += ';' + content;
else this.res[item] = content;
this.list = [];
this.state = this.Space;
}
}

View File

@ -1,577 +0,0 @@
/*
html 解析为适用于小程序 rich-text DOM 结构
githubhttps://github.com/jin-yufeng/Parser
docshttps://jin-yufeng.github.io/Parser
authorJinYufeng
update2020/04/13
*/
var cfg = require('./config.js'),
blankChar = cfg.blankChar,
CssHandler = require('./CssHandler.js'),
{
screenWidth,
system
} = wx.getSystemInfoSync();
// #ifdef MP-BAIDU || MP-ALIPAY || MP-TOUTIAO
var entities = {
lt: '<',
gt: '>',
amp: '&',
quot: '"',
apos: "'",
nbsp: '\xA0',
ensp: '\u2002',
emsp: '\u2003',
ndash: '',
mdash: '—',
middot: '·',
lsquo: '',
rsquo: '',
ldquo: '“',
rdquo: '”',
bull: '•',
hellip: '…',
permil: '‰',
copy: '©',
reg: '®',
trade: '™',
times: '×',
divide: '÷',
cent: '¢',
pound: '£',
yen: '¥',
euro: '€',
sect: '§'
};
// #endif
var emoji; // emoji 补丁包 https://jin-yufeng.github.io/Parser/#/instructions?id=emoji
class MpHtmlParser {
constructor(data, options = {}) {
this.attrs = {};
this.compress = options.compress;
this.CssHandler = new CssHandler(options.tagStyle, screenWidth);
this.data = data;
this.domain = options.domain;
this.DOM = [];
this.i = this.start = this.audioNum = this.imgNum = this.videoNum = 0;
this.protocol = this.domain && this.domain.includes('://') ? this.domain.split('://')[0] : '';
this.state = this.Text;
this.STACK = [];
this.useAnchor = options.useAnchor;
this.xml = options.xml;
}
parse() {
if (emoji) this.data = emoji.parseEmoji(this.data);
for (var c; c = this.data[this.i]; this.i++)
this.state(c);
if (this.state == this.Text) this.setText();
while (this.STACK.length) this.popNode(this.STACK.pop());
// #ifdef MP-BAIDU || MP-TOUTIAO
// 将顶层标签的一些样式提取出来给 rich-text
(function f(ns) {
for (var i = ns.length, n; n = ns[--i];) {
if (n.type == 'text') continue;
if (!n.c) {
var style = n.attrs.style;
if (style) {
var j, k, res;
if ((j = style.indexOf('display')) != -1)
res = style.substring(j, (k = style.indexOf(';', j)) == -1 ? style.length : k);
if ((j = style.indexOf('float')) != -1)
res += ';' + style.substring(j, (k = style.indexOf(';', j)) == -1 ? style.length : k);
n.attrs.contain = res;
}
} else f(n.children);
}
})(this.DOM);
// #endif
if (this.DOM.length) {
this.DOM[0].PoweredBy = 'Parser';
if (this.title) this.DOM[0].title = this.title;
}
return this.DOM;
}
// 设置属性
setAttr() {
var name = this.getName(this.attrName);
if (cfg.trustAttrs[name]) {
if (!this.attrVal) {
if (cfg.boolAttrs[name]) this.attrs[name] = 'T';
} else if (name == 'src') this.attrs[name] = this.getUrl(this.attrVal.replace(/&amp;/g, '&'));
else this.attrs[name] = this.attrVal;
}
this.attrVal = '';
while (blankChar[this.data[this.i]]) this.i++;
if (this.isClose()) this.setNode();
else {
this.start = this.i;
this.state = this.AttrName;
}
}
// 设置文本节点
setText() {
var back, text = this.section();
if (!text) return;
text = (cfg.onText && cfg.onText(text, () => back = true)) || text;
if (back) {
this.data = this.data.substr(0, this.start) + text + this.data.substr(this.i);
let j = this.start + text.length;
for (this.i = this.start; this.i < j; this.i++) this.state(this.data[this.i]);
return;
}
if (!this.pre) {
// 合并空白符
var tmp = [];
for (let i = text.length, c; c = text[--i];)
if (!blankChar[c] || (!blankChar[tmp[0]] && (c = ' '))) tmp.unshift(c);
text = tmp.join('');
if (text == ' ') return;
}
// 处理实体
var siblings = this.siblings(),
i = -1,
j, en;
while (1) {
if ((i = text.indexOf('&', i + 1)) == -1) break;
if ((j = text.indexOf(';', i + 2)) == -1) break;
if (text[i + 1] == '#') {
en = parseInt((text[i + 2] == 'x' ? '0' : '') + text.substring(i + 2, j));
if (!isNaN(en)) text = text.substr(0, i) + String.fromCharCode(en) + text.substring(j + 1);
} else {
en = text.substring(i + 1, j);
// #ifdef MP-WEIXIN || MP-QQ || APP-PLUS
if (en == 'nbsp') text = text.substr(0, i) + '\xA0' + text.substr(j + 1); // 解决 &nbsp; 失效
else if (en != 'lt' && en != 'gt' && en != 'amp' && en != 'ensp' && en != 'emsp' && en != 'quot' && en != 'apos') {
i && siblings.push({
type: 'text',
text: text.substr(0, i)
})
siblings.push({
type: 'text',
text: `&${en};`,
en: 1
})
text = text.substr(j + 1);
i = -1;
}
// #endif
// #ifdef MP-BAIDU || MP-ALIPAY || MP-TOUTIAO
if (entities[en]) text = text.substr(0, i) + entities[en] + text.substr(j + 1);
// #endif
}
}
text && siblings.push({
type: 'text',
text
})
}
// 设置元素节点
setNode() {
var node = {
name: this.tagName.toLowerCase(),
attrs: this.attrs
},
close = cfg.selfClosingTags[node.name] || (this.xml && this.data[this.i] == '/');
this.attrs = {};
if (!cfg.ignoreTags[node.name]) {
this.matchAttr(node);
if (!close) {
node.children = [];
if (node.name == 'pre' && cfg.highlight) {
this.remove(node);
this.pre = node.pre = true;
}
this.siblings().push(node);
this.STACK.push(node);
} else if (!cfg.filter || cfg.filter(node, this) != false)
this.siblings().push(node);
} else {
if (!close) this.remove(node);
else if (node.name == 'source') {
var parent = this.STACK[this.STACK.length - 1],
attrs = node.attrs;
if (parent && attrs.src)
if (parent.name == 'video' || parent.name == 'audio')
parent.attrs.source.push(attrs.src);
else {
var i, media = attrs.media;
if (parent.name == 'picture' && !parent.attrs.src && !(attrs.src.indexOf('.webp') && system.includes('iOS')) &&
(!media || (media.includes('px') &&
(((i = media.indexOf('min-width')) != -1 && (i = media.indexOf(':', i + 8)) != -1 && screenWidth > parseInt(
media.substr(i + 1))) ||
((i = media.indexOf('max-width')) != -1 && (i = media.indexOf(':', i + 8)) != -1 && screenWidth < parseInt(
media.substr(i + 1)))))))
parent.attrs.src = attrs.src;
}
} else if (node.name == 'base' && !this.domain) this.domain = node.attrs.href;
}
if (this.data[this.i] == '/') this.i++;
this.start = this.i + 1;
this.state = this.Text;
}
// 移除标签
remove(node) {
var name = node.name,
j = this.i;
while (1) {
if ((this.i = this.data.indexOf('</', this.i + 1)) == -1) {
if (name == 'pre' || name == 'svg') this.i = j;
else this.i = this.data.length;
return;
}
this.start = (this.i += 2);
while (!blankChar[this.data[this.i]] && !this.isClose()) this.i++;
if (this.getName(this.section()) == name) {
// 代码块高亮
if (name == 'pre') {
this.data = this.data.substr(0, j + 1) + cfg.highlight(this.data.substring(j + 1, this.i - 5), node.attrs) +
this.data.substr(this.i - 5);
return this.i = j;
} else if (name == 'style')
this.CssHandler.getStyle(this.data.substring(j + 1, this.i - 7));
else if (name == 'title')
this.title = this.data.substring(j + 1, this.i - 7);
if ((this.i = this.data.indexOf('>', this.i)) == -1) this.i = this.data.length;
// 处理 svg
if (name == 'svg') {
var src = this.data.substring(j, this.i + 1);
if (!node.attrs.xmlns) src = ' xmlns="http://www.w3.org/2000/svg"' + src;
var i = j;
while (this.data[j] != '<') j--;
src = this.data.substring(j, i) + src;
var parent = this.STACK[this.STACK.length - 1];
if (node.attrs.width == '100%' && parent && (parent.attrs.style || '').includes('inline'))
parent.attrs.style = 'width:300px;max-width:100%;' + parent.attrs.style;
this.siblings().push({
name: 'img',
attrs: {
src: 'data:image/svg+xml;utf8,' + src.replace(/#/g, '%23'),
ignore: 'T'
}
})
}
return;
}
}
}
// 处理属性
matchAttr(node) {
var attrs = node.attrs,
style = this.CssHandler.match(node.name, attrs, node) + (attrs.style || ''),
styleObj = {};
if (attrs.id) {
if (this.compress & 1) attrs.id = void 0;
else if (this.useAnchor) this.bubble();
}
if ((this.compress & 2) && attrs.class) attrs.class = void 0;
switch (node.name) {
case 'img':
if (attrs['data-src']) {
attrs.src = attrs.src || attrs['data-src'];
attrs['data-src'] = void 0;
}
if (attrs.src && !attrs.ignore) {
if (this.bubble()) attrs.i = (this.imgNum++).toString();
else attrs.ignore = 'T';
}
break;
case 'a':
case 'ad':
// #ifdef APP-PLUS
case 'iframe':
case 'embed':
// #endif
this.bubble();
break;
case 'font':
if (attrs.color) {
styleObj['color'] = attrs.color;
attrs.color = void 0;
}
if (attrs.face) {
styleObj['font-family'] = attrs.face;
attrs.face = void 0;
}
if (attrs.size) {
var size = parseInt(attrs.size);
if (size < 1) size = 1;
else if (size > 7) size = 7;
var map = ['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large'];
styleObj['font-size'] = map[size - 1];
attrs.size = void 0;
}
break;
case 'video':
case 'audio':
if (!attrs.id) attrs.id = node.name + (++this[`${node.name}Num`]);
else this[`${node.name}Num`]++;
if (node.name == 'video') {
if (attrs.width) {
style = `width:${parseFloat(attrs.width) + (attrs.width.includes('%') ? '%' : 'px')};${style}`;
attrs.width = void 0;
}
if (attrs.height) {
style = `height:${parseFloat(attrs.height) + (attrs.height.includes('%') ? '%' : 'px')};${style}`;
attrs.height = void 0;
}
if (this.videoNum > 3) node.lazyLoad = true;
}
attrs.source = [];
if (attrs.src) attrs.source.push(attrs.src);
if (!attrs.controls && !attrs.autoplay)
console.warn(`存在没有 controls 属性的 ${node.name} 标签,可能导致无法播放`, node);
this.bubble();
break;
case 'td':
case 'th':
if (attrs.colspan || attrs.rowspan)
for (var k = this.STACK.length, item; item = this.STACK[--k];)
if (item.name == 'table') {
item.c = void 0;
break;
}
}
if (attrs.align) {
styleObj['text-align'] = attrs.align;
attrs.align = void 0;
}
// 压缩 style
var styles = style.replace(/&quot;/g, '"').replace(/&amp;/g, '&').split(';');
style = '';
for (var i = 0, len = styles.length; i < len; i++) {
var info = styles[i].split(':');
if (info.length < 2) continue;
let key = info[0].trim().toLowerCase(),
value = info.slice(1).join(':').trim();
if (value.includes('-webkit') || value.includes('-moz') || value.includes('-ms') || value.includes('-o') || value
.includes(
'safe'))
style += `;${key}:${value}`;
else if (!styleObj[key] || value.includes('import') || !styleObj[key].includes('import'))
styleObj[key] = value;
}
if (node.name == 'img' && parseInt(styleObj.width || attrs.width) > screenWidth)
styleObj.height = 'auto';
for (var key in styleObj) {
var value = styleObj[key];
if (key.includes('flex') || key == 'order' || key == 'self-align') node.c = 1;
// 填充链接
if (value.includes('url')) {
var j = value.indexOf('(');
if (j++ != -1) {
while (value[j] == '"' || value[j] == "'" || blankChar[value[j]]) j++;
value = value.substr(0, j) + this.getUrl(value.substr(j));
}
}
// 转换 rpx
else if (value.includes('rpx'))
value = value.replace(/[0-9.]+\s*rpx/g, $ => parseFloat($) * screenWidth / 750 + 'px');
else if (key == 'white-space' && value.includes('pre'))
this.pre = node.pre = true;
style += `;${key}:${value}`;
}
style = style.substr(1);
if (style) attrs.style = style;
}
// 节点出栈处理
popNode(node) {
// 空白符处理
if (node.pre) {
node.pre = this.pre = void 0;
for (let i = this.STACK.length; i--;)
if (this.STACK[i].pre)
this.pre = true;
}
if (node.name == 'head' || (cfg.filter && cfg.filter(node, this) == false))
return this.siblings().pop();
var attrs = node.attrs;
// 替换一些标签名
if (node.name == 'picture') {
node.name = 'img';
if (!attrs.src && (node.children[0] || '').name == 'img')
attrs.src = node.children[0].attrs.src;
if (attrs.src && !attrs.ignore)
attrs.i = (this.imgNum++).toString();
return node.children = void 0;
}
if (cfg.blockTags[node.name]) node.name = 'div';
else if (!cfg.trustTags[node.name]) node.name = 'span';
// 处理列表
if (node.c) {
if (node.name == 'ul') {
var floor = 1;
for (let i = this.STACK.length; i--;)
if (this.STACK[i].name == 'ul') floor++;
if (floor != 1)
for (let i = node.children.length; i--;)
node.children[i].floor = floor;
} else if (node.name == 'ol') {
for (let i = 0, num = 1, child; child = node.children[i++];)
if (child.name == 'li') {
child.type = 'ol';
child.num = ((num, type) => {
if (type == 'a') return String.fromCharCode(97 + (num - 1) % 26);
if (type == 'A') return String.fromCharCode(65 + (num - 1) % 26);
if (type == 'i' || type == 'I') {
num = (num - 1) % 99 + 1;
var one = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'],
ten = ['X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'],
res = (ten[Math.floor(num / 10) - 1] || '') + (one[num % 10 - 1] || '');
if (type == 'i') return res.toLowerCase();
return res;
}
return num;
})(num++, attrs.type) + '.';
}
}
}
// 处理表格的边框
if (node.name == 'table') {
var padding = attrs.cellpadding,
spacing = attrs.cellspacing,
border = attrs.border;
if (node.c) {
this.bubble();
if (!padding) padding = 2;
if (!spacing) spacing = 2;
}
if (border) attrs.style = `border:${border}px solid gray;${attrs.style || ''}`;
if (spacing) attrs.style = `border-spacing:${spacing}px;${attrs.style || ''}`;
if (border || padding)
(function f(ns) {
for (var i = 0, n; n = ns[i]; i++) {
if (n.name == 'th' || n.name == 'td') {
if (border) n.attrs.style = `border:${border}px solid gray;${n.attrs.style}`;
if (padding) n.attrs.style = `padding:${padding}px;${n.attrs.style}`;
} else f(n.children || []);
}
})(node.children)
}
this.CssHandler.pop && this.CssHandler.pop(node);
// 自动压缩
if (node.name == 'div' && !Object.keys(attrs).length) {
var siblings = this.siblings();
if (node.children.length == 1 && node.children[0].name == 'div')
siblings[siblings.length - 1] = node.children[0];
}
}
// 工具函数
bubble() {
for (var i = this.STACK.length, item; item = this.STACK[--i];) {
if (cfg.richOnlyTags[item.name]) {
if (item.name == 'table' && !Object.hasOwnProperty.call(item, 'c')) item.c = 1;
return false;
}
item.c = 1;
}
return true;
}
getName = val => this.xml ? val : val.toLowerCase();
getUrl(url) {
if (url[0] == '/') {
if (url[1] == '/') url = this.protocol + ':' + url;
else if (this.domain) url = this.domain + url;
} else if (this.domain && url.indexOf('data:') != 0 && !url.includes('://'))
url = this.domain + '/' + url;
return url;
}
isClose = () => this.data[this.i] == '>' || (this.data[this.i] == '/' && this.data[this.i + 1] == '>');
section = () => this.data.substring(this.start, this.i);
siblings = () => this.STACK.length ? this.STACK[this.STACK.length - 1].children : this.DOM;
// 状态机
Text(c) {
if (c == '<') {
var next = this.data[this.i + 1],
isLetter = c => (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
if (isLetter(next)) {
this.setText();
this.start = this.i + 1;
this.state = this.TagName;
} else if (next == '/') {
this.setText();
if (isLetter(this.data[++this.i + 1])) {
this.start = this.i + 1;
this.state = this.EndTag;
} else
this.Comment();
} else if (next == '!') {
this.setText();
this.Comment();
}
}
}
Comment() {
var key;
if (this.data.substring(this.i + 2, this.i + 4) == '--') key = '-->';
else if (this.data.substring(this.i + 2, this.i + 9) == '[CDATA[') key = ']]>';
else key = '>';
if ((this.i = this.data.indexOf(key, this.i + 2)) == -1) this.i = this.data.length;
else this.i += key.length - 1;
this.start = this.i + 1;
this.state = this.Text;
}
TagName(c) {
if (blankChar[c]) {
this.tagName = this.section();
while (blankChar[this.data[this.i]]) this.i++;
if (this.isClose()) this.setNode();
else {
this.start = this.i;
this.state = this.AttrName;
}
} else if (this.isClose()) {
this.tagName = this.section();
this.setNode();
}
}
AttrName(c) {
var blank = blankChar[c];
if (blank) {
this.attrName = this.section();
c = this.data[this.i];
}
if (c == '=') {
if (!blank) this.attrName = this.section();
while (blankChar[this.data[++this.i]]);
this.start = this.i--;
this.state = this.AttrValue;
} else if (blank) this.setAttr();
else if (this.isClose()) {
this.attrName = this.section();
this.setAttr();
}
}
AttrValue(c) {
if (c == '"' || c == "'") {
this.start++;
if ((this.i = this.data.indexOf(c, this.i + 1)) == -1) return this.i = this.data.length;
this.attrVal = this.section();
this.i++;
} else {
for (; !blankChar[this.data[this.i]] && !this.isClose(); this.i++);
this.attrVal = this.section();
}
this.setAttr();
}
EndTag(c) {
if (blankChar[c] || c == '>' || c == '/') {
var name = this.getName(this.section());
for (var i = this.STACK.length; i--;)
if (this.STACK[i].name == name) break;
if (i != -1) {
var node;
while ((node = this.STACK.pop()).name != name);
this.popNode(node);
} else if (name == 'p' || name == 'br')
this.siblings().push({
name,
attrs: {}
});
this.i = this.data.indexOf('>', this.i);
this.start = this.i + 1;
if (this.i == -1) this.i = this.data.length;
else this.state = this.Text;
}
}
}
module.exports = MpHtmlParser;

View File

@ -1,80 +0,0 @@
/* 配置文件 */
// #ifdef MP-WEIXIN
const canIUse = wx.canIUse('editor'); // 高基础库标识,用于兼容
// #endif
module.exports = {
// 过滤器函数
filter: null,
// 代码高亮函数
highlight: null,
// 文本处理函数
onText: null,
blankChar: makeMap(' ,\xA0,\t,\r,\n,\f'),
// 块级标签,将被转为 div
blockTags: makeMap('address,article,aside,body,caption,center,cite,footer,header,html,nav,section' + (
// #ifdef MP-WEIXIN
canIUse ? '' :
// #endif
',pre')),
// 将被移除的标签
ignoreTags: makeMap(
'area,base,basefont,canvas,command,frame,input,isindex,keygen,link,map,meta,param,script,source,style,svg,textarea,title,track,use,wbr'
// #ifdef MP-WEIXIN
+ (canIUse ? ',rp' : '')
// #endif
// #ifndef APP-PLUS
+ ',embed,iframe'
// #endif
),
// 只能被 rich-text 显示的标签
richOnlyTags: makeMap('a,colgroup,fieldset,legend,picture,table'
// #ifdef MP-WEIXIN
+ (canIUse ? ',bdi,bdo,caption,rt,ruby' : '')
// #endif
),
// 自闭合的标签
selfClosingTags: makeMap(
'area,base,basefont,br,col,circle,ellipse,embed,frame,hr,img,input,isindex,keygen,line,link,meta,param,path,polygon,rect,source,track,use,wbr'
),
// 信任的属性
trustAttrs: makeMap(
'align,alt,app-id,author,autoplay,border,cellpadding,cellspacing,class,color,colspan,controls,data-src,dir,face,height,href,id,ignore,loop,media,muted,name,path,poster,rowspan,size,span,src,start,style,type,unit-id,width,xmlns'
),
// bool 型的属性
boolAttrs: makeMap('autoplay,controls,ignore,loop,muted'),
// 信任的标签
trustTags: makeMap(
'a,abbr,ad,audio,b,blockquote,br,code,col,colgroup,dd,del,dl,dt,div,em,fieldset,h1,h2,h3,h4,h5,h6,hr,i,img,ins,label,legend,li,ol,p,q,source,span,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,title,ul,video'
// #ifdef MP-WEIXIN
+ (canIUse ? ',bdi,bdo,caption,pre,rt,ruby' : '')
// #endif
// #ifdef APP-PLUS
+ ',embed,iframe'
// #endif
),
// 默认的标签样式
userAgentStyles: {
address: 'font-style:italic',
big: 'display:inline;font-size:1.2em',
blockquote: 'background-color:#f6f6f6;border-left:3px solid #dbdbdb;color:#6c6c6c;padding:5px 0 5px 10px',
caption: 'display:table-caption;text-align:center',
center: 'text-align:center',
cite: 'font-style:italic',
dd: 'margin-left:40px',
img: 'max-width:100%',
mark: 'background-color:yellow',
picture: 'max-width:100%',
pre: 'font-family:monospace;white-space:pre;overflow:scroll',
s: 'text-decoration:line-through',
small: 'display:inline;font-size:0.8em',
u: 'text-decoration:underline'
}
}
function makeMap(str) {
var map = {},
list = str.split(',');
for (var i = list.length; i--;)
map[list[i]] = true;
return map;
}

View File

@ -1,35 +0,0 @@
var inlineTags = {
abbr: 1,
b: 1,
big: 1,
code: 1,
del: 1,
em: 1,
i: 1,
ins: 1,
label: 1,
q: 1,
small: 1,
span: 1,
strong: 1
}
export default {
// 从顶层标签的样式中取出一些给 rich-text
getStyle: function(style) {
if (style) {
var i, j, res = '';
if ((i = style.indexOf('display')) != -1)
res = style.substring(i, (j = style.indexOf(';', i)) == -1 ? style.length : j);
if ((i = style.indexOf('float')) != -1)
res += ';' + style.substring(i, (j = style.indexOf(';', i)) == -1 ? style.length : j);
return res;
}
},
getNode: function(item) {
return [item];
},
// 是否通过 rich-text 显示
useRichText: function(item) {
return !item.c && !inlineTags[item.name] && (item.attrs.style || '').indexOf('display:inline') == -1;
}
}

View File

@ -1,44 +0,0 @@
var inlineTags = {
abbr: 1,
b: 1,
big: 1,
code: 1,
del: 1,
em: 1,
i: 1,
ins: 1,
label: 1,
q: 1,
small: 1,
span: 1,
strong: 1
}
module.exports = {
// 从顶层标签的样式中取出一些给 rich-text
getStyle: function(style) {
if (style) {
var i, j, res = '';
if ((i = style.indexOf('display')) != -1)
res = style.substring(i, (j = style.indexOf(';', i)) == -1 ? style.length : j);
if ((i = style.indexOf('float')) != -1)
res += ';' + style.substring(i, (j = style.indexOf(';', i)) == -1 ? style.length : j);
return res;
}
},
// 处理懒加载
getNode: function(item, imgLoad) {
if (!imgLoad && item.attrs.i != '0') {
var img = {
name: 'img',
attrs: JSON.parse(JSON.stringify(item.attrs))
}
delete img.attrs.src;
img.attrs.style += ';width:20px;height:20px';
return [img];
} else return [item];
},
// 是否通过 rich-text 显示
useRichText: function(item) {
return !item.c && !inlineTags[item.name] && (item.attrs.style || '').indexOf('display:inline') == -1;
}
}

View File

@ -1,476 +0,0 @@
<!--
trees 递归显示组件
githubhttps://github.com/jin-yufeng/Parser
docshttps://jin-yufeng.github.io/Parser
插件市场https://ext.dcloud.net.cn/plugin?id=805
authorJinYufeng
update2020/04/13
-->
<template>
<view class="interlayer">
<block v-for="(n, index) in nodes" v-bind:key="index">
<!--图片-->
<!--#ifdef MP-WEIXIN || MP-QQ || MP-ALIPAY || APP-PLUS-->
<rich-text v-if="n.name=='img'" :id="n.attrs.id" class="_img" :style="''+handler.getStyle(n.attrs.style)" :nodes="handler.getNode(n,!lazyLoad||imgLoad)"
:data-attrs="n.attrs" @tap="imgtap" @longpress="imglongtap" />
<!--#endif-->
<!--#ifdef MP-BAIDU || MP-TOUTIAO-->
<rich-text v-if="n.name=='img'" :id="n.attrs.id" class="_img" :style="n.attrs.contain" :nodes='[n]' :data-attrs="n.attrs"
@tap="imgtap" @longpress="imglongtap" />
<!--#endif-->
<!--文本-->
<!--#ifdef MP-WEIXIN || MP-QQ || APP-PLUS-->
<rich-text v-else-if="n.decode" class="_entity" :nodes="[n]"></rich-text>
<!--#endif-->
<text v-else-if="n.type=='text'" decode>{{n.text}}</text>
<text v-else-if="n.name=='br'">\n</text>
<!--视频-->
<view v-else-if="n.name=='video'">
<view v-if="(!loadVideo||n.lazyLoad)&&!(controls[n.attrs.id]&&controls[n.attrs.id].play)" :id="n.attrs.id" :class="'_video '+(n.attrs.class||'')"
:style="n.attrs.style" @tap="_loadVideo" />
<video v-else :id="n.attrs.id" :class="n.attrs.class" :style="n.attrs.style" :autoplay="n.attrs.autoplay||(controls[n.attrs.id]&&controls[n.attrs.id].play)"
:controls="n.attrs.controls" :loop="n.attrs.loop" :muted="n.attrs.muted" :poster="n.attrs.poster" :src="n.attrs.source[(controls[n.attrs.id]&&controls[n.attrs.id].index)||0]"
:unit-id="n.attrs['unit-id']" :data-id="n.attrs.id" data-from="video" data-source="source" @error="error" @play="play" />
</view>
<!--音频-->
<audio v-else-if="n.name=='audio'" :class="n.attrs.class" :style="n.attrs.style" :author="n.attrs.author" :autoplay="n.attrs.autoplay"
:controls="n.attrs.controls" :loop="n.attrs.loop" :name="n.attrs.name" :poster="n.attrs.poster" :src="n.attrs.source[(controls[n.attrs.id]&&controls[n.attrs.id].index)||0]"
:data-id="n.attrs.id" data-from="audio" data-source="source" @error="error" @play="play" />
<!--链接-->
<view v-else-if="n.name=='a'" :class="'_a '+(n.attrs.class||'')" hover-class="_hover" :style="n.attrs.style"
:data-attrs="n.attrs" @tap="linkpress">
<trees class="_span" :nodes="n.children" />
</view>
<!--广告按需打开注释-->
<!--#ifdef MP-WEIXIN || MP-QQ || MP-TOUTIAO-->
<!--<ad v-else-if="n.name=='ad'" :class="n.attrs.class" :style="n.attrs.style" :unit-id="n.attrs['unit-id']"
data-from="ad" @error="error" />-->
<!--#endif-->
<!--#ifdef MP-BAIDU-->
<!--<ad v-else-if="n.name=='ad'" :class="n.attrs.class" :style="n.attrs.style" :appid="n.attrs.appid"
:apid="n.attrs.apid" :type="n.attrs.type" data-from="ad" @error="error" />-->
<!--#endif-->
<!--#ifdef APP-PLUS-->
<!--<ad v-else-if="n.name=='ad'" :class="n.attrs.class" :style="n.attrs.style" :adpid="n.attrs.adpid"
data-from="ad" @error="error" />-->
<!--#endif-->
<!--列表-->
<view v-else-if="n.name=='li'" :id="n.attrs.id" :class="n.attrs.class" :style="(n.attrs.style||'')+';display:flex'">
<view v-if="n.type=='ol'" class="_ol-bef">{{n.num}}</view>
<view v-else class="_ul-bef">
<view v-if="n.floor%3==0" class="_ul-p1"></view>
<view v-else-if="n.floor%3==2" class="_ul-p2" />
<view v-else class="_ul-p1" style="border-radius:50%"></view>
</view>
<!--#ifdef MP-ALIPAY-->
<view class="_li">
<trees :nodes="n.children" />
</view>
<!--#endif-->
<!--#ifndef MP-ALIPAY-->
<trees class="_li" :nodes="n.children" :lazyLoad="lazyLoad" :loadVideo="loadVideo" />
<!--#endif-->
</view>
<!--表格-->
<view v-else-if="n.name=='table'&&n.c" :id="n.attrs.id" :class="n.attrs.class" :style="(n.attrs.style||'')+';display:table'">
<view v-for="(tbody, i) in n.children" v-bind:key="i" :class="tbody.attrs.class" :style="(tbody.attrs.style||'')+(tbody.name[0]=='t'?';display:table-'+(tbody.name=='tr'?'row':'row-group'):'')">
<view v-for="(tr, j) in tbody.children" v-bind:key="j" :class="tr.attrs.class" :style="(tr.attrs.style||'')+(tr.name[0]=='t'?';display:table-'+(tr.name=='tr'?'row':'cell'):'')">
<trees v-if="tr.name=='td'" :nodes="tr.children" :lazyLoad="lazyLoad" :loadVideo="loadVideo" />
<block v-else>
<!--#ifdef MP-ALIPAY-->
<view v-for="(td, k) in tr.children" v-bind:key="k" :class="td.attrs.class" :style="(td.attrs.style||'')+(td.name[0]=='t'?';display:table-'+(td.name=='tr'?'row':'cell'):'')">
<trees :nodes="td.children" />
</view>
<!--#endif-->
<!--#ifndef MP-ALIPAY-->
<trees v-for="(td, k) in tr.children" v-bind:key="k" :class="td.attrs.class" :style="(td.attrs.style||'')+(td.name[0]=='t'?';display:table-'+(td.name=='tr'?'row':'cell'):'')"
:nodes="td.children" :lazyLoad="lazyLoad" :loadVideo="loadVideo" />
<!--#endif-->
</block>
</view>
</view>
</view>
<!--#ifdef APP-PLUS-->
<iframe v-else-if="n.name=='iframe'" :style="n.attrs.style" :allowfullscreen="n.attrs.allowfullscreen" :frameborder="n.attrs.frameborder"
:width="n.attrs.width" :height="n.attrs.height" :src="n.attrs.src" />
<embed v-else-if="n.name=='embed'" :style="n.attrs.style" :width="n.attrs.width" :height="n.attrs.height" :src="n.attrs.src" />
<!--#endif-->
<!--富文本-->
<!--#ifdef MP-WEIXIN || MP-QQ || MP-ALIPAY || APP-PLUS-->
<rich-text v-else-if="handler.useRichText(n)" :id="n.attrs.id" :class="'_p __'+n.name" :nodes="[n]" />
<!--#endif-->
<!--#ifdef MP-BAIDU || MP-TOUTIAO-->
<rich-text v-else-if="!(n.c||n.continue)" :id="n.attrs.id" :class="_p" :style="n.attrs.contain" :nodes="[n]" />
<!--#endif-->
<!--#ifdef MP-ALIPAY-->
<view v-else :id="n.attrs.id" :class="'_'+n.name+' '+(n.attrs.class||'')" :style="n.attrs.style">
<trees :nodes="n.children" />
</view>
<!--#endif-->
<!--#ifndef MP-ALIPAY-->
<trees v-else :class="(n.attrs.id||'')+' _'+n.name+' '+(n.attrs.class||'')" :style="n.attrs.style" :nodes="n.children"
:lazyLoad="lazyLoad" :loadVideo="loadVideo" />
<!--#endif-->
</block>
</view>
</template>
<script module="handler" lang="wxs" src="./handler.wxs"></script>
<script module="handler" lang="sjs" src="./handler.sjs"></script>
<script>
global.Parser = {};
import trees from './trees'
export default {
components: {
trees
},
name: 'trees',
data() {
return {
controls: {},
// #ifdef MP-WEIXIN || MP-QQ || APP-PLUS
imgLoad: false,
// #endif
// #ifndef APP-PLUS
loadVideo: true
// #endif
}
},
props: {
nodes: Array,
// #ifdef MP-WEIXIN || MP-QQ || H5 || APP-PLUS
lazyLoad: Boolean,
// #endif
// #ifdef APP-PLUS
loadVideo: Boolean
// #endif
},
mounted() {
//
this.top = this.$parent;
while (this.top.$options.name != 'parser') {
if (this.top.top) {
this.top = this.top.top;
break;
}
this.top = this.top.$parent;
}
},
// #ifdef MP-WEIXIN || MP-QQ || APP-PLUS
beforeDestroy() {
if (this.observer)
this.observer.disconnect();
},
// #endif
methods: {
// #ifndef MP-ALIPAY
play(e) {
if (this.top.videoContexts.length > 1 && this.top.autopause)
for (var i = this.top.videoContexts.length; i--;)
if (this.top.videoContexts[i].id != e.currentTarget.dataset.id)
this.top.videoContexts[i].pause();
},
// #endif
imgtap(e) {
var attrs = e.currentTarget.dataset.attrs;
if (!attrs.ignore) {
var preview = true, data = {
id: e.target.id,
src: attrs.src,
ignore: () => preview = false
};
global.Parser.onImgtap && global.Parser.onImgtap(data);
this.top.$emit('imgtap', data);
if (preview) {
var urls = this.top.imgList,
current = urls[attrs.i] ? parseInt(attrs.i) : (urls = [attrs.src], 0);
uni.previewImage({
current,
urls
})
}
}
},
imglongtap(e) {
var attrs = e.item.dataset.attrs;
if (!attrs.ignore)
this.top.$emit('imglongtap', {
id: e.target.id,
src: attrs.src
})
},
linkpress(e) {
var jump = true,
attrs = e.currentTarget.dataset.attrs;
attrs.ignore = () => jump = false;
global.Parser.onLinkpress && global.Parser.onLinkpress(attrs);
this.top.$emit('linkpress', attrs);
if (jump) {
// #ifdef MP
if (attrs['app-id']) {
return uni.navigateToMiniProgram({
appId: attrs['app-id'],
path: attrs.path
})
}
// #endif
if (attrs.href) {
if (attrs.href[0] == '#') {
if (this.top.useAnchor)
this.top.navigateTo({
id: attrs.href.substring(1)
})
} else if (attrs.href.indexOf('http') == 0 || attrs.href.indexOf('//') == 0) {
// #ifdef APP-PLUS
plus.runtime.openWeb(attrs.href);
// #endif
// #ifndef APP-PLUS
uni.setClipboardData({
data: attrs.href,
success: () =>
uni.showToast({
title: '链接已复制'
})
})
// #endif
} else
uni.navigateTo({
url: attrs.href
})
}
}
},
error(e) {
var context, target = e.currentTarget,
source = target.dataset.from;
if (source == 'video' || source == 'audio') {
// source
var index = this.controls[target.id] ? this.controls[target.id].index + 1 : 1;
if (index < target.dataset.source.length)
this.$set(this.controls, target.id + '.index', index);
if (source == 'video') context = uni.createVideoContext(target.id, this);
}
this.top && this.top.$emit('error', {
source,
target,
errMsg: e.detail.errMsg,
errCode: e.detail.errCode,
context
});
},
_loadVideo(e) {
this.$set(this.controls, e.currentTarget.id, {
play: true,
index: 0
})
}
}
}
</script>
<style>
/* 在这里引入自定义样式 */
/* 链接和图片效果 */
._a {
display: inline;
color: #366092;
word-break: break-all;
padding: 1.5px 0 1.5px 0;
}
._hover {
opacity: 0.7;
text-decoration: underline;
}
._img {
display: inline-block;
text-indent: 0;
}
/* #ifdef MP-WEIXIN */
:host {
display: inline;
}
/* #endif */
/* #ifdef MP */
.interlayer {
align-content: inherit;
align-items: inherit;
display: inherit;
flex-direction: inherit;
flex-wrap: inherit;
justify-content: inherit;
width: 100%;
white-space: inherit;
}
/* #endif */
._b,
._strong {
font-weight: bold;
}
._blockquote,
._div,
._p,
._ol,
._ul,
._li {
display: block;
}
._code {
font-family: monospace;
}
._del {
text-decoration: line-through;
}
._em,
._i {
font-style: italic;
}
._h1 {
font-size: 2em;
}
._h2 {
font-size: 1.5em;
}
._h3 {
font-size: 1.17em;
}
._h5 {
font-size: 0.83em;
}
._h6 {
font-size: 0.67em;
}
._h1,
._h2,
._h3,
._h4,
._h5,
._h6 {
display: block;
font-weight: bold;
}
._ins {
text-decoration: underline;
}
._li {
flex: 1;
width: 0;
}
._ol-bef {
margin-right: 5px;
text-align: right;
width: 36px;
}
._ul-bef {
line-height: normal;
margin: 0 12px 0 23px;
}
._ol-bef,
._ul_bef {
flex: none;
user-select: none;
}
._ul-p1 {
display: inline-block;
height: 0.3em;
line-height: 0.3em;
overflow: hidden;
width: 0.3em;
}
._ul-p2 {
border: 0.05em solid black;
border-radius: 50%;
display: inline-block;
height: 0.23em;
width: 0.23em;
}
._q::before {
content: '"';
}
._q::after {
content: '"';
}
._sub {
font-size: smaller;
vertical-align: sub;
}
._sup {
font-size: smaller;
vertical-align: super;
}
/* #ifndef MP-WEIXIN */
._abbr,
._b,
._code,
._del,
._em,
._i,
._ins,
._label,
._q,
._span,
._strong,
._sub,
._sup {
display: inline;
}
/* #endif */
/* #ifdef MP-WEIXIN || MP-QQ || MP-ALIPAY */
.__bdo,
.__bdi,
.__ruby,
.__rt,
._entity {
display: inline-block;
}
/* #endif */
._video {
background-color: black;
display: inline-block;
height: 225px;
position: relative;
width: 300px;
}
._video::after {
border-color: transparent transparent transparent white;
border-style: solid;
border-width: 15px 0 15px 30px;
content: '';
left: 50%;
margin: -15px 0 0 -15px;
position: absolute;
top: 50%;
}
</style>

View File

@ -1,272 +0,0 @@
<template>
<view v-if="isUp">
<view class="mobile-bg" v-if="isShow" @click="close"></view>
<view class="mobile-mask animated" :class="{slideInUp:isUp}" :style="{position:isPos?'fixed':'static'}">
<view class="input-item">
<input type="text" v-model="account" placeholder="输入手机号" />
</view>
<view class="input-item">
<input type="text" v-model="codeNum" placeholder="输入验证码" />
<button class="code" :disabled="disabled" @click="code">{{text}}</button>
</view>
<view class="sub_btn" @click="loginBtn">{{(!userInfo.phone && isLogin) || (userInfo.phone && isLogin)?'':''}}</view>
</view>
</view>
</template>
<script>
const app = getApp();
import sendVerifyCode from "@/mixins/SendVerifyCode";
import {mapGetters} from "vuex";
import * as AuthApi from "@/api/member/auth";
import * as UserApi from "@/api/member/user";
import * as BrokerageAPI from '@/api/trade/brokerage.js'
import { iosBinding } from '@/api/public';
const BACK_URL = "login_back_url";
export default {
name: 'login_mobile',
computed: mapGetters(['userInfo','isLogin']),
props: {
isUp: {
type: Boolean,
default: false,
},
authKey: {
type: String,
default: '',
},
socialCode: {
type: String,
default: '',
},
socialState: {
type: String,
default: '',
},
isShow: {
type: Boolean,
default: true
},
isPos: {
type: Boolean,
default: true
},
appleShow: {
type: String,
default: ''
},
platform: {
type: String,
default: '',
}
},
data() {
return {
account: '',
codeNum: '',
isApp: 0
}
},
mixins: [sendVerifyCode],
methods: {
//
async code() {
if (!this.account) {
return this.$util.Tips({
title: '请填写手机号码'
});
}
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(this.account)) {
return this.$util.Tips({
title: '请输入正确的手机号码'
});
}
await AuthApi.sendSmsCode(this.account, 1)
.then(res => {
this.$util.Tips({title:res.message});
this.sendCode();
})
.catch(err => {
return this.$util.Tips({
title: err
});
});
},
close() {
this.$emit('close', false)
},
//
loginBtn() {
if (!this.account) {
return this.$util.Tips({
title: '请填写手机号码'
});
}
if (!/^1(3|4|5|7|8|9|6)\d{9}$/i.test(this.account)) {
return this.$util.Tips({
title: '请输入正确的手机号码'
});
}
if (!this.codeNum) return this.$util.Tips({
title: '请填写验证码'
});
if (!/^[\w\d]+$/i.test(this.codeNum)) {
return this.$util.Tips({
title: '请输入正确的验证码'
});
}
uni.showLoading({
title: !this.userInfo.phone && this.isLogin?'正在绑定中':'正在登录中'
});
if (!this.userInfo.phone && this.isLogin) {
// TODO
iosBinding({
captcha: this.codeNum,
phone: this.account
}).then(res => {
this.$util.Tips({
title: '绑定手机号成功',
icon: 'success'
}, {
tab: 3
})
this.isApp = 1;
this.getUserInfo();
}).catch(error => {
uni.hideLoading()
this.$util.Tips({
title: error
})
})
} else {
AuthApi.smsLogin({
mobile: this.account,
code: this.codeNum,
socialType: 31,
socialCode: this.socialCode,
socialState: this.socialState
}).then(res => {
// TODO refreshToken
let data = res.data;
this.$store.commit("LOGIN", {
'token': res.data.accessToken
});
this.getUserInfo(data);
this.bindBrokerUser();
}).catch(error => {
uni.hideLoading()
this.$util.Tips({
title: error
})
})
}
},
/**
* 获取个人用户信息
*/
getUserInfo: function(data) {
this.$store.commit("SETUID", data.userId);
this.$store.commit("OPENID", data.openid);
UserApi.getUserInfo().then(res => {
uni.hideLoading();
this.$store.commit("UPDATE_USERINFO", res.data);
//
// #ifdef MP
this.$util.Tips({
title: '登录成功',
icon: 'success'
}, {
tab: 3
})
this.close()
// #endif
// #ifdef H5
this.$emit('wechatPhone', true)
// #endif
});
},
bindBrokerUser() {
const spread = this.$Cache.get("spread");
if (spread > 0) {
BrokerageAPI.bindBrokerageUser(spread)
}
}
}
}
</script>
<style lang="stylus" scoped>
.mobile-bg {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
}
.isPos {
position: static;
}
.mobile-mask {
z-index: 20;
// position: fixed;
left: 0;
bottom: 0;
width: 100%;
padding: 67rpx 30rpx;
background: #fff;
.input-item {
display: flex;
justify-content: space-between;
width: 100%;
height: 86rpx;
margin-bottom: 38rpx;
input {
flex: 1;
display: block;
height: 100%;
padding-left: 40rpx;
border-radius: 43rpx;
border: 1px solid #DCDCDC;
}
.code {
display: flex;
align-items: center;
justify-content: center;
width: 220rpx;
height: 86rpx;
margin-left: 30rpx;
background: rgba(233, 51, 35, 0.05);
font-size: 28rpx;
color: $theme-color;
border-radius: 43rpx;
&[disabled] {
background: rgba(0, 0, 0, 0.05);
color: #999;
}
}
}
.sub_btn {
width: 690rpx;
height: 86rpx;
line-height: 86rpx;
margin-top: 60rpx;
background: #E93323;
border-radius: 43rpx;
color: #fff;
font-size: 28rpx;
text-align: center;
}
}
.animated {
animation-duration: .4s
}
</style>

View File

@ -1,160 +0,0 @@
<template>
<view v-if="isPhoneBox">
<view class="mobile-bg" @click="close"></view>
<view class="mobile-mask animated" :class="{slideInUp:isUp}">
<view class="info-box">
<image :src="logoUrl"></image>
<view class="title">获取授权</view>
<view class="txt">获取微信的手机号授权</view>
</view>
<button class="sub_btn" open-type="getPhoneNumber" @getphonenumber="getphonenumber"></button>
</view>
</view>
</template>
<script>
const app = getApp();
import Routine from '@/libs/routine';
import {
loginMobile,
registerVerify,
getCodeApi,
getUserInfo
} from "@/api/user";
import { getLogo, getUserPhone } from '@/api/public';
export default{
name:'routine_phone',
props:{
isPhoneBox:{
type:Boolean,
default:false,
},
logoUrl:{
type:String,
default:'',
},
authKey:{
type:String,
default:'',
}
},
data(){
return {
keyCode:'',
account:'',
codeNum:'',
isStatus:false
}
},
mounted() {
},
methods:{
// #ifdef MP
//
getphonenumber(e){
uni.showLoading({ title: '加载中' });
Routine.getCode()
.then(code => {
this.getUserPhoneNumber(e.detail.encryptedData, e.detail.iv, code);
})
.catch(error => {
uni.hideLoading();
});
},
//
getUserPhoneNumber(encryptedData, iv, code) {
getUserPhone({
encryptedData: encryptedData,
iv: iv,
code: code,
key:this.authKey,
type: 'routine'
})
.then(res => {
this.$store.commit('LOGIN', {
token: res.data.token
});
this.$store.commit("SETUID", res.data.uid);
this.getUserInfo();
})
.catch(res => {
uni.hideLoading();
this.$util.Tips({
title: res
});
});
},
/**
* 获取个人用户信息
*/
getUserInfo: function() {
let that = this;
getUserInfo().then(res => {
uni.hideLoading();
that.userInfo = res.data
that.$store.commit("UPDATE_USERINFO", res.data);
that.isStatus = true
this.close()
});
},
// #endif
close(){
this.$emit('close',{isStatus:this.isStatus})
}
}
}
</script>
<style lang="scss">
.mobile-bg{
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
}
.mobile-mask {
z-index: 20;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
padding: 67rpx 30rpx;
background: #fff;
.info-box{
display:flex;
flex-direction: column;
align-items: center;
justify-content: center;
image{
width: 150rpx;
height: 150rpx;
border-radius: 10rpx;
}
.title{
margin-top: 30rpx;
margin-bottom: 20rpx;
font-size: 36rpx;
}
.txt{
font-size: 30rpx;
color: #868686;
}
}
.sub_btn{
width: 690rpx;
height: 86rpx;
line-height: 86rpx;
margin-top: 60rpx;
background: $theme-color;
border-radius: 43rpx;
color: #fff;
font-size: 28rpx;
text-align: center;
}
}
.animated{
animation-duration:.4s
}
</style>

View File

@ -1,406 +0,0 @@
.mpvue-calendar {
margin:auto;
width: 100%;
min-width:350px;
background: #fff;
user-select:none;
position: relative;
}
.calendar-tools{
height:40px;
font-size: 20px;
line-height: 40px;
color:#5e7a88;
box-shadow: 0px 4px 8px rgba(25, 47, 89, 0.1);
margin-bottom: 20px;
border-top: 1px solid rgba(200, 200, 200, .1);
}
.calendar-tools span{
cursor: pointer;
}
.calendar-prev{
width: 14.28571429%;
float:left;
text-align: center;
}
.calendar-prev img, .calendar-next img{
width: 34px;
height: 34px;
}
.calendar-info{
font-size:16px;
line-height: 1.3;
text-align: center;
width: 220px;
margin: 0 auto;
}
.calendar-info>div.mc-month{
margin:auto;
height:24px;
width:100px;
text-align: center;
color:#5e7a88;
overflow: hidden;
position: relative;
}
.calendar-info>div.mc-month .mc-month-inner{
position: absolute;
left:0;
top:0;
height:480px;
}
.month-transition{
transition:top .5s cubic-bezier(0.075, 0.82, 0.165, 1);
}
.calendar-info .mc-month-text{
display:block;
font-size:28px;
height:40px;
width:200px;
overflow:hidden;
text-align:center;
}
.calendar-info>div.mc-month .mc-month-inner>span{
display: block;
font-size: 14px;
height:24px;
line-height:24px;
width:100px;
overflow: hidden;
text-align: center;
}
.calendar-info>div.mc-year{
font-size:10px;
line-height: 1;
color:#999;
}
.calendar-next{
width: 14.28571429%;
float:right;
text-align: center;
}
.mpvue-calendar table {
clear: both;
width: 100%;
margin-bottom:10px;
border-collapse: collapse;
color: #444444;
}
.mpvue-calendar td {
margin:2px !important;
padding: 4px;
width: 14.28571429%;
box-sizing: border-box;
text-align: center;
vertical-align: middle;
font-size:14px;
cursor: pointer;
position: relative;
vertical-align: top;
}
.mpvue-calendar td.mc-week{
font-size:10px;
pointer-events:none !important;
cursor: default !important;
}
.mpvue-calendar td.disabled {
color: #ccc;
}
.mpvue-calendar td.disabled div{
color: #ccc;
}
.mpvue-calendar td span{
display:block;
height:100%;
width:100%;
margin:0px auto;
border-radius:50%;
position: relative;
z-index: 3;
}
.mpvue-calendar td:not(.disabled) span.mc-date-red{
color:#ea6151;
}
.mc-today{
color: #3b75fb;
}
.mpvue-calendar td.selected span{
background-color: #3b75fb;
color: #fff;
border-radius: 50%;
}
.mpvue-calendar td .mc-text{
box-sizing: border-box;
height: 0.7em;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
position: absolute;
bottom: 0px;
left: 0;
right: 0;
text-align: center;
font-size: 0.7em;
line-height: 0.7em;
z-index: 4;
}
.mpvue-calendar td .isGregorianFestival,
.mpvue-calendar td .isTerm,
.mpvue-calendar td .isLunarFestival{
color:#ea6151;
}
.mpvue-calendar td.selected span.mc-date-red{
background-color: #3b75fb;
color: #fff;
}
.selected .mc-text {
color: #fff !important;
}
.mpvue-calendar .lunarStyle .mc-text{
overflow: visible;
bottom: 20%;
}
.mpvue-calendar thead td {
text-transform: uppercase;
height:30px;
vertical-align: middle;
}
.mc-head {
margin-bottom: 10px;
}
.mc-head div {
overflow: hidden;
}
.mc-head-box div {
flex:1;
text-align: center;
font-size: 18px;
}
.mc-head-box {
display: flex;
flex-direction: row;
justify-content: center;
align-content: space-between
}
.mc-body {
padding-bottom: 20px;
}
.mc-body tr {
display: flex;
flex-direction: row;
justify-content: center;
align-content: space-between;
}
.mc-dot {
width: 8px;
height: 8px;
background-color: #ea6151;
border-radius: 50%;
position: absolute;
bottom: -4px;
left: 50%;
margin-left: -4px;
z-index: 5;
}
.remark-text {
box-sizing: border-box;
height: 0.7em;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
position: absolute;
bottom: 0px;
left: 0;
right: 0;
text-align: center;
font-size: 0.7em;
line-height: 0.7em;
z-index: 5;
}
.slot-element{
line-height: normal;
position: absolute;
z-index: 5;
}
.mpvue-calendar-change{
position: absolute;
left:0px;
top:42px;
right:0px;
bottom:0px;
background:#fff;
display: flex;
justify-content: center;
align-items: center;
flex-wrap:wrap;
overflow: auto;
transition:all .5s cubic-bezier(0.075, 0.82, 0.165, 1);
opacity: 0;
pointer-events: none;
transform: translateY(-10px);
z-index: 9;
}
.mpvue-calendar-change.show{
opacity: 1;
pointer-events: auto;
transform: translateY(0px);
}
.mpvue-calendar-change span{
margin:4px 2%;
display: inline-block;
line-height: 30px;
border-radius: 20px;
text-align:center;
color:#999;
width: 20%;
float: left;
text-align: center;
border-radius: 40px;
box-sizing: border-box;
margin-bottom: 4%;
cursor: pointer;
}
.mpvue-calendar-change span.active{
background-color: #587dff;
box-shadow: 2px 2px 2px rgba(88, 125, 255, 0.7);
color:#fff;
}
.mpvue-calendar-change .calendar-week-switch-months{
height: 100%;
}
.mpvue-calendar-change .calendar-week-switch-months span {
margin-bottom: 10px;
margin-top: 0px;
}
.calendar-years, .calendar-months{
height: 50%;
width: 100%;
padding: 10px;
box-sizing: border-box;
position: relative;
}
.calendar-years:after {
content: '';
display: block;
width: 86%;
height: 1px;
background-color: #eee;
position: absolute;
bottom: 2%;
left: 7%;
}
/*range background*/
.mc-range-mode .selected .mc-range-bg{
content: '';
display: block;
width: 150%;
height: 100%;
background-color: #01a1ed;
position: relative;
top: -100%;
left: 50%;
}
.mpvue-calendar .mc-range-mode .selected .calendar-date{
background-color: transparent;
}
.mpvue-calendar .mc-range-mode .mc-range-row-last .calendar-date, .mpvue-calendar .mc-range-mode .mc-range-row-first .calendar-date{
border-radius: 4px;
background-color: #01a1ed;
}
.mpvue-calendar .mc-range-mode .mc-range-month-first.selected .calendar-date, .mpvue-calendar .mc-range-mode .mc-range-month-last.selected .calendar-date{
background-color: #01a1ed;
border-radius: 4px;
}
.mc-range-mode .mc-range-month-last .mc-range-bg{
background-color: transparent;
border-radius: 4px;
}
.mc-range-mode .mc-range-end .mc-range-bg, .mc-range-mode .mc-range-row-last .mc-range-bg{
display: none;
}
.mc-range-row-first.mc-range-end .mc-range-bg{
display: block;
margin-left: -50%;
width: 50%;
border-radius: 4px;
}
.mpvue-calendar .mc-range-row-first.mc-range-end.month-first-date .mc-range-bg{
margin-left: 0px;
}
.mc-range-row-last.mc-range-begin .mc-range-bg{
display: block;
width: 50%;
border-radius: 4px;
}
.mpvue-calendar .mc-range-mode .selected.mc-range-second-to-last span{
background-color: #01a1ed;
border-radius: 4px;
}
.mc-range-begin.mc-range-second-to-last{
background-color: #01a1ed;
border-radius: 4px;
}
.mpvue-calendar .mc-range-mode .mc-range-end span.calendar-date, .mpvue-calendar .mc-range-mode .mc-range-begin span.calendar-date{
background-color: #3b75fb;
color: #fff;
border-radius: 50%;
}
.mpvue-calendar .mc-range-mode .month-last-date.mc-range-begin .mc-range-bg{
display: block;
width: 50%;
border-radius: 4px;
}
.mpvue-calendar .mc-range-mode .month-first-date.mc-range-end .mc-range-bg{
display: block;
width: 50%;
border-radius: 4px;
left: 0px;
}
.calendar-wrapper .mpvue-calendar .mc-range-mode .mc-range-select-one div.mc-range-bg{
display: none;
}
.mc-range-mode .mc-range-second-to-last .mc-range-bg{
border-radius: 0px 25% 25% 0px;
}
.mc-today-element .calendar-date{
background-color: rgba(25, 47, 89, 0.1);
border-radius: 4px;
}
/*week switch*/
.mpvue-calendar .mc-range-mode.week-switch .month-last-date.mc-range-begin .mc-range-bg{
width: 150%;
border-radius: 0px 20% 20% 0px;
}
.mpvue-calendar .mc-range-mode.week-switch .mc-range-month-last .mc-range-bg{
background-color: #01a1ed;
border-radius: 0px 20% 20% 0px;
}
/*month range*/
.mpvue-calendar .month-range-mode{
border-bottom: 1px solid #f2f2f2;
position: relative;
}
.mpvue-calendar .mc-month-range-mode-head{
box-shadow: 0 4px 8px rgba(25,47,89,.1);
padding: 8px 0px;
position: sticky;
top: 0px;
background-color: #fff;
z-index: 9;
}
.month-range-mode .month-rang-head {
text-align: left;
margin: 10px 0px;
padding-left: 10px;
}
.month-range-mode .mc-last-month, .month-range-mode .mc-next-month{
opacity: 0 !important;
}
.month-text-background{
position: absolute;
font-size: 140px;
width: 100%;
height: 100%;
text-align: center;
line-height: 2.4;
}

View File

@ -1,524 +0,0 @@
/**
* @1900-2100区间内的公历农历互转
* @charset UTF-8
* @Author Jea杨(JJonline@JJonline.Cn)
* @Time 2014-7-21
* @Time 2016-8-13 Fixed 2033hexAttribution Annals
* @Time 2016-9-25 Fixed lunar LeapMonth Param Bug
* @Version 1.0.2
* @公历转农历calendar.solar2lunar(1987,11,01); //[you can ignore params of prefix 0]
* @农历转公历calendar.lunar2solar(1987,09,10); //[you can ignore params of prefix 0]
*/
var calendar = {
/**
* 农历1900-2100的润大小信息表
* @Array Of Property
* @return Hex
*/
lunarInfo:[0x04bd8,0x04ae0,0x0a570,0x054d5,0x0d260,0x0d950,0x16554,0x056a0,0x09ad0,0x055d2,//1900-1909
0x04ae0,0x0a5b6,0x0a4d0,0x0d250,0x1d255,0x0b540,0x0d6a0,0x0ada2,0x095b0,0x14977,//1910-1919
0x04970,0x0a4b0,0x0b4b5,0x06a50,0x06d40,0x1ab54,0x02b60,0x09570,0x052f2,0x04970,//1920-1929
0x06566,0x0d4a0,0x0ea50,0x06e95,0x05ad0,0x02b60,0x186e3,0x092e0,0x1c8d7,0x0c950,//1930-1939
0x0d4a0,0x1d8a6,0x0b550,0x056a0,0x1a5b4,0x025d0,0x092d0,0x0d2b2,0x0a950,0x0b557,//1940-1949
0x06ca0,0x0b550,0x15355,0x04da0,0x0a5b0,0x14573,0x052b0,0x0a9a8,0x0e950,0x06aa0,//1950-1959
0x0aea6,0x0ab50,0x04b60,0x0aae4,0x0a570,0x05260,0x0f263,0x0d950,0x05b57,0x056a0,//1960-1969
0x096d0,0x04dd5,0x04ad0,0x0a4d0,0x0d4d4,0x0d250,0x0d558,0x0b540,0x0b6a0,0x195a6,//1970-1979
0x095b0,0x049b0,0x0a974,0x0a4b0,0x0b27a,0x06a50,0x06d40,0x0af46,0x0ab60,0x09570,//1980-1989
0x04af5,0x04970,0x064b0,0x074a3,0x0ea50,0x06b58,0x055c0,0x0ab60,0x096d5,0x092e0,//1990-1999
0x0c960,0x0d954,0x0d4a0,0x0da50,0x07552,0x056a0,0x0abb7,0x025d0,0x092d0,0x0cab5,//2000-2009
0x0a950,0x0b4a0,0x0baa4,0x0ad50,0x055d9,0x04ba0,0x0a5b0,0x15176,0x052b0,0x0a930,//2010-2019
0x07954,0x06aa0,0x0ad50,0x05b52,0x04b60,0x0a6e6,0x0a4e0,0x0d260,0x0ea65,0x0d530,//2020-2029
0x05aa0,0x076a3,0x096d0,0x04afb,0x04ad0,0x0a4d0,0x1d0b6,0x0d250,0x0d520,0x0dd45,//2030-2039
0x0b5a0,0x056d0,0x055b2,0x049b0,0x0a577,0x0a4b0,0x0aa50,0x1b255,0x06d20,0x0ada0,//2040-2049
/**Add By JJonline@JJonline.Cn**/
0x14b63,0x09370,0x049f8,0x04970,0x064b0,0x168a6,0x0ea50, 0x06b20,0x1a6c4,0x0aae0,//2050-2059
0x0a2e0,0x0d2e3,0x0c960,0x0d557,0x0d4a0,0x0da50,0x05d55,0x056a0,0x0a6d0,0x055d4,//2060-2069
0x052d0,0x0a9b8,0x0a950,0x0b4a0,0x0b6a6,0x0ad50,0x055a0,0x0aba4,0x0a5b0,0x052b0,//2070-2079
0x0b273,0x06930,0x07337,0x06aa0,0x0ad50,0x14b55,0x04b60,0x0a570,0x054e4,0x0d160,//2080-2089
0x0e968,0x0d520,0x0daa0,0x16aa6,0x056d0,0x04ae0,0x0a9d4,0x0a2d0,0x0d150,0x0f252,//2090-2099
0x0d520],//2100
/**
* 公历每个月份的天数普通表
* @Array Of Property
* @return Number
*/
solarMonth:[31,28,31,30,31,30,31,31,30,31,30,31],
/**
* 天干地支之天干速查表
* @Array Of Property trans["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"]
* @return Cn string
*/
Gan:["\u7532","\u4e59","\u4e19","\u4e01","\u620a","\u5df1","\u5e9a","\u8f9b","\u58ec","\u7678"],
/**
* 天干地支之地支速查表
* @Array Of Property
* @trans["子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"]
* @return Cn string
*/
Zhi:["\u5b50","\u4e11","\u5bc5","\u536f","\u8fb0","\u5df3","\u5348","\u672a","\u7533","\u9149","\u620c","\u4ea5"],
/**
* 天干地支之地支速查表<=>生肖
* @Array Of Property
* @trans["鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"]
* @return Cn string
*/
Animals:["\u9f20","\u725b","\u864e","\u5154","\u9f99","\u86c7","\u9a6c","\u7f8a","\u7334","\u9e21","\u72d7","\u732a"],
/**
* 24节气速查表
* @Array Of Property
* @trans["小寒","大寒","立春","雨水","惊蛰","春分","清明","谷雨","立夏","小满","芒种","夏至","小暑","大暑","立秋","处暑","白露","秋分","寒露","霜降","立冬","小雪","大雪","冬至"]
* @return Cn string
*/
solarTerm:["\u5c0f\u5bd2","\u5927\u5bd2","\u7acb\u6625","\u96e8\u6c34","\u60ca\u86f0","\u6625\u5206","\u6e05\u660e","\u8c37\u96e8","\u7acb\u590f","\u5c0f\u6ee1","\u8292\u79cd","\u590f\u81f3","\u5c0f\u6691","\u5927\u6691","\u7acb\u79cb","\u5904\u6691","\u767d\u9732","\u79cb\u5206","\u5bd2\u9732","\u971c\u964d","\u7acb\u51ac","\u5c0f\u96ea","\u5927\u96ea","\u51ac\u81f3"],
/**
* 1900-2100各年的24节气日期速查表
* @Array Of Property
* @return 0x string For splice
*/
sTermInfo:['9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f',
'97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f','b027097bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd0b06bdb0722c965ce1cfcc920f',
'b027097bd097c36b0b6fc9274c91aa','9778397bd19801ec9210c965cc920e','97b6b97bd19801ec95f8c965cc920f',
'97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2','9778397bd197c36c9210c9274c91aa',
'97b6b97bd19801ec95f8c965cc920e','97bd09801d98082c95f8e1cfcc920f','97bd097bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec95f8c965cc920e','97bcf97c3598082c95f8e1cfcc920f',
'97bd097bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf97c3598082c95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f',
'97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf97c359801ec95f8c965cc920f','97bd097bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf97c359801ec95f8c965cc920f','97bd097bd07f595b0b6fc920fb0722',
'9778397bd097c36b0b6fc9210c8dc2','9778397bd19801ec9210c9274c920e','97b6b97bd19801ec95f8c965cc920f',
'97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e',
'97b6b97bd19801ec95f8c965cc920f','97bd07f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36c9210c9274c91aa','97b6b97bd19801ec9210c965cc920e','97bd07f1487f595b0b0bc920fb0722',
'7f0e397bd097c36b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c965cc920e','97bcf7f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e','97bcf7f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b97bd19801ec9210c965cc920e',
'97bcf7f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b97bd19801ec9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa','97b6b97bd197c36c9210c9274c920e','97bcf7f0e47f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','9778397bd097c36c9210c9274c920e',
'97b6b7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c36b0b6fc9210c8dc2',
'9778397bd097c36b0b70c9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f595b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
'9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc920fb0722','9778397bd097c36b0b6fc9274c91aa','97b6b7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9274c91aa',
'97b6b7f0e47f531b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
'9778397bd097c36b0b6fc9210c91aa','97b6b7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','9778397bd097c36b0b6fc9210c8dc2','977837f0e37f149b0723b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722','7f0e37f5307f595b0b0bc920fb0722','7f0e397bd097c35b0b6fc9210c8dc2',
'977837f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0721','7f0e37f1487f595b0b0bb0b6fb0722',
'7f0e397bd097c35b0b6fc9210c8dc2','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722','977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd097c35b0b6fc920fb0722',
'977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14998082b0787b06bd',
'7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0b0bb0b6fb0722','7f0e397bd07f595b0b0bc920fb0722',
'977837f0e37f14998082b0723b06bd','7f07e7f0e37f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
'7f0e397bd07f595b0b0bc920fb0722','977837f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f595b0b0bb0b6fb0722','7f0e37f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e37f1487f531b0b0bb0b6fb0722',
'7f0e37f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e37f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e37f14898082b072297c35',
'7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722',
'7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f149b0723b0787b0721',
'7f0e27f1487f531b0b0bb0b6fb0722','7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14998082b0723b06bd',
'7f07e7f0e47f149b0723b0787b0721','7f0e27f0e47f531b0723b0b6fb0722','7f0e37f0e366aa89801eb072297c35',
'7ec967f0e37f14998082b0723b06bd','7f07e7f0e37f14998083b0787b0721','7f0e27f0e47f531b0723b0b6fb0722',
'7f0e37f0e366aa89801eb072297c35','7ec967f0e37f14898082b0723b02d5','7f07e7f0e37f14998082b0787b0721',
'7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66aa89801e9808297c35','665f67f0e37f14898082b0723b02d5',
'7ec967f0e37f14998082b0787b0721','7f07e7f0e47f531b0723b0b6fb0722','7f0e36665b66a449801e9808297c35',
'665f67f0e37f14898082b0723b02d5','7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721',
'7f0e36665b66a449801e9808297c35','665f67f0e37f14898082b072297c35','7ec967f0e37f14998082b0787b06bd',
'7f07e7f0e47f531b0723b0b6fb0721','7f0e26665b66a449801e9808297c35','665f67f0e37f1489801eb072297c35',
'7ec967f0e37f14998082b0787b06bd','7f07e7f0e47f531b0723b0b6fb0721','7f0e27f1487f531b0b0bb0b6fb0722'],
/**
* 数字转中文速查表
* @Array Of Property
* @trans ['日','一','二','三','四','五','六','七','八','九','十']
* @return Cn string
*/
nStr1:["\u65e5","\u4e00","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341"],
/**
* 日期转农历称呼速查表
* @Array Of Property
* @trans ['初','十','廿','卅']
* @return Cn string
*/
nStr2:["\u521d","\u5341","\u5eff","\u5345"],
/**
* 月份转农历称呼速查表
* @Array Of Property
* @trans ['正','一','二','三','四','五','六','七','八','九','十','冬','腊']
* @return Cn string
*/
nStr3:["\u6b63","\u4e8c","\u4e09","\u56db","\u4e94","\u516d","\u4e03","\u516b","\u4e5d","\u5341","\u51ac","\u814a"],
/**
* 返回农历y年一整年的总天数
* @param lunar Year
* @return Number
* @eg:var count = calendar.lYearDays(1987) ;//count=387
*/
lYearDays:function(y) {
var i, sum = 348;
for(i=0x8000; i>0x8; i>>=1) { sum += (calendar.lunarInfo[y-1900] & i)? 1: 0; }
return(sum+calendar.leapDays(y));
},
/**
* 返回农历y年闰月是哪个月若y年没有闰月 则返回0
* @param lunar Year
* @return Number (0-12)
* @eg:var leapMonth = calendar.leapMonth(1987) ;//leapMonth=6
*/
leapMonth:function(y) { //闰字编码 \u95f0
return(calendar.lunarInfo[y-1900] & 0xf);
},
/**
* 返回农历y年闰月的天数 若该年没有闰月则返回0
* @param lunar Year
* @return Number (02930)
* @eg:var leapMonthDay = calendar.leapDays(1987) ;//leapMonthDay=29
*/
leapDays:function(y) {
if(calendar.leapMonth(y)) {
return((calendar.lunarInfo[y-1900] & 0x10000)? 30: 29);
}
return(0);
},
/**
* 返回农历y年m月非闰月的总天数计算m为闰月时的天数请使用leapDays方法
* @param lunar Year
* @return Number (-12930)
* @eg:var MonthDay = calendar.monthDays(1987,9) ;//MonthDay=29
*/
monthDays:function(y,m) {
if(m>12 || m<1) {return -1}//月份参数从1至12参数错误返回-1
return( (calendar.lunarInfo[y-1900] & (0x10000>>m))? 30: 29 );
},
/**
* 返回公历(!)y年m月的天数
* @param solar Year
* @return Number (-128293031)
* @eg:var solarMonthDay = calendar.leapDays(1987) ;//solarMonthDay=30
*/
solarDays:function(y,m) {
if(m>12 || m<1) {return -1} //若参数错误 返回-1
var ms = m-1;
if(ms==1) { //2月份的闰平规律测算后确认返回28或29
return(((y%4 == 0) && (y%100 != 0) || (y%400 == 0))? 29: 28);
}else {
return(calendar.solarMonth[ms]);
}
},
/**
* 农历年份转换为干支纪年
* @param lYear 农历年的年份数
* @return Cn string
*/
toGanZhiYear:function(lYear) {
var ganKey = (lYear - 3) % 10;
var zhiKey = (lYear - 3) % 12;
if(ganKey == 0) ganKey = 10;//如果余数为0则为最后一个天干
if(zhiKey == 0) zhiKey = 12;//如果余数为0则为最后一个地支
return calendar.Gan[ganKey-1] + calendar.Zhi[zhiKey-1];
},
/**
* 公历月日判断所属星座
* @param cMonth [description]
* @param cDay [description]
* @return Cn string
*/
toAstro:function(cMonth,cDay) {
var s = "\u9b54\u7faf\u6c34\u74f6\u53cc\u9c7c\u767d\u7f8a\u91d1\u725b\u53cc\u5b50\u5de8\u87f9\u72ee\u5b50\u5904\u5973\u5929\u79e4\u5929\u874e\u5c04\u624b\u9b54\u7faf";
var arr = [20,19,21,21,21,22,23,23,23,23,22,22];
return s.substr(cMonth*2 - (cDay < arr[cMonth-1] ? 2 : 0),2) + "\u5ea7";//座
},
/**
* 传入offset偏移量返回干支
* @param offset 相对甲子的偏移量
* @return Cn string
*/
toGanZhi:function(offset) {
return calendar.Gan[offset%10] + calendar.Zhi[offset%12];
},
/**
* 传入公历(!)y年获得该年第n个节气的公历日期
* @param y公历年(1900-2100)n二十四节气中的第几个节气(1~24)从n=1(小寒)算起
* @return day Number
* @eg:var _24 = calendar.getTerm(1987,3) ;//_24=4;意即1987年2月4日立春
*/
getTerm:function(y,n) {
if(y<1900 || y>2100) {return -1;}
if(n<1 || n>24) {return -1;}
var _table = calendar.sTermInfo[y-1900];
var _info = [
parseInt('0x'+_table.substr(0,5)).toString() ,
parseInt('0x'+_table.substr(5,5)).toString(),
parseInt('0x'+_table.substr(10,5)).toString(),
parseInt('0x'+_table.substr(15,5)).toString(),
parseInt('0x'+_table.substr(20,5)).toString(),
parseInt('0x'+_table.substr(25,5)).toString()
];
var _calday = [
_info[0].substr(0,1),
_info[0].substr(1,2),
_info[0].substr(3,1),
_info[0].substr(4,2),
_info[1].substr(0,1),
_info[1].substr(1,2),
_info[1].substr(3,1),
_info[1].substr(4,2),
_info[2].substr(0,1),
_info[2].substr(1,2),
_info[2].substr(3,1),
_info[2].substr(4,2),
_info[3].substr(0,1),
_info[3].substr(1,2),
_info[3].substr(3,1),
_info[3].substr(4,2),
_info[4].substr(0,1),
_info[4].substr(1,2),
_info[4].substr(3,1),
_info[4].substr(4,2),
_info[5].substr(0,1),
_info[5].substr(1,2),
_info[5].substr(3,1),
_info[5].substr(4,2),
];
return parseInt(_calday[n-1]);
},
/**
* 传入农历数字月份返回汉语通俗表示法
* @param lunar month
* @return Cn string
* @eg:var cnMonth = calendar.toChinaMonth(12) ;//cnMonth='腊月'
*/
toChinaMonth:function(m) { // 月 => \u6708
if(m>12 || m<1) {return -1} //若参数错误 返回-1
var s = calendar.nStr3[m-1];
s+= "\u6708";//加上月字
return s;
},
/**
* 传入农历日期数字返回汉字表示法
* @param lunar day
* @return Cn string
* @eg:var cnDay = calendar.toChinaDay(21) ;//cnMonth='廿一'
*/
toChinaDay:function(d){ //日 => \u65e5
var s;
switch (d) {
case 10:
s = '\u521d\u5341'; break;
case 20:
s = '\u4e8c\u5341'; break;
break;
case 30:
s = '\u4e09\u5341'; break;
break;
default :
s = calendar.nStr2[Math.floor(d/10)];
s += calendar.nStr1[d%10];
}
return(s);
},
/**
* 年份转生肖[!仅能大致转换] => 精确划分生肖分界线是立春
* @param y year
* @return Cn string
* @eg:var animal = calendar.getAnimal(1987) ;//animal='兔'
*/
getAnimal: function(y) {
return calendar.Animals[(y - 4) % 12]
},
/**
* 传入阳历年月日获得详细的公历农历object信息 <=>JSON
* @param y solar year
* @param m solar month
* @param d solar day
* @return JSON object
* @eg:console.log(calendar.solar2lunar(1987,11,01));
*/
solar2lunar:function (y,m,d) { //参数区间1900.1.31~2100.12.31
if(y<1900 || y>2100) {return -1;}//年份限定、上限
if(y==1900&&m==1&&d<31) {return -1;}//下限
if(!y) { //未传参 获得当天
var objDate = new Date();
}else {
var objDate = new Date(y,parseInt(m)-1,d)
}
var i, leap=0, temp=0;
//修正ymd参数
var y = objDate.getFullYear(),m = objDate.getMonth()+1,d = objDate.getDate();
var offset = (Date.UTC(objDate.getFullYear(),objDate.getMonth(),objDate.getDate()) - Date.UTC(1900,0,31))/86400000;
for(i=1900; i<2101 && offset>0; i++) { temp=calendar.lYearDays(i); offset-=temp; }
if(offset<0) { offset+=temp; i--; }
//是否今天
var isTodayObj = new Date(),isToday=false;
if(isTodayObj.getFullYear()==y && isTodayObj.getMonth()+1==m && isTodayObj.getDate()==d) {
isToday = true;
}
//星期几
var nWeek = objDate.getDay(),cWeek = calendar.nStr1[nWeek];
if(nWeek==0) {nWeek =7;}//数字表示周几顺应天朝周一开始的惯例
//农历年
var year = i;
var leap = calendar.leapMonth(i); //闰哪个月
var isLeap = false;
//效验闰月
for(i=1; i<13 && offset>0; i++) {
//闰月
if(leap>0 && i==(leap+1) && isLeap==false){
--i;
isLeap = true; temp = calendar.leapDays(year); //计算农历闰月天数
}
else{
temp = calendar.monthDays(year, i);//计算农历普通月天数
}
//解除闰月
if(isLeap==true && i==(leap+1)) { isLeap = false; }
offset -= temp;
}
if(offset==0 && leap>0 && i==leap+1)
if(isLeap){
isLeap = false;
}else{
isLeap = true; --i;
}
if(offset<0){ offset += temp; --i; }
//农历月
var month = i;
//农历日
var day = offset + 1;
//天干地支处理
var sm = m-1;
var gzY = calendar.toGanZhiYear(year);
//月柱 1900年1月小寒以前为 丙子月(60进制12)
var firstNode = calendar.getTerm(year,(m*2-1));//返回当月「节」为几日开始
var secondNode = calendar.getTerm(year,(m*2));//返回当月「节」为几日开始
//依据12节气修正干支月
var gzM = calendar.toGanZhi((y-1900)*12+m+11);
if(d>=firstNode) {
gzM = calendar.toGanZhi((y-1900)*12+m+12);
}
//传入的日期的节气与否
var isTerm = false;
var Term = null;
if(firstNode==d) {
isTerm = true;
Term = calendar.solarTerm[m*2-2];
}
if(secondNode==d) {
isTerm = true;
Term = calendar.solarTerm[m*2-1];
}
//日柱 当月一日与 1900/1/1 相差天数
var dayCyclical = Date.UTC(y,sm,1,0,0,0,0)/86400000+25567+10;
var gzD = calendar.toGanZhi(dayCyclical+d-1);
//该日期所属的星座
var astro = calendar.toAstro(m,d);
return {'lYear':year,'lMonth':month,'lDay':day,'Animal':calendar.getAnimal(year),'IMonthCn':(isLeap?"\u95f0":'')+calendar.toChinaMonth(month),'IDayCn':calendar.toChinaDay(day),'cYear':y,'cMonth':m,'cDay':d,'gzYear':gzY,'gzMonth':gzM,'gzDay':gzD,'isToday':isToday,'isLeap':isLeap,'nWeek':nWeek,'ncWeek':"\u661f\u671f"+cWeek,'isTerm':isTerm,'Term':Term,'astro':astro};
},
/**
* 传入农历年月日以及传入的月份是否闰月获得详细的公历农历object信息 <=>JSON
* @param y lunar year
* @param m lunar month
* @param d lunar day
* @param isLeapMonth lunar month is leap or not.[如果是农历闰月第四个参数赋值true即可]
* @return JSON object
* @eg:console.log(calendar.lunar2solar(1987,9,10));
*/
lunar2solar:function(y,m,d,isLeapMonth) { //参数区间1900.1.31~2100.12.1
var isLeapMonth = !!isLeapMonth;
var leapOffset = 0;
var leapMonth = calendar.leapMonth(y);
var leapDay = calendar.leapDays(y);
if(isLeapMonth&&(leapMonth!=m)) {return -1;}//传参要求计算该闰月公历 但该年得出的闰月与传参的月份并不同
if(y==2100&&m==12&&d>1 || y==1900&&m==1&&d<31) {return -1;}//超出了最大极限值
var day = calendar.monthDays(y,m);
var _day = day;
//bugFix 2016-9-25
//if month is leap, _day use leapDays method
if(isLeapMonth) {
_day = calendar.leapDays(y,m);
}
if(y < 1900 || y > 2100 || d > _day) {return -1;}//参数合法性效验
//计算农历的时间差
var offset = 0;
for(var i=1900;i<y;i++) {
offset+=calendar.lYearDays(i);
}
var leap = 0,isAdd= false;
for(var i=1;i<m;i++) {
leap = calendar.leapMonth(y);
if(!isAdd) {//处理闰月
if(leap<=i && leap>0) {
offset+=calendar.leapDays(y);isAdd = true;
}
}
offset+=calendar.monthDays(y,i);
}
//转换闰月农历 需补充该年闰月的前一个月的时差
if(isLeapMonth) {offset+=day;}
//1900年农历正月一日的公历时间为1900年1月30日0时0分0秒(该时间也是本农历的最开始起始点)
var stmap = Date.UTC(1900,1,30,0,0,0);
var calObj = new Date((offset+d-31)*86400000+stmap);
var cY = calObj.getUTCFullYear();
var cM = calObj.getUTCMonth()+1;
var cD = calObj.getUTCDate();
return calendar.solar2lunar(cY,cM,cD);
}
};
export default calendar

View File

@ -1,15 +0,0 @@
@font-face {font-family: "iconfont";
src: url('data:font/truetype;charset=utf-8;base64,d09GRgABAAAAAASEAAsAAAAABuwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFY7d0f0Y21hcAAAAYAAAABTAAABhmJUzs9nbHlmAAAB1AAAALcAAADIzC0F5mhlYWQAAAKMAAAALwAAADYS7IZUaGhlYQAAArwAAAAcAAAAJAfeA4RobXR4AAAC2AAAAAwAAAAMDAAAAGxvY2EAAALkAAAACAAAAAgANgBkbWF4cAAAAuwAAAAfAAAAIAEOACluYW1lAAADDAAAAUUAAAJtPlT+fXBvc3QAAARUAAAALQAAAEOUPjuMeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2BkYWCcwMDKwMHUyXSGgYGhH0IzvmYwYuRgYGBiYGVmwAoC0lxTGByeMj5jYm7438AQw9zA0AAUZgTJAQDdSgvleJztkMERgDAIBPdIzMOxEB8W5MvuTRsRMHbhzSwHR/IBWIDiHE4FXYjQ6akyL6yZ13zT3IXd6jYGfO6S75q7xT81fm1Z9zlZXOsl+j5BD35IDU4AeJwVzUEOwUAYBeD/mfxTEso/mkEJoYluqgtajUjYsHEOSytncROJK/QErjNMd+8lL+8jEP3eqq8uNCPiokK1L4t1ihzVCSPMEekAep3mQCh4tpVm95JWz2QGj3iyiN3LZMJBODU49IMuDxk32YifuI89X4+xqwcsHUtEjfVVWt1p5MvWNs9RY4RowNLrJ7Tq8ZKNN7wmvMp8jBc7PDpW3RPfPrISV5ss4QEO9pxcdrix/gMMIyHOAHicY2BkYGAAYmNBZtV4fpuvDNwsDCBw/dlCBQT9fzMLA3MKkMvBwAQSBQDyNAlAAHicY2BkYGBu+N/AEMPCAAJAkpEBFTADAEcJAmwEAAAABAAAAAQAAAAAAAAAADYAZHicY2BkYGBgZpBlANEMDExAzAWEDAz/wXwGAAuHATgAeJxlj01OwzAQhV/6B6QSqqhgh+QFYgEo/RGrblhUavdddN+mTpsqiSPHrdQDcB6OwAk4AtyAO/BIJ5s2lsffvHljTwDc4Acejt8t95E9XDI7cg0XuBeuU38QbpBfhJto41W4Rf1N2MczpsJtdGF5g9e4YvaEd2EPHXwI13CNT+E69S/hBvlbuIk7/Aq30PHqwj7mXle4jUcv9sdWL5xeqeVBxaHJIpM5v4KZXu+Sha3S6pxrW8QmU4OgX0lTnWlb3VPs10PnIhVZk6oJqzpJjMqt2erQBRvn8lGvF4kehCblWGP+tsYCjnEFhSUOjDFCGGSIyujoO1Vm9K+xQ8Jee1Y9zed0WxTU/3OFAQL0z1xTurLSeTpPgT1fG1J1dCtuy56UNJFezUkSskJe1rZUQuoBNmVXjhF6XNGJPyhnSP8ACVpuyAAAAHicY2BigAAuBuyAmZGJkZmRhYEnKzMxryS/tDgjMS+dC8qpzC9lYAAAiPIJlAAAAA==');
}
.iconfont {
font-family:"iconfont" !important;
font-size:16px;
font-style:normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-arrow-right:before { content: "\e602"; }
.icon-arrow-left:before { content: "\e501"; }

File diff suppressed because it is too large Load Diff

View File

@ -1,394 +0,0 @@
.mpvue-calendar {
margin:auto;
width: 100%;
min-width:300rpx;
background: #fff;
user-select:none;
position: relative;
}
.calendar-tools{
height:40px;
font-size: 20px;
line-height: 40px;
color:#5e7a88;
box-shadow: 0rpx 4rpx 8rpx rgba(25, 47, 89, 0.1);
margin-bottom: 30rpx;
border-top: 1px solid rgba(200, 200, 200, .1);
}
.calendar-prev{
width: 14.28571429%;
float:left;
text-align: center;
}
.calendar-prev img, .calendar-next img{
width: 34rpx;
height: 34rpx;
}
.calendar-info{
padding-top: 3px;
font-size:16px;
line-height: 1.3;
text-align: center;
width: 220rpx;
margin: 0 auto;
}
.calendar-info>div.mc-month{
margin:auto;
height:40rpx;
width:100px;
text-align: center;
color:#5e7a88;
overflow: hidden;
position: relative;
}
.calendar-info>div.mc-month .mc-month-inner{
position: absolute;
left:0;
top:0;
height:480rpx;
}
.month-transition{
transition:top .5s cubic-bezier(0.075, 0.82, 0.165, 1);
}
.calendar-info .mc-month-text{
display:block;
font-size:28rpx;
height:40rpx;
width:200rpx;
overflow:hidden;
text-align:center;
}
.calendar-info>div.mc-month .mc-month-inner>span{
display: block;
font-size: 14px;
height:20px;
width:100px;
overflow: hidden;
text-align: center;
}
.calendar-info>div.mc-year{
font-size:10px;
line-height: 1;
color:#999;
}
.calendar-next{
width: 14.28571429%;
float:right;
text-align: center;
}
.mpvue-calendar table {
clear: both;
width: 100%;
margin-bottom:10px;
border-collapse: collapse;
color: #444444;
}
.mpvue-calendar td {
margin:2px !important;
padding:0px 0;
width: 14.28571429%;
height:88rpx;
text-align: center;
vertical-align: middle;
font-size:14px;
line-height: 125%;
cursor: pointer;
position: relative;
vertical-align: top;
}
.mpvue-calendar td.mc-week{
font-size:10px;
pointer-events:none !important;
cursor: default !important;
}
.mpvue-calendar td.disabled {
color: #ccc;
}
.mpvue-calendar td.disabled div{
color: #ccc;
}
.mpvue-calendar td span{
display:block;
height:76rpx;
width:76rpx;
font-size: 28rpx;
line-height:76rpx;
margin:0px auto;
position: relative;
z-index: 3;
}
.mpvue-calendar td:not(.disabled) span.mc-date-red{
color:#ea6151;
}
.mc-today{
color: #3b75fb;
}
.mpvue-calendar td.selected span{
background-color: #3b75fb;
color: #fff;
border-radius:50%;
}
.mpvue-calendar td .mc-text{
position: absolute;
top:28px;
left:0;
right:0;
text-align: center;
padding:2px;
font-size:20rpx;
line-height: 1.2;
color:#444;
z-index: 4;
}
.mpvue-calendar td .isGregorianFestival,
.mpvue-calendar td .isTerm,
.mpvue-calendar td .isLunarFestival{
color:#ea6151;
}
.mpvue-calendar td.selected span.mc-date-red{
background-color: #3b75fb;
color: #fff;
}
.selected .mc-text {
color: #fff !important;
}
.mpvue-calendar .lunarStyle span{
width: 80rpx;
height: 80rpx;
line-height:54rpx;
}
.mpvue-calendar .lunarStyle .mc-text{
top: 44rpx;
}
.mpvue-calendar thead td {
text-transform: uppercase;
height:30px;
vertical-align: middle;
}
.mc-head {
margin-bottom: 20rpx;
}
.mc-head div {
overflow: hidden;
}
.mc-head-box div {
flex:1;
text-align: center;
}
.mc-head-box {
display: flex;
flex-direction: row;
justify-content: center;
align-content: space-between
}
.mc-head-box div {
font-size: 28rpx;
}
.mc-body tr {
display: flex;
flex-direction: row;
justify-content: center;
align-content: space-between
}
.mc-dot {
width: 10rpx;
height: 10rpx;
background-color: #ea6151;
border-radius: 50%;
margin: 0 auto;
margin-top: 5rpx;
position: absolute;
bottom: -5rpx;
left: 50%;
margin-left: -5rpx;
z-index: 5;
}
.remark-text {
padding-left: 8rpx;
padding-right: 8rpx;
box-sizing: border-box;
height: 34rpx;
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
.slot-element{
line-height: normal;
position: absolute;
z-index: 5;
}
.mpvue-calendar-change{
position: absolute;
left:0rpx;
top:85rpx;
right:0rpx;
bottom:0rpx;
background:#fff;
display: flex;
justify-content: center;
align-items: center;
flex-wrap:wrap;
overflow: auto;
transition:all .5s cubic-bezier(0.075, 0.82, 0.165, 1);
opacity: 0;
pointer-events: none;
transform: translateY(-10px);
z-index: 9;
}
.mpvue-calendar-change.show{
opacity: 1;
pointer-events: auto;
transform: translateY(0px);
}
.mpvue-calendar-change span{
margin:4px 2%;
display: inline-block;
line-height: 30px;
border-radius: 20px;
text-align:center;
color:#999;
width: 20%;
float: left;
text-align: center;
border-radius: 40px;
box-sizing: border-box;
margin-bottom: 4%;
}
.mpvue-calendar-change span.active{
background-color: #587dff;
box-shadow: 2px 2px 2px rgba(88, 125, 255, 0.7);
color:#fff;
}
.mpvue-calendar-change .calendar-week-switch-months{
height: 100%;
padding: 10rpx 20rpx;
}
.mpvue-calendar-change .calendar-week-switch-months span {
margin-bottom: 20rpx;
margin-top: 0px;
font-size: 26rpx;
line-height: 40rpx;
}
.calendar-years, .calendar-months{
height: 50%;
width: 100%;
padding: 10px;
box-sizing: border-box;
position: relative;
}
.calendar-years:after {
content: '';
display: block;
width: 86%;
height: 1rpx;
background-color: #eee;
position: absolute;
bottom: 2%;
left: 7%;
}
/*range background*/
.mc-range-mode .selected .mc-range-bg{
content: '';
display: block;
width: 110rpx;
height: 80rpx;
background-color: #01a1ed;
position: absolute;
top: 0rpx;
left: 50%;
}
.mpvue-calendar .mc-range-mode .selected .calendar-date{
background-color: transparent;
}
.mpvue-calendar .mc-range-mode .mc-range-row-last span.calendar-date, .mpvue-calendar .mc-range-mode .mc-range-row-first span.calendar-date{
border-radius: 6rpx;
background-color: #01a1ed;
}
.mpvue-calendar .mc-range-mode .mc-range-month-first.selected .calendar-date, .mpvue-calendar .mc-range-mode .mc-range-month-last.selected .calendar-date{
border-radius: 6rpx;
background-color: #01a1ed;
}
.mc-range-mode .mc-range-month-last .mc-range-bg{
background-color: transparent;
border-radius: 6rpx;
}
.mc-range-mode .mc-range-end .mc-range-bg, .mc-range-mode .mc-range-row-last .mc-range-bg{
display: none;
}
.mpvue-calendar .mc-range-mode .mc-range-end span.calendar-date, .mpvue-calendar .mc-range-mode .mc-range-begin span.calendar-date{
background-color: #3b75fb;
color: #fff;
border-radius: 50%;
}
.mc-range-mode .mc-range-row-first.mc-range-end .mc-range-bg{
display: block;
border-radius: 6rpx;
width: 40rpx;
left: 5px;
}
.mpvue-calendar .mc-range-row-first.mc-range-end.month-first-date .mc-range-bg{
margin-left: 0px;
}
.mc-range-mode .mc-range-row-last.mc-range-begin .mc-range-bg{
display: block;
border-radius: 4rpx;
width: 40rpx;
right: 10px;
}
.mpvue-calendar .mc-range-mode .month-last-date.mc-range-begin .mc-range-bg{
display: block;
width: 40rpx;
border-radius: 6rpx;
}
.mpvue-calendar .mc-range-mode .month-first-date.mc-range-end .mc-range-bg{
display: block;
width: 40rpx;
border-radius: 6rpx;
left: 10rpx;
}
.mpvue-calendar .mc-range-mode .mc-range-select-one div.mc-range-bg{
display: none !important;
}
.mc-body .mc-today-element .calendar-date{
background-color: rgba(25, 47, 89, 0.1);
border-radius: 6rpx;
}
/*week switch*/
.mpvue-calendar .mc-range-mode.week-switch .month-last-date.mc-range-begin .mc-range-bg{
width: 130%;
border-radius: 0px 20% 20% 0px;
}
.mpvue-calendar .mc-range-mode.week-switch .mc-range-month-last .mc-range-bg{
background-color: #01a1ed;
border-radius: 0px 20% 20% 0px;
}
/*month range*/
.mpvue-calendar .month-range-mode{
border-bottom: 1px solid #f2f2f2;
position: relative;
}
.mpvue-calendar .mc-month-range-mode-head{
box-shadow: 0 4px 8px rgba(25,47,89,.1);
padding: 15rpx 0rpx;
position: sticky;
top: 0px;
background-color: #fff;
z-index: 9;
}
.month-range-mode .month-rang-head {
text-align: left;
margin: 20rpx 0px;
padding-left: 40rpx;
font-size: 28rpx;
}
.month-range-mode .mc-last-month, .month-range-mode .mc-next-month{
opacity: 0 !important;
}
.month-text-background{
position: absolute;
font-size: 140px;
width: 100%;
height: 100%;
text-align: center;
line-height: 2.4;
}

View File

@ -1,160 +0,0 @@
<template>
<view class="number-box">
<block v-for="(myIndex, index) in indexArr" :key="index">
<swiper class="swiper" vertical="true" :current="myIndex" circular="true"
v-bind:style="{color:color,width:myIndex == 10 ? '14rpx' : myIndex == 1 ? '22rpx' : width+'rpx',height:height+'rpx',lineHeight:fontSize+'rpx',fontSize:fontSize+'rpx',fontWeight: fontWeight}">
<swiper-item>
<view class="swiper-item">0</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">1</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">2</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">3</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">4</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">5</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">6</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">7</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">8</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">9</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">.</view>
</swiper-item>
</swiper>
</block>
</view>
</template>
<script>
export default {
props: {
num: [String, Number],
color: {
type: String,
default: '#000000'
},
width: {
type: String,
default: '30'
},
height: {
type: String,
default: '30'
},
fontSize: {
type: String,
default: '30'
},
fontWeight: {
type: [String, Number],
default: 500
}
},
data() {
return {
indexArr: []
};
},
created() {
let {
num
} = this;
let arr = new Array(num.toString().length);
arr.fill(0);
this.indexArr = arr;
},
watch: {
num: function(val, oldVal) {
//
let arr = Array.prototype.slice.apply(this.indexArr);
let newLen = val.toString().length;
let oldLen = oldVal.toString().length;
if (newLen > oldLen) {
for (let i = 0; i < newLen - oldLen; i++) {
arr.push(0);
}
this.indexArr = arr;
}
if (newLen < oldLen) {
for (let i = 0; i < oldLen - newLen; i++) {
arr.pop();
}
this.indexArr = arr;
}
this.numChange(val);
}
},
mounted() {
//app
this._time = setTimeout(() => {
this.numChange(this.num);
clearTimeout(this._time);
}, 50);
},
methods: {
/**
* 数字改变
* @value 数字
*/
numChange(num) {
this.$nextTick(() => {
let {
indexArr
} = this;
let copyIndexArr = Array.prototype.slice.apply(indexArr);
let _num = num.toString();
for (let i = 0; i < _num.length; i++) {
if (_num[i] === '.') {
copyIndexArr[i] = 10;
} else {
copyIndexArr[i] = Number(_num[i]);
}
}
this.indexArr = copyIndexArr;
})
}
}
};
</script>
<style lang="scss">
.number-box {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.swiper {
position: relative;
// line-height: 30upx;
// width: 30upx;
// height: 30upx;
// font-size: 30upx;
// background: red;
}
.swiper:after {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
</style>

View File

@ -1,136 +0,0 @@
<template>
<view class="orderGoods borRadius14">
<view class='total'>{{ totalNmu }}件商品</view>
<view class='goodWrapper pad30'>
<view class='item acea-row row-between-wrapper' v-for="(item,index) in cartInfo" :key="index"
@click="jumpCon(item.spuId)">
<view class='pictrue'>
<image :src='item.picUrl' />
</view>
<view class='text'>
<view class='acea-row row-between-wrapper'>
<view class='name line1'>{{ item.spuName }}</view>
<view class='num'>x {{ item.count }}</view>
</view>
<view class='attr line1'>
<text v-for="(property, propertyIndex) in item.properties" :key="propertyIndex" style="padding-right: 10rpx;">
{{ property.valueName }} 
</text>
</view>
<view class='money font-color'>{{ fen2yuan(item.price) }}</view>
<!-- 售后状态 -->
<!-- TODO 芋艿这样式不太合理应该顺着向右对齐 -->
<view class="evaluate" style="right: 60px;" v-if="afterSale" @click.stop="afterSaleTap(item)">
{{
item.afterSaleStatus === 0 ? '申请退款' :
item.afterSaleStatus === 10 ? '退款中' : '退款成功'
}}
</view>
<!-- 评价状态 -->
<view class='evaluate' v-if='item.commentStatus === false && evaluate === 2' @click.stop="evaluateTap(item)">评价</view>
<view class='evaluate' v-else-if="item.replyStatus === true">已评价</view>
</view>
</view>
</view>
</view>
</template>
<script>
import * as Util from '@/utils/util.js';
export default {
props: {
evaluate: {
type: Number,
default: 0, // 0 - 2 -
},
afterSale: { //
type: Boolean,
default: false,
},
cartInfo: {
type: Array,
default: function() {
return [];
}
},
orderId: {
type: String,
default: '',
},
jump: {
type: Boolean,
default: false,
},
productType: {
type: Number,
default: function() {
return 0;
}
}
},
data() {
return {
totalNmu: 0 //
};
},
watch: {
cartInfo: function(nVal, oVal) {
let num = 0
nVal.forEach((item, index) => {
num += item.count
})
this.totalNmu = num
}
},
methods: {
evaluateTap(item) {
uni.navigateTo({
url: "/pages/users/goods_comment_con/index?orderItemId=" + item.id
})
},
afterSaleTap(item) {
if (item.afterSaleStatus === 0) {
uni.navigateTo({
url: "/pages/users/goods_return/index?orderId=" + item.orderId + '&orderItemId=' + item.id
})
return;
}
uni.navigateTo({
url: "/pages/users/user_return_detail/index?id=" + item.afterSaleId
})
},
jumpCon: function(id) {
let type = this.productType === 0 ?'normal':'video'
if (this.jump) {
uni.navigateTo({
url: `/pages/goods_details/index?id=${id}&type=${type}`
})
}
},
fen2yuan(price) {
return Util.fen2yuan(price)
},
}
}
</script>
<style scoped lang="scss">
.orderGoods {
background-color: #fff;
margin-top: 15rpx;
}
.orderGoods .total {
width: 100%;
height: 86rpx;
padding: 0 24rpx;
border-bottom: 2rpx solid #f0f0f0;
font-size: 30rpx;
color: #282828;
line-height: 86rpx;
box-sizing: border-box;
}
.pictrue image {
background: #f4f4f4;
}
</style>

View File

@ -1,314 +0,0 @@
<template>
<view>
<view class="payment" :class="pay_close ? 'on' : ''">
<view class="title acea-row row-center-wrapper">
选择付款方式<text class="iconfont icon-guanbi" @click='close'></text>
</view>
<view class="item acea-row row-between-wrapper" @click='goPay(item.number || 0 , item.value)'
v-for="(item,index) in payMode" :key="index">
<view class="left acea-row row-between-wrapper">
<view class="iconfont" :class="item.icon"></view>
<view class="text">
<view class="name">{{item.name}}</view>
<view class="info" v-if="item.number">
{{item.title}} <span class="money">{{ item.number }}</span>
</view>
<view class="info" v-else>{{item.title}}</view>
</view>
</view>
<view class="iconfont icon-xiangyou"></view>
</view>
</view>
<view class="mask" @click='close' v-if="pay_close"></view>
</view>
</template>
<script>
import {
orderPay,
wechatOrderPay,
wechatQueryPayResult
} from '@/api/order.js';
import {
mapGetters
} from "vuex";
export default {
props: {
payMode: {
type: Array,
default: function() {
return [];
}
},
pay_close: {
type: Boolean,
default: false,
},
order_id: {
type: String,
default: ''
},
totalPrice: {
type: String,
default: '0'
}
},
data() {
return {
};
},
computed: mapGetters(['systemPlatform']),
methods: {
close: function() {
this.$emit('onChangeFun', {
action: 'payClose'
});
},
goPay: function(number, paytype) {
let that = this;
let goPages = '/pages/order_pay_status/index?order_id=' + that.order_id;
if (!that.order_id) return that.$util.Tips({
title: '请选择要支付的订单'
});
if (paytype == 'yue' && parseFloat(number) < parseFloat(that.totalPrice)) return that.$util.Tips({
title: '余额不足!'
});
uni.showLoading({
title: '支付中'
});
wechatOrderPay({
orderNo: that.order_id,
// #ifdef MP
payChannel: 'routine',
// #endif
// #ifdef H5
payChannel: that.$wechat.isWeixin() ? 'public' : 'weixinh5',
// #endif
payType: paytype
}).then(res => {
let jsConfig = res.data.jsConfig;
that.order_id = res.data.orderNo;
switch (res.data.payType) {
case 'weixin':
// #ifdef MP
uni.requestPayment({
timeStamp: jsConfig.timeStamp,
nonceStr: jsConfig.nonceStr,
package: jsConfig.packages,
signType: jsConfig.signType,
paySign: jsConfig.paySign,
success: function(ress) {
uni.hideLoading();
wechatQueryPayResult(that.order_id).then(res => {
uni.hideLoading();
return that.$util.Tips({
title: "支付成功",
icon: 'success'
}, () => {
that.$emit('onChangeFun', {
action: 'pay_complete'
});
});
}).cache(err => {
uni.hideLoading();
return that.$util.Tips({
title: err
});
})
},
fail: function(e) {
uni.hideLoading();
return that.$util.Tips({
title: '取消支付'
}, () => {
that.$emit('onChangeFun', {
action: 'pay_fail'
});
});
},
complete: function(e) {
uni.hideLoading();
if (e.errMsg == 'requestPayment:cancel') return that.$util
.Tips({
title: '取消支付'
}, () => {
that.$emit('onChangeFun', {
action: 'pay_fail'
});
});
},
})
// #endif
// #ifdef H5
let datas = {
timestamp: jsConfig.timeStamp,
nonceStr: jsConfig.nonceStr,
package: jsConfig.packages,
signType: jsConfig.signType,
paySign: jsConfig.paySign
};
that.$wechat.pay(datas).then(res => {
if (res.errMsg == 'chooseWXPay:cancel') {
uni.hideLoading();
return that.$util.Tips({
title: '支付失败'
});
} else {
wechatQueryPayResult(that.order_id).then(res => {
uni.hideLoading();
return that.$util.Tips({
title: "支付成功",
icon: 'success'
}, () => {
that.$emit('onChangeFun', {
action: 'pay_complete'
});
});
}).cache(err => {
uni.hideLoading();
return that.$util.Tips({
title: err
});
})
}
}).cache(errW => {
uni.hideLoading();
return that.$util.Tips({
title: errW
});
})
// #endif
break;
case 'yue':
uni.hideLoading();
return that.$util.Tips({
title: '余额支付成功',
icon: 'success'
}, () => {
that.$emit('onChangeFun', {
action: 'pay_complete'
});
});
break;
case 'weixinh5':
uni.hideLoading();
location.replace(jsConfig.mwebUrl + '&redirect_url=' + window.location.protocol +
'//' + window.location.host + goPages + '&status=1');
return that.$util.Tips({
title: "支付中",
icon: 'success'
}, () => {
that.$emit('onChangeFun', {
action: 'pay_complete'
});
});
break;
}
}).catch(err => {
uni.hideLoading();
return that.$util.Tips({
title: err
}, () => {
that.$emit('onChangeFun', {
action: 'pay_fail'
});
});
})
}
}
}
</script>
<style scoped lang="scss">
.payment {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
border-radius: 16rpx 16rpx 0 0;
background-color: #fff;
padding-bottom: 60rpx;
z-index: 99;
transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
transform: translate3d(0, 100%, 0);
}
.payment.on {
transform: translate3d(0, 0, 0);
}
.payment .title {
text-align: center;
height: 123rpx;
font-size: 32rpx;
color: #282828;
font-weight: bold;
padding-right: 30rpx;
margin-left: 30rpx;
position: relative;
border-bottom: 1rpx solid #eee;
}
.payment .title .iconfont {
position: absolute;
right: 30rpx;
top: 50%;
transform: translateY(-50%);
font-size: 43rpx;
color: #8a8a8a;
font-weight: normal;
}
.payment .item {
border-bottom: 1rpx solid #eee;
height: 130rpx;
margin-left: 30rpx;
padding-right: 30rpx;
}
.payment .item .left {
width: 610rpx;
}
.payment .item .left .text {
width: 540rpx;
}
.payment .item .left .text .name {
font-size: 32rpx;
color: #282828;
}
.payment .item .left .text .info {
font-size: 24rpx;
color: #999;
}
.payment .item .left .text .info .money {
color: #ff9900;
}
.payment .item .left .iconfont {
font-size: 45rpx;
color: #09bb07;
}
.payment .item .left .iconfont.icon-zhifubao {
color: #00aaea;
}
.payment .item .left .iconfont.icon-yuezhifu {
color: #ff9900;
}
.payment .item .left .iconfont.icon-yuezhifu1 {
color: #eb6623;
}
.payment .item .iconfont {
font-size: 0.3rpx;
color: #999;
}
</style>

View File

@ -1,151 +0,0 @@
<template>
<view class='product-bg'>
<swiper :indicator-dots="indicatorDots" indicator-active-color="#e93323" :autoplay="autoplay"
:circular="circular" :interval="interval" :duration="duration" @change="change">
<!-- 视频 -->
<swiper-item v-if="videoline">
<view class="item">
<view v-show="!controls" style="width:100%;height:100% ">
<video id="myVideo" :src='videoline' objectFit="cover" controls style="width:100%;height:100% "
show-center-play-btn show-mute-btn="true" auto-pause-if-navigate :custom-cache="false"
:enable-progress-gesture="false" :poster="imgUrls[0]" @pause="videoPause"></video>
</view>
<view class="poster" v-show="controls">
<image class="image" :src="imgUrls[0]"></image>
</view>
<view class="stop" v-show="controls" @tap="bindPause">
<image class="image" src="../../static/images/stop.png"></image>
</view>
</view>
</swiper-item>
<!-- 图片 -->
<block v-for="(item,index) in imgUrls" :key='index'>
<swiper-item>
<image :src="item" class="slide-image" />
</swiper-item>
</block>
</swiper>
</view>
</template>
<script>
export default {
props: {
imgUrls: {
type: Array,
default: function() {
return [];
}
},
videoline: {
type: String,
value: ""
}
},
data() {
return {
indicatorDots: true,
circular: true,
autoplay: true,
interval: 3000,
duration: 500,
currents: "1",
controls: true,
isPlay:true,
videoContext:''
};
},
mounted() {
if (this.videoline) {
this.imgUrls.shift()
}
},
methods: {
videoPause(e){
},
bindPause: function() {
this.videoContext.play();
this.$set(this, 'controls', false)
this.autoplay = false
},
change: function(e) {
this.$set(this, 'currents', e.detail.current + 1);
}
}
}
</script>
<style scoped lang="scss">
.product-bg {
width: 100%;
height: 750rpx;
position: relative;
}
.product-bg swiper {
width: 100%;
height: 100%;
position: relative;
}
.product-bg .slide-image {
width: 100%;
height: 100%;
}
.product-bg .pages {
position: absolute;
background-color: #fff;
height: 34rpx;
padding: 0 10rpx;
border-radius: 3rpx;
right: 30rpx;
bottom: 30rpx;
line-height: 34rpx;
font-size: 24rpx;
color: #050505;
}
#myVideo {
width: 100%;
height: 100%
}
.product-bg .item {
position: relative;
width: 100%;
height: 100%;
}
.product-bg .item .poster {
position: absolute;
top: 0;
left: 0;
height: 750rpx;
width: 100%;
z-index: 9;
}
.product-bg .item .poster .image {
width: 100%;
height: 100%;
}
.product-bg .item .stop {
position: absolute;
top: 50%;
left: 50%;
width: 136rpx;
height: 136rpx;
margin-top: -68rpx;
margin-left: -68rpx;
z-index: 9;
}
.product-bg .item .stop .image {
width: 100%;
height: 100%;
}
</style>

View File

@ -1,350 +0,0 @@
<template>
<view>
<view class="product-window"
:class="(attr.cartAttr === true ? 'on' : '') + ' ' + (iSbnt ? 'join':'') + ' ' + (iScart ? 'joinCart':'')">
<view class="textpic acea-row row-between-wrapper">
<view class="pictrue">
<image :src="attr.productSelect.picUrl"></image>
</view>
<view class="text">
<view class="line1">
{{ attr.productSelect.spuName }}
</view>
<view class="money font-color">
<text class="num">{{ fen2yuan(attr.productSelect.price) }}</text>
<text class="stock" v-if='isShow'>库存: {{ attr.productSelect.stock }}</text>
<text class='stock' v-if="attr.productSelect.limitCount > 0">: {{ attr.productSelect.limitCount }}</text>
</view>
</view>
<view class="iconfont icon-guanbi" @click="close"></view>
</view>
<view class="rollTop">
<!-- 属性 key + value 列表 -->
<view class="productWinList">
<view class="item" v-for="(property, propertyIndex) in attr.properties" :key="propertyIndex">
<view class="title">{{ property.name }}</view>
<view class="listn acea-row row-middle">
<view class="itemn" :class="property.index === value.name ? 'on' : ''"
v-for="(value, valueIndex) in property.values" :key="valueIndex"
@click="clickProperty(propertyIndex, valueIndex)">
{{ value.name }}
</view>
</view>
</view>
</view>
<view class="cart acea-row row-between-wrapper">
<view class="title">数量</view>
<view class="carnum acea-row row-left">
<view class="item reduce" :class="attr.productSelect.cart_num <= 1 ? 'on' : ''"
@click="CartNumDes">
-
</view>
<view class='item num'>
<input type="number" v-model="attr.productSelect.cart_num"
data-name="productSelect.cart_num"
@input="bindCode(attr.productSelect.cart_num)" />
</view>
<view v-if="iSplus" class="item plus" :class="attr.productSelect.cart_num >= attr.productSelect.stock ? 'on' : ''" @click="CartNumAdd">
+
</view>
<view v-else class='item plus'
:class='(attr.productSelect.cart_num >= attr.productSelect.stock)
|| (attr.productSelect.cart_num >= attr.productSelect.limitCount)
? "on":""'
@click='CartNumAdd'>+</view>
</view>
</view>
</view>
<!-- TODO 芋艿拼团 -->
<view class="joinBnt bg-color" v-if="iSbnt && attr.productSelect.stock > 0"
@click="goCat">我要参团</view>
<view class="joinBnt on"
v-else-if="iSbnt && attr.productSelect.stock <= 0">已售罄</view>
<!-- TODO 芋艿购物车 -->
<view class="joinBnt bg-color" v-if="iScart && attr.productSelect.stock"
@click="goCat">确定</view>
<view class="joinBnt on"
v-else-if="(iScart && !attr.productSelect.stock)">已售罄</view>
</view>
<view class="mask" @touchmove.prevent :hidden="attr.cartAttr === false" @click="close"></view>
</view>
</template>
<script>
import * as Util from '@/utils/util.js';
export default {
props: {
attr: {
type: Object,
default: () => {}
},
isShow: { //
type: Number,
value: 0
},
iSbnt: { //
type: Number,
value: 0
},
iSplus: { // + -
type: Number,
value: 0
},
iScart: { //
type: Number,
value: 0
}
},
data() {
return {};
},
mounted() {},
methods: {
goCat: function() {
this.$emit('goCat');
},
/**
* 购物车手动输入数量
*/
bindCode: function(e) {
// TODO
this.$emit('iptCartNum', this.attr.productSelect.cart_num);
},
close: function() {
this.$emit('close');
},
CartNumDes: function() {
// TODO
this.$emit('ChangeCartNum', false);
},
CartNumAdd: function() {
// TODO
this.$emit('ChangeCartNum', true);
},
/**
* 选中某个规格属性
*
* @param propertyIndex properties 的下标
* @param valueIndex values 的下标
*/
clickProperty: function(propertyIndex, valueIndex) {
this.$set(this.attr.properties[propertyIndex], 'index', this.attr.properties[propertyIndex].values[valueIndex].name);
let newSkuKey = this.getCheckedValueNames().join(",");
// TODO ChangeAttr selectSku
this.$emit("ChangeAttr", newSkuKey, propertyIndex, valueIndex);
},
/**
* 获取被选中属性值的数组
*
* @returns {*[]} 例如说['红色', '大']
*/
getCheckedValueNames: function() {
let properties = this.attr.properties;
let valueNames = [];
for (let i = 0; i < properties.length; i++) {
for (let j = 0; j < properties[i].values.length; j++) {
if (properties[i].index === properties[i].values[j].name) {
valueNames.push(properties[i].values[j].name);
}
}
}
return valueNames;
},
fen2yuan(price) {
return Util.fen2yuan(price)
}
}
}
</script>
<style scoped lang="scss">
.product-window {
position: fixed;
bottom: 0;
width: 100%;
left: 0;
background-color: #fff;
z-index: 77;
border-radius: 16rpx 16rpx 0 0;
padding-bottom: 140rpx;
transform: translate3d(0, 100%, 0);
transition: all .3s cubic-bezier(.25, .5, .5, .9);
}
.product-window.on {
transform: translate3d(0, 0, 0);
}
.product-window.join {
padding-bottom: 30rpx;
}
.product-window.joinCart {
padding-bottom: 30rpx;
z-index: 999;
}
.product-window .textpic {
padding: 0 130rpx 0 30rpx;
margin-top: 29rpx;
position: relative;
}
.product-window .textpic .pictrue {
width: 150rpx;
height: 150rpx;
}
.product-window .textpic .pictrue image {
width: 100%;
height: 100%;
border-radius: 10rpx;
}
.product-window .textpic .text {
width: 410rpx;
font-size: 32rpx;
color: #333333;
}
.product-window .textpic .text .money {
font-size: 24rpx;
margin-top: 40rpx;
}
.product-window .textpic .text .money .num {
font-size: 36rpx;
}
.product-window .textpic .text .money .stock {
color: #999;
margin-left: 18rpx;
}
.product-window .textpic .iconfont {
position: absolute;
right: 30rpx;
top: -5rpx;
font-size: 35rpx;
color: #8a8a8a;
}
.product-window .rollTop {
max-height: 500rpx;
overflow: auto;
margin-top: 36rpx;
}
.product-window .productWinList .item~.item {
margin-top: 36rpx;
}
.product-window .productWinList .item .title {
font-size: 30rpx;
color: #999;
padding: 0 30rpx;
}
.product-window .productWinList .item .listn {
padding: 0 30rpx 0 16rpx;
}
.product-window .productWinList .item .listn .itemn {
border: 1px solid #F2F2F2;
font-size: 26rpx;
color: #282828;
padding: 7rpx 33rpx;
border-radius: 40rpx;
margin: 20rpx 0 0 14rpx;
background-color: #F2F2F2;
}
.product-window .productWinList .item .listn .itemn.on {
color: $theme-color;
background: rgba(255, 244, 243, 1);
border-color: $theme-color;
}
.product-window .productWinList .item .listn .itemn.limit {
color: #999;
text-decoration: line-through;
}
.product-window .cart {
margin-top: 36rpx;
padding: 0 30rpx;
}
.product-window .cart .title {
font-size: 30rpx;
color: #999;
}
.product-window .cart .carnum {
height: 54rpx;
margin-top: 24rpx;
}
.product-window .cart .carnum view {
// border: 1px solid #a4a4a4;
width: 84rpx;
text-align: center;
height: 100%;
line-height: 54rpx;
color: #282828;
font-size: 45rpx;
}
.product-window .cart .carnum .reduce {
border-right: 0;
border-radius: 6rpx 0 0 6rpx;
line-height: 48rpx;
}
.product-window .cart .carnum .reduce.on {
// border-color: #e3e3e3;
color: #DEDEDE;
font-size: 44rpx;
}
.product-window .cart .carnum .plus {
border-left: 0;
border-radius: 0 6rpx 6rpx 0;
line-height: 46rpx;
}
.product-window .cart .carnum .plus.on {
border-color: #e3e3e3;
color: #dedede;
}
.product-window .cart .carnum .num {
background: rgba(242, 242, 242, 1);
color: #282828;
font-size: 28rpx;
border-radius: 12rpx;
line-height: 29px;
height: 54rpx;
input {
display: -webkit-inline-box;
}
}
.product-window .joinBnt {
font-size: 30rpx;
width: 620rpx;
height: 86rpx;
border-radius: 50rpx;
text-align: center;
line-height: 86rpx;
color: #fff;
margin: 21rpx auto 0 auto;
}
.product-window .joinBnt.on {
background-color: #bbb;
color: #fff;
}
</style>

View File

@ -1,115 +0,0 @@
<template>
<view class='recommend'>
<view class='title acea-row row-center-wrapper'>
<text class='iconfont icon-zhuangshixian'></text>
<text class='name'>热门推荐</text>
<text class='iconfont icon-zhuangshixian lefticon'></text>
</view>
<view class='recommendList acea-row row-between-wrapper'>
<view class='item' v-for="(item,index) in hostProduct" :key="index" hover-class='none' @tap="goDetail(item)">
<view class='pictrue'>
<image :src='item.picUrl'></image>
<span class="pictrue_log_big pictrue_log_class" v-if="item.activityList && item.activityList[0] && item.activityList[0].type === 1"></span>
<span class="pictrue_log_big pictrue_log_class" v-if="item.activityList && item.activityList[0] && item.activityList[0].type === 2"></span>
<span class="pictrue_log_big pictrue_log_class" v-if="item.activityList && item.activityList[0] && item.activityList[0].type === 3"></span>
</view>
<view class='name line1'>{{ item.name }}</view>
<view class='money font-color'><text class='num'>{{ fen2yuan(item.price) }}</text></view>
</view>
</view>
</view>
</template>
<script>
import { mapGetters } from "vuex";
import { goShopDetail } from '@/libs/order.js'
import * as Util from '@/utils/util.js';
export default {
computed: mapGetters(['uid']),
props: {
hostProduct: {
type: Array,
default: function() {
return [];
}
}
},
methods: {
goDetail(item){
goShopDetail(item,this.uid).then(() => {
uni.navigateTo({
url:`/pages/goods_details/index?id=${item.id}`
})
})
},
fen2yuan(price) {
return Util.fen2yuan(price)
}
}
}
</script>
<style scoped lang="scss">
.recommend {
background-color: #fff;
}
.recommend .title {
height: 135rpx;
line-height: 135rpx;
font-size: 28rpx;
color: #282828;
}
.recommend .title .name {
margin: 0 28rpx;
}
.recommend .title .iconfont {
font-size: 170rpx;
color: #454545;
}
.recommend .title .iconfont.lefticon {
transform: rotate(180deg);
}
.recommend .recommendList {
padding: 0 30rpx;
/* #ifdef H5 */
padding-bottom: 50rpx;
/* #endif */
}
.recommend .recommendList .item {
width: 335rpx;
margin-bottom: 30rpx;
}
.recommend .recommendList .item .pictrue {
position: relative;
width: 100%;
height: 335rpx;
}
.recommend .recommendList .item .pictrue image {
width: 100%;
height: 100%;
border-radius: 14rpx;
}
.recommend .recommendList .item .name {
font-size: 28rpx;
color: #282828;
margin-top: 20rpx;
}
.recommend .recommendList .item .money {
font-size: 20rpx;
margin-top: 8rpx;
font-weight: 600;
}
.recommend .recommendList .item .money .num {
font-size: 28rpx;
}
</style>

View File

@ -1,43 +0,0 @@
<template>
<view v-if="shareInfoStatus" class="poster-first">
<view class="mask-share">
<image src="/static/images/share-info.png" @click="shareInfoClose" @touchmove.stop.prevent="false" />
</view>
</view>
</template>
<script>
export default {
props: {
shareInfoStatus: {
type: Boolean,
default:false,
}
},
data: function() {
return {};
},
mounted: function() {},
methods: {
shareInfoClose: function() {
this.$emit("setShareInfoStatus");
}
}
};
</script>
<style scoped lang="scss">
.poster-first {
overscroll-behavior: contain;
}
.mask-share {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99;
}
.mask-share image {
width: 100%;
height:100%;
}
</style>

View File

@ -1,75 +0,0 @@
<template>
<view class='sharing-packets' :class='!enabled ? "on":""'>
<view class='iconfont icon-guanbi' @click="closeShare"></view>
<view class='line'></view>
<view class='sharing-con' @click='goShare'>
<image src='../../static/images/red-packets.png'></image>
<view class='text font-color'>
<view>会员分享返</view>
<view class='money' v-if="sharePacket.brokerageMinPrice && sharePacket.brokerageMaxPrice">
<text class='label'></text>{{ fen2yuan(sharePacket.brokerageMinPrice) }}~{{ fen2yuan(sharePacket.brokerageMaxPrice) }}
</view>
<view class='money' v-else-if="sharePacket.brokerageMinPrice">
<text class='label'></text>{{ fen2yuan(sharePacket.brokerageMinPrice) }}
</view>
<view class='money' v-else-if="sharePacket.brokerageMaxPrice">
<text class='label'></text>{{ fen2yuan(sharePacket.brokerageMaxPrice) }}
</view>
<view class='tip'>下单即返佣金</view>
<view class='shareBut'>立即分享</view>
</view>
</view>
</view>
</template>
<script>
import * as Util from '@/utils/util.js';
export default {
props: {
sharePacket: {
type: Object,
default: function() {
return {
enabled: true,
brokerageMinPrice: undefined,
brokerageMaxPrice: undefined,
}
}
}
},
data() {
return {
};
},
computed: {
enabled() {
return this.sharePacket.enabled && (this.sharePacket.brokerageMinPrice || this.sharePacket.brokerageMaxPrice)
}
},
methods: {
closeShare:function(){
this.$emit('closeChange');
},
goShare:function(){
this.$emit('listenerActionSheet');
},
fen2yuan(price) {
return Util.fen2yuan(price)
}
}
}
</script>
<style scoped lang="scss">
.sharing-packets{position:fixed;left:30rpx;bottom:200rpx;z-index:5;transition:all 0.3s ease-in-out 0s;opacity:1;transform: scale(1);}
.sharing-packets.on{transform: scale(0);opacity:0;}
.sharing-packets .iconfont{width:44rpx;height:44rpx;border-radius:50%;text-align:center;line-height:44rpx;background-color:#999;font-size:20rpx;color:#fff;margin:0 auto;box-sizing:border-box;padding-left:1px;}
.sharing-packets .line{width:2rpx;height:40rpx;background-color:#999;margin:0 auto;}
.sharing-packets .sharing-con{width:187rpx;height:210rpx;position:relative;}
.sharing-packets .sharing-con image{width:100%;height:100%;}
.sharing-packets .sharing-con .text{position:absolute;top:30rpx;font-size:20rpx;width:100%;text-align:center;}
.sharing-packets .sharing-con .text .money{font-size:32rpx;font-weight:bold;margin-top:5rpx;white-space: nowrap}
.sharing-packets .sharing-con .text .money .label{font-size:20rpx;}
.sharing-packets .sharing-con .text .tip{font-size:18rpx;color:#999;margin-top:5rpx;}
.sharing-packets .sharing-con .text .shareBut{font-size:22rpx;color:#fff;margin-top:18rpx;height:50rpx;line-height:50rpx;}
</style>

View File

@ -1,52 +0,0 @@
<template>
<view class='swiper'>
<swiper :autoplay="autoplay" :circular="circular" :interval="interval" :duration="duration" @change="swiperChange">
<block v-for="(item,index) in imgUrls" :key="index">
<swiper-item>
<navigator :url="item.link" style='width:100%;height:100%;' hover-class='none'><image :src="item.img" class="slide-image"/></navigator>
</swiper-item>
</block>
</swiper>
<view class="dots acea-row">
<view class="dot" :class="index == currentSwiper ? 'active' : ''" v-for="(item,index) in imgUrls" :key="index"></view>
</view>
</view>
</template>
<script>
export default {
props: {
imgUrls: {
type: Array,
default: function(){
return [];
}
}
},
data() {
return {
circular: true,
autoplay: true,
interval: 3000,
duration: 500,
currentSwiper: 0
};
},
methods: {
swiperChange: function (e) {
this.currentSwiper = e.detail.current
}
}
}
</script>
<style scoped lang="scss">
.swiper{width:100%;height:282rpx;position:relative;}
.swiper swiper{width:100%;height:100%;position:relative;}
.swiper swiper .slide-image{width:100%;height:100%;}
.swiper .dots{position:absolute;right:40rpx;bottom:20rpx;}
.swiper .dots .dot{width:12rpx;height:12rpx;border:2rpx solid #fff;border-radius:50%;margin-right:15rpx;}
.swiper .dots .dot.active{border-color:$theme-color;background-color:$theme-color;}
</style>

View File

@ -1,165 +0,0 @@
<template>
<canvas v-if="canvasId" :id="canvasId" :canvasId="canvasId" :style="{'width':cWidth*pixelRatio+'px','height':cHeight*pixelRatio+'px', 'transform': 'scale('+(1/pixelRatio)+')','margin-left':-cWidth*(pixelRatio-1)/2+'px','margin-top':-cHeight*(pixelRatio-1)/2+'px'}"
@touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd" @error="error">
</canvas>
</template>
<script>
import uCharts from './u-charts.js';
var canvases = {};
export default {
props: {
chartType: {
required: true,
type: String,
default: 'column'
},
opts: {
required: true,
type: Object,
default () {
return null;
},
},
canvasId: {
type: String,
default: 'u-canvas',
},
cWidth: {
default: 375,
},
cHeight: {
default: 250,
},
pixelRatio: {
type: Number,
default: 1,
},
},
mounted() {
this.init();
},
methods: {
init() {
switch (this.chartType) {
case 'column':
this.initColumnChart();
break;
case 'line':
this.initLineChart();
break;
default:
break;
}
},
initColumnChart() {
canvases[this.canvasId] = new uCharts({
$this: this,
canvasId: this.canvasId,
type: 'column',
legend: true,
fontSize: 11,
background: '#FFFFFF',
pixelRatio: this.pixelRatio,
animation: true,
categories: this.opts.categories,
series: this.opts.series,
enableScroll: true,
xAxis: {
disableGrid: true,
itemCount: 4,
scrollShow: true
},
yAxis: {
//disabled:true
},
dataLabel: true,
width: this.cWidth * this.pixelRatio,
height: this.cHeight * this.pixelRatio,
extra: {
column: {
type: 'group',
}
}
});
},
initLineChart() {
canvases[this.canvasId] = new uCharts({
$this: this,
canvasId: this.canvasId,
type: 'line',
fontSize: 11,
legend: true,
dataLabel: false,
dataPointShape: true,
background: '#FFFFFF',
pixelRatio: this.pixelRatio,
categories: this.opts.categories,
series: this.opts.series,
animation: true,
enableScroll: true,
xAxis: {
type: 'grid',
gridColor: '#CCCCCC',
gridType: 'dash',
dashLength: 8,
itemCount: 4,
scrollShow: true
},
yAxis: {
gridType: 'dash',
gridColor: '#CCCCCC',
dashLength: 8,
splitNumber: 5,
min: 10,
max: 180,
format: (val) => {
return val.toFixed(0) + '元'
}
},
width: this.cWidth * this.pixelRatio,
height: this.cHeight * this.pixelRatio,
extra: {
line: {
type: 'straight'
}
}
});
},
// cidcanvas-id,newdata
changeData(cid,newdata) {
canvases[cid].updateData({
series: newdata.series,
categories: newdata.categories
});
},
touchStart(e) {
canvases[this.canvasId].showToolTip(e, {
format: function(item, category) {
return category + ' ' + item.name + ':' + item.data
}
});
canvases[this.canvasId].scrollStart(e);
},
touchMove(e) {
canvases[this.canvasId].scroll(e);
},
touchEnd(e) {
canvases[this.canvasId].scrollEnd(e);
},
error(e) {
console.log(e)
}
},
};
</script>
<style scoped>
.charts {
width: 100%;
height: 100%;
flex: 1;
background-color: #FFFFFF;
}
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,152 +0,0 @@
<template>
<view class="uni-calendar-item__weeks-box" :class="{
'uni-calendar-item--disable':weeks.disable,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':(calendar.fullDate === weeks.fullDate && !weeks.isDay) ,
'uni-calendar-item--multiple': weeks.multiple
}"
@click="choiceDate(weeks)">
<view class="uni-calendar-item__weeks-box-item">
<text v-if="selected&&weeks.extraInfo" class="uni-calendar-item__weeks-box-circle"></text>
<text class="uni-calendar-item__weeks-box-text" :class="{
'uni-calendar-item--isDay-text': weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.date}}</text>
<text v-if="!lunar&&!weeks.extraInfo && weeks.isDay" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--multiple': weeks.multiple,
}">今天</text>
<text v-if="lunar&&!weeks.extraInfo" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.isDay?'今天': (weeks.lunar.IDayCn === '初一'?weeks.lunar.IMonthCn:weeks.lunar.IDayCn)}}</text>
<text v-if="weeks.extraInfo&&weeks.extraInfo.info" class="uni-calendar-item__weeks-lunar-text" :class="{
'uni-calendar-item--extra':weeks.extraInfo.info,
'uni-calendar-item--isDay-text':weeks.isDay,
'uni-calendar-item--isDay':calendar.fullDate === weeks.fullDate && weeks.isDay,
'uni-calendar-item--checked':calendar.fullDate === weeks.fullDate && !weeks.isDay,
'uni-calendar-item--multiple': weeks.multiple,
'uni-calendar-item--disable':weeks.disable,
}">{{weeks.extraInfo.info}}</text>
</view>
</view>
</template>
<script>
export default {
props: {
weeks: {
type: Object,
default () {
return {}
}
},
calendar: {
type: Object,
default: () => {
return {}
}
},
selected: {
type: Array,
default: () => {
return []
}
},
lunar: {
type: Boolean,
default: false
}
},
methods: {
choiceDate(weeks) {
this.$emit('change', weeks)
}
}
}
</script>
<style lang="scss" scoped>
.uni-calendar-item__weeks-box {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
}
.uni-calendar-item__weeks-box-text {
font-size: $uni-font-size-base;
color: $uni-text-color;
}
.uni-calendar-item__weeks-lunar-text {
font-size: $uni-font-size-sm;
color: $uni-text-color;
}
.uni-calendar-item__weeks-box-item {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
width: 100rpx;
height: 100rpx;
}
.uni-calendar-item__weeks-box-circle {
position: absolute;
top: 5px;
right: 5px;
width: 8px;
height: 8px;
border-radius: 8px;
background-color: $uni-color-error;
}
.uni-calendar-item--disable {
background-color: rgba(249, 249, 249, $uni-opacity-disabled);
color: $uni-text-color-disable;
}
.uni-calendar-item--isDay-text {
color: $uni-color-primary;
}
.uni-calendar-item--isDay {
background-color: $uni-color-primary;
opacity: 0.8;
color: #fff;
}
.uni-calendar-item--extra {
color: $uni-color-error;
opacity: 0.8;
}
.uni-calendar-item--checked {
background-color: $uni-color-primary;
color: #fff;
opacity: 0.8;
}
.uni-calendar-item--multiple {
background-color: $uni-color-primary;
color: #fff;
opacity: 0.8;
}
</style>

View File

@ -1,434 +0,0 @@
<template>
<view class="uni-calendar" @touchmove.stop.prevent="clean">
<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" @click="clean"></view>
<view v-if="insert || show" class="uni-calendar__content" :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow}">
<view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top">
<view class="uni-calendar__header-btn-box" @click="close">
<text class="uni-calendar__header-text uni-calendar--fixed-width">取消</text>
</view>
<view class="uni-calendar__header-btn-box" @click="confirm">
<text class="uni-calendar__header-text uni-calendar--fixed-width">确定</text>
</view>
</view>
<view class="uni-calendar__header">
<view class="uni-calendar__header-btn-box" @click="pre">
<view class="uni-calendar__header-btn uni-calendar--left"></view>
</view>
<text class="uni-calendar__header-text">{{ (nowDate.year||'') +'年'+( nowDate.month||'') +'月'}}</text>
<view class="uni-calendar__header-btn-box" @click="next">
<view class="uni-calendar__header-btn uni-calendar--right"></view>
</view>
<text class="uni-calendar__backtoday" @click="backtoday"></text>
</view>
<view class="uni-calendar__box">
<view v-if="showMonth" class="uni-calendar__box-bg">
<text class="uni-calendar__box-bg-text">{{nowDate.month}}</text>
</view>
<view class="uni-calendar__weeks">
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text"></text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text"></text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text"></text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text"></text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text"></text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text"></text>
</view>
<view class="uni-calendar__weeks-day">
<text class="uni-calendar__weeks-day-text"></text>
</view>
</view>
<view class="uni-calendar__weeks" v-for="(item,weekIndex) in weeks" :key="weekIndex">
<view class="uni-calendar__weeks-item" v-for="(weeks,weeksIndex) in item" :key="weeksIndex">
<uni-calendar-item :weeks="weeks" :calendar="calendar" :selected="selected" :lunar="lunar" @change="choiceDate"></uni-calendar-item>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import Calendar from './util.js';
import uniCalendarItem from './uni-calendar-item.vue'
export default {
components: {
uniCalendarItem
},
props: {
/**
* 当前日期
*/
date: {
type: String,
default: ''
},
/**
* 打点日期
*/
selected: {
type: Array,
default () {
return []
}
},
/**
* 是否开启阴历日期
*/
lunar: {
type: Boolean,
default: false
},
/**
* 开始时间
*/
startDate: {
type: String,
default: ''
},
/**
* 结束时间
*/
endDate: {
type: String,
default: ''
},
/**
* 范围
*/
range: {
type: Boolean,
default: false
},
/**
* 插入
*/
insert: {
type: Boolean,
default: true
},
/**
* 是否显示月份背景
*/
showMonth: {
type: Boolean,
default: true
}
},
data() {
return {
show: false,
weeks: [],
calendar: {},
nowDate: '',
aniMaskShow: false
}
},
watch: {
selected(newVal) {
this.cale.setSelectInfo(this.nowDate.fullDate, newVal)
this.weeks = this.cale.weeks
}
},
created() {
//
this.cale = new Calendar({
date: this.date,
selected: this.selected,
startDate: this.startDate,
endDate: this.endDate,
range: this.range,
})
this.init(this.cale.date.fullDate)
},
methods: {
// 穿
clean() {},
init(date) {
this.weeks = this.cale.weeks
this.nowDate = this.calendar = this.cale.getInfo(date)
},
open() {
this.show = true
this.$nextTick(() => {
setTimeout(()=>{
this.aniMaskShow = true
},50)
})
},
close() {
this.aniMaskShow = false
this.$nextTick(() => {
setTimeout(() => {
this.show = false
}, 300)
})
},
confirm() {
this.setEmit('confirm')
this.close()
},
change() {
if (!this.insert) return
this.setEmit('change')
},
monthSwitch() {
let {
year,
month
} = this.nowDate
this.$emit('monthSwitch', {
year,
month: Number(month)
})
},
setEmit(name) {
let {
year,
month,
date,
fullDate,
lunar,
extraInfo
} = this.calendar
this.$emit(name, {
range: this.cale.multipleStatus,
year,
month,
date,
fulldate: fullDate,
lunar,
extraInfo: extraInfo || {}
})
},
choiceDate(weeks) {
if (weeks.disable) return
this.calendar = weeks
//
this.cale.setMultiple(this.calendar.fullDate)
this.weeks = this.cale.weeks
this.change()
},
backtoday() {
this.cale.setDate(this.date)
this.weeks = this.cale.weeks
this.nowDate = this.calendar = this.cale.getInfo(this.date)
this.change()
},
pre() {
const preDate = this.cale.getDate(this.nowDate.fullDate, -1, 'month').fullDate
this.setDate(preDate)
this.monthSwitch()
},
next() {
const nextDate = this.cale.getDate(this.nowDate.fullDate, +1, 'month').fullDate
this.setDate(nextDate)
this.monthSwitch()
},
setDate(date) {
this.cale.setDate(date)
this.weeks = this.cale.weeks
this.nowDate = this.cale.getInfo(date)
}
}
}
</script>
<style lang="scss" scoped>
.uni-calendar {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
}
.uni-calendar__mask {
position: fixed;
bottom: 0;
top: 0;
left: 0;
right: 0;
background-color: $uni-bg-color-mask;
transition-property: opacity;
transition-duration: 0.3s;
opacity: 0;
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.uni-calendar--mask-show {
opacity: 1
}
.uni-calendar--fixed {
position: fixed;
bottom: 0;
left: 0;
right: 0;
transition-property: transform;
transition-duration: 0.3s;
transform: translateY(460px);
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
}
.uni-calendar--ani-show {
transform: translateY(0);
}
.uni-calendar__content {
background-color: #fff;
}
.uni-calendar__header {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
align-items: center;
height: 50px;
border-bottom-color: $uni-border-color;
border-bottom-style: solid;
border-bottom-width: 1px;
}
.uni-calendar--fixed-top {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: space-between;
border-top-color: $uni-border-color;
border-top-style: solid;
border-top-width: 1px;
}
.uni-calendar--fixed-width {
width: 50px;
// padding: 0 15px;
}
.uni-calendar__backtoday {
position: absolute;
right: 0;
top: 25rpx;
padding: 0 5px;
padding-left: 10px;
height: 25px;
line-height: 25px;
font-size: 12px;
border-top-left-radius: 25px;
border-bottom-left-radius: 25px;
color: $uni-text-color;
background-color: $uni-bg-color-hover;
}
.uni-calendar__header-text {
text-align: center;
width: 100px;
font-size: $uni-font-size-base;
color: $uni-text-color;
}
.uni-calendar__header-btn-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
}
.uni-calendar__header-btn {
width: 10px;
height: 10px;
border-left-color: $uni-text-color-placeholder;
border-left-style: solid;
border-left-width: 2px;
border-top-color: $uni-color-subtitle;
border-top-style: solid;
border-top-width: 2px;
}
.uni-calendar--left {
transform: rotate(-45deg);
}
.uni-calendar--right {
transform: rotate(135deg);
}
.uni-calendar__weeks {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.uni-calendar__weeks-item {
flex: 1;
}
.uni-calendar__weeks-day {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
height: 45px;
border-bottom-color: #F5F5F5;
border-bottom-style: solid;
border-bottom-width: 1px;
}
.uni-calendar__weeks-day-text {
font-size: 14px;
}
.uni-calendar__box {
position: relative;
}
.uni-calendar__box-bg {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.uni-calendar__box-bg-text {
font-size: 200px;
font-weight: bold;
color: $uni-text-color-grey;
opacity: 0.1;
text-align: center;
/* #ifndef APP-NVUE */
line-height: 1;
/* #endif */
}
</style>

View File

@ -1,156 +0,0 @@
<template>
<view class="evaluateWtapper" v-if="reply.length > 0">
<view class="evaluateItem" v-for="(item, index) in reply" :key="index">
<view class="pic-text acea-row">
<view class="pictrue">
<image :src="item.userAvatar"></image>
</view>
<view class="content">
<view>
<view class="acea-row row-between">
<view class="acea-row">
<view class="name line1">{{ item.userNickname }}</view>
<view class="start" :class="'star' + item.scores"></view>
</view>
<view class="time">{{ formatDate(item.createTime) }}</view>
</view>
<view class="sku">规格
<text v-for="(property, propertyIndex) in item.skuProperties" :key="propertyIndex" style="padding-right: 2px">
{{ property.valueName }}
</text>
</view>
</view>
<view class="evaluate-infor">{{ item.content }}</view>
<view class="imgList acea-row" v-if="item.picUrls && item.picUrls.length > 0">
<view class="pictrue" v-for="(picUrl, indexn) in item.picUrls" :key="indexn">
<image :src="picUrl" class="image" @click='getpreviewImage(index, indexn)'></image>
</view>
</view>
<view class="reply" v-if="item.replyContent">
<text class="font-color">店小二</text>{{ item.replyContent }}
</view>
</view>
</view>
</view>
</view>
</template>
<script>
import dayjs from "@/plugin/dayjs/dayjs.min.js";
export default {
props: {
reply: {
type: Array,
default: []
}
},
data: function() {
return {};
},
methods: {
getpreviewImage: function(indexw, indexn) {
uni.previewImage({
urls: this.reply[indexw].picUrls,
current: this.reply[indexw].picUrls[indexn]
});
},
formatDate: function(date) {
return dayjs(date).format("YYYY-MM-DD HH:mm:ss");
}
}
}
</script>
<style scoped lang='scss'>
.evaluateWtapper .evaluateItem {
background-color: #fff;
padding: 24rpx;
border-bottom-left-radius: 14rpx;
border-bottom-right-radius: 14rpx;
}
.evaluateWtapper .evaluateItem~.evaluateItem {
border-top: 1rpx solid #f5f5f5;
}
.evaluateWtapper .evaluateItem .pic-text {
font-size: 26rpx;
color: #282828;
.content{
width: 84%;
margin-left: 20rpx;
}
}
.evaluateWtapper .evaluateItem .pic-text .pictrue {
width: 62rpx;
height: 62rpx;
}
.evaluateWtapper .evaluateItem .pic-text .pictrue image {
width: 100%;
height: 100%;
border-radius: 50%;
}
.evaluateWtapper .evaluateItem .pic-text .name {
max-width: 450rpx;
}
.evaluateWtapper .evaluateItem .time {
font-size: 24rpx;
color: #999999;
}
.sku{
font-size: 24rpx;
color: #999999;
margin: 10rpx 0;
}
.evaluateWtapper .evaluateItem .evaluate-infor {
font-size: 28rpx;
color: #333;
margin-bottom: 14rpx;
}
.evaluateWtapper .evaluateItem .imgList {/*
padding: 0 24rpx;
margin-top: 16rpx; */
}
.evaluateWtapper .evaluateItem .imgList .pictrue {
width: 102rpx;
height: 102rpx;
margin-right: 14rpx;
border-radius: 14rpx;
margin-bottom: 16rpx;
/* margin: 0 0 15rpx 15rpx; */
}
.evaluateWtapper .evaluateItem .imgList .pictrue image {
width: 100%;
height: 100%;
background-color: #f7f7f7;
border-radius: 14rpx;
}
.evaluateWtapper .evaluateItem .reply {
font-size: 26rpx;
color: #454545;
background-color: #f7f7f7;
border-radius: 14rpx;
margin: 20rpx 30rpx 0 0rpx;
padding: 20rpx;
position: relative;
}
.evaluateWtapper .evaluateItem .reply::before {
content: "";
width: 0;
height: 0;
border-left: 20rpx solid transparent;
border-right: 20rpx solid transparent;
border-bottom: 30rpx solid #f7f7f7;
position: absolute;
top: -14rpx;
left: 40rpx;
}
</style>

File diff suppressed because one or more lines are too long

View File

@ -1,29 +0,0 @@
let domain = 'http://apif.java.crmeb.net'
// let domain = 'http://127.0.0.1:48080'
module.exports = {
// 请求域名 格式: https://您的域名
// #ifdef MP
HTTP_REQUEST_URL: domain,
// #endif
// #ifdef H5
//H5接口是浏览器地址
// HTTP_REQUEST_URL: window.location.protocol+"//"+window.location.host,
// http://api.java.crmeb.net:20001
HTTP_REQUEST_URL: domain,
// #endif
HEADER:{
'content-type': 'application/json'
},
HEADERPARAMS:{
'content-type': 'application/x-www-form-urlencoded'
},
// 回话密钥名称 请勿修改此配置
TOKENNAME: 'Authori-zation',
// 缓存时间 0 永久
EXPIRE:0,
//分页最多显示条数
LIMIT: 10
};

View File

@ -1,34 +0,0 @@
module.exports = {
//token
LOGIN_STATUS: 'LOGIN_STATUS_TOKEN',
// uid
UID:'UID',
// openid
OPENID: 'OPENID',
//用户信息
USER_INFO: 'USER_INFO',
//token 过期时间
EXPIRES_TIME: 'EXPIRES_TIME',
//微信授权
WX_AUTH: 'WX_AUTH',
//微信授权状态
STATE_KEY: 'wx_authorize_state',
//登录回调地址
BACK_URL: 'login_back_url',
// 小程序授权状态
STATE_R_KEY: 'roution_authorize_state',
//logo Url
LOGO_URL: 'LOGO_URL',
//模板缓存
// SUBSCRIBE_MESSAGE: 'SUBSCRIBE_MESSAGE',
TIPS_KEY: 'TIPS_KEY',
SPREAD: 'spread',
//缓存经度
CACHE_LONGITUDE: 'LONGITUDE',
//缓存纬度
CACHE_LATITUDE: 'LATITUDE',
//app手机信息
PLATFORM: 'systemPlatform'
}

View File

@ -1,8 +0,0 @@
module.exports = {
// Socket链接 暂不做配置
WSS_SERVER_URL:'',
// Socket调试模式
SERVER_DEBUG:true,
// 心跳间隔
PINGINTERVAL:3000
}

17
index.html Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
/>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

9
jsconfig.json Normal file
View File

@ -0,0 +1,9 @@
{
"compilerOptions": {
"jsx": "preserve",
"baseUrl": ".",
"paths": {
"@/*": ["./*"]
}
}
}

View File

@ -1,22 +0,0 @@
import { appAuth } from '../api/public';
class Apps{
/**
* 授权登录获取token
* @param {Object} code
*/
authApp(code) {
return new Promise((resolve, reject) => {
appAuth(code,{'spread_spid': 0})
.then(({
data
}) => {
resolve(data);
Cache.set(WX_AUTH, code);
Cache.clear(STATE_KEY);
})
.catch(reject);
});
}
}
export default new Apps();

View File

@ -1,62 +0,0 @@
import $store from "@/store";
import { VUE_APP_WS_URL } from "@/utils/index.js";
const Socket = function() {
this.ws = new WebSocket(wss(VUE_APP_WS_URL));
this.ws.onopen = this.onOpen.bind(this);
this.ws.onerror = this.onError.bind(this);
this.ws.onmessage = this.onMessage.bind(this);
this.ws.onclose = this.onClose.bind(this);
};
function wss(wsSocketUrl) {
let ishttps = document.location.protocol == 'https:';
if (ishttps) {
return wsSocketUrl.replace('ws:', 'wss:');
} else {
return wsSocketUrl.replace('wss:', 'ws:');
}
}
Socket.prototype = {
vm(vm) {
this.vm = vm;
},
close() {
clearInterval(this.timer);
this.ws.close();
},
onOpen: function() {
console.log("ws open");
this.init();
this.send({
type: "login",
data: $store.state.app.token
});
this.vm.$emit("socket_open");
},
init: function() {
var that = this;
this.timer = setInterval(function() {
that.send({ type: "ping" });
}, 10000);
},
send: function(data) {
return this.ws.send(JSON.stringify(data));
},
onMessage: function(res) {
const { type, data = {} } = JSON.parse(res.data);
this.vm.$emit(type, data);
},
onClose: function() {
clearInterval(this.timer);
},
onError: function(e) {
console.log(e);
this.vm.$emit("socket_error", e);
}
};
Socket.prototype.constructor = Socket;
export default Socket;

View File

@ -1,84 +0,0 @@
import store from "../store";
import Cache from '../utils/cache';
import { Debounce } from '@/utils/validate.js'
// #ifdef H5
import { isWeixin } from "../utils";
import auth from './wechat';
// #endif
import { LOGIN_STATUS, USER_INFO, EXPIRES_TIME, STATE_R_KEY, BACK_URL} from './../config/cache';
function prePage(){
let pages = getCurrentPages();
let prePage = pages[pages.length - 1];
return prePage.route;
}
export const toLogin = Debounce(_toLogin,800)
export function _toLogin(push, pathLogin) {
store.commit("LOGOUT");
let path = prePage();
let login_back_url = Cache.get(BACK_URL);
// #ifdef H5
// path = location.href;
path = location.pathname + location.search;
// #endif
if(!pathLogin){
pathLogin = '/page/users/login/index'
Cache.set('login_back_url',path);
}
// #ifdef H5
if (isWeixin()) {
let urlData = location.pathname + location.search
if (!Cache.has('snsapiKey')) {
auth.oAuth('snsapi_base', urlData);
} else {
if (['/pages/user/index'].indexOf(login_back_url) === -1) {
uni.navigateTo({
url: '/pages/users/wechat_login/index'
})
}
}
} else {
if (['/pages/user/index'].indexOf(login_back_url) === -1) {
uni.navigateTo({
url: '/pages/users/login/index'
})
}
}
// #endif
if (['pages/user/index','/pages/user/index'].indexOf(login_back_url) === -1) {
// #ifdef MP
uni.navigateTo({
url: '/pages/users/wechat_login/index'
})
// #endif
}
}
export function checkLogin()
{
let token = Cache.get(LOGIN_STATUS);
let expiresTime = Cache.get(EXPIRES_TIME);
let newTime = Math.round(new Date() / 1000);
if (expiresTime < newTime || !token){
Cache.clear(LOGIN_STATUS);
Cache.clear(EXPIRES_TIME);
Cache.clear(USER_INFO);
Cache.clear(STATE_R_KEY);
return false;
}else{
store.commit('UPDATE_LOGIN',token);
let userInfo = Cache.get(USER_INFO,true);
if(userInfo){
store.commit('UPDATE_USERINFO',userInfo);
}
return true;
}
}

View File

@ -1,49 +0,0 @@
import {
preOrderApi
} from '@/api/order.js';
import util from 'utils/util'
// TODO 芋艿:需要调整位置
/**
* 去商品详情
*/
export function goShopDetail(item, uid) {
return new Promise(resolve => {
const activityH5 = item.activityList && item.activityList[0] ? item.activityList[0] : null;
if (activityH5 && activityH5.type === 1) {
uni.navigateTo({
url: `/pages/activity/goods_seckill_details/index?id=${activityH5.id}`
})
} else if (activityH5 && activityH5.type === 2) {
uni.navigateTo({
url: `/pages/activity/goods_bargain_details/index?id=${activityH5.id}&startBargainUid=${uid}`
})
} else if (activityH5 && activityH5.type === 3) {
uni.navigateTo({
url: `/pages/activity/goods_combination_details/index?id=${activityH5.id}`
})
} else {
resolve(item);
}
});
}
/**
* 活动商品普通商品购物车再次购买预下单
*/
export function getPreOrder(preOrderType, orderDetails) {
return new Promise((resolve, reject) => {
preOrderApi({
"preOrderType": preOrderType,
"orderDetails": orderDetails
}).then(res => {
uni.navigateTo({
url: '/pages/users/order_confirm/index?preOrderNo=' + res.data.preOrderNo
});
}).catch(err => {
return util.Tips({
title: err
});
})
});
}

View File

@ -1,154 +0,0 @@
import store from '../store';
import { checkLogin } from './login';
import Cache from '../utils/cache';
import { STATE_R_KEY, USER_INFO, OPENID} from './../config/cache';
import * as AuthApi from "@/api/member/auth";
import * as BrokerageAPI from '@/api/trade/brokerage.js'
class Routine
{
constructor()
{
this.scopeUserInfo = 'scope.userInfo';
}
async getUserCode(){
let isAuth = await this.isAuth(), code = '' ;
if(isAuth)
code = await this.getCode();
return code;
}
/**
* 获取用户信息
*/
getUserProfile(){
let that = this , code = this.getUserCode();
return new Promise( (resolve,reject) => {
uni.getUserProfile({
lang: 'zh_CN',
desc: '用于完善会员资料', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写
success(user) {
if(code) user.code = code;
resolve({userInfo:user,islogin:false});
},
fail(res){
reject(res);
}
})
})
}
/**
* 获取用户信息
*/
authorize()
{
let that = this;
return new Promise((resolve,reject)=>{
if(checkLogin())
return resolve({
userInfo:Cache.get(USER_INFO,true),
islogin:true,
});
uni.authorize({
scope: that.scopeUserInfo,
success() {
resolve({islogin:false});
},
fail(res){
reject(res);
}
})
})
}
async getCode(){
let provider = await this.getProvider();
return new Promise((resolve,reject)=>{
uni.login({
provider:provider,
success(res) {
if (res.code) {
Cache.set(STATE_R_KEY, res.code ,10800);
}
return resolve(res.code);
},
fail(){
return reject(null);
}
})
})
}
/**
* 获取服务供应商
*/
getProvider()
{
return new Promise((resolve,reject)=>{
uni.getProvider({
service:'oauth',
success(res) {
resolve(res.provider);
},
fail() {
resolve(false);
}
});
});
}
/**
* 是否授权
*/
isAuth(){
let that = this;
return new Promise((resolve,reject)=>{
uni.getSetting({
success(res) {
if (!res.authSetting[that.scopeUserInfo]) {
resolve(true)
} else {
resolve(true);
}
},
fail(){
resolve(false);
}
});
});
}
/**
* 微信小程序静默登录
*
* @param code 授权码
* @param spread 推广员编号
*/
authUserInfo(code, spread) {
return new Promise((resolve, reject)=>{
// 34 的原因,它是小程序登录的社交类型
AuthApi.socialLogin(34, code, 'default').then(res => {
if (res.code !== 0) {
return;
}
// 设置访问令牌
store.commit('LOGIN', {
token: res.data.accessToken
});
store.commit("SETUID", res.data.userId);
store.commit("OPENID", res.data.openid);
// 绑定推广员
if (spread > 0) {
BrokerageAPI.bindBrokerageUser(spread)
}
return resolve(res);
}).catch(res=>{
return reject(res);
})
})
}
}
export default new Routine();

View File

@ -1,283 +0,0 @@
// #ifdef H5
import WechatJSSDK from "@/plugin/jweixin-module/index.js";
import * as AuthApi from "@/api/member/auth";
import * as BrokerageAPI from '@/api/trade/brokerage.js'
import {
WX_AUTH,
STATE_KEY,
BACK_URL
} from '@/config/cache';
import {
parseQuery
} from '@/utils';
import store from '@/store';
import Cache from '@/utils/cache';
class AuthWechat {
constructor() {
this.instance = WechatJSSDK; // 微信实例化对象
this.status = false; // 是否实例化
this.initConfig = {};
}
/**
* 初始化 wechat(分享配置)
*/
wechat() {
return new Promise((resolve, reject) => {
// if (this.status) return resolve(this.instance);
AuthApi.createWeixinMpJsapiSignature(location.href).then(res => {
// debugger
const jsapiTicket = res.data;
jsapiTicket.jsApiList = ['chooseWXPay']; // TODO 芋艿:这里要设置下
jsapiTicket.debug = false;
this.instance.config(jsapiTicket);
this.initConfig = jsapiTicket;
this.status = true;
this.instance.ready(() => {
resolve(this.instance);
})
}).catch(err => {
console.log('WechatJSSDK 初始化失败 ',err);
this.status = false;
reject(err);
});
});
}
/**
* 验证是否初始化
*/
verifyInstance() {
let that = this;
return new Promise((resolve, reject) => {
if (that.instance === null && !that.status) {
that.wechat().then(res => {
resolve(that.instance);
}).catch(() => {
return reject();
})
} else {
return resolve(that.instance);
}
})
}
// 微信公众号的共享地址
openAddress() {
return new Promise((resolve, reject) => {
this.wechat().then(wx => {
this.toPromise(wx.openAddress).then(res => {
resolve(res);
}).catch(err => {
reject(err);
});
}).catch(err => {
reject(err);
})
});
}
// 获取经纬度;
location(){
return new Promise((resolve, reject) => {
this.wechat().then(wx => {
this.toPromise(wx.getLocation,{type: 'wgs84'}).then(res => {
resolve(res);
}).catch(err => {
reject(err);
});
}).catch(err => {
reject(err);
})
});
}
// 使用微信内置地图查看位置接口;
seeLocation(config){
return new Promise((resolve, reject) => {
this.wechat().then(wx => {
this.toPromise(wx.openLocation, config).then(res => {
resolve(res);
}).catch(err => {
reject(err);
});
}).catch(err => {
reject(err);
})
});
}
/**
* 微信支付
* @param {Object} config
*/
pay(config) {
return new Promise((resolve, reject) => {
this.wechat().then((wx) => {
this.toPromise(wx.chooseWXPay, config).then(res => {
resolve(res);
}).catch(res => {
resolve(res);
});
}).catch(res => {
reject(res);
});
});
}
toPromise(fn, config = {}) {
return new Promise((resolve, reject) => {
fn({
...config,
success(res) {
resolve(res);
},
fail(err) {
reject(err);
},
complete(err) {
reject(err);
},
cancel(err) {
reject(err);
}
});
});
}
/**
* 自动去授权
*/
oAuth(snsapiBase,url) {
if (uni.getStorageSync(WX_AUTH) && store.state.app.token && snsapiBase === 'snsapi_base') {
return;
}
const { code } = parseQuery();
if (!code || code === uni.getStorageSync('snsapiCode')){
return this.toAuth(snsapiBase,url);
} else{
if(Cache.has('snsapiKey'))
return this.auth(code).catch(error=>{
uni.showToast({
title:error,
icon:'none'
})
})
}
}
/**
* 微信公众号的授权登录获取 token
*
* 实现逻辑是发起社交登录
*/
auth(code, state, spread) {
return new Promise((resolve, reject) => {
// 31 的原因,它是公众号登录的社交类型
AuthApi.socialLogin(31, code, state)
.then(res => {
// 设置访问令牌
store.commit('LOGIN', {
token: res.data.accessToken
});
store.commit("SETUID", res.data.userId);
store.commit("OPENID", res.data.openid);
// 绑定推广员
if (spread > 0) {
BrokerageAPI.bindBrokerageUser(spread)
}
// 回调
resolve(res);
Cache.set(WX_AUTH, code);
Cache.clear(STATE_KEY);
}).catch(reject);
});
}
/**
* 获取跳转授权后的地址
* @param {Object} appId
*/
getAuthUrl(appId,snsapiBase,backUrl) {
let url = `${location.origin}${backUrl}`
if(url.indexOf('?') === -1){
url = url+'?'
}else{
url = url+'&'
}
const redirect_uri = encodeURIComponent(`${url}scope=${snsapiBase}&back_url=` +
encodeURIComponent(
encodeURIComponent(
uni.getStorageSync(BACK_URL) ? uni.getStorageSync(BACK_URL) : location.pathname + location.search
)
)
);
uni.removeStorageSync(BACK_URL);
const state = encodeURIComponent(
("" + Math.random()).split(".")[1] + "authorizestate"
);
uni.setStorageSync(STATE_KEY, state);
return `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appId}&redirect_uri=${redirect_uri}&response_type=code&scope=${snsapiBase}&state=${state}#wechat_redirect`;
}
/**
* 跳转自动登录
*/
toAuth(snsapiBase,backUrl) {
let that = this;
this.wechat().then(wx => {
location.href = this.getAuthUrl(that.initConfig.appId,snsapiBase,backUrl);
})
}
/**
* 绑定事件
* @param {Object} name 事件名
* @param {Object} config 参数
*/
wechatEvevt(name, config) {
let that = this;
return new Promise((resolve, reject) => {
let configDefault = {
fail(res) {
if (that.instance) return reject({
is_ready: true,
wx: that.instance
});
that.verifyInstance().then(wx => {
return reject({
is_ready: true,
wx: wx
});
})
},
success(res) {
return resolve(res,2222);
}
};
Object.assign(configDefault, config);
that.wechat().then(wx => {
if (typeof name === 'object') {
name.forEach(item => {
wx[item] && wx[item](configDefault)
})
} else {
wx[name] && wx[name](configDefault)
}
})
});
}
/**
* 判断是否在微信公众号的浏览器中
*/
isWeixin() {
return navigator.userAgent.toLowerCase().indexOf("micromessenger") !== -1;
}
}
export default new AuthWechat();
// #endif

69
main.js
View File

@ -1,62 +1,15 @@
import Vue from 'vue'
import App from './App'
import store from './store'
import Cache from './utils/cache'
import util from 'utils/util'
import configs from './config/app.js'
import * as Order from './libs/order';
import App from './App';
import { createSSRApp } from 'vue';
import { setupPinia } from './sheep/store';
Vue.prototype.$util = util;
Vue.prototype.$config = configs;
Vue.prototype.$Cache = Cache;
Vue.prototype.$eventHub = new Vue();
Vue.config.productionTip = false
Vue.prototype.$Order = Order;
// #ifdef H5
import { parseQuery } from "./utils";
import Auth from './libs/wechat';
import { SPREAD } from './config/cache';
Vue.prototype.$wechat = Auth;
let cookieName = "VCONSOLE",
query = parseQuery(),
urlSpread = query["spread"],
vconsole = query[cookieName.toLowerCase()],
md5Crmeb = "b14d1e9baeced9bb7525ab19ee35f2d2", //CRMEB MD5 加密开启vconsole模式 TODO 芋艿:这个是啥,后面研究下
md5UnCrmeb = "3dca2162c4e101b7656793a1af20295c"; //UN_CREMB MD5 加密关闭vconsole模式
export function createApp() {
if (urlSpread !== undefined) {
var spread = Cache.get(SPREAD);
urlSpread = parseInt(urlSpread);
if (!Number.isNaN(urlSpread) && spread !== urlSpread) {
Cache.set("spread", urlSpread || 0);
} else if (spread === 0 || typeof spread !== "number") {
Cache.set("spread", urlSpread || 0);
}
const app = createSSRApp(App);
setupPinia(app);
return {
app,
};
}
if (vconsole !== undefined) {
if (vconsole === md5UnCrmeb && Cache.has(cookieName))
Cache.clear(cookieName);
} else vconsole = Cache.get(cookieName);
import VConsole from './components/vconsole.min.js'
if (vconsole !== undefined && vconsole === md5Crmeb) {
Cache.set(cookieName, md5Crmeb, 3600);
let vConsole = new VConsole();
}
// Auth.isWeixin() && Auth.oAuth();
// #endif
App.mpType = 'app'
const app = new Vue({
...App,
store,
Cache
})
app.$mount();

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