first commit

This commit is contained in:
编码猿
2024-09-27 01:32:49 +08:00
commit 28ebe05a64
7399 changed files with 1174529 additions and 0 deletions

View File

@@ -0,0 +1 @@
c35788ee-4086-4903-bbc9-e93917bdd48d

View File

@@ -0,0 +1 @@
fa1cac3b-74e7-40ce-92f2-991ec64862dd

View File

@@ -0,0 +1,7 @@
import Component from 'vue-class-component';
Component.registerHooks([
'beforeRouteEnter',
'beforeRouteLeave',
'beforeRouteUpdate'
])

View File

@@ -0,0 +1 @@
7c4a4e64-72aa-49d8-ab93-234dd6ba1b4a

View File

@@ -0,0 +1,277 @@
import VueRouter from 'vue-router';
// vue 插件配置
import 'amfe-flexible/index.js';
import Vant from 'vant';
import 'vant/lib/index.css';
// 自定义的非vue插件
import Service from "../service/imports";
import {Utils} from '../utils';
// 消息提示文字js
// const Message = window.Message
export class config {
/**
* 接口配置,测试环境,正式环境,具体接口
*/
public static AjaxConfig: any = {
DevUrl: 'http://new.gddh999.com/',
ProdUrl: 'http://api.alkid888.com/',
WsDevUrl: 'ws://118.25.189.247:2345',
WsProdUrl: 'ws://ws.alkid888.com:2345',
ApiList: {
reg: '/index/reg/index', //注册买家
login: '/index/login/index', //登录买家
captcha: '/api/Sms/captcha', //注册验证码
getvantcity: '/api/address/getvantcity', //省市区地址接口
accountlist: '/index/index/accountAndAddressInfo', //买号列表
accountTagInfo: '/index/buyer_accounts/accountTagInfo', //添加买号标签
saveaccount: '/index/buyer_accounts/saveaccount', //买号添加
modifyAccount: '/index/buyer_accounts/modifyAccount', //审核未通过修改买号
uploadImg: '/index/api/upload', //买家图片上传
referMoney: '/index/index/referMoney', //我的页面推广的资金
financeInfo: '/index/index/financeInfo', //我的页面账户余额
memberInfo: '/index/index/memberInfo', //我的页面用户信息
saveAccountAddress: '/index/buyer_accounts/saveAccountAddress', //账号地址修改
accountListByPlatform: '/index/buyer_accounts/accountInfoById', //查询买号详情
cashout: '/index/finance/cashout', // 提现操作
saveidcard: '/index/authentication/saveidcard', //实名认证添加修改
banklist: '/index/authentication/banklist', //銀行列表
idCardBankInfo: '/index/authentication/idCardBankInfo', //实名认证信息渲染
getTaskAccount: '/index/Task/getTaskAccount', // 获取接单账号列表
getTaskList: '/index/task/tasklist', //任务列表
orderTask: 'index/Task/orderTask',
commitTask: 'index/Task/commitTask',
announceInfoById: 'index/index/announceInfoById', //公告详细内容
announceList: 'index/index/announceList', //公告列表,
messageList: 'index/message/messageList', // 消息列表
taskDetail: '/index/Task/taskDetail', //任务详情
setComparePrice: '/index/Task/setComparePrice', //确认货比信息
verifyShop: '/index/Task/verifyShop', //验证店铺
purchaseDone: '/index/Task/purchaseDone', //选购完成
buyerOrder: '/index/Task/buyerOrder', //买家下单/付款
confirmAccept: '/index/Task/confirmAccept', //买家确认收货
financelist: '/index/finance/financelist', //资金列表
commissionList: '/index/finance/commissionList', //佣金列表
cashlist: '/index/cash_out/cashlist', //提现列表
getMemberInfo: '/index/member/getMemberInfo', //获取用户信息
forget: '/index/login/forget',
referinfo: '/index/refer/referinfo', //推广信息
index: '/index/index/index', //首页基础信息
cancelTask: '/index/Task/cancelTask', //取消任务
nextStep: '/index/Task/nextStep', //任务进入下一步
setTaskTag: '/index/Task/setTaskTag', //任务打标
},
};
/**
* 需要控制未登录跳转的路由
*/
public static isRouter: Array<string> = ['/']
/**
* 浏览器本地缓存的前缀
*/
public static prefix: string = 'h5_'
/**
* 需要被挂载的节点
*/
public static mountElement: string = '#app';
/**
* 非Vue插件
*/
public static NotVuePlugs: Array<Object> = [
{n: '$http', f: Service},
{n: '$utils', f: Utils},
{n: '$config', f: config}
];
/**
* Vue插件
*/
public static VuePlugs: Array<any> = [VueRouter, Vant];
/**
* Vue-router 配置
*/
public static RouterConfigUrl: Object = {
routes: [
{
path: '/',
name: 'index',
component: Utils.AsyncComponentHook("subject/subject"),
redirect: {
name: 'home'
},
children: [
{
path: 'home',
name: 'home',
component: Utils.AsyncComponentHook("subject/index"),
meta: {
title: '首页',
alive: false
}
},{
path: 'task',
name: 'task',
component: Utils.AsyncComponentHook("subject/Task"),
meta: {
title: '任务',
alive: false
}
},{
path: 'news',
name: 'news',
component: Utils.AsyncComponentHook("subject/News"),
meta: {
title: '消息',
alive: false
}
},{
path: 'my',
name: 'my',
component: Utils.AsyncComponentHook("subject/My"),
meta: {
title: '我的',
alive: false
}
}
]
},
{
path: '/taskInfo',
name: 'taskinfo',
component: Utils.AsyncComponentHook("TaskInfo"),
meta: {
title: '任务详情'
}
},
{
path: '/taskHall',
name: 'taskhall',
component: Utils.AsyncComponentHook("TaskHall"),
meta: {
title: '任务大厅'
}
},
{
path: '/login',
name: '登录',
component: Utils.AsyncComponentHook("Login"),
meta: {
title: '登录'
}
},
{
path: '/register',
name: 'register',
component: Utils.AsyncComponentHook("Register"),
meta: {
title: '注册'
}
},
{
path: '/fund',
name: 'fund',
component: Utils.AsyncComponentHook("Fund"),
meta: {
title: '资金管理'
}
},
{
path: '/collection',
name: 'collection',
component: Utils.AsyncComponentHook("CollectionRecords"),
meta: {
title: '佣金记录'
}
},
{
path: '/feedback',
name: 'feedback',
component: Utils.AsyncComponentHook("Feedback"),
meta: {
title: '意见反馈'
}
},
{
path: '/extension',
name: 'extension',
component: Utils.AsyncComponentHook("Extension"),
meta: {
title: '推广赚钱'
}
},
{
path: '/addAccount',
name: 'addAccount',
component: Utils.AsyncComponentHook("AddAccount"),
meta: {
title: '添加买号'
}
},
{
path: '/authentication',
name: 'authentication',
component: Utils.AsyncComponentHook("Authentication"),
meta: {
title: '买号认证'
}
},
{
path: '/modifyAddress',
name: 'modifyAddress',
component: Utils.AsyncComponentHook("ModifyAddress"),
meta: {
title: '修改地址'
}
},
{
path: '/realName',
name: 'realName',
component: Utils.AsyncComponentHook("RealName"),
meta: {
title: '实名认证'
}
},
{
path: '/forget',
name: 'forget',
component: Utils.AsyncComponentHook("Forget"),
meta: {
title: '修改密码'
}
},
{
path: '/cashwithdrawal',
name: 'cashwithdrawal',
component: Utils.AsyncComponentHook("Cashwithdrawal"),
meta: {
title: '提现记录'
}
},
{
path: '/principalRecord',
name: 'principalRecord',
component: Utils.AsyncComponentHook("PrincipalRecord"),
meta: {
title: '本金记录'
}
},
{
path: '/noticeInfo',
name: 'noticeInfo',
component: Utils.AsyncComponentHook("NoticeInfo"),
meta: {
title: '公告详细内容'
}
}
]
}
}

View File

@@ -0,0 +1 @@
0c33df44-42a1-4d79-9e5f-cb1363eaaf83

View File

@@ -0,0 +1,152 @@
import {Utils} from '../utils';
import axios, {AxiosInstance} from 'axios';
import {Dialog, Toast} from 'vant';
export class Axios {
private instance: AxiosInstance;
private Utils: Utils = new Utils()
// @ts-ignore
public async constructor() {
this.instance = axios.create({
baseURL: Utils.CheckAjaxUrl(),
timeout: 3000
});
this.ResponseInterceptor();
this.RequestInterceptor();
console.log(Utils.CheckAjaxUrl());
}
/**
* Get 请求
* 请求参数请参考接口RequestParams
* @param params
*/
public async get(params: { url: string, data: Object }): Promise<Object> {
try {
return await this.instance.get(params.url, {params: params.data})
} catch (e) {
return e.message
}
}
/**
* Post 请求
* 请求参数请参考接口RequestParams
* @param params
*/
public async post(params: { url: string, data: Object, header?: Object }): Promise<Object> {
try {
return await this.instance.post(params.url, params.data, {
headers: Object.assign({}, params.header)
})
} catch (e) {
return e.message
}
}
/**
* Put 请求
* 请求参数请参考接口RequestParams
* @param params
*/
public async put(params: { url: string, data: Object }): Promise<Object> {
try {
return await this.instance.put(params.url, params.data)
} catch (e) {
return e.message
}
}
/**
* delete 请求
* 请求参数请参考接口RequestParams
* @param params
*/
public async delete(params: { url: string, data: Object }): Promise<Object> {
try {
return await this.instance.delete(params.url, {params: params.data})
} catch (e) {
return e.message
}
}
/**
* 添加响应拦截器
* @constructor
*/
public async ResponseInterceptor(): Promise<any> {
this.instance.interceptors.response.use( async response => {
this.CloseLoadingData();
switch (response.data.code) {
case 0:
switch (response.data.status) {
case 1:
if(response.data.data !== null && response.data.data !== void 0){
return response.data.data;
}else{
Toast(response.data.msg)
}
break;
default:
await Dialog.alert({
message: `[${response.data.status}]${response.data.msg}`
})
return -1
break;
}
break;
case 1001:
Dialog.alert({
message: response.data.msg
}).then(() => {
this.Utils.delStorage('access_token')
window.location.href = `${window.location.origin}${window.location.pathname}#/login`
});
break;
default:
alert(`[${response.data.code}]${response.data.msg}`)
break;
}
}, function (error) {
return Promise.reject(error)
})
}
/**
* 添加请求拦截器
* @constructor
*/
public async RequestInterceptor(): Promise<any> {
this.instance.interceptors.request.use(config => {
// 添加token
Object.assign(config.headers,{
'authorization': this.Utils.getToken()
})
this.OpenLoadingData();
return config
}, function (error) {
return Promise.reject(error)
})
}
/**
* 显示加载进度
* @constructor
*/
private OpenLoadingData(): void {
Toast.loading({
message: '加载中...',
forbidClick: true,
loadingType: 'circular'
});
}
/**
* 清除加载进度条
*/
private CloseLoadingData(): void {
Toast.clear();
}
}

View File

@@ -0,0 +1 @@
32b784bd-1a75-43f8-9b0b-565c56d600fc

View File

@@ -0,0 +1,60 @@
import Vue, {VueConstructor} from 'vue';
import App from '@/App.vue';
import VueRouter from 'vue-router';
import '../class-component-hooks';
import {config} from '../config'
/**
* 初始化Vue需要的插件和构造Vue启动参数
*/
export class init {
private initVuePlugsArray: Array<any> = config.VuePlugs;
private initOtherPlugsArray: Array<Object> = config.NotVuePlugs;
protected router: any;
protected Vues: any = Vue;
public static App: VueConstructor = App;
constructor() {
this.Vues.config.productionTip = false;
this.initPlugs();
}
/**
* 初始化Vue和非Vue插件
*/
private initPlugs(): void {
// @ts-ignore
this.initOtherPlugsArray.forEach(v => this.Vues.prototype[v['n']] = new (v['f'])());
this.initVuePlugsArray.forEach(v => this.Vues.use(v));
this.InitVueRouter();
}
/**
* 初始化配置全局路由
* @constructor
*/
private InitVueRouter(): void {
this.router = new VueRouter(config.RouterConfigUrl);
// 重写路由Push
const routerPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location: any): any {
// @ts-ignore
return routerPush.call(this, location).catch((error: any) => error)
}
this.router.beforeEach((to: any, from: any, next: any) => {
if (to.meta.title) {
document.title = to.meta.title;
}
// 如果用户未登录跳转至登录页
if(!localStorage.getItem(`${config.prefix}access_token`) && config.isRouter.indexOf(to.path) !== -1){
next('/login')
}else{
next();
}
// next();
});
}
}

View File

@@ -0,0 +1,20 @@
import {init} from './init';
import {config} from '../config';
import store from '../store/index'
/**
* Vue项目的启动文件
*/
class Run extends init {
public initApp(): void {
const router = this.router;
new this.Vues({
router,
store,
render: (h: (arg0: any) => void): any => h(init.App)
}).$mount(config.mountElement);
}
}
(new Run()).initApp();

View File

@@ -0,0 +1 @@
e44ecb30-2f2c-4ec3-b47e-63ecc51c9842

View File

@@ -0,0 +1,14 @@
import * as ServeTypes from '../types/ServeTypes'
export interface HomeService {
register(data: ServeTypes.registerType): Promise<Object[]>;
login(data: ServeTypes.registerType): Promise<Object[]>;
captcha(cellphone: string): Promise<Object[]>;
saveaccount(data: ServeTypes.buyNumber): Promise<Object[]>;
accountTagInfo(type: number): Promise<Object[]>;
referMoney(): Promise<Object[]>;
financeInfo(): Promise<Object[]>;
memberInfo(): Promise<Object[]>;
forget(data: ServeTypes.forget): Promise<Object[]>;
getIndex(): Promise<Object[]>
}

View File

@@ -0,0 +1,5 @@
export interface NewsService {
announceList(data: object): Promise<any>;
announceInfoById(data: object): Promise<any>;
messageList(data: object): Promise<any>;
}

View File

@@ -0,0 +1,7 @@
import * as ServeTypes from '../types/ServeTypes'
export interface PublicService {
getvantcity(): Promise<Object[]>
uploadImg(data: ServeTypes.imageType): Promise<Object[]>
banklist(): Promise<Object[]>
}

View File

@@ -0,0 +1,17 @@
import * as ServeTypes from '../types/ServeTypes'
export interface TaskService {
getTaskAccount(data: { platform_id: string }): Promise<any>;
getTaskList(data: object): Promise<any>;
orderTask(data: object): Promise<any>;
commitTask(data: object): Promise<any>;
taskDetail(id: string): Promise<any>;
setComparePrice(data: ServeTypes.setComparePriceType): Promise<any>;
verifyShop(data: ServeTypes.verifyShopType): Promise<any>;
purchaseDone(data: ServeTypes.purchaseDoneType): Promise<any>;
buyerOrder(data: ServeTypes.buyerOrderType): Promise<any>;
confirmAccept(id: string): Promise<any>;
cancelTask(id: string): Promise<any>;
nextStep(id: string): Promise<any>;
setTaskTag(data: ServeTypes.TaskTagType): Promise<any>;
}

View File

@@ -0,0 +1,16 @@
import * as ServeTypes from '../types/ServeTypes'
export interface UserService {
getAccountlist(): Promise<Object[]>
saveAccountAddress(data: ServeTypes.saveAddress): Promise<Object[]>
accountListByPlatform(id: string): Promise<Object[]>
modifyAccount(data: ServeTypes.buyNumber): Promise<Object[]>
cashout(type: number): Promise<Object[]>
saveidcard(data: ServeTypes.realNameType): Promise<Object[]>
idCardBankInfo(): Promise<Object[]>
financelist(data: ServeTypes.paging): Promise<Object[]>
commissionList(data: ServeTypes.paging): Promise<Object[]>
cashlist(data: ServeTypes.paging): Promise<Object[]>
getMemberInfo(): Promise<Object[]>
referinfo(data: ServeTypes.paging): Promise<Object[]>
}

View File

@@ -0,0 +1 @@
aa3cef1a-23ef-4f83-8be1-790da8f42bfe

View File

@@ -0,0 +1,91 @@
import {HomeService} from "../HomeService"
import {Axios} from "../../dao";
import {config} from "../../config";
import * as ServeTypes from '../../types/ServeTypes'
export class HomeServiceImpl extends Axios implements HomeService {
// 买家注册接口
public async register(data: ServeTypes.registerType): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.reg,
data: data
});
}
// 买家登录接口
public async login(data: ServeTypes.registerType): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.login,
data: data
});
}
// 注册的时候验证码
public async captcha(cellphone: string): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.captcha,
data: {
'cellphone': cellphone,
'template_id': '1'
}
});
}
// 添加买号
public async saveaccount(data: ServeTypes.buyNumber): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.saveaccount,
data: data
});
}
// 添加买号标签
public async accountTagInfo(type: number): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.accountTagInfo,
data: {
platform: type
}
});
}
// 我的页面推广的资金
public async referMoney(): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.referMoney,
data: {}
});
}
// 我的页面账户余额
public async financeInfo(): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.financeInfo,
data: {}
});
}
// 我的页面个人信息
public async memberInfo(): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.memberInfo,
data: {}
});
}
// 忘记密码
public async forget(data: ServeTypes.forget): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.forget,
data: data
});
}
// 忘记密码
public async getIndex(): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.index,
data: {}
});
}
}

View File

@@ -0,0 +1,30 @@
import { Axios } from "../../dao";
import { NewsService } from "../NewsService";
import { config } from "../../config";
export class NewsServiceImpl extends Axios implements NewsService {
// 公共列表
public async announceList(data: object): Promise<any> {
return await this.get({
url: config.AjaxConfig.ApiList.announceList,
data: data
});
}
// 公告详情
public async announceInfoById(data: object): Promise<any> {
return await this.get({
url: config.AjaxConfig.ApiList.announceInfoById,
data: data
});
}
// 消息列表
public async messageList(data: object): Promise<any> {
return await this.get({
url: config.AjaxConfig.ApiList.messageList,
data: data
});
}
}

View File

@@ -0,0 +1,33 @@
import { PublicService } from '../PublicService'
import {Axios} from "../../dao";
import {config} from "../../config";
import * as ServeTypes from '../../types/ServeTypes'
export class PublicServiceImpl extends Axios implements PublicService {
public async getvantcity(): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.getvantcity,
data: {}
});
}
// 买家图片上传
public async uploadImg(data: ServeTypes.imageType): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.uploadImg,
data: data,
header: {
'Content-Type': 'multipart/form-data'
}
});
}
// 银行卡列表
public async banklist(): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.banklist,
data: {}
});
}
}

View File

@@ -0,0 +1,105 @@
import { TaskService } from '../TaskService'
import {Axios} from "../../dao";
import {config} from "../../config";
import * as ServeTypes from '../../types/ServeTypes'
export class TaskServiceImpl extends Axios implements TaskService {
public async getTaskAccount(data: { platform_id: string }): Promise<any> {
return await this.get({
url: config.AjaxConfig.ApiList.getTaskAccount,
data: data
});
}
public async getTaskList(data: object): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.getTaskList,
data: data
});
}
public async orderTask(data: object): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.orderTask,
data: data
});
}
public async commitTask(data: object): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.commitTask,
data: data
});
}
public async taskDetail(id: string): Promise<any> {
return await this.get({
url: config.AjaxConfig.ApiList.taskDetail,
data: {
task_id: id
}
});
}
public async setComparePrice(data: ServeTypes.setComparePriceType): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.setComparePrice,
data: data
});
}
public async verifyShop(data: ServeTypes.verifyShopType): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.verifyShop,
data: data
});
}
public async purchaseDone(data: ServeTypes.purchaseDoneType): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.purchaseDone,
data: data
});
}
public async buyerOrder(data: ServeTypes.buyerOrderType): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.buyerOrder,
data: data
});
}
public async confirmAccept(id: string): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.confirmAccept,
data: {
task_id: id
}
});
}
public async cancelTask(id: string): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.cancelTask,
data: {
task_id: id
}
});
}
public async nextStep(id: string): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.nextStep,
data: {
task_id: id
}
});
}
public async setTaskTag(data: ServeTypes.TaskTagType): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.setTaskTag,
data: data
});
}
}

View File

@@ -0,0 +1,108 @@
import { UserService } from '../UserService'
import {Axios} from "../../dao";
import {config} from "../../config";
import * as ServeTypes from '../../types/ServeTypes'
export class UserServiceImpl extends Axios implements UserService {
// 买号列表
public async getAccountlist(): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.accountlist,
data: {}
});
}
// 修改买号地址
public async saveAccountAddress(data: ServeTypes.saveAddress): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.saveAccountAddress,
data: data
});
}
// 获取当前买号信息
public async accountListByPlatform(id: string): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.accountListByPlatform,
data: {
id: id
}
});
}
// 修改买号
public async modifyAccount(data: ServeTypes.buyNumber): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.modifyAccount,
data: data
});
}
// 提现
public async cashout(type: number): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.cashout,
data: {
type_id: type
}
});
}
// 实名认证
public async saveidcard(data: ServeTypes.realNameType): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.saveidcard,
data: data
});
}
// 实名认证查询
public async idCardBankInfo(): Promise<any> {
return await this.post({
url: config.AjaxConfig.ApiList.idCardBankInfo,
data: {}
});
}
// 资金列表
public async financelist(data: ServeTypes.paging): Promise<any> {
return await this.get({
url: config.AjaxConfig.ApiList.financelist,
data: data
});
}
// 佣金列表
public async commissionList(data: ServeTypes.paging): Promise<any> {
return await this.get({
url: config.AjaxConfig.ApiList.commissionList,
data: data
});
}
// 提现列表
public async cashlist(data: ServeTypes.paging): Promise<any> {
return await this.get({
url: config.AjaxConfig.ApiList.cashlist,
data: data
});
}
// 获取用户信息
public async getMemberInfo(): Promise<any> {
return await this.get({
url: config.AjaxConfig.ApiList.getMemberInfo,
data: {}
});
}
// 推广信息
public async referinfo(data: ServeTypes.paging): Promise<any> {
return await this.get({
url: config.AjaxConfig.ApiList.referinfo,
data: data
});
}
}

View File

@@ -0,0 +1,13 @@
import {HomeServiceImpl} from "./impl/HomeServiceImpl";
import {PublicServiceImpl} from "./impl/PublicServiceImpl";
import {UserServiceImpl} from "./impl/UserServiceImpl";
import {TaskServiceImpl} from "./impl/TaskServiceImpl";
import {NewsServiceImpl} from "./impl/NewsServiceImpl";
export default class Imports {
public HomeService = new HomeServiceImpl()
public PublicService = new PublicServiceImpl()
public UserService = new UserServiceImpl()
public TaskService = new TaskServiceImpl()
public NewsService = new NewsServiceImpl()
}

View File

@@ -0,0 +1 @@
2d824815-2536-4b1e-a089-96dda5ed23c6

View File

@@ -0,0 +1,7 @@
import { Commit } from 'vuex'
export default {
NEWSNUM(context: { commit: Commit }, n: Object){
context.commit('SET_NEWSNUM', n)
}
}

View File

@@ -0,0 +1,5 @@
export default {
getNewsNum: (state:any) => {
return state.newsNum
}
}

View File

@@ -0,0 +1,21 @@
import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'
Vue.use(Vuex)
const store = new Vuex.Store({
state:{
newsNum: 0, // 任务角标
},
actions,
mutations,
getters
})
export default store

View File

@@ -0,0 +1 @@
70091933-524c-4d73-a89f-5c3d0bd021d8

View File

@@ -0,0 +1,5 @@
export default {
SET_NEWSNUM (state:any, n: Object) {
state.newsNum = n
}
}

View File

@@ -0,0 +1 @@
28eee31e-8881-4fd1-87fb-de52da83c8e4

View File

@@ -0,0 +1,199 @@
export type registerType = {
// 手机号
cellphone: string
// 密码8-25位数组字母组合
password: string
// 验证码(暂未做验证4位)
verifyCode?: string
// 短信模板ID此处为1注册验证码
templateId?: string
// 邀请码
inviteCode?: string
}
export type buyNumber = {
// 买号id修改买号时需要
id?: string
// 账号
account: string
// 账号性别
account_gender: number
// 账号等级
account_rate: number
// 账号年龄
account_ages: number
// 账号积分(淘气值,京享值,拼多多没有
account_points: number
// 上传id
image_id: number
// 姓名
full_name: string
// 手机号码
cellphone: string
// 地区id
area_id: string
// 详细地址
detail: string
// 标签id1,2,3 最多三个
category_id: string
// 账号类型(1淘宝2京东3拼多多)
account_type: string
}
// 上传图片接口
export type imageType = {
file: File
imageType: string
}
export type saveAddress = {
// 买号id
id: string
// 姓名
full_name: string
// 手机号码
cellphone: string
// 地区id
area_id: string
// 详情
detail: string
}
export type realNameType = {
// 姓名
username: string
// 省份证卡号
id_card: string
// 上传身份证图片id
id_card_image_id: string
// 手势图片id
user_image_id: string
// 银行账号
account: string
// 银行id
bank_id: string
// 支行名称(开户行)
bank_name: string
// 地区id
bank_area_id: string
}
export type setComparePriceType = {
// 任务ID
task_id: string
// 淘口令
compare_item_value: string
// 货比信息的主键ID没有则表示新增货比信息 编辑时需传
compare_price_id?: string
}
export type verifyShopType = {
// 任务ID
task_id: string
// 店铺名或淘口令
verify_value: string
// 图片id
image_id: string
}
export type purchaseDoneType = {
// 任务ID
task_id: string
// 加购物车
item_cart: 'no' | 1 | ''
// 宝贝收藏
item_collect: 'no' | 1 | ''
// 拍前假聊
item_chat: 'no' | 1 | ''
// 宝贝浏览
item_scan: 'no' | 1 | ''
}
export type buyerOrderType = {
// 任务ID
task_id: string
// 淘宝/京东/PDD订单号
trade_num: string
// 实付金额
amount: string
}
export type paging = {
// 当前页
page: number
// 分页大小
limit: number
}
// 忘记密码
export type forget = {
// 手机号
cellphone: string
// 验证码
verify_code: string
// 模板id
template_id: string
// 密码
password: string
// 确认密码
repassword: string
}
// 任务打标
export type TaskTagType = {
// 任务id
task_id: string
// 任务详情接口种的参数
process_id: string
// 图片上传后返回的id
tag_image: number
}

View File

@@ -0,0 +1 @@
34dc31dd-011b-4cc8-b29e-abd8f67f862a

View File

@@ -0,0 +1,210 @@
import { config } from '../config';
import { Toast } from 'vant';
import { format } from 'timeago.js';
export class Utils {
/**
* 检测当前环境动态返回ajax接口的对应的URL地址
* @constructor
*/
public static CheckAjaxUrl(): string {
if (process.env.NODE_ENV.replace(/^\s+|\s+$/g, '') == 'production') {
return config.AjaxConfig.ProdUrl;
} else {
return config.AjaxConfig.DevUrl;
}
}
/**
* 检测当前环境动态返回socket对应的URL地址
* @constructor
*/
public static CheckWsUrl(): string {
if (process.env.NODE_ENV.replace(/^\s+|\s+$/g, '') == 'production') {
return config.AjaxConfig.WsProdUrl;
} else {
return config.AjaxConfig.WsDevUrl;
}
}
/**
* 异步加载组件,仅限 pages 中组件
* @param fileName 组件的文件名称
* @constructor
*/
public static AsyncComponentHook(fileName: String): Function {
const component = import(/* webpackChunkName: "[request]" */ `@/pages/${fileName}.vue`);
component.catch(e => console.error(`组件加载失败: ${e}`));
return () => component;
}
/**
* 动态设置网页title
* @param title
*/
public setTitle(title: string): void {
document.title = title;
}
/**
* 本地存储
* @param key 存储的名称
* @param value 存储的数据
*/
public setStorage(key: string, value: any): void {
try {
if (typeof key !== 'string') {
throw "key必须为字符串";
}
localStorage.setItem(config.prefix + key, JSON.stringify(value))
} catch (error) {
console.error(error)
}
}
/**
* 获取本地存储
* @param key 存储的名称
*/
public getStorage(key: string): any {
try {
let value: string = localStorage.getItem(config.prefix + key) as string
if (value !== void 0 && value !== null) {
return JSON.parse(value)
} else {
throw `获取key:${key}的本地缓存数据失败`
}
} catch (error) {
console.error(error)
}
}
/**
* 删除本地存储
* @param key 存储的名称
*/
public delStorage(key: string): void {
return localStorage.removeItem(config.prefix + key);
}
/**
* 获取token
*/
public getToken(): void {
return this.getStorage('access_token')
}
/**
* id 身份证号
* 身份证验证
*/
public isIdentity(id: string): boolean{
let str: RegExp = /^[1-9]\d{5}(18|19|20|(3\d))\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/
return str.test(id)
}
/**
* id 手机号
* 手机号证验证
*/
public isTel(id: string): boolean{
let str: RegExp = /^1[3456789]\d{9}$/
return str.test(id)
}
// 计算倒计时
public leftTimer(time: number): string{
//3.获取现在的时间
let presentDate = new Date();
//4.获取时间戳
let funtureTime = time * 1000;
let presenTime = presentDate.getTime();
//5.获取剩余的时间戳
let allTime = funtureTime - presenTime;
//6.把毫秒转换为秒
let allSecond: any = (allTime / 1000)
//7.获取剩余多少天
let day = this.size((allSecond / 3600 / 24))
//8.获取剩余多少小时
let hour = this.size((allSecond / 3600 % 24))
//9.获取剩余多少分钟
let minute = this.size((allSecond / 60 % 60));
//10.获取剩余多少秒
let second = this.size((allSecond % 60));
if(second >= 0){
return `${parseInt(hour)}${parseInt(minute)}${parseInt(second)}`
}else{
return '任务已超时'
}
}
private size(num: any) {
return num < 10 && num >= 0 ? '0' + num : num;
}
// 时间戳转正常时间
public formatDate(data: number): string {
let now=new Date(data*1000);
let year=now.getFullYear();
let month=now.getMonth()+1;
let date=now.getDate();
let hour=now.getHours();
let minute=now.getMinutes();
let second=now.getSeconds();
return year+"-"+month+"-"+date+" "+hour+":"+minute+":"+second;
}
/**
* 时间戳 转最近时间 转换后 类如(1天前)
* @param time 时间戳
*/
public formatAge(time: number): string {
return format(time*1000, 'zh_CN')
}
// 复制到粘贴板
public copy(str: string): void {
var tag = document.createElement('input');
tag.setAttribute('id', 'cp_hgz_input');
tag.value = str;
document.getElementsByTagName('body')[0].appendChild(tag);
// @ts-ignore
document.getElementById('cp_hgz_input').select();
document.execCommand('copy');
// @ts-ignore
document.getElementById('cp_hgz_input').remove();
Toast('复制成功')
}
/**
* 用于把 单位为分 转换成 单位为元
* @param m 后端返回被处理成 单位为分 的钱
*/
public conversionMoney(m: number): string {
return (m/10/10).toFixed(2)
}
/**
* 使元素在可视区域内
* @param event
*/
public onFocus(event: Event): void {
try {
// 获取对应事件的 input dom
const inputDom: any = event.target;
setTimeout(() => {
// px to rem 的比例
const rate = (window.screen.width || document.documentElement.clientWidth) / 375;
// 底部按钮 375基准 的高度为 56根据 rate 计算实际高度
const bottomFixHeight = 56 * rate;
// 高度计算
const clientHeight = document.documentElement.clientHeight;
const top = inputDom.getBoundingClientRect().top;
const diff = clientHeight - top;
// scrollIntoViewIfNeeded方法使 元素滚动到浏览器窗口的可视区域内
inputDom.scrollIntoViewIfNeeded(true);
inputDom.scrollIntoView(true)
}, 200);
} catch (error) {
new Error(error)
}
}
}

View File

@@ -0,0 +1,159 @@
import {Utils} from './index'
import store from '../store/index'
interface wxConfig {
// 链接的通道的地址
url: string
// 心跳时间间隔
heartTime: number
// 心跳信息,默认为'ping'
heartMsg: any
// 是否自动重连
isReconnect: boolean
// 重连时间间隔
reconnectTime: number
// 重连次数 -1 则不限制
reconnectCount: number
}
export class Socket {
private Utils: Utils = new Utils()
private ws!: WebSocket
private wxConfig: wxConfig = {
url: Utils.CheckWsUrl(),
heartTime: 40000,
heartMsg: {dataType:'ping'},
isReconnect: true,
reconnectTime: 5000,
reconnectCount: 5
}
// 重连定时器
private restartTime!: number
// 销毁定时器
private closeTime!: number
constructor(option?: any){
Object.assign(this.wxConfig, option)
this.create()
}
// 启动心跳
private start() {
// 开启定时器
this.restartTime = setTimeout(() => {
this.send(this.wxConfig.heartMsg)
// 如果发送消息返回失败则触发关闭
this.closeTime = setTimeout(() => {
console.error('服务器长时间无响应,尝试重启服务');
this.destroy()
this.create()
}, this.wxConfig.heartTime);
}, this.wxConfig.heartTime);
}
// 重启心跳
private restart() {
clearTimeout(this.restartTime) // 清除重连定时器
clearTimeout(this.closeTime) // 清除销毁定时器
this.start()
}
// 创建链接
private create() {
if (!('WebSocket' in window)) {
new Error('当前浏览器不支持,无法使用')
return
}
if (!this.wxConfig.url) {
new Error('地址不存在,无法建立通道')
return
}
this.ws = new WebSocket(this.wxConfig.url)
this.start()
this.onopen()
this.onmessage()
this.onerror()
}
/**
* 自定义连接成功事件
*/
onopen () {
this.ws.onopen = (event) => {
let login = {
dataType: 'login',
token: this.Utils.getToken()
}
this.send(login)
}
}
/**
* 自定义关闭事件
*/
onclose () {
this.ws.onclose = (event) => {
console.log(event);
}
}
/**
* 自定义错误事件
*/
onerror () {
this.ws.onerror = (event) => {
console.log(event);
}
}
/**
* 自定义消息监听事件
*/
onmessage () {
this.ws.onmessage = (event) => {
this.restart()
let data = JSON.parse(event.data)
// if(data.status == -1){
// this.destroy()
// this.create()
// }
// 如果返回的数据中有data存在则保存 消息数量
if(data.data !== void 0){
store.commit('SET_NEWSNUM', data.data.msg_num)
}
}
}
/**
* 自定义发送消息事件
* @param {any} msg 发送的文本
*/
send (msg: any) {
if (this.ws.readyState !== this.ws.OPEN) {
new Error('没有连接到服务器,无法推送')
return
}
console.log(msg);
let str: string = JSON.stringify(msg)
this.ws.send(str)
}
/**
* 销毁
*/
destroy () {
this.restart()
clearTimeout(this.restartTime) // 清除重连定时器
this.ws.close()
}
}

View File

@@ -0,0 +1 @@
e416f7aa-cb1f-4934-9b8d-a6747b59848c

View File

@@ -0,0 +1,43 @@
<template lang="pug">
#app
router-view
TabbarComponent(v-if="isTabBar")
</template>
<script lang="ts">
import {Component, Provide, Vue} from 'vue-property-decorator';
import TabbarComponent from "@/components/Tabbar.vue";
@Component({
components: {
TabbarComponent
}
})
export default class App extends Vue {
// 控制导航条是否显示
public isTabBar: boolean = true;
// 为后代组件提供方法 HiddenTabBarShowTabBar
@Provide() HiddenTabBar = this.hiddenTabBar
@Provide() ShowTabBar = this.showTabBar
// 关闭底部导航条
public hiddenTabBar(): void {
this.$nextTick(function () {
this.isTabBar = false
})
}
// 显示底部导航
public showTabBar(): void {
this.$nextTick(function () {
this.isTabBar = true
})
}
}
</script>
<style lang="stylus">
@import "./assets/stylus/tpl/_public.styl"
</style>

View File

@@ -0,0 +1 @@
521441a4-f37b-450c-b7f1-74cfbfe0c1f2

View File

@@ -0,0 +1 @@
c01e48bd-35c8-4ccb-b979-bb633d72fc8c

View File

@@ -0,0 +1,3 @@
// vue.config.js被导入
@import "./tpl/colors.styl"
@import "./tpl/mixins.styl"

View File

@@ -0,0 +1 @@
21f1c3b8-5019-41d5-b760-4818c65eae54

View File

@@ -0,0 +1,43 @@
.add_account
.alipay
padding 0.267rem 0.48rem
.alipay_title
color: #323233;
font-size: 0.37333rem;
margin 0.3rem 0
.alipay_img
display flex
align-items center
.category
margin-top 1.2rem
.category_list
height 5rem
overflow-y scroll
.row_list
display: inline-block;
width 25%
padding 0.1rem
box-sizing border-box
.row
height 0.83rem
border 0.03rem solid #e5e5e5
font-size 0.38rem
color #999999
border-radius 0.1rem
.row_active
border 0.03rem solid #4fc08d
.category_custom
margin-bottom 0.3rem
input
font-size 13px
color #ccc
padding-left 0.24rem
padding-bottom 0.213rem
border none
width 100%
border-bottom 0.026rem solid #ccc
box-sizing border-box
margin-bottom 0.507rem
&:last-child {
margin-bottom 0
}

View File

@@ -0,0 +1,23 @@
.platform_list
padding-top 0.3rem
.platform
display flex
align-items center
padding 0.19rem
border 0.05rem solid #e5e5e5
border-radius 0.1rem
img
width 1.12rem
height 1.12rem
overflow hidden
border-radius 50%
p,span
font-size 0.38rem
.already
background-color $taskColor
padding 0.1rem
color #ffffff
.examine
background-color #ee0a24
padding 0.1rem
color #ffffff

View File

@@ -0,0 +1,21 @@
@import '../imports.styl';
.fund
box-sizing border-box
.fund_center
padding-top 0.4rem
padding-bottom 0.4rem
.account
background-color $themeColor
height 3.37rem
border-radius 0.1rem
overflow hidden
padding 0 0.6rem
.money
text-align center
.money_text
font-size 0.38rem
font-weight 500
color #ffffff
p
font-size 0.42rem
color #ffffff

View File

@@ -0,0 +1,87 @@
.Index
padding-bottom 0.9rem
.capital
height 2.75rem
background-color #20c6c2
text-align center
.p1,.p2
color #ffffff
.p1
font-size 0.36rem
font-weight 500
.p2
font-size 0.42rem
font-weight 600
margin 0.2rem 0 0.3rem 0
span
padding 0.09rem 0.19rem
background-color #ffffff
border-radius 0.1rem
display flex
align-items center
font-size 0.32rem
.text
font-size 0.38rem
color #666666
.notice
border 0.03rem solid #cccccc
margin-top 0.52rem
.news
padding 0.4rem 0.53rem
.news_cen
p
color #666666
font-size 0.42rem
margin 0.1rem 0
.news_end
text-align center
span
color #cccccc
font-size 0.34rem
position relative
&:after
content ''
position absolute
top 50%
left 1.5rem
margin-top 0.015rem
width 0.96rem
height 0.03rem
background-color #cccccc
&:before
content ''
position absolute
top 50%
right 1.5rem
margin-top 0.015rem
width 0.96rem
height 0.03rem
background-color #cccccc
.advertisement
height 2.48rem
border-radius 0.1rem
overflow hidden
img
height 2.48rem
width 100%
.task_num
height 2.48rem
border-radius 0.1rem
overflow hidden
box-shadow 0 2px 10px #0a10143d
.task_num_li
text-align center
color #000
span
font-size 0.4rem
font-weight bold
p
margin-top 0.2rem
font-size 0.4rem
.receipt
font-size 0.42rem
padding 0.3rem 0
background-color #20c6c2
color #ffffff
font-weight 500
text-align center

View File

@@ -0,0 +1,58 @@
.login
margin 0 auto
width 8.227rem
padding-top 1.32rem
.head_portrait
width 2.907rem
height 2.88rem
margin: 0 auto
margin-bottom 1.32rem
img
width 100%
height 100%
.user_input
margin-bottom 1.347rem
input
font-size 13px
color #ccc
padding-left 0.24rem
padding-bottom 0.213rem
border none
width 100%
border-bottom 0.026rem solid #ccc
box-sizing border-box
margin-bottom 0.507rem
&:last-child {
margin-bottom 0
}
.user_login
width 100%
height 1.267rem
background $themeColor
color #fff
text-align center
line-height 1.267rem
font-size 16px
margin-bottom 0.84rem
.login_other
text-align center
span
color #666
font-size 14px
.forget_password
&:after
content "|"
margin-left 0.64rem
margin-right 0.64rem
color #ccc
.agreement
width 100%
text-align center
font-size 0.34667rem
display flex
justify-content center
margin-top 1rem
// margin-bottom 1rem
.text
color #ccc !important
// vertical-align -webkit-baseline-middle

View File

@@ -0,0 +1,3 @@
.ModifyAddress
padding-left 0.2rem
padding-right 0.2rem

View File

@@ -0,0 +1,82 @@
@import '../imports.styl';
.home
width 100%
height 100%
background-color $themeColor
.user
padding 0.8rem 0.8rem 0.26rem 0.8rem
.user_img
height 1.5rem
width 1.5rem
border-radius 50%
overflow hidden
.user_info
margin-left 0.2rem
.user_name
color #ffffff
font-size 0.48rem
font-weight 500
.user_href
margin-top 0.2rem
color $themeColor
background-color #ffffff
padding 0.1rem 0.2rem
border-radius 0.2rem
font-size 0.38rem
text-align center
.sign_out
font-size 0.42rem
display flex
justify-content center
align-items center
align-content center
color #fff
.home_center
background-color #ffffff
overflow hidden
padding-bottom 1.33333rem
border-radius 0.4rem 0.4rem 0 0
.capital
border_bottom();
.capital_text
display flex
.capital_row
flex 1
padding 0.4rem 0.4rem
box-sizing border-box
.title
color #000
font-size 0.42rem
.balance
margin-top 0.4rem
color #ccc
font-size 0.46rem
.order_row
text-align center
padding 0.4rem 0
.row_l
position relative
p
color #000000
font-size 0.38rem
span
position absolute
right -0.1rem
top -0.1rem
border-radius 50%
background-color red
color #fff
font-size 0.28rem
height 0.5rem
width 0.5rem
line-height 0.5rem
text-align center
.propaganda
height 2.48rem
padding 0.56rem 0.3rem 0.8rem 0.3rem
img
height 2.48rem
width 100%
.text_r
text-align right

View File

@@ -0,0 +1,17 @@
.RealName
.certificates
padding 0.26667rem 0.42667rem
.example
width 50%
padding 0.26667rem
box-sizing border-box
display inline-block
img
width 100%
height 3.56rem
.identity
position relative
.statusIcon
position absolute
right 0
top -0.5rem

View File

@@ -0,0 +1,3 @@
.task
//padding 0 0.427rem
box-sizing border-box

View File

@@ -0,0 +1,89 @@
.task_info
.remaining_time
width 100%
height 1.067rem
background #334b4b
text-align center
line-height 1.067rem
color #fff
font-size 14px
.info
padding 0.267rem 0.48rem
.info_message
margin-top 0.413rem
display flex
img
width 2.453rem
height 2.453rem
margin-right 0.293rem
.message_right
color $themeFontColor
font-size 13px
p
margin-bottom 0.293rem
.question
vertical-align bottom
margin-left 0.067rem
.marking_task
padding 0.267rem 0.48rem
.task_title
height 0.933rem
display flex
justify-content space-between
align-items center
margin-bottom 0.48rem
border_bottom()
span
font-size 13px
.title
color #000
.tips
color $taskColor
.question
color $taskColor
margin-left 0.147rem
vertical-align bottom
.steps
margin-bottom 0.1rem
.steps_button
text-align right
margin-bottom 0.107rem
.collapse
margin-top 0.253rem
.upload
margin-top 0.413rem
.bottom_bar
position fixed
bottom 0
left 0
right 0
z-index 999
background-color #fff
border-top 0.01rem solid #cccccc
height 1.2rem
width 100%
display flex
align-items center
padding 0 0.32rem
box-sizing border-box
.bottom_bar_l
flex 1
text-align left
display inline-flex
.bottom_bar_r
flex 2
display flex
justify-content flex-end
.bottom_bar_but
border 0.02rem solid #cccccc
padding 0.15rem 0.32rem
border-radius 2rem
font-size 0.38rem
display inline-block
margin 0 0.1rem
.bottom_bar_but_finish
border 0.02rem solid #FF5722
color #FF5722
.fuzhi
margin-left 0.2rem

View File

@@ -0,0 +1 @@
4234538f-5565-4a2a-8666-e4dad3fe402d

View File

@@ -0,0 +1,186 @@
//
html,body,#app
height 100%
h1,h2,h3,h4,h5,h6,ul,li,p
padding 0
margin 0
// css
.line
width 100%
height 0.267rem
background #f6f6f6
.content
padding-top 46px
padding-bottom 50px
overflow auto
.inline_block
display inline-block
.mt80
margin-top 0.8rem
.mt25
margin-top 0.25rem
.mt10
margin-top 0.1rem
.mt36
margin-top 0.36rem
.mt40
margin-top 0.4rem
.ml10
margin-left 0.1rem
.ml20
margin-left 0.2rem
.ml40
margin-left 0.4rem
.mr10
margin-right 0.1rem
.pd43
padding 0 0.43rem
.pd30
padding 0 0.30rem
.pt20
padding-top 0.2rem
.mt
margin-top mt()
//
// .task task
.task .van-tab--active,
.news .van-tab--active
background $themeColor
.task .van-tabs__line,
.news .van-tabs__line
background #ee0a2400 !important
.task .van-tabs__wrap,
.news .van-tabs__wrap
height 1.17333rem
border-bottom 2px solid $themeColor
.task_info .van-cell,
.news .van-cell
padding-left 0
padding-right 0
.task_hall .van-tabs__line,
.news .van-tabs__line,
.CapitalDetails .van-tabs__line{
background-color: $themeColor;
}
// tasktaskinfo
//
.items_title
display flex
justify-content space-between
height 1.187rem
align-items center
border_bottom()
.title_status
color: red;
font-size 13px
.title_left
display flex
align-items center
img
width 0.573rem
height 0.573rem
margin-right 0.28rem
span
font-size 13px
margin-right 0.16rem
margin-left 0.16rem
max-width 3.5rem
.y
padding 0.107rem 0.23rem
// width 1.067rem
text-align center
color #fff
font-size 12px
display inline-block
.y_1
margin-right 0.147rem
//
.tv_b
color #e6a23c !important
.tv_c
color #67c23a !important
.topic
padding 0.2rem 0
.title
font-size 0.34667rem
color #969799
border-bottom 0.01rem #cccccc solid
padding-bottom 0.1rem
display flex
.topic_title
flex 1
.topic_value
flex 1
text-align right
.center
padding 0.2rem 0.1rem 0
.text
padding 0 0.2rem
.text_f
display flex
p
font-size 0.36rem
line-height 2
color #969799
flex 1
.text_separate
font-size 0.36rem
line-height 2
color #969799
display flex
.p
width 20%
.span
width 80%
.radio
padding-top 0.2rem
font-size 0.36rem
color #969799
//
.prompting
flex 1
font-size 0.24rem
color red
.prompting_m
margin 0.2rem
.prompting_cen
text-align center
//
.account_sub
padding 0.267rem 0.48rem
.account_sub_top
padding 0.267rem 0
// 线
// .mycell
// &:not(:last-child)::after
// position: absolute;
// box-sizing: border-box;
// content: ' ';
// pointer-events: none;
// right: 0;
// bottom: 0;
// left: 0.42667rem;
// border-bottom: 0.02667rem solid #ebedf0;
// transform: scaleY(.5);
//
.border_r
border-right 0.01rem solid #eeeeee
.border_b
border-bottom 0.01rem solid #eeeeee
.task,
.news
.van-tab__pane
overflow-y: scroll;

View File

@@ -0,0 +1,8 @@
//
// app
$themeColor = #20c6c2
$themeFontColor = #999
$taskColor = #1ab51f

View File

@@ -0,0 +1,22 @@
//css
.img
width 100%;
height 100%;
.flex
display flex;
.direction_column
flex-direction column;
.flex1
flex 1;
.flex_cen
display: flex;
justify-content: center;
align-items: center;
align-content: center
.pointer
cursor pointer;
border_bottom()
border-bottom: 1px solid #ebedf0;
mt(a=10)
unit(a, px)

View File

@@ -0,0 +1 @@
985e0234-6659-4c29-8dd9-56637c6fd0fa

View File

@@ -0,0 +1,70 @@
<template lang="pug">
.Address
van-field(clearable='', :label='areaTitle', disabled right-icon='arrow', :placeholder="area !== '选择地址'? area : areaText", @click="isPopup")
//- 地址选择弹窗
van-popup(v-model='show', position='bottom', :style="{ height: '40%' }")
van-area( :value='value' :area-list="areaList" @confirm="onConfirm" @cancel="isPopup" show-toolbar :columns-num="level")
</template>
<script lang="ts">
import {Component, Provide, Vue, Prop} from 'vue-property-decorator';
type AreaType<T> = {
[K in keyof T]: T[K]
}
interface AreaList {
[id: string]: AreaType<object>[]
}
@Component
export default class Address extends Vue {
$http: any
// 回显的区id
@Prop({default: '110101'}) readonly value!: string
// 回显的文字
@Prop({default: '选择地址'}) readonly areaText!: string
// 回显的文字
@Prop({default: '收货地址'}) readonly areaTitle!: string
// 是否禁止弹出框弹出
@Prop({default: false}) readonly isShow!: boolean
// 是否禁止弹出框弹出
@Prop({default: 3}) readonly level!: number
private show: Boolean = false
private area: string = '选择地址'
private areaId: number[] = []
// 省市区数据
private areaList: AreaList = {}
created() {
this.getvantcity()
}
private isPopup() {
if(this.isShow) return;
this.show = !this.show
}
// 地址数据
private async getvantcity(): Promise<void> {
let res = await this.$http.PublicService.getvantcity()
this.areaList = res
}
// 确定选择城市
private onConfirm(value: any, index: any): void {
this.area = ''
this.areaId = []
value.forEach((v: any, i: number) => {
this.area += (v.name + ' ')
this.areaId.push(v.code)
});
this.show = !this.show
this.$emit('confirm', this.areaId)
}
}
</script>
<style lang="stylus" scoped>
</style>

View File

@@ -0,0 +1,126 @@
<template lang="pug">
.Choose
div(v-for='it in data')
.topic(v-for='(item, index) in optionConfig' :key='index' v-if='index == isType(it.item_type)')
.title
.topic_title {{item.title}}
.topic_value.tv_b(v-if='!it.finish') 进行中
.topic_value.tv_c(v-else) 已完成
.center
.text
p(v-for='list in item.text') {{list}}
.radio
van-checkbox(v-model="item.checkbox" shape="square" icon-size='0.36rem' :disabled="isFinish" ) {{item.checkboxText}}
.prompting 请按照任务要求完成选购环节,平台严惩任务欺诈行为
van-button.my_button(type="primary" size="large" @click='purchaseDone' :disabled="isFinish") 我确认完成以上操作
//- van-button.my_button(type="primary" size="large" color='#cccccc') 180s后可提交
</template>
<script lang="ts">
// 进店组件
import {Component, Provide, Vue, Prop} from 'vue-property-decorator';
@Component({})
export default class Choose extends Vue {
$http: any
@Prop({default: {}}) readonly data: any
@Prop({default: ''}) readonly id!: string
// 是否完成
private isFinish: boolean = true
private optionConfig: any = [
{
title: '宝贝浏览',
text: [
'浏览宝贝的说明文字'
],
checkboxText: '我已完成宝贝浏览',
type: 'item_scan',
checkbox: false
},{
title: '拍前咨询',
text: [
'浏览宝贝的说明文字'
],
checkboxText: '我已完成拍前咨询',
type: 'item_chat',
checkbox: false
},{
title: '宝贝收藏',
text: [
'浏览宝贝的说明文字'
],
checkboxText: '我已完成宝贝收藏',
type: 'item_collect',
checkbox: false
},{
title: '加入购物车',
text: [
'浏览宝贝的说明文字'
],
checkboxText: '我已完成加入购物车',
type: 'item_cart',
checkbox: false
}
]
private created(): void {
this.isCheckbox()
}
private isType(str: string): number | undefined {
switch (str) {
case 'item_scan':
return 0
break;
case 'item_chat':
return 1
break;
case 'item_collect':
return 2
break;
case 'item_cart':
return 3
break;
default:
break;
}
}
private async purchaseDone(): Promise<void> {
let obj = this.optionConfig
let data = {
task_id: this.id
}
obj.forEach((v: any, i:number) => {
if(v.checkbox){
Object.assign(data, { [v.type]: 1})
}else{
Object.assign(data, { [v.type]: ''})
}
});
let res = await this.$http.TaskService.purchaseDone(data)
setTimeout(() => {
this.$emit('click')
}, 2000);
}
private isCheckbox(): void {
let data = this.data
for(let it in data){
this.optionConfig[this.isType(data[it].item_type) as number].checkbox = data[it].finish
// 循环接口中的所有数据判断是否完成当前step的所有步骤
// 如果全部完成则不需要修改isFinish如果有未完成的则修改isFinish为可修改
if(!data[it].finish){
this.isFinish = false
}
}
}
}
</script>
<style lang="stylus">
.Choose
.van-checkbox__label
color red
.my_button
margin-top 0.4rem
</style>

View File

@@ -0,0 +1,41 @@
<template lang="pug">
span.CountDown {{timeText}}
</template>
<script lang="ts">
// 倒计时组件
import {Component, Vue, Prop} from 'vue-property-decorator';
@Component({})
export default class CountDown extends Vue {
$utils: any
@Prop({default: 0}) readonly time!:number
private timeText: string = ''
private timer: number = NaN
private created(): void {
this.fromDate()
}
private beforeDestroy(): void {
// 在页面销毁时关闭定时器
clearInterval(this.timer)
}
private fromDate(): void {
this.timer = setInterval(()=>{
let str: string = this.$utils.leftTimer(this.time)
if(str == '任务已超时'){
clearInterval(this.timer)
}
this.timeText = str
},1000)
}
}
</script>
<style lang="stylus" scoped>
</style>

View File

@@ -0,0 +1,44 @@
<template lang="pug">
.CustomTabs
</template>
<script lang="ts">
import {Component, Provide, Vue, Prop, Watch} from 'vue-property-decorator';
import Icons from '@/components/Icons.vue'
@Component({
components:{
Icons
}
})
export default class CustomTabs extends Vue {
$utils: any;
$http: any;
private active: number = 0;
private SearchKey: String = "";
@Prop({ default: [] }) readonly list: Array<Object> | undefined
@Prop({ default: 0 }) readonly index!: number
private created(): void {
this.active = this.index
}
private onClick(name: string, title: number): void {
this.$emit('click', this.active)
}
// @Watch('index')
// private getIndex(n:number, o:number):void {
// this.active = n
// }
}
</script>
<style scoped lang="stylus">
</style>

View File

@@ -0,0 +1,190 @@
<template lang="pug">
.EnterShop
//- 如果type等于三则是淘口令
.message(v-if="message.channel_info.type == 3")
p 淘口令: {{message.channel_info.channel_value}}
Icons.fuzhi( name="buyer-icon-fuzhi" color='#ccc' size='0.5' @click='$utils.copy(message.channel_info.channel_value)')
//- 其他正常显示
.message(v-else)
p 搜索关键词: {{message.channel_info.channel_value}}
p 搜索页价格: {{$utils.conversionMoney(message.channel_info.search_price)}}
p 排序方式: {{message.channel_info.search_sort == 1?'默认排序':'销量排序'}}
span.prompting 手动输入关键字,禁止复制粘贴
van-collapse(class="collapse" :border="false" v-model='activeNames' accordion)
van-collapse-item(
v-for='(item, key, index) in data'
:key='index'
:name='index'
:title="isTitle(item.item_type, item.process_id)"
:value-class="item.finish?'tv_c':'tv_b'"
:value="item.finish?'已完成':'进行中'"
v-if="item.item_type !== 'task_start'")
div(v-if="item.item_type == 'compare_price'")
p.prompting 1. 在搜索结果页点击任意一个非"{{message.shop_info.shop_name}}"的宝贝
p.prompting 2. 浏览宝贝的主图详情不得少于3-5分钟,点击手机右上角"分享"
p.prompting 3. 在分享页面点击"复制链接"获取淘口令提交平台完成货比
van-field(v-model="item.detail" center clearable readonly v-if="item.finish" disabled)
van-field(v-model="ambush[index]" center clearable placeholder="输入淘口令" @focus="$utils.onFocus" v-if="!item.finish")
van-button(slot="button" size="small" type="primary" @click='setComparePrice(index,item.process_id)' :disabled="item.finish") 提交
.prompting 系统自动检测淘口令,平台严惩任务欺诈行为
div(v-if="item.item_type == 'verify_shop'")
.message
p 店铺名称: {{message.shop_info.shop_name}}
p 店铺旺旺: {{message.shop_info.shop_wangwang}}
p 店铺类型: {{message.shop_info.platform_id == 10?'淘宝':'天猫'}}
.uploader(v-if="item.finish===false")
span 搜索截图:
.alipay_img
van-uploader(v-model="fileList1" multiple :max-count='1' :deletable='false')
van-uploader(v-model='fileList2' multiple :max-count='1' :after-read='afterRead')
van-field(v-model="item.detail" center clearable readonly v-if="item.finish" disabled)
van-field(v-model="sms" center clearable placeholder="输入店铺名或淘口令" ref='input3' @focus="$utils.onFocus" v-if="!item.finish")
van-button(slot="button" size="small" type="primary" @click='verifyShop' :disabled="item.finish") 提交
.prompting
p 1.淘宝店铺名无法验证请联系平台客服
p 2.禁止使用淘宝客农村淘宝等一切返利
//- div(v-if="item.item_type == 'task_start'")
//- p 开始时间: {{$utils.formatDate(item.finish_time)}}
</template>
<script lang="ts">
// 进店组件
import {Component, Provide, Vue, Prop, Watch} from 'vue-property-decorator';
import Icons from '@/components/Icons.vue'
@Component({
components:{
Icons
}
})
export default class EnterShop extends Vue {
$http: any
$utils: any
$refs: any
// 仅渲染列表需要的数据
@Prop({default: {}}) readonly data!: any
// 全部数据
@Prop({default: {}}) readonly message!: any
private activeNames: string[] = ['0'];
// 淘口令
private ambush: any = []
private sms: string = ''
private fileList1: any[] = [
{ url: 'http://static.alkid888.com/example/verifyShop.jpg' }
]
private fileList2: any[] = []
private imgId: string = ''
private async setComparePrice(index: number,process_id: string): Promise<void> {
if(this.ambush[index] == void 0 || this.ambush[index] == ''){
this.$toast('请输入淘口令')
return
}
let data = {
task_id: String(this.message.base_info.id),
process_id: String(process_id),
compare_item_value: this.ambush[index]
}
let res = await this.$http.TaskService.setComparePrice(data)
setTimeout(()=>{
this.$emit('click')
},2000)
}
private async verifyShop(): Promise<void> {
if(this.imgId == ''){
this.$toast('请上传搜索截图')
return
}
if(this.sms == ''){
this.$toast('请输入店铺名或淘口令')
return
}
let data = {
task_id: String(this.message.base_info.id),
verify_value: this.sms,
image_id: this.imgId
}
let res = await this.$http.TaskService.verifyShop(data)
this.$emit('click')
}
// 支付宝图片上传
private async afterRead(cell: any): Promise<void> {
let fd = new FormData()
fd.append('file', cell.file)
fd.append('imageType', '4')
let res = await this.$http.PublicService.uploadImg(fd)
this.imgId = res.id
}
// 显示手风琴标题
private isTitle(str: string, process_id: number): string | undefined {
switch (str) {
case 'task_start':
return '开始任务'
break;
case 'compare_price':
return `货比${this.isIndex(process_id)}`
break;
case 'verify_shop':
return '店铺确认'
break;
}
}
// 判断货比
private isIndex(id: number): number | undefined {
switch (id) {
case 311:
return 1
case 312:
return 2
case 313:
return 3
default:
break;
}
}
}
</script>
<style lang="stylus">
.EnterShop
.van-field__body
background-color #ccc
.van-cell:not(:last-child)::after
display none
.message
padding 0.24rem 0.253rem
width 100%
background #e5fffe
box-sizing border-box
font-size 13px
color #969799
line-height 1.5
p
line-height 1.8
.uploader
margin-top 0.4rem
display flex
.alipay_img
flex 1
display flex
align-items center
span
margin-right 0.2rem
.tips
font-size 0.24rem
color #ccc
.fuzhi
vertical-align middle
margin-left 0.2rem
</style>

View File

@@ -0,0 +1,79 @@
<template lang="pug">
.Evaluate
.topic
.title
.topic_title 本金返还
.topic_value.tv_c(v-if='data.order_refund.finish') 已完成
.topic_value.tv_b(v-else) 进行中
.center.flex
.text
p 下单时间: {{$utils.formatDate(data.order_refund.trade_time)}}
p 返款时间: {{$utils.formatDate(data.order_refund.refund_time)}}
p 返款金额: {{$utils.conversionMoney(data.order_refund.refund_amount)}}
span.prompting ({{data.order_refund.amount_confirm?'商家已确认':'商家未确认'}})
p 收款账户: {{data.order_refund.refund_account}}
FinishPrompt
.topic
.title
.topic_title 确认收货
.topic_value.tv_c(v-if='data.order_receive.finish') 已完成
.topic_value.tv_b(v-else) 进行中
.center
.text
p 收货姓名: {{data.order_receive.receiver}}
p 收货地址: {{spellAdd(data.order_receive.address)}}
.topic
.title
.topic_title 任务评价
.topic_value.tv_b(v-if='data.order_comment.finish') 已完成
.topic_value.tv_c(v-else) 进行中
.center
.text
.comment_text {{data.order_comment.comment_text}}
van-button.my_button(type="primary" block @click='confirmAccept' :disabled="isFinish" ) 确认收货
</template>
<script lang="ts">
// 进店组件
import {Component, Provide, Vue, Prop} from 'vue-property-decorator';
import FinishPrompt from '@/components/FinishPrompt.vue'
@Component({
components:{
FinishPrompt
}
})
export default class Evaluate extends Vue {
$http: any
$utils: any
@Prop({default: {}}) readonly data!: any
@Prop({default: ''}) readonly id!: string
// 是否完成
@Prop({default:false}) readonly isFinish!: boolean
private radio: string = ''
private spellAdd(data: any): string {
return data.province+data.city+data.country+data.detail
}
private async created(): Promise<void>{
console.log(typeof this.data.order_receive.finish)
}
private async confirmAccept(): Promise<void> {
let res = await this.$http.TaskService.confirmAccept(this.id)
setTimeout(() => {
this.$emit('click')
}, 2000);
}
}
</script>
<style lang="stylus">
.Evaluate
.my_button
margin-top 0.4rem
.comment_text
color #ff0000
font-size 0.4rem
line-height 1.8
</style>

View File

@@ -0,0 +1,30 @@
<template lang="pug">
.FinanceRecord
.news_item(v-for="(item,index) in itemArr" :key="index" v-if="item.model_type == 'FinanceRecord'")
.item_title
h2 资金到账
span {{ $utils.formatAge(item.update_time) }}
.item_content
.content_left
p.df 资金类型: {{item.notice.remark}}
p.yj 到账金额:{{item.notice.amount / 100}}
p.df 关联任务: {{item.notice.model_id}}
//- .content_right(@click="showInfo(item.id)") 查看任务
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component({})
export default class FinanceRecord extends Vue {
@Prop({default: [] }) readonly itemArr!: Array<object>;
public showInfo (id: number): void {
alert(`查看任务任务id为${id}`)
}
}
</script>
<style scoped lang="stylus">
</style>

View File

@@ -0,0 +1,10 @@
<template lang="pug">
.prompting
p 下单后24小时之内返本金超时未返款请联系平台客服禁止旺旺联系商家一经发现立即封号处理
</template>
<script lang="ts">
import {Component, Provide, Vue, Prop} from 'vue-property-decorator';
@Component({})
export default class FinishPrompt extends Vue {}
</script>

View File

@@ -0,0 +1,23 @@
<template lang="pug">
i.icons( :class="'buyer-font '+name" :style='`font-size:${size}rem;color:${color};`' @click='onClick')
</template>
<script lang="ts">
import {Component, Provide, Vue, Prop} from 'vue-property-decorator';
@Component
export default class Icons extends Vue {
@Prop({default:''}) readonly name!: string
@Prop({default:''}) readonly color!: string
@Prop({default:'0.2'}) readonly size!: string
private onClick() :void {
this.$emit('click')
}
}
</script>
<style lang="stylus" scoped>
.icons
display inline-block
box-sizing border-box
line-height normal
</style>

View File

@@ -0,0 +1,89 @@
<template lang="pug">
.matter
van-popup(v-model="show" :style="{ width: '80%' }" :close-on-click-overlay='false')
.matter_center
.title 注意事项
.text
p(v-for='(item, index) in taskMsg' :key='index') {{index+1}}.{{item}}
.button( :class=" time<=0 ? '':'button_c'" @click='onClick')
span.time(v-if='time > 0') {{time}}
span 关闭
</template>
<script lang="ts">
import {Component, Provide, Vue, Prop} from 'vue-property-decorator';
@Component
export default class Matter extends Vue {
name = '任务注意事项组件'
$utils: any
@Prop({default:''}) readonly id!:string
@Prop({default: []}) readonly taskMsg!: string[]
private show: boolean = true
// 倒计时时间
private time: number = 0
private created():void {
let isMatter: any = this.$utils.getStorage(`isMatter${this.id}`) as any || 0
if((Date.parse(String(new Date())) - isMatter) > 24*60*60*1000){
this.$utils.delStorage(`isMatter${this.id}`)
this.time = 8
}
this.countDown()
}
private countDown(): void {
if(this.time > 0){
--this.time
setTimeout(()=>{
this.countDown()
},1000)
}
}
private onClick(): void {
if(this.time <= 0){
this.show = !this.show
this.$utils.setStorage(`isMatter${this.id}`,Date.parse(String(new Date())))
}
}
}
</script>
<style lang="stylus" scoped>
.matter
.van-popup--center
border-radius 0.1rem
.matter_center
background-color #ffffff
padding 0.32rem
.title
font-size 0.42rem
font-weight 500
text-align center
margin 0.3rem 0
.text
color red
font-size 0.36rem
max-height 5rem
overflow-y scroll
p
line-height 1.5
.button
font-size 0.42rem
height 0.8rem
width 2.5rem
color #ffffff
background-color #ff976a
text-align center
line-height 0.8rem
margin 0.4rem auto 0.2rem
border-radius inherit
.time
margin-right 0.2rem
.button_c
background-color #ccc
</style>

View File

@@ -0,0 +1,75 @@
<template lang="pug">
//- 面板组件
.mycell.van-cell(@click='onClick')
Icons.Icons.mr(:name='icon' :size='size' :color='color' v-if="icon !== ''")
.cell__title
span {{title}}
.cell__value
slot
van-icon.Icons(name="arrow" v-if='isLink' size='0.42667rem' color='#969799')
</template>
<script lang="ts">
import {Component, Prop, Vue} from 'vue-property-decorator';
import Icons from '@/components/Icons.vue'
@Component({
components:{
Icons
}
})
export default class Fund extends Vue {
// 标题名称
@Prop({default:''}) protected title!:string
// 左边icon
@Prop({default:''}) protected icon!:string
// 左边icon 大小
@Prop({default:'0.6'}) protected size!:string
// 左边icon 颜色
@Prop({default:''}) protected color!:string
// 是否显示右边箭头
@Prop({default: false}) protected isLink!:boolean
// 跳转地址
@Prop({default: ''}) protected to!:string
private onClick(): void {
if(this.to !== void 0 && this.to !== '' ){
this.$router.push(this.to)
}
}
}
</script>
<style lang="stylus" scoped>
.mycell
position: relative;
display: flex;
box-sizing: border-box;
width: 100%;
padding: 0.26667rem 0.42667rem;
overflow: hidden;
color: #323233;
font-size: 0.37333rem;
line-height: 0.64rem;
background-color: #fff;
.mr
margin-right 0.2rem
.Icons
display: flex;
justify-content: center;
align-items: center;
align-content: center
.cell__title
flex: none;
width: 2.4rem;
.cell__value
position: relative;
overflow: hidden;
color: #969799;
vertical-align: middle;
word-wrap: break-word;
flex 1
</style>

View File

@@ -0,0 +1,51 @@
<template lang="pug">
.MyPanel
.title
Icons(:name='icon' :size='size' color='#ccc' v-if="icon !== ''")
.title_text {{title}}
.title_tips {{tips}}
.center
slot
</template>
<script lang="ts">
// 面板组件
import {Component, Provide, Vue, Prop} from 'vue-property-decorator';
import Icons from '@/components/Icons.vue'
@Component({
components:{
Icons
}
})
export default class MyPanel extends Vue {
// icon的http链接后期改成css需要修改
@Prop({default: ''}) readonly icon!: string
// icon大小
@Prop({default: '0.4'}) readonly size!: string
// 标题文字
@Prop({default: '标题'}) readonly title!: string
// 标题右侧提示语
@Prop({default: ''}) readonly tips!: string
}
</script>
<style lang="stylus" scoped>
.MyPanel
padding 0 0.42667rem
.title
padding 0.26667rem 0.22667rem 0
display flex
align-items center
img
width auto
.title_text
margin-left 0.2rem
font-size 0.42rem
.title_tips
text-align right
font-size 0.24rem
color red
</style>

View File

@@ -0,0 +1,30 @@
<template lang="pug">
van-nav-bar(:title="title",
:fixed="true"
:left-arrow="showLeft",
@click-left='onClickLeft')
</template>
<script lang="ts">
import {Component, Provide, Vue, Prop} from 'vue-property-decorator';
@Component
export default class Navbar extends Vue {
// 标题栏文字
@Prop({ default: '' }) readonly title: String | undefined
// 是否展示左边返回按钮
@Prop({ default: false }) readonly showLeft: boolean | undefined
$router: any;
private onClickLeft(): void {
this.$router.go(-1)
}
}
</script>
<style scoped lang="stylus">
.van-nav-bar .van-icon
color #666
.van-nav-bar--fixed
z-index 999
</style>

View File

@@ -0,0 +1,45 @@
<template lang="pug">
.NewsItem
.news_item(v-for="(item,index) in itemArr" :key="index" v-if="item.model_type == 'TaskNotice'")
.item_title
h2 任务编号{{item.notice.notice_content.task_id}}
span {{ $utils.formatAge(item.notice.notice_content.step_time) }}
.item_content
.content_left
.name
//- Icons(v-if='item.notice.platform_id == 10' name="buyer-icon-taobao_" color='#ff5000' size='0.5')
//- Icons( v-else name="buyer-icon-tianmaobao" color='#FF0036' size='0.5')
span 任务买号: {{item.notice.notice_content.account_text}}
p.df 任务佣金:{{$utils.conversionMoney(item.notice.notice_content.commission)}}
p.yj 任务状态:{{item.notice.notice_content.step_text}}
p.df 消息时间{{ $utils.formatDate(item.update_time) }}
.content_right(@click="showInfo(item.id)") 查看任务
</template>
<script lang="ts">
import {Component, Prop, Vue} from 'vue-property-decorator';
import Icons from '@/components/Icons.vue';
@Component({
components:{
Icons
}
})
export default class NewsItem extends Vue {
$utils: any
@Prop({default: [] }) readonly itemArr!: Array<object>;
async created() {
}
public showInfo(id: number): void{
this.$router.push(`/taskInfo?id=${id}`)
}
}
</script>
<style scoped lang="stylus">
</style>

View File

@@ -0,0 +1,112 @@
<template lang="pug">
.PlaceOrder
.topic
.title
.topic_title 下单信息
.topic_value.tv_b(v-if='!isFinish') 进行中
.topic_value.tv_c(v-else) 已完成
.center
.text
.text_separate
.p 店铺名称:
.span {{data.shop_info.shop_name}}
.text_separate
.p 宝贝标题:
.span {{data.sku_info.spu_title}}
.text_separate
.p 宝贝规格:
.span {{data.sku_info.sku_title}}
.text_separate
.p 宝贝单价:
.span {{$utils.conversionMoney(data.sku_info.sku_price)}}
.text_separate
.p 购买数量:
.span {{data.sku_info.order_num}}
.topic(v-for='(item, index) in data.coupon_info' :key='index')
.title
.topic_title 优惠卷
.topic_value.tv_b(v-if='!isFinish') 进行中
.topic_value.tv_c(v-else) 已完成
.center
.text
.text_f
p 优惠名称: {{item.title}}
p 优惠类型: {{item.coupon_type_text}}
.text_f
p 领取位置: {{item.coupon_position_text}}
p 优惠金额: {{$utils.conversionMoney(item.coupon_amount)}}
.topic
.title
.topic_title 其他费用
.topic_value.tv_b(v-if='!isFinish') 进行中
.topic_value.tv_c(v-else) 已完成
.center
.text
.addition_text {{this.data.process_flow.item_order.order_addition.addition_text}}
van-field(placeholder="请填写订单编号" v-model='trade_num' @focus="$utils.onFocus" v-bind:disabled="this.isFinish" v-bind:readonly="this.isFinish")
.prompting.prompting_m 再次核对商家店铺名称与下单买号避免拍错店铺或者用错买号
van-field(placeholder="请填写实付金额" type='number' v-model='amount' @focus="$utils.onFocus" v-bind:disabled="this.isFinish" v-bind:readonly="this.isFinish")
.prompting.prompting_m 商家无特殊要求一律禁止使用花呗信用卡付款
.placeOrder_button
van-button(type="primary" size="large" @click='buyerOrder' v-bind:disabled="this.isFinish") 提交订单号
</template>
<script lang="ts">
// 进店组件
import {Component, Provide, Vue, Prop} from 'vue-property-decorator';
@Component({})
export default class PlaceOrder extends Vue {
$http: any
$utils: any
@Prop({default: {} }) readonly data!: any
@Prop({default: false }) readonly isFinish!: boolean
private trade_num: string =''
private amount: string =''
private async created(): Promise<void> {
let that =this;
if(this.data.process_flow.item_order.trade_info.hasOwnProperty('trade_num')){
that.trade_num = this.data.process_flow.item_order.trade_info.trade_num
}
if(this.data.process_flow.item_order.trade_info.hasOwnProperty('trade_amount')){
that.amount = that.$utils.conversionMoney(+this.data.process_flow.item_order.trade_info.trade_amount)
}
}
private async buyerOrder(): Promise<void> {
console.log(this.data.process_flow.item_order.trade_info.trade_amount)
if(this.trade_num == ''){
this.$toast('请填写订单编号')
return
}
if(this.amount == ''){
this.$toast('请填写实付金额')
return
}
let data = {
task_id: String(this.data.base_info.id),
trade_num: this.trade_num,
amount: this.amount
}
let res = await this.$http.TaskService.buyerOrder(data)
setTimeout(() => {
this.$emit('click')
}, 2000);
}
}
</script>
<style lang="stylus">
.PlaceOrder
.van-cell
margin-top 0.1rem
background-color #eee
.placeOrder_button
margin-top 0.4rem
.addition_text
color #ff0000
font-size 0.4rem
line-height 1.8
</style>

View File

@@ -0,0 +1,24 @@
<template lang="pug">
.SystemNotice
.news_item(v-for="(item,index) in itemArr" :key="index" v-if="item.model_type == 'SystemNotice'")
.item_title
h2 {{ item.notice.notice_title }}
span {{ $utils.formatAge(item.update_time) }}
.item_content {{ item.notice.notice_content }}
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component({})
export default class SystemNotice extends Vue {
@Prop({default: [] }) readonly itemArr!: Array<object>;
}
</script>
<style scoped lang="stylus">
.item_content
font-size 14px
padding-left 0.1rem !important
</style>

View File

@@ -0,0 +1,32 @@
<template lang="pug">
van-tabbar(class="tabbar" v-model='active' route @change="onChange")
van-tabbar-item(:icon='item.icon' :to="item.href" v-for="(item,index) in TabBarList" :key="index" :info="index === 2?getNewsNum:''") {{item.title}}
</template>
<script lang="ts">
import {Component, Provide, Vue} from 'vue-property-decorator';
import { Getter } from 'vuex-class'
@Component
export default class Tabbar extends Vue {
@Getter('getNewsNum') getNewsNum: any
private active: number = 0;
private TabBarList: Array<Object> = [
{ title: '首页', icon: ' buyer-font buyer-icon-shouye', href: '/home' },
{ title: '任务', icon: ' buyer-font buyer-icon-renwu', href: '/task' },
{ title: '消息', icon: ' buyer-font buyer-icon-xiaoxi', href: '/news' },
{ title: '我的', icon: ' buyer-font buyer-icon-wode', href: '/my' },
];
private onChange(index: number): void {
console.log(index);
}
}
</script>
<style scoped lang="stylus">
.tabbar
background #f6f6f6
</style>

View File

@@ -0,0 +1,98 @@
<template lang="pug">
.TaskHallItem
.list-item(v-for="(item,index) in item" :key="index" @click="itemSendBroadcast(item, index)" :class="index == active?'active_shadow':'active_is'")
.item-left
Icons.Icons(v-if='item.account_type == 10' name="buyer-icon-taobao_" color='#ff5000' size='1.507')
Icons.Icons(v-else name="buyer-icon-tianmaobao" color='#FF0036' size='1.507')
.left-info
p 账号: {{ item.account }}
span 今日已接收任务{{ item.today_task }}/{{ item.today_task_limit }}
.item-right(v-if="item.status == 1") 已经认证
.item-right.item-right_color(v-if="item.status == -1") 认证失败
.item-right.item-right_color(v-if="item.status == 0") 认证中
.item-right.item-right_color(v-if="item.status == -9") 拒绝认证
.active(v-if='index == active')
Icons(v-if='item.account_type == 10' name="buyer-icon--jiaobiao-xuanzhong" color='#07c160' size='0.8')
</template>
<script lang="ts">
import {Component, Provide, Vue, Prop} from 'vue-property-decorator';
import Icons from '@/components/Icons.vue'
@Component({
components:{
Icons
}
})
export default class TaskHallItem extends Vue {
@Prop({default: [] }) readonly item!: Array<any>;
private TaskItemBroadcast = new BroadcastChannel('TaskItemClick');
private active: number = NaN
async created() {
}
public itemSendBroadcast(data: {[key: string]: any}, index: number): void {
if(data.status !== 1){
this.$toast('买号必须认证通过才能接取任务')
return
}
this.active = index
this.TaskItemBroadcast.postMessage(data)
}
}
</script>
<style scoped lang="stylus">
.TaskHallItem
margin-top: 0.48rem;
.active_shadow
box-shadow 0 2px 10px #23fd004f
.active_is
border 0.01rem solid #cccccc
.list-item
display flex
justify-content space-between
padding 0.28rem 0.307rem
box-sizing border-box
align-items center
width 95%
margin 0 auto
margin-bottom 0.293rem
position relative
.item-left
.Icons
width 1.507rem
height 1.507rem
margin-right 0.587rem
float left
border-radius 100%
.left-info
float left
padding-top 5px
p
color #333333
font-size 16px
span
color #999999
font-size 14px
.item-right
width 1.707rem
height 0.613rem
background #1ab51f
text-align center
color #fff
font-size 12px
line-height 0.643rem
margin-right 0.6rem
.item-right_color
background-color red
.active
position absolute
right -0.1rem
bottom -0.18rem
</style>

View File

@@ -0,0 +1,136 @@
<template lang="pug">
.TaskTag
div(v-if="isTask()")
.message
p 打标关键字: {{data.tag}}
span.prompting 手动输入关键字,禁止复制粘贴
//- 如果任务已经完成也就是 data.finish 是true 则隐藏
div(v-if='!data.finish')
.topic
.title
.topic_title 打标
.topic_value.tv_b 进行中
//- 已完成直接隐藏图片部分
.center
.uploader
span 搜索截图:
.alipay_img
van-uploader(v-model="fileList1" multiple :max-count='1' :deletable='false')
van-uploader(v-model='fileList2' multiple :max-count='1' :after-read='afterRead')
van-button.my_button(type="primary" size="large" @click='setTaskTag' :disabled="data.finish") 提交
.topic(v-else)
.title
.topic_title 打标
.topic_value.tv_c 已完成
.marking(v-else)
p 打标关键字倒计时: &nbsp;
CountDown( :time='data.next_time')
span.prompting 打标间隔最少为12小时
</template>
<script lang="ts">
// 进店组件
import {Component, Provide, Vue, Prop, Watch} from 'vue-property-decorator';
import Icons from '@/components/Icons.vue'
import CountDown from '@/components/CountDown.vue'
@Component({
components:{
Icons,
CountDown
}
})
export default class TaskTag extends Vue {
$http: any
$utils: any
@Prop({default: {} }) readonly data!: any
// 任务id
@Prop({default: ''}) readonly id!: string
private fileList1: any[] = [
{ url: 'https://img.yzcdn.cn/vant/leaf.jpg' }
]
private fileList2: any[] = []
private imgId!: number
// 图片上传
private async afterRead(cell: any): Promise<void> {
let fd = new FormData()
fd.append('file', cell.file)
fd.append('imageType', '4')
let res = await this.$http.PublicService.uploadImg(fd)
this.imgId = res.id
}
private async setTaskTag(): Promise<void> {
if(this.imgId == void 0){
this.$toast('请上传图片截图')
return
}
let data = {
task_id: this.id,
process_id: this.data.process_id,
tag_image: this.imgId
}
let res = await this.$http.TaskService.setTaskTag(data)
setTimeout(() => {
this.$emit('click')
}, 2000);
}
// 如果返回true则代表任务开始可以做任务了
private isTask(): boolean {
if(this.$utils.leftTimer(this.data.next_time) !== '任务已超时'){
return false
}else{
return true
}
}
}
</script>
<style lang="stylus" scoped>
.TaskTag
.van-field__body
background-color #ccc
.van-cell:not(:last-child)::after
display none
.message
padding 0.24rem 0.253rem
width 100%
background #e5fffe
box-sizing border-box
font-size 13px
color #969799
line-height 1.5
p
line-height 1.8
.uploader
margin-top 0.4rem
display flex
.alipay_img
flex 1
display flex
align-items center
span
margin-right 0.2rem
padding 0.42667rem
color #969799
font-size 0.34667rem
line-height 1.5
background-color #fff
.topic
margin-top 0.2rem
.marking
margin-top 2rem
padding 0.24rem 0.253rem
box-sizing border-box
font-size 0.34667rem
color red
text-align center
span
margin-top 0.2rem
display inline-block
</style>

View File

@@ -0,0 +1,17 @@
<template lang="pug">
.test
h3 测试子组件
</template>
<script lang="ts">
import {Component, Provide, Vue} from 'vue-property-decorator';
@Component
export default class Test extends Vue {
}
</script>
<style scoped lang="stylus">
</style>

View File

@@ -0,0 +1 @@
9b3f3449-84cd-4272-bf48-295d2c9ce78d

View File

@@ -0,0 +1,413 @@
<template lang="pug">
//- 添加账号
.add_account.content
NavbarComponent(:title="status == 0?'添加账号':'修改信息'" showLeft)
.line
van-field(v-model="account" placeholder="输入账号" label="账号")
MyCell(title='性别')
van-radio-group(v-model="gender")
van-radio(name="1")
van-radio(name="2")
MyCell(title='花呗/白条')
van-radio-group(v-model="credit")
van-radio(name="0") 未开通
van-radio(name="1") 已开通
van-field(:placeholder="age.text == ''?'请选择年龄段':age.text" label="年龄段" disabled right-icon='arrow' @click='ageShow = true')
van-field(v-model="points" placeholder="淘气值" label="淘气值")
van-field(:placeholder="rate.text == ''?'信誉等级':rate.text" label="信誉等级" disabled right-icon='arrow' @click='levelShow = true')
//- 最多选择三个
van-field(clearable='', label='购买标签', disabled right-icon='arrow', :placeholder='labelName', @click="isPopup('show')")
van-field(v-model="name" placeholder="输入姓名" label="收货人姓名")
van-field(v-model="cellphone" type="tel" placeholder="输入手机号" label="收货人电话")
Address(@confirm="onConfirm" :areaText='areaText' :value='areaIndex')
van-field(v-model="detail" placeholder="地址详情" label="地址详情")
.alipay
.alipay_title 支付截图
.alipay_img
van-uploader(v-model="fileList1" multiple :deletable='false' :max-count='1')
van-uploader(v-model="fileList2" multiple :max-count='1' :after-read='afterRead')
.account_sub
van-button(type='default' size='large' color='#20c6c2' @click='saveaccount') 提交
//- 类目弹窗
van-popup(v-model='show', closeable, :style="{ width: '80%' }")
.category
.category_list.pd30
.row_list(v-for='(item,index) in label' :key='index' @click='changeLabel(index)')
.row.flex_cen(:class="categoryId.indexOf(item.id) !== -1 ?'row_active':''") {{item.title}}
.category_custom.pd30
//- input( placeholder="自定义类目" type="text")
.category_sub
van-button(type='default' size='large' color='#20c6c2' @click='labelConfirm') 确定
//- 信用等级选择
van-popup(v-model='levelShow', position="bottom" )
van-picker( :columns="level[type==10?0:1]" value-key='text' @cancel='levelShow = false' @confirm="onConfirmLevel" show-toolbar)
//- 年龄段选择
van-popup(v-model='ageShow', position="bottom" )
van-picker( :columns="ageGroup" value-key='text' @cancel='ageShow = false' @confirm="onConfirmAge" show-toolbar)
</template>
<script lang="ts">
import { Component, Provide, Vue, Inject } from "vue-property-decorator";
import NavbarComponent from "@/components/Navbar.vue";
import MyCell from "@/components/MyCell.vue";
import Address from "@/components/Address.vue";
import { Dialog } from 'vant';
type levelType = {
text: string
id: number
}
@Component({
components: {
MyCell,
NavbarComponent,
Address
}
})
export default class AddAccount extends Vue {
$http: any
$utils: any
// 1淘宝2京东3拼多多
private type: number = 1
// 当前页面的状态对应买号列表的显示状态 0默认 1审核中 2已通过 -1 未通过
private status: number = 0
// 买号id 修改买号时需要
private id: string = ''
// 信誉等级配置
private level: Array<levelType[]> =[
[{
text: '3心',
id: 1
},{
text: '4心',
id: 2
},{
text: '5心',
id: 3
},{
text: '一钻以上',
id: 4
}],[{
text: '铜牌会员',
id: 5
},{
text: '银牌会员',
id: 6
},{
text: '金牌会员',
id: 7
},{
text: '砖石会员',
id: 8
}]
]
// 信誉等级弹出层控制
private levelShow: boolean = false
// 年龄段
private ageGroup: object[] = [
{
text: '18岁以下',
id: 0
},{
text: '18-25岁',
id: 1
},{
text: '26-30岁',
id: 2
},{
text: '31-35岁',
id: 3
},{
text: '36-40岁',
id: 4
},{
text: '41-45岁',
id: 5
},{
text: '45岁以上',
id: 6
}
]
// 年龄段弹出层控制
private ageShow: boolean = false
private account: string = ''
private credit: string = ''
private gender: string = ''
// 年龄段
private age: levelType = {
text: '',
id: 0
}
private points: string = ''
// 信誉等级
private rate: levelType = {
text: '',
id: 0
}
private name: string = ''
private cellphone: string = ''
private areaId: Number[] = []
private detail: string = ''
// 回显的地址信息
private areaText: string = '选择收货地址'
private areaIndex: string = ''
// 图片地址id
private fileImg: string = '';
// 标签数据
private label: any[] = []
// 选中的标签最多三个
private categoryId: Array<number> = []
private labelName: string = '选择标签'
private fileList1: Array<any> = [
{ url: "http://static.alkid888.com/example/alipay.png" }
];
private fileList2: Array<any> = []
// 控制弹出层
private show: boolean = false;
@Inject() HiddenTabBar!: Function;
async created() {
this.HiddenTabBar()
this.accountTagInfo()
if(this.$route.query.id !== void 0){
let id = this.$route.query.id as string
this.id = id
this.status = parseInt(this.$route.query.status as string) | 0
this.accountListByPlatform(id)
}
if(this.$route.query.type !== void 0){
this.type = parseInt(this.$route.query.type as string)
}
}
// 获取回显的信息
private async accountListByPlatform(id:string): Promise<void> {
this.areaText = ''
let res = (await this.$http.UserService.accountListByPlatform(id))[0]
let area = res.address.area_text
this.account = res.account
this.gender = String(res.account_gender)
this.ageGroup.forEach((v: any,i:number)=>{
if(v.id == res.account_ages){
this.age = {
id: v.id,
text: v.text
}
}
})
this.points = res.account_points
this.rate.id = res.account_rate
this.level[this.type==10?0:1].forEach((v: any,i:number)=>{
if(v.id == res.account_ages){
this.rate = {
id: v.id,
text: v.text
}
}
})
this.name = res.address.full_name
this.cellphone = res.address.cellphone
this.areaText = `${area.province} ${area.city} ${area.country}`
this.areaIndex = String(res.address.area_id)
this.detail = res.address.detail
this.fileList2.push({url:res.review_img[0].uploads.local_path})
this.fileImg = res.review_img[0].id
this.labelName = ''
this.areaId.push(res.address.area_id)
res.tag.forEach((v:any,i:number)=>{
if(v.title !== null){
this.labelName += (v.title + ' ')
this.categoryId.push(v.id)
}
})
if(res.status == -1){
Dialog.alert({
title: '审核未通过',
message: res.remark,
}).then(() => {
// on close
});
}
}
// 支付宝图片上传
private async afterRead(cell: any): Promise<void> {
let fd = new FormData()
fd.append('file', cell.file)
fd.append('imageType', '1')
let res = await this.$http.PublicService.uploadImg(fd)
this.fileImg = res.id
}
// 打开关闭弹出层
private isPopup(id: string): void {
if (id == "show") this.show = !this.show;
}
// 选中的标签
private changeLabel(index: number): void {
let categoryId: number[] = this.categoryId
let id: number = this.label[index].id
if(categoryId.indexOf(id) !== -1){
categoryId.splice(categoryId.indexOf(id), 1)
this.categoryId = [...categoryId]
return
}
if(categoryId.length >= 3){
this.$toast('最多选择三个标签')
return
}
this.categoryId.push(id)
}
// 标签提交
private labelConfirm(): void {
this.labelName = ''
this.categoryId.forEach((v:any, i:number)=>{
let s = this.label.filter(n=>{return n.id == v})
this.labelName += (s[0].title + ' ')
})
this.show = !this.show
}
// 信誉等级选择
private onConfirmLevel(e: any): void {
this.rate = e
this.levelShow = false
}
// 年龄段选择
private onConfirmAge(e: any): void {
this.age = e
this.ageShow = false
}
// 确定选择城市
private onConfirm(value: any): void {
this.areaId = value
}
// 添加买号的标签
private async accountTagInfo(): Promise<void> {
let res = await this.$http.HomeService.accountTagInfo(1)
this.label = res[0].sub
}
// 添加买号
private async saveaccount(): Promise<void> {
if(this.account == ''){
this.$toast('请填写账号')
return
}
if(this.gender == ''){
this.$toast('请选择性别')
return
}
if(this.credit == ''){
this.$toast('请选择是否开通花呗/白条')
return
}
if(this.age.text == ''){
this.$toast('请填写年龄')
return
}
if(this.points == ''){
this.$toast('请填写淘气值')
return
}
if(this.rate.text == ''){
this.$toast('请填写信用等级')
return
}
if(this.labelName == '选择标签'){
this.$toast('请选择标签')
return
}
if(this.name == ''){
this.$toast('请填写收货人姓名')
return
}
if(this.cellphone == ''){
this.$toast('请填写收货人电话')
return
}
if(!this.$utils.isTel(this.cellphone)){
this.$toast('收货人电话填写有误')
return
}
if(this.areaId.length <= 0){
this.$toast('请选择收货地址')
return
}
if(this.detail == ''){
this.$toast('请填写收货地详情')
return
}
if(this.fileImg == ''){
this.$toast('请上传支付宝截图')
return
}
let data = {
account: this.account,
account_gender: this.gender,
account_rate: this.rate.id,
account_ages: this.age,
account_points: this.points,
image_id: this.fileImg,
full_name: this.name,
cellphone: this.cellphone,
area_id: this.areaId[this.areaId.length-1],
detail: this.detail,
category_id: this.categoryId,
account_type: this.type,
credit_pay: this.credit
}
Dialog.confirm({
title: '是否提交',
message: '点击确定提交信息'
}).then( async () => {
if(this.status == 0){
let res = await this.$http.HomeService.saveaccount(data)
this.$toast('添加成功等待审核')
setTimeout(() => {
this.$router.go(-1)
}, 2000);
}else if(this.status == -1){
Object.assign(data, {id: this.id})
let res = await this.$http.UserService.modifyAccount(data)
if(!!res){
this.$toast('修改成功等待审核')
setTimeout(() => {
this.$router.go(-1)
}, 2000)
}else{
setTimeout(() => {
this.$router.go(-1)
}, 2000)
}
}
}).catch(() => {
// on cancel
});
}
}
</script>
<style lang="stylus" scoped>
@import '~@assets/stylus/page/addAccount';
</style>
<style lang="stylus">
.add_account
.van-radio-group
display flex
.van-radio
margin-right: 0.6rem;
</style>

View File

@@ -0,0 +1,165 @@
<template lang="pug">
.authentication.content
NavbarComponent(:title=" mode == 'add'?'修改地址':'买号认证'" showLeft)
.line
.pd43
.platform_list(v-for='item in bindAccount.info')
div(@click='goUrl(item.account_id,item.status)')
.platform.mt30.flex.pd30
Icons(name='buyer-icon-taobao_' size='1' color='#ff5000' v-if='item.account_type == 10')
Icons(name='buyer-icon-jingdong_' size='1' color='#e6241a' v-if='item.account_type == 20')
p.flex1.ml40 {{item.account_type_text}}
span.examine(v-if='item.status == -1') {{item.status_text}}
span.examine(v-if='item.status == 0') {{item.status_text}}
span.already(v-if='item.status == 1') {{item.status_text}}
span.examine(v-if='item.status == -9') {{item.status_text}}
van-icon(name="arrow" size='0.46rem')
.platform_list(v-for='item in platform' v-if="mode !== 'add'")
div(@click='goAdd(item.id)')
.platform.mt30.flex.pd30
Icons( :name='item.icon' size='1' :color='item.color')
p.flex1.ml40 {{item.name}}
span 去认证
van-icon(name="arrow" size='0.46rem')
</template>
<script lang="ts">
import {Component, Provide, Vue, Inject} from 'vue-property-decorator';
import NavbarComponent from "@/components/Navbar.vue";
import { Dialog } from 'vant';
import Icons from '@/components/Icons.vue'
@Component({
components: {
NavbarComponent,
Icons
}
})
export default class Authentication extends Vue {
$http: any
// inject 注入 App.vue 提供的变量
@Inject() readonly HiddenTabBar!: Function
@Inject() readonly ShowTabBar!: Function
// 进入此页面的不同方式 add表示地址不显示添加买号
private mode: string = ''
private platform: Array<any> = [
{
name: '淘宝认证',
id: 10,
num: 0,
icon: 'buyer-icon-taobao_',
color: '#ff5000'
}
// {
// name: '京东认证',
// id: 20,
// num: 0,
// icon: 'buyer-icon-jingdong_',
// color: '#e6241a'
// }
// {
// name: '拼多多认证',
// id: 3,
// num: 0,
// icon: ''
// }
]
// 已绑账号数据
private bindAccount: any = {}
private created(): void {
this.HiddenTabBar()
this.getAccountlist()
if(this.$route.query.mode !== void 0){
this.mode = this.$route.query.mode as string
}
}
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar()
next()
}
// 获取买号列表
private async getAccountlist(): Promise<void> {
let res = await this.$http.UserService.getAccountlist()
this.bindAccount = res
res.info.forEach((v: any, i: number) => {
switch (v.account_type) {
case 10:
this.platform[0].num++
break;
case 20:
this.platform[1].num++
break;
case 30:
this.platform[2].num++
break;
default:
break;
}
});
}
private goUrl(id: string, status: number): void {
let url = "";
if (status == -1) {
url = "/AddAccount";
} else if (status == 1) {
url = "/ModifyAddress";
}else{
return
}
this.$router.push({ path: url, query: { id: id, status: String(status),type: '10' } });
}
private goAdd(id: string): void {
let info: any = this.bindAccount
switch (info.auth_status) {
case -4:
Dialog.alert({
message: info.auth_msg,
confirmButtonText: '前往'
}).then(()=>{
this.$router.push({ path: '/realName' });
})
break;
case -3:
Dialog.alert({
message: info.auth_msg
})
break;
case -2:
Dialog.alert({
message: info.auth_msg,
confirmButtonText: '前往'
}).then(()=>{
this.$router.push({ path: '/realName' });
})
break;
case -1:
Dialog.alert({
message: info.auth_msg
})
break;
case 1:
let index = parseInt(id) == 10?0:1
if(this.platform[index].num >= 2) {
Dialog.alert({
title: '账号已达到上限',
message: '每个平台最多添加2个账号'
})
return
}
this.$router.push({ path: '/AddAccount', query: { type: id } });
break;
default:
break;
}
}
}
</script>
<style lang="stylus" scoped>
@import '~@assets/stylus/page/authentication';
</style>

View File

@@ -0,0 +1,133 @@
<!--领取记录-->
<template lang="pug">
.CollectionRecords
NavbarComponent(title="提现记录" :show-left="true")
.content
.header
p {{money}}
span 金币
van-list(v-model='loading'
:finished='finished'
finished-text='没有更多了'
@load='onLoad')
.records_list
.list_item(v-for="i in testList")
.item_left
p {{i.finance_one.remark}}
span {{$utils.formatDate(i.create_time)}}
.item_right
p {{i.status_text}}
span {{i.amount}}金币
</template>
<script lang="ts">
import {Component, Provide, Inject, Vue} from 'vue-property-decorator';
import NavbarComponent from '@/components/Navbar.vue'
@Component({
components: {
NavbarComponent
}
})
export default class Cashwithdrawal<T> extends Vue {
$http: any
// inject 注入 App.vue 提供的变量
@Inject() readonly HiddenTabBar!: Function;
@Inject() readonly ShowTabBar!: Function;
private titleName: String = "资金明细";
private loading: boolean = false;
private finished: boolean = false;
private testList: Array<T | number | object | string> = [];
private money: number = 0
private page: number = 0
private limit: number = 10
// 进入页面,关闭底部导航条
private created(): void {
this.HiddenTabBar()
}
// 演示加载数据
private onLoad(): void {
if(this.finished){
this.$toast('已经到底了')
return
}
++this.page
this.getList()
}
private async getList(): Promise<void> {
let data = {
page: this.page,
limit: this.limit
}
let res = await this.$http.UserService.cashlist(data)
// 数据全部加载完成
if (res.list < this.limit) {
this.finished = true;
}
// 加载状态结束
this.loading = false;
this.testList = [...this.testList, ...res.list]
this.money = res.total_money
}
// 离开页面,开启底部导航条
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar()
next()
}
}
</script>
<style scoped lang="stylus">
.records_list
padding 0 0.49rem 0.49rem 0.49rem
.list_item
padding-top 0.49rem
padding-bottom 0.44rem
border-bottom 1px solid #c5c5c5
display flex
justify-content space-between
align-items center
.item_right
font-size 17px
color #e9920a
text-align right
p
font-size 17px
color #ccc
margin-bottom 0.293rem
.item_left
height 1.187rem
display flex
flex-direction column
p
font-size 17px
color #000
margin-bottom 0.293rem
span
font-size 14px
color #717171
.header
width 100%
height 4.733rem
background #4db0fe
display flex
align-items center
justify-content center
p
color #fff
font-size 25px
span
margin-left 4px
font-size 15px !important
</style>

View File

@@ -0,0 +1,112 @@
<!--领取记录-->
<template lang="pug">
.CollectionRecords
NavbarComponent(title="佣金记录" :show-left="true")
.list
van-list(v-model='loading'
:finished='finished'
finished-text='没有更多了'
@load='onLoad')
.records_list
.list_item(v-for="i in testList")
.item_left
p {{i.finance_one.remark}}
span {{$utils.formatDate(i.create_time)}}
.item_right {{i.amount}}金币
</template>
<script lang="ts">
import {Component, Provide, Inject, Vue} from 'vue-property-decorator';
import NavbarComponent from '@/components/Navbar.vue'
@Component({
components: {
NavbarComponent
}
})
export default class CollectionRecords<T> extends Vue {
$http: any
$utils: any
// inject 注入 App.vue 提供的变量
@Inject() readonly HiddenTabBar!: Function;
@Inject() readonly ShowTabBar!: Function;
private titleName: String = "";
private loading: boolean = false;
private finished: boolean = false;
private testList: Array<T | number | object | string> = [];
private page: number = 0
private limit: number = 10
// 进入页面,关闭底部导航条
private created(): void {
this.HiddenTabBar()
}
// 演示加载数据
private onLoad(): void {
if(this.finished){
this.$toast('已经到底了')
return
}
++this.page
this.getList()
}
private async getList(): Promise<void> {
let data = {
page: this.page,
limit: this.limit
}
let res = await this.$http.UserService.commissionList(data)
// 数据全部加载完成
if (res.list < this.limit) {
this.finished = true;
}
// 加载状态结束
this.loading = false;
this.testList = [...this.testList,...res.list]
}
// 离开页面,开启底部导航条
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar()
next()
}
}
</script>
<style scoped lang="stylus">
.list
padding-top 1.22667rem
.records_list
padding 0 0.49rem 0.49rem 0.49rem
.list_item
padding-top 0.49rem
padding-bottom 0.44rem
border-bottom 1px solid #c5c5c5
display flex
justify-content space-between
align-items center
.item_right
font-size 17px
color #e9920a
.item_left
height 1.187rem
display flex
flex-direction column
p
font-size 17px
color #000
margin-bottom 0.293rem
span
font-size 14px
color #717171
</style>

View File

@@ -0,0 +1,241 @@
<!--推广赚钱-->
<template lang="pug">
.Extension
NavbarComponent(title="推广赚钱" :show-left="true" icon='')
.content
.extension_info
.extension_info_money
p {{extensionData.refer_commission}}
span 累计赚取佣金
.extension_info_list
.info_list_item
.item_top
p {{extensionData.son_num}}
p 已注册徒弟
.item_top
p {{extensionData.grandson_num}}
p 已注册徒孙
.info_list_item
.item_top
p {{extensionData.son_active_num}}
p 已激活徒弟
.item_top
p {{extensionData.grandson_active_num}}
p 已激活徒孙
.extension_rule
MyPanelComponent(title="奖励规则")
ul.rule
li(v-for="(item, index) in ruleList" :key="index") {{index+1}}. {{item}}
.extension_link
.copy_link
span {{url}}
.copy_action(@click='extension') 复制推广链接
.extension_ranking_list
MyPanelComponent(title="邀请奖励排行榜")
.cont
.ranking_list_title
span 排名
span 名称
span 邀请人数
span 累计奖励
van-list(v-model="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad")
.ranking_list_wrap(v-for="(item, index) in rankingList" :key='index')
span {{index+1}}
span {{item.cellphone}}
span {{item.refer_num}}
span {{$utils.conversionMoney(item.commission.total)}}
</template>
<script lang="ts">
import {Component, Provide, Inject, Vue} from 'vue-property-decorator';
import NavbarComponent from '@/components/Navbar.vue'
import MyPanelComponent from '@/components/MyPanel.vue'
@Component({
components: {
NavbarComponent,
MyPanelComponent
}
})
export default class Extension extends Vue {
$http: any
$utils: any
// inject 注入 App.vue 提供的变量
@Inject() readonly HiddenTabBar!: Function;
@Inject() readonly ShowTabBar!: Function;
private loading: boolean = false
private finished: boolean = false
private extensionData: any = {}
private rankingList: any[] = []
private page: number = 0
private limit: number = 10
private userInfo: any = {}
private url: string = ''
// 规则列表
private ruleList: string[] = [
'邀请好友成为你的徒弟完成任务确认收货您可得15%的佣金奖励',
'徒弟再邀请他的徒弟完成任务确认收货后您可得5%的佣金奖励'
]
// 进入页面,关闭底部导航条
private created(): void {
this.HiddenTabBar();
this.myAll()
}
// 离开页面,开启底部导航条
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar();
next()
}
private onLoad() {
if(this.finished){
return
}
++this.page
this.referinfo()
}
private async referinfo(): Promise<void> {
let data = {
page: this.page,
limit: this.limit
}
let res = await this.$http.UserService.referinfo(data)
if(res.referList < this.limit){
this.finished = true
}
this.loading = false
this.extensionData = res
this.rankingList = [...this.rankingList, ...res.referList]
this.finished = true
}
private extension(): void {
let str: string = `${window.location.origin}${window.location.pathname}#/register?invite=${this.userInfo.refer_code}`
this.$utils.copy(str)
}
private async myAll(): Promise<void> {
let res = await this.$http.UserService.getMemberInfo()
this.userInfo = res
this.url = `${window.location.origin}${window.location.pathname}#/register?invite=${this.userInfo.refer_code}`
}
}
</script>
<style scoped lang="stylus">
.extension_info
padding 0.44rem
border-bottom 0.267rem solid #f6f6f6
.extension_info_money
text-align center
padding 0.42rem
display flex
flex-direction column
p
color #20c6c2
font-size 28px
margin-bottom 0.193rem
span
font-size 11px
color #666
.extension_info_list
width 100%
background #20c6c2
padding 0.35rem 0
box-sizing border-box
display flex
justify-content space-around
align-items center
border-radius 4px
.info_list_item
width 50%
.item_top
text-align center
&:first-child
margin-bottom 0.72rem
p
color #fff
font-size 15px
&:first-child
margin-bottom 0.373rem
&:first-child
border-right 1px solid #fff
.extension_rule
border-bottom 0.267rem solid #f6f6f6
.rule
padding 0.44rem
li
line-height 1.5
font-size 14px
color #666
margin-bottom 0.3rem
.extension_link
border-bottom 0.267rem solid #f6f6f6
padding 0.747rem 0.72rem
.copy_link
width 100%
padding 0.28rem 0.32rem
height 1.33rem
box-sizing border-box
border-radius 3px
box-shadow 1px 1px 11px #b0acac
display flex
align-items center
justify-content space-between
span
font-size 13px
color #20c6c2
display -webkit-box
-webkit-box-orient vertical
-webkit-line-clamp 1
overflow: hidden
.copy_action
font-size 13px
color #20c6c2
background #e5fffe
padding 0.227rem 0.387rem
width 5rem
text-align center
.extension_ranking_list
.cont
padding 0.44rem
.ranking_list_title
display flex
justify-content space-around
align-items center
height 0.8rem
background #efefef
span
font-size 14px
color #666
text-align center
// &:nth-child(2),
// &:nth-child(3)
width 25%
.ranking_list_wrap
display flex
justify-content space-around
align-items center
span
font-size 14px
color #999
margin-top 0.32rem
text-align center
// &:nth-child(2),
// &:nth-child(3)
width 25%
</style>

View File

@@ -0,0 +1,112 @@
<!--意见反馈-->
<template lang="pug">
.Feedback
NavbarComponent(title="意见反馈" :show-left="true")
.content
.input_message
van-field(v-model='UserInput'
rows='4'
autosize=''
type='textarea'
placeholder='欢迎输入反馈意见,平台的成长感谢有你!'
show-word-limit='')
van-uploader(:after-read='UploaderAfterRead')
p.tips 截图说明详情更明确哦
van-button(type='primary' color="#20c6c2" size="large") 提交
.input_history
MyPanelComponent(title="反馈历史")
.history_item(v-for="i in 3")
.item_title {{i}}: 应用太卡现在完全打不开啊
.item_other 李白 2019/11/27
.image_list
img(src="https://img.alicdn.com/tfscom/tuitui/TB1w9HDLXXXXXb8XXXXXXXXXXXX_30x30.jpg")
.reply
p 已经反馈给技术部门我们会尽快安排人员进行解决感谢您提的宝贵意见
</template>
<script lang="ts">
import {Component, Provide, Inject, Vue} from 'vue-property-decorator';
import NavbarComponent from '@/components/Navbar.vue'
import MyPanelComponent from '@/components/MyPanel.vue'
@Component({
components: {
NavbarComponent,
MyPanelComponent
}
})
export default class Feedback extends Vue {
private UserInput: string = "";
// inject 注入 App.vue 提供的变量
@Inject() readonly HiddenTabBar!: Function;
@Inject() readonly ShowTabBar!: Function;
// 进入页面,关闭底部导航条
private created(): void {
this.HiddenTabBar();
}
// 文件上传
private UploaderAfterRead(): void {
}
// 离开页面,开启底部导航条
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar();
next()
}
}
</script>
<style scoped lang="stylus">
.input_message
padding 0.28rem
border-bottom 0.267rem solid #f6f6f6
.van-field
border: 1px solid #e5e5e5
margin-bottom 0.267rem
.tips
font-size 14px
color #999
margin-top 0.213rem
margin-bottom 1.16rem
.input_history
padding 0.28rem
.MyPanel
padding 0 !important
.title
padding-left 0 !important
padding-right 0 !important
.history_item
border-bottom 1px solid #e5e5e5
padding-bottom 15px
margin-top 20px
.item_title
color #666
font-size 14px
margin-bottom 6px
.item_other
color #aeaeae
font-size 13px
margin-bottom 10px
padding-left 17px
.image_list
padding-left 17px
img
width 50px
.reply
margin-left 15px
&:before
content '最新回复'
color #aeaeae
font-size 13px
p
font-size 14px
margin-top 5px
color #666
</style>

View File

@@ -0,0 +1,103 @@
<template lang="pug">
.forget
.login
.head_portrait
img(src="image/logo.png" alt="用户头像")
.user_input
van-field(v-model='cellphone', label='手机号', placeholder='请输入手机号')
van-field(v-model='verifyCode', label='验证码', placeholder='请输入短信验证码')
van-button(slot='button', size='small', type='primary' @click='captcha') 发送验证码
van-field(v-model='password', type="password", label='修改密码', placeholder='8-25位字母与数字组合')
van-field(v-model='isPassword', type="password", label='确认密码', placeholder='请保持两次密码一致')
div
.user_login(@click='forget') 修改
.login_other
router-link.forget_password(to="/register" tag="span") 注册
router-link(to="/login" tag="span") 登录
</template>
<script lang="ts">
import {Component, Provide, Vue, Inject} from 'vue-property-decorator';
@Component
export default class Forget extends Vue {
$http: any
$utils: any
// inject 注入 App.vue 提供的变量
@Inject() readonly HiddenTabBar!: Function
@Inject() readonly ShowTabBar!: Function
private cellphone: string = ''
private verifyCode: string = ''
private password: string = ''
private isPassword: string = ''
private created(): void {
this.HiddenTabBar()
}
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar()
next()
}
// 修改密码
private async forget(): Promise<void> {
if(!this.$utils.isTel(this.cellphone)){
this.$toast('手机号不正确')
return
}
if(this.verifyCode == ''){
this.$toast('请输入验证码')
return
}
if(this.password == ''){
this.$toast('请填写密码')
return
}
if(this.isPassword == ''){
this.$toast('请填写确认密码')
return
}
if(this.password !== this.isPassword){
this.$toast('两次密码不一致')
return
}
let data = {
cellphone: this.cellphone,
verify_code: this.verifyCode,
password: this.password,
repassword: this.isPassword,
template_id: 1
}
let res = await this.$http.HomeService.forget(data)
if(res !== -1){
setTimeout(() => {
this.$router.push('/login')
}, 2000);
}
}
// 发送验证码
private async captcha(): Promise<void> {
if(!(/^1[3456789]\d{9}$/.test(this.cellphone))){
this.$toast('手机号不正确')
return
}
let res:any = await this.$http.HomeService.captcha(this.cellphone)
if(!!res.validate_token){
this.$toast('发送成功')
}
}
}
</script>
<style lang="stylus">
.login
.van-field__label
width 2rem
</style>
<style lang="stylus" scoped>
@import "~@assets/stylus/page/login"
</style>

View File

@@ -0,0 +1,85 @@
<template lang="pug">
//- 资金管理
.fund.content
NavbarComponent(title="资金管理" showLeft)
.pd43.fund_center
.account.flex
.flex_cen.flex1
.money
.money_text 本金余额
p.mt25 {{userInfo.capital}}
.mt25
van-button(type="default" size='small' @click='cashout(1, userInfo.capital)') 提现
.flex_cen.flex1
.money
.money_text 佣金余额
p.mt25 {{userInfo.commission}}
.mt25
van-button(type="default" size='small' @click='cashout(2, userInfo.commission)') 提现
.line
//- van-cell(title="绑定卡号" is-link )
//- van-cell(title="资金明细" is-link )
van-cell(title="本金记录" is-link to='/principalRecord' )
van-cell(title="提现记录" is-link to='/cashwithdrawal' )
van-cell(title="佣金记录" is-link to='/collection' )
.line
</template>
<script lang="ts">
import {Component, Provide, Vue, Inject} from 'vue-property-decorator';
import NavbarComponent from "@/components/Navbar.vue";
import { Dialog } from 'vant';
@Component({
components: {
NavbarComponent
}
})
export default class Fund extends Vue {
$http: any
// inject 注入 App.vue 提供的变量
@Inject() readonly HiddenTabBar!: Function
@Inject() readonly ShowTabBar!: Function
private userInfo: any = {}
private created(): void {
this.HiddenTabBar()
this.getMemberInfo()
}
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar()
next()
}
// 提现操作
private cashout(type: number ,money: number): void {
if(money <= 0){
this.$toast('余额不足')
return
}
let message = type == 1?`本次本金提现金额为 ${money}`: `本次本金提现金额为 ${money}`
Dialog.confirm({
title: '你正在进行提现操作',
message: message,
confirmButtonText: '提现'
}).then(async () => {
let res = await this.$http.UserService.cashout(type)
if(res !== -1){
this.getMemberInfo()
}
}).catch(() => {
// on cancel
});
}
// 获取资金信息
private async getMemberInfo(): Promise<void> {
let res = await this.$http.UserService.getMemberInfo()
this.userInfo = res
}
}
</script>
<style lang="stylus" scoped>
@import "~@assets/stylus/page/fund";
</style>

View File

@@ -0,0 +1,59 @@
<template lang="pug">
.login
.head_portrait
img(src="image/logo.png" alt="用户头像")
.user_input
input(class="user_name" placeholder="请输入手机号" type="text" v-model='cellphone')
input(class="user_pwd" placeholder="请输入密码" type="password" v-model='password')
.user_login(@click='login') 登录
.login_other
router-link.forget_password(to="/Forget" tag="span") 忘记密码
router-link(to="/register" tag="span") 用户注册
</template>
<script lang="ts">
import {Component, Provide, Vue, Inject} from 'vue-property-decorator';
import { Socket } from '../../core/utils/socket'
@Component
export default class Login extends Vue {
// inject 注入 App.vue 提供的变量
@Inject() readonly HiddenTabBar!: Function
$http: any
$utils: any
private cellphone: string = ''
private password: string = ''
private created(): void {
this.HiddenTabBar()
}
private async login():Promise<void> {
if(this.cellphone == ''){
this.$toast('请输入手机号')
return
}
if(this.password == ''){
this.$toast('请输入密码')
return
}
let data = {
cellphone: this.cellphone,
password: this.password
}
let res = await this.$http.HomeService.login(data)
if (res !== -1) {
await this.$utils.setStorage("access_token", res.access_token);
// 当登录成功后开启socket,用于获取消息角标
new Socket()
this.$router.push("/");
}
}
}
</script>
<style scoped lang="stylus">
@import "~@assets/stylus/page/login"
</style>

View File

@@ -0,0 +1,111 @@
<template lang="pug">
.ModifyAddress.content
NavbarComponent(title="修改地址" showLeft)
van-field.disabled(v-model='account' label="账号" readonly disabled)
van-field(v-model="name", label="姓名" placeholder="输入姓名")
van-field(v-model="tel", label="手机号" placeholder="输入手机号")
Address(@confirm="onConfirm" :value='area' :areaText='areaText')
van-field(v-model="detail" placeholder="地址详情" label="地址详情")
.account_sub_top
van-button(type='default' size='large' color='#20c6c2' @click='saveAccountAddress') 修改
</template>
<script lang="ts">
import {Component, Provide, Vue, Inject} from 'vue-property-decorator';
import NavbarComponent from "@/components/Navbar.vue";
import Address from "@/components/Address.vue";
import { Dialog } from 'vant';
@Component({
components:{
NavbarComponent,
Address
}
})
export default class ModifyAddress extends Vue {
$http: any
// inject 注入 App.vue 提供的变量
@Inject() readonly HiddenTabBar!: Function
@Inject() readonly ShowTabBar!: Function
// 买号id
private account_id: string = ''
private account: string = ''
private name: string = ''
private tel: string = ''
private area: string = ''
private detail: string = ''
private areaText: string = ''
// 控制弹出层
private show1: boolean = false;
private created(): void {
this.HiddenTabBar()
if(this.$route.query.id !== void 0){
this.account_id = this.$route.query.id as string
this.accountListByPlatform()
}
}
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar()
next()
}
// 打开关闭弹出层
private isPopup(id: string): void {
if (id == "show1") this.show1 = !this.show1;
}
// 确定选择城市
private onConfirm(value: any) {
this.area = value[value.length-1]
}
// 获取当前账号信息
private async accountListByPlatform(): Promise<void>{
let res = await this.$http.UserService.accountListByPlatform(this.account_id)
let area = res[0].address
this.account = res[0].account
this.name = res[0].address.full_name
this.tel = res[0].address.cellphone
this.area = String(area.area_id)
this.detail = area.detail
this.areaText = `${area.area_text.province} ${area.area_text.city} ${area.area_text.country}`
}
// 修改地址
private async saveAccountAddress(): Promise<void>{
let data = {
id: this.account_id,
full_name: this.name,
cellphone: this.tel,
area_id: this.area,
detail: this.detail
}
Dialog.confirm({
title: '是否提交',
message: '点击确定提交信息'
}).then( async () => {
let res = await this.$http.UserService.saveAccountAddress(data)
this.$toast('提交成功')
setTimeout(()=>{
this.$router.go(-1)
},2000)
})
}
}
</script>
<style lang="stylus">
.ModifyAddress
.disabled
background #f6f6f6
margin-top 0.2rem
.van-field__control
color #000000
</style>
<style lang="stylus" scoped>
@import '~@assets/stylus/page/modifyAddress';
</style>

View File

@@ -0,0 +1,72 @@
<template lang="pug">
.notice
NavbarComponent(:title='NoticTitle' :show-left="true")
.content
.title {{listData.title}}
.time
| {{ $utils.formatDate(listData.publish_time) }}
.l_content(v-html="listData.content")
</template>
<script lang="ts">
import { Component, Provide, Vue, Inject } from 'vue-property-decorator';
import NavbarComponent from "@/components/Navbar.vue";
@Component({
components: {
NavbarComponent
}
})
export default class News extends Vue {
@Inject() readonly HiddenTabBar!: Function;
@Inject() readonly ShowTabBar!: Function;
public id: string | (string | null)[] | number = 0;
public listData: { [key:string]: string } = {};
private $http!: { [key: string]: { [key: string]: (args: {[key: string]: any} ) => Promise<any> }; };
private NoticTitle: string = "";
async created() {
this.id = this.$route.query.id;
this.getInfoData();
this.HiddenTabBar();
}
public async getInfoData(): Promise<void> {
this.listData = await this.$http.NewsService.announceInfoById({
id: this.id
});
this.NoticTitle = this.listData.title
}
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar();
next()
}
}
</script>
<style scoped lang="stylus">
.notice
padding 10px
.title
font-size: 0.5rem;
font-family:PingFang SC;
font-weight:bold;
color:rgba(51,51,51,1);
line-height: 1.24rem;
.time
font-size:0.32rem;
font-family:PingFang SC;
font-weight:500;
color:rgba(153,153,153,1);
.l_content
margin-top 20px;
font-size:0.325rem;
font-family:PingFang SC;
font-weight:500;
color:rgba(0,0,0,1);
line-height: 0.5rem;
img
width 100%
</style>

View File

@@ -0,0 +1,123 @@
<!--领取记录-->
<template lang="pug">
.CollectionRecords
NavbarComponent(title="本金记录" :show-left="true")
.content
van-list(v-model='loading'
:finished='finished'
finished-text='没有更多了'
@load='onLoad')
.records_list
.list_item(v-for="i in testList")
.item_left
p {{i.sub_type_text}}
span {{$utils.formatDate(i.create_time)}}
.item_right {{i.amount}}金币
</template>
<script lang="ts">
import {Component, Provide, Inject, Vue} from 'vue-property-decorator';
import NavbarComponent from '@/components/Navbar.vue'
@Component({
components: {
NavbarComponent
}
})
export default class PrincipalRecord<T> extends Vue {
$http: any
// inject 注入 App.vue 提供的变量
@Inject() readonly HiddenTabBar!: Function;
@Inject() readonly ShowTabBar!: Function;
private titleName: String = "资金明细";
private loading: boolean = false;
private finished: boolean = false;
private testList: Array<T | number | object | string> = [];
private money: number = 0
private page: number = 0
private limit: number = 10
// 进入页面,关闭底部导航条
private created(): void {
this.HiddenTabBar()
}
// 演示加载数据
private onLoad(): void {
if(this.finished){
this.$toast('已经到底了')
return
}
++this.page
this.getList()
}
private async getList(): Promise<void> {
let data = {
page: this.page,
limit: this.limit
}
let res = await this.$http.UserService.financelist(data)
// 数据全部加载完成
if (res < this.limit) {
this.finished = true;
}
// 加载状态结束
this.loading = false;
this.testList = [...this.testList, ...res]
this.money = res.total_money
}
// 离开页面,开启底部导航条
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar()
next()
}
}
</script>
<style scoped lang="stylus">
.records_list
padding 0 0.49rem 0.49rem 0.49rem
.list_item
padding-top 0.49rem
padding-bottom 0.44rem
border-bottom 1px solid #c5c5c5
display flex
justify-content space-between
align-items center
.item_right
font-size 17px
color #e9920a
.item_left
height 1.187rem
display flex
flex-direction column
p
font-size 17px
color #000
margin-bottom 0.293rem
span
font-size 14px
color #717171
.header
width 100%
height 4.733rem
background #4db0fe
display flex
align-items center
justify-content center
p
color #fff
font-size 25px
span
margin-left 4px
font-size 15px !important
</style>

View File

@@ -0,0 +1,270 @@
<template lang="pug">
.RealName.content
NavbarComponent(title="实名认证" showLeft)
.line
MyPanel(title='证件信息' icon='buyer-icon-credentials_icon' size='0.6')
.identity
van-field(v-model="name" placeholder="输入姓名" label='姓名' :disabled='status == 0 || status == 1')
van-field(v-model="id" placeholder="输入身份证" label='身份证号码' :disabled='status == 0 || status == 1')
.statusIcon(v-if='status == 0')
myIcon(name='buyer-icon-shenhezhong' size='2.5' color='#cdcdcd')
.statusIcon(v-if='status == 1')
myIcon(name='buyer-icon-yitongguo' size='2.5' color='#1afa29')
.prompting.prompting_m 跑单全网曝光身份信息追查到底追究刑事责任
.line
MyPanel(title='身份证照片' icon='buyer-icon-gerenxinxi' size='0.6')
.certificates.flex_cen
.example
.prompting.prompting_m.prompting_cen 参考示例图
img(src='http://static.alkid888.com/example/zhengmian.png')
.example
.prompting.prompting_m.prompting_cen 身份证照片需清晰
van-uploader(v-model="fileList1" capture='camera' multiple :max-count="1" :after-read='afterRead1' :deletable='!(status == 0 || status == 1)')
MyPanel(title='手持身份证照片')
.certificates.flex_cen
.example
.prompting.prompting_m.prompting_cen 参考示例图
img(src='http://static.alkid888.com/example/shouchi.png')
.example
.prompting.prompting_m.prompting_cen 身份证照片需清洗
van-uploader(v-model="fileList2" capture='camera' multiple :max-count="1" :after-read='afterRead2' :deletable='!(status == 0 || status == 1)')
.line
MyPanel(title='绑定银行卡' icon='buyer-icon-bank-card' size='0.6')
van-field(clearable='', label='提现银行', disabled right-icon='arrow', :placeholder="bankText", @click="isShow")
.prompting.prompting_m 请仔细核对银行卡卡号避免卡号填写错误导致提现返款失败
Address(@confirm='area' areaTitle='开户行地址' :value='areaValue' :areaText='areaText' :level='2' :isShow='status == 0 || status == 1')
van-field(v-model="bankName" placeholder="输入支行名称" label='支行名称' :disabled='status == 0 || status == 1')
van-field(v-model="card" placeholder="输入卡号" label='银行卡号' type="digit" :disabled='status == 0 || status == 1')
.prompting.prompting_m 确保绑定银行卡信息和平台注册姓名一致避免造成资金损失
.prompting.prompting_m 银行卡 手机号身份证号姓名需一致
.account_sub(v-if='!(status == 0 || status == 1)')
van-button(type='default' size='large' color='#20c6c2' @click='saveidcard') 提交
van-popup(v-model="show" position='bottom' :style="{ height: '40%' }")
van-picker(:columns="bank" :default-index='0' @confirm="onConfirm" @cancel="show = !show" show-toolbar)
</template>
<script lang="ts">
import {Component, Provide, Vue, Inject} from 'vue-property-decorator';
import NavbarComponent from "@/components/Navbar.vue";
import MyPanel from "@/components/MyPanel.vue"
import Address from "@/components/Address.vue";
import myIcon from "@/components/Icons.vue";
import { Dialog } from 'vant';
@Component({
components:{
NavbarComponent,
MyPanel,
Address,
myIcon
}
})
export default class RealName extends Vue {
$http: any
$utils: any
// inject 注入 App.vue 提供的变量
@Inject() readonly HiddenTabBar!: Function
@Inject() readonly ShowTabBar!: Function
private name: string = ''
private id: string = ''
private card: string = ''
private areaId: number[] = []
private status: number = NaN
private bankName: string = ''
// 回显的地址id
private areaValue: string = ''
// 回显的地区拼接
private areaText: string = '选择地址'
private show: boolean = false
// 原始银行卡数组
private banklist: any = []
// 处理后银行卡数组
private bank: string[] = []
// 当前选中的下标
private bankIndex: number = 0
// 当前选中银行的文字
private bankText: string = '选择银行'
// 图片上传
private fileList1:any = []
private fileList2:any = []
// 图片id
private fileId1: string = ''
private fileId2: string = ''
private async created(): Promise<void> {
this.HiddenTabBar()
await this.getBanklist()
this.idCardBankInfo()
}
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar()
next()
}
private isShow(): void{
if(this.status == 0 || this.status == 1) return;
this.show = !this.show
}
// 身份证上传
private async afterRead1(cell: any): Promise<void> {
let fd = new FormData()
fd.append('file', cell.file)
fd.append('imageType', '2')
let res = await this.$http.PublicService.uploadImg(fd)
this.fileId1 = res.id
}
// 手持身份证上传
private async afterRead2(cell: any): Promise<void> {
let fd = new FormData()
fd.append('file', cell.file)
fd.append('imageType', '3')
let res = await this.$http.PublicService.uploadImg(fd)
this.fileId2 = res.id
}
// 银行点击确定
private onConfirm(value: any, index: any): void {
this.bankText = value
this.bankIndex = index
this.show = !this.show
}
// 地址点击确定
private area(id: number[]): void {
this.areaId = id
}
// 银行卡列表
private async getBanklist(): Promise<void> {
let res = await this.$http.PublicService.banklist()
let rel: any[] = res;
if(typeof res == 'object'){
rel = [...Object.values(res)]
}
this.banklist = rel
rel.forEach((v:any, i:number) => {
this.bank.push(v.bank_full_title)
});
}
// 提交实名认证
private async saveidcard(): Promise<void> {
if(this.name == ''){
this.$toast('填写姓名')
return
}
if(!this.$utils.isIdentity(this.id)){
this.$toast('身份证不正确')
return
}
if(this.fileList1.length <= 0){
this.$toast('请上传身份证')
return
}
if(this.fileList2.length <= 0){
this.$toast('请上传手持身份证')
return
}
if(this.bankText == '选择银行'){
this.$toast('请选择提现银行')
return
}
if(this.areaId.length <= 0){
this.$toast('请选择开户行地址')
return
}
if(this.bankName == ''){
this.$toast('请输入银行支行名称')
return
}
if(this.card == ''){
this.$toast('请输入银行卡号')
return
}
let data = {
username: this.name,
id_card: this.id,
id_card_image_id: this.fileId1,
user_image_id: this.fileId2,
account: this.card,
bank_id: this.banklist[this.bankIndex].id,
bank_name: this.bankName,
bank_area_id: this.areaId[this.areaId.length-1]
}
this.$http.UserService.saveidcard(data)
Dialog.confirm({
message: '实名认证提交成功,是否前往添加买号?',
confirmButtonText: '前往',
}).then(()=>{
this.$router.push({ path: '/authentication' });
}).catch(()=>{
this.idCardBankInfo()
})
}
private async idCardBankInfo(): Promise<void> {
let res = await this.$http.UserService.idCardBankInfo()
if(res.bank.length >= 0 || res.id_card.length >= []) return ;
this.name = res.id_card.username
this.id = res.id_card.id_card
this.areaId.push(res.bank.bank_area_id)
this.bankName = res.bank.bank_name
// 先重置图片列表
this.fileList1 = []
this.fileList2 = []
res.id_card.review_img.forEach((v:any,i:number)=>{
if(v.image_type == 2){
this.fileList1.push({url:v.uploads.path})
this.fileId1 = v.image_id
}else if(v.image_type == 3){
this.fileList2.push({url:v.uploads.path})
this.fileId2 = v.image_id
}
})
this.banklist.forEach((v: any, i: number)=>{
if(res.bank.bank_id == v.id){
this.bankIndex = i
this.bankText = v.bank_full_title
}
})
this.areaValue = String(res.bank.bank_area_id)
this.areaText = `${res.bank.bank_area.province} ${res.bank.bank_area.city}`
this.card = res.bank.account
this.status = res.id_card.status
if(res.id_card.status == -1){
Dialog.alert({
title: '审核未通过',
message: res.id_card.remark,
}).then(() => {
// on close
});
this.$toast
}
}
}
</script>
<style lang="stylus">
.RealName
.van-uploader
width 100%
.van-uploader__preview,.van-uploader__upload
width 100%
margin 0
box-sizing border-box
.van-uploader__preview-image,.van-uploader__input
width 100%
height 3.56rem
.van-uploader__upload
height 3.56rem
</style>
<style lang="stylus" scoped>
@import '~@assets/stylus/page/realName';
</style>

View File

@@ -0,0 +1,132 @@
<template lang="pug">
.register
.login
.head_portrait
img(src="image/logo.png" alt="用户头像")
.user_input
van-field(v-model='cellphone', label='手机号', placeholder='请输入手机号')
van-field(v-model='verifyCode', label='验证码', placeholder='短信验证码')
van-button(slot='button', size='small', type='primary' :disabled="isCode>0" @click='captcha') {{isCode>0?isCode:''}} 发送验证码
van-field(v-model='password', type="password", label='密码', placeholder='8-25位字母与数字组合')
van-field(v-model='isPassword', type="password", label='确认密码', placeholder='请保持两次密码一致')
van-field(v-model='inviteCode', label='邀请码', placeholder='邀请码')
van-checkbox(class="agreement",
v-model="agreement",
icon-size="12px",
checked-color="#20c6c2")
span.text 登录即代表阅读并且同意服务协议
.user_login(@click='register') 注册
.login_other
router-link.forget_password(to="/Forget" tag="span") 忘记密码
router-link(to="/login" tag="span") 登录
</template>
<script lang="ts">
import {Component, Provide, Vue, Inject} from 'vue-property-decorator';
@Component
export default class Register extends Vue {
// inject 注入 App.vue 提供的变量
@Inject() readonly HiddenTabBar!: Function
@Inject() readonly ShowTabBar!: Function
$http: any
$utils: any
private cellphone: string = ''
private verifyCode: string = ''
private password: string = ''
private isPassword: string = ''
private inviteCode: string = ''
private agreement: boolean = false
// 60秒发送验证码
private isCode: number = 0
private created(): void {
this.HiddenTabBar()
if(this.$route.query.invite !== void 0){
this.inviteCode = this.$route.query.invite as string
}
}
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar()
next()
}
// 发送验证码
private async captcha(): Promise<void> {
if(!(/^1[3456789]\d{9}$/.test(this.cellphone))){
this.$toast('手机号不正确')
return
}
let res:any = await this.$http.HomeService.captcha(this.cellphone)
if(!!res.validate_token){
this.$toast('发送成功')
}
this.isCode = 60
let time: number = setInterval(()=>{
if(this.isCode <= 0){
clearInterval(time)
}
--this.isCode
},1000)
}
private async register(): Promise<void> {
if(this.cellphone == ''){
this.$toast('请填写手机号')
return
}
if(!(/^1[3456789]\d{9}$/.test(this.cellphone))){
this.$toast('手机号不正确')
return
}
if(this.verifyCode == '' || this.verifyCode.length !== 4){
this.$toast('请填写正确的验证码')
return
}
if(this.password == ''){
this.$toast('请填写密码')
return
}
if(!(/^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{8,20}$/.test(this.password))){
this.$toast('密码必须为8-25位字母与数字组合')
return
}
if(this.password !== this.isPassword){
this.$toast('两次密码不相同')
return
}
if(this.inviteCode == ''){
this.$toast('请填写邀请码')
return
}
if(!this.agreement){
this.$toast('同意用户协议才可注册')
return
}
let data = {
cellphone: this.cellphone,
password: this.password,
verify_code: this.verifyCode,
template_id: 1,
invite_code: this.inviteCode
}
let res = await this.$http.HomeService.register(data)
if (res !== -1) {
await this.$utils.setStorage("access_token", res.access_token);
this.$router.push("/");
}
}
}
</script>
<style lang="stylus">
.login
.van-field__label
width 2rem
</style>
<style scoped lang="stylus">
@import "~@assets/stylus/page/login"
</style>

View File

@@ -0,0 +1,385 @@
<!--任务大厅-->
<template lang="pug">
.task_hall
NavbarComponent(title="任务大厅" :show-left="true")
.content
//- van-tabs(v-model='active'
//- line-width="25px"
//- swipeable)
//- van-tab(title='销量任务')
TaskHallItem(:item="TaskItemList")
router-link(to='/authentication')
.sales_volume_list.flex_cen
Icons(name='buyer-icon-jiahao' color='#ccc' size='0.7')
.start_receiving_orders
van-button(type='primary' block @click="StartOrders") 开始接单
//- van-tab(title='流量任务')
//- TaskHallItem(:item="TaskItemList")
//- .flow_task
//- .flow_task_item(v-for="i in 6")
//- .item_left
//- img(src="https://img.alicdn.com/tfscom/tuitui/TB1w9HDLXXXXXb8XXXXXXXXXXXX_30x30.jpg")
//- .item_left_text
//- p 商家姓名
//- p 无需垫付
//- p 淘宝流量任务 普通任务
//- .item_right
//- span ¥6
//- div() 接单
van-popup(v-if="JSON.stringify(this.startReceivingOrders.setupTwoData) !== '{}' " v-model='startReceivingOrders.actionPopupStatus' class="receipt" :close-on-click-overlay="false")
.receipt_title
img(src="https://img.alicdn.com/tfscom/tuitui/TB1w9HDLXXXXXb8XXXXXXXXXXXX_30x30.jpg")
span {{startReceivingOrders.setupTwoData.shop_info.shop_name}}
div
.green 直返
.yello 信誉
.receipt_content
.line-block
p 任务编号{{startReceivingOrders.setupTwoData.base_info.id}}
p 垫付货款{{$utils.conversionMoney(startReceivingOrders.setupTwoData.base_info.capital)}}
.line-block
p 剩余时间{{$utils.leftTimer(startReceivingOrders.setupTwoData.base_info.end_time)}}
p 任务佣金{{$utils.conversionMoney(startReceivingOrders.setupTwoData.base_info.commission)}}
.receipt_action
van-button( class='cancel' color="#e5e5e5" type='default' size="small" @click='onCancel') 取消({{cancelNum}}/3)
van-button(type='danger' size="small" @click="StartReceipt") 接单
| ({{startReceivingOrders.actionPopupTime}}s)
</template>
<script lang="ts">
import {Component, Provide, Vue, Inject} from 'vue-property-decorator';
import NavbarComponent from '@/components/Navbar.vue'
import TaskHallItem from '@/components/TaskHallItem.vue'
import Icons from '@/components/Icons.vue'
import { Toast, Dialog } from "vant";
@Component({
components: {
NavbarComponent,
TaskHallItem,
Icons
}
})
export default class TaskHall extends Vue {
$utils: any
// inject 注入 App.vue 提供的变量
@Inject() readonly HiddenTabBar!: Function;
@Inject() readonly ShowTabBar!: Function;
//广播接收子组件点击传过来的数据
private TaskItemBroadcast = new BroadcastChannel('TaskItemClick');
protected TaskItemList: Array<Object> = [];
private active: number = 0;
private $http: any;
// 当前可取消的任务数量
private cancelNum: number = 0
private startReceivingOrders: {
[key:string]: { [key:string]: string | any } | boolean | number | null
} = {
// 存储用户点击买号的数据
childItemClickData: {},
// 弹窗展示控制false 不展示true 展示
actionPopupStatus: false,
actionPopupTime: 15,
actionPopupTimer: null,
setupTwoData: {},
buttonText: {
OrderNotReceived: "开始接单",
ReceivingOrders: "努力接单中..."
}
};
private created(): void {
this.HiddenTabBar();
this.getTaskAccount();
this.addOnBroadcast();
this.cancelNumTask();
}
/**
* 选择买号然后点击抢单toast倒计时8秒然后调用第二个接口有结果弹出窗口无结果不弹
* @constructor
*/
public StartOrders(): void {
if((this.startReceivingOrders.childItemClickData as {id: number}).id == void 0){
this.$toast('请选择买号,如果未添加买号,请点击加号前往')
return
}
const toast = Toast.loading({
duration: 0, // 持续展示 toast
forbidClick: true,
message: '倒计时 8 秒'
});
let second = 8;
const timer = setInterval( async () => {
second--;
if (second) {
toast.message = `倒计时 ${second}`;
} else {
clearInterval(timer);
// 手动清除 Toast
Toast.clear();
let setupTwo = await this.$http.TaskService.orderTask({
account_id: (this.startReceivingOrders.childItemClickData as {id: number}).id
});
// 如果data 有数据,展示弹窗,没,不展示
if(typeof setupTwo !== 'object'){
this.Time();
this.startReceivingOrders.actionPopupStatus = true
return
}
this.startReceivingOrders.setupTwoData = setupTwo;
}
}, 1000);
}
/**
* 倒计时
*/
public Time() {
this.startReceivingOrders.actionPopupTimer = setInterval(() => {
(<number>this.startReceivingOrders.actionPopupTime)--;
if ((<number>this.startReceivingOrders.actionPopupTime)) {
} else {
clearInterval(<any>this.startReceivingOrders.actionPopupTimer);
this.startReceivingOrders.actionPopupStatus = false
this.startReceivingOrders.actionPopupTime = 15;
}
}, 1000);
}
/**
* 买号被点击存储用户点击的item数据
*/
public addOnBroadcast(): void {
this.TaskItemBroadcast.onmessage = (evt: any) => {
this.startReceivingOrders.childItemClickData = evt.data;
}
}
/**
* 任务取消的逻辑处理
*/
private onCancel(): void {
if(this.cancelNum >= 3){
this.$toast('已主动取消三次,请再明天再试')
return
}
this.startReceivingOrders.actionPopupStatus = false
this.cancelNum++
this.$utils.setStorage('cancelNumTask', {
num: this.cancelNum,
time: (new Date(new Date().toLocaleDateString()).getTime())
})
// 清除自动关闭定时器并且把定时器数值重置
this.startReceivingOrders.actionPopupTime = 15
clearInterval(<any>this.startReceivingOrders.actionPopupTimer);
}
/**
* 任务取消每日数量统计和重置
*/
private cancelNumTask(): void {
// 获取上次存储的时间
let cancelNum: {num:number, time:number} = this.$utils.getStorage('cancelNumTask')
// 第二天零点时间有可能使用 (new Date(new Date().toLocaleDateString()).getTime()) + 86400000
// 获取第二天的时间戳
let zero: number = Date.parse(new Date() as any)
if(!cancelNum) return;
// 如果现在时间减去上一次0点时间大于86400000则代表是第二天了
if((zero - cancelNum.time) > 86400000){
this.$utils.setStorage('cancelNumTask', {
num: 0,
time: (new Date(new Date().toLocaleDateString()).getTime())
})
this.cancelNum = 0
}else{
this.cancelNum = cancelNum.num
}
}
private async getTaskAccount(): Promise<void> {
let data = await this.$http.TaskService.getTaskAccount({
platform_id: '10'
});
switch (data.auth_status) {
case -4:
Dialog.alert({
message: data.auth_msg,
confirmButtonText: '前往'
}).then(()=>{
this.$router.replace({ path: '/realName' });
})
break;
case -3:
Dialog.alert({
message: data.auth_msg
})
break;
case -2:
Dialog.alert({
message: data.auth_msg,
confirmButtonText: '前往'
}).then(()=>{
this.$router.replace({ path: '/realName' });
})
break;
case -1:
Dialog.alert({
message: data.auth_msg,
confirmButtonText: '前往'
}).then(()=>{
this.$router.replace({ path: '/realName' });
})
break;
default:
break;
}
this.TaskItemList = data.account_list;
}
// 开始接单
private async StartReceipt(): Promise<void> {
let setupThree = await this.$http.TaskService.commitTask({
account_id: (this.startReceivingOrders.childItemClickData as {id: number}).id,
task_id: ((this.startReceivingOrders.setupTwoData as {base_info: any}).base_info as { id: number}).id
});
if(setupThree == null) {
this.$router.push({path: '/task'})
}
}
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar();
next()
}
}
</script>
<style scoped lang="stylus">
.receipt
width 93%
.receipt_title
padding 0.333rem 0.187rem 0.16rem
display flex
justify-content flex-start
align-items center
border-bottom 1px solid #e5e5e5
img
width 0.56rem
height 0.56rem
border-radius 100%
margin-right 0.187rem
span
color #333
font-size 14px
margin-right 0.147rem
.green
color #fff
font-size 12px
background #1ab51f
margin-right 0.133rem
float left
width 1.067rem
height 0.507rem
box-sizing border-box
text-align center
line-height 0.52rem
.yello
color #fff
font-size 12px
background #ff9c07
float left
width 1.067rem
height 0.507rem
box-sizing border-box
text-align center
line-height 0.52rem
.receipt_content
padding 0.373rem 0.687rem
font-size 14px
border-bottom 1px solid #e5e5e5
p
margin-bottom 0.333rem
.line-block
display flex
justify-content space-between
padding 0 0
p
color #8d8d8d
.receipt_action
padding-top 0.28rem
padding-bottom 0.453rem
padding-right 0.427rem
box-sizing border-box
display flex
justify-content flex-end
.cancel
color #999 !important
margin-right 0.16rem
.sales_volume_list
padding 0.553rem 0.307rem
height 1rem
border 0.02rem dashed #cccccc
margin 0.6rem 0.32rem 0
.start_receiving_orders
padding 0 10px
.van-button
position fixed !important
bottom 90px
left 50%
width 95%
margin-left -(95% / 2)
.flow_task
padding 0.267rem 0.553rem
.flow_task_item
padding-bottom 0.133rem
border-bottom 1px solid #e5e5e5
margin-bottom 0.133rem
display flex
justify-content space-between
padding-right 0.453rem
box-sizing border-box
.item_left
img
width 2.187rem
margin-right 0.28rem
float left
.item_left_text
float left
padding-top 6px
p
font-size 13px
color #999
margin-bottom 0.333rem
&:last-child
color #ff5858
.item_right
text-align center
span
font-size 14px
color #ff5858
div
height 0.613rem
background #ff5858
color #fff
text-align center
width 1.707rem
line-height 0.62rem
font-size 12px
border-radius 50px
margin-top 0.347rem
box-sizing border-box
</style>

View File

@@ -0,0 +1,229 @@
<template lang="pug">
.task_info
NavbarComponent(title="任务详情" :show-left="true")
.content
.remaining_time(v-if='taskData.cut_down.show') {{taskData.cut_down.text}}
CountDown(:time='taskData.cut_down.left_time')
.info
.items_title
.title_left
//- img(src="image/user_av.png" alt="")
Icons(v-if='taskData.shop_info.platform_id == 10' name="buyer-icon-taobao_" color='#ff5000' size='0.7')
Icons( v-else name="buyer-icon-tianmaobao" color='#FF0036' size='0.7')
span {{taskData.shop_info.shop_name}}
.y_1.y(v-for='(li,n) in taskData.shop_info.flag' :key='n' :style="`background:${li.flag_color}`") {{li.flag_title}}
.info_message
img(:src="taskData.sku_info.images[0].path")
.message_right
p 任务编号{{id}}
Icons.fuzhi( name="buyer-icon-fuzhi" color='#ccc' size='0.5' @click='$utils.copy(id)')
p(v-if="taskData.base_info.trade_id !== null") 下单编号{{taskData.base_info.trade_id}}
p 垫付金额{{$utils.conversionMoney(taskData.base_info.capital)}}
//- van-icon(class="question" name='question' color="#20c6c2")
p 任务佣金{{$utils.conversionMoney(taskData.base_info.commission)}}
.line
.marking_task
//- .task_title
//- span.title 打标任务
//- span.tips 详情
//- van-icon(class="question" name='question')
van-steps(class="steps" :active='StepActive')
van-step(v-for='(item,index) in taskData.step_flow' :key='index') {{item.title}}
.steps_button
van-button(type="default" size='mini' @click='stepClick(1)') 上一步
van-button(type="default" size='mini' @click='stepClick(2)') 下一步
TaskTag(v-if='isStep() == 0' :data='process()' :id='id' @click='onClick')
EnterShop(v-if='isStep() == 1' :data='process()' :message='taskData' @click='onClick')
Choose(v-if='isStep() == 2' :data='process()' :id='id' :isFinish='taskData.step_flow[1].finish' @click='onClick')
PlaceOrder(v-if='isStep() == 3' :data='taskData' @click='onClick' :isFinish='taskData.step_flow[2].finish')
Evaluate(v-if='isStep() == 4' :data='process()' :isFinish='taskData.step_flow[3].finish' :id='id' @click='onClick')
.bottom_bar
.bottom_bar_l
.bottom_bar_but(v-if='taskData.buttons.cancel.is_able' @click='cancelTask(id)') {{taskData.buttons.cancel.title}}
.bottom_bar_r
.bottom_bar_but.bottom_bar_but_finish(v-if='taskData.buttons.comment.is_able') {{taskData.buttons.comment.title}}
.bottom_bar_but.bottom_bar_but_finish(v-if='taskData.buttons.next.is_able' @click='nextStep') {{taskData.buttons.next.title}}
//- 任务注意事项弹窗
Matter(:id='id' :taskMsg='taskMsg')
</template>
<script lang="ts">
import {Component, Provide, Vue, Inject} from 'vue-property-decorator';
import NavbarComponent from '@/components/Navbar.vue'
import EnterShop from '@/components/EnterShop.vue'
import Choose from '@/components/Choose.vue'
import PlaceOrder from '@/components/PlaceOrder.vue'
import Evaluate from '@/components/Evaluate.vue'
import Icons from '@/components/Icons.vue'
import Matter from '@/components/Matter.vue'
import CountDown from '@/components/CountDown.vue'
import TaskTag from '@/components/TaskTag.vue'
@Component({
components: {
NavbarComponent,
EnterShop,
Choose,
PlaceOrder,
Evaluate,
Icons,
Matter,
CountDown,
TaskTag
}
})
export default class TaskInfo extends Vue {
$http: any
$utils: any
// inject 注入 App.vue 提供的变量
@Inject() readonly HiddenTabBar!: Function
@Inject() readonly ShowTabBar!: Function
// 买号id
private id: string = ''
// 任务详情所有数据
private taskData: any = {
shop_info: {},
base_info: {},
step_flow: [{process: 'entry_shop'},{process: 'item_order'},{process: 'order_finish'},{process: 'purchase'}],
process_flow: {
entry_shop: {},
item_order: {},
order_finish: {},
purchase: {}
},
channel_info: {},
sku_info: {
images: [{path:''}]
},
cut_down: {},
buttons: {
cancel: {},
comment: {},
next: {}
}
}
// 任务须知
private taskMsg: string[] = []
// step 绑定的变量
private StepActive: number = 0
// 当前所在的步骤
private current: number = 0
// 进入页面,关闭底部导航条
private async created(): Promise<void> {
this.HiddenTabBar()
if(this.$route.query.id !== void 0){
this.id = this.$route.query.id as string
await this.taskDetail()
}
}
// 离开页面,开启底部导航条
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar()
next()
}
// 获取详情信息
private async taskDetail(): Promise<void> {
let msg: any = await this.getTaskMsg()
let res = await this.$http.TaskService.taskDetail(this.id)
this.taskData = res
// 判断当前step是那一步
res.step_flow.forEach((v:any, i:number) => {
if(v.process == res.current_step){
this.StepActive = i
this.current = i
}
});
// 获取当前该任务的任务须知
for (const key in res.alert_info) {
if(res.alert_info[key] !== 0){
this.taskMsg.push(msg[key][res.alert_info[key]])
}
}
}
// step控制步骤
private stepClick(num: number): void {
let StepActive = this.StepActive
// 获取当前所有step数量进行最大值步骤控制
let currentNum: number = this.taskData.step_flow.length
if(num == 1 && --StepActive >= 0){
--this.StepActive
}else if(num == 2 && ++StepActive <= currentNum && StepActive <= this.current){
// 如果 当前步骤小于3 并且 小于 当前所要完成的步骤则++
++this.StepActive
}else if( ++StepActive > this.current && this.current !== currentNum){
this.$toast('请完成当前步骤再进行下一步')
}
}
// 当完成步骤的时候触发
private async onClick(): Promise<void> {
this.taskDetail()
}
// 单独获取任务须知
private async getTaskMsg(): Promise<void> {
return new Promise((resolve, reject)=>{
fetch('https://qichen-1300617764.cos.ap-shanghai.myqcloud.com/statics/js/taskDetailMsg.js')
.then( async (response)=> {
resolve(await response.json())
})
})
}
// 完成事件
private async nextStep(): Promise<void> {
let res = await this.$http.TaskService.nextStep(this.id)
if(res == 'success'){
this.taskDetail()
}
}
/**
* 根据当前step和step_flow 判断当前显示那个组件
* 用于显示对应进度的组件
*/
private isStep(): number | undefined {
switch (this.taskData.step_flow[this.StepActive].item_type) {
case 'task_tag':
return 0
break;
case 'entry_shop':
return 1
break;
case 'purchase':
return 2
break;
case 'item_order':
return 3
break;
case 'order_finish':
return 4
break;
}
}
// 根据当前step获取对应组件的数据
private process(): any{
return this.taskData.process_flow[this.taskData.step_flow[this.StepActive].process]
}
// 取消任务
private async cancelTask(id: string): Promise<void> {
let res = await this.$http.TaskService.cancelTask(id)
console.log(res);
}
}
</script>
<style scoped lang="stylus">
@import "~@assets/stylus/page/taskinfo"
</style>

View File

@@ -0,0 +1 @@
f6f9c40e-d691-4f1a-b75e-134e4d115bf8

View File

@@ -0,0 +1,150 @@
<template lang="pug">
//- 我的页面
.home
.user.flex
.user_img
img.img( v-if="userInfo.base_info.gender==1" src="image/nan.png")
img.img( v-else-if="userInfo.base_info.gender==2" src="image/nv.png")
img.img( v-else="" src="image/unknown.png")
.user_info.flex1
.inline_block
.user_name {{userInfo.base_info.cellphone}}
.user_href(@click='extension') 复制推广链接
//- .user_icon
//- van-icon(name="filter-o" color="#ffffff" size="0.8rem")
.sign_out(@click='signOut') 退出登陆
.home_center
.capital
.capital_cell
MyCell(title="资金管理" :isLink='true' to='/fund' icon='buyer-icon-zijinguanli' color='#fdb554')
van-icon(slot='right-icon', name='arrow', style='line-height: inherit;')
.capital_text
.capital_row.border_r.border_b
.title 本金账户
.balance {{userInfo.capital}}
.capital_row.border_b
.title 佣金账户
.balance {{userInfo.commission}}
.capital_text
.capital_row.border_r
.title 我的徒弟
.balance {{userInfo.refer_fans}}
.capital_row
.title 账号积分
.balance {{userInfo.point}}
.line
.capital
.capital_cell
MyCell(title="我的任务" :isLink='true' to='/task' icon='buyer-icon-renwu' color='#65461c')
van-icon(slot='right-icon', name='arrow', style='line-height: inherit;')
.capital_text
.order_row.flex_cen.flex1(v-for='(item, index) in orderList' :key='index' @click='goUrl(item)')
.row_l
Icons(name='buyer-icon-dd' color='#ccc' size='0.9')
p {{item.title}}
span(v-if='item.count > 0') {{item.count}}
.line
MyCell(title="买号认证" :isLink='true' to='/authentication' icon='buyer-icon-zhanghaobangding1' color='#5cc560')
p.text_r 已认证{{userInfo.account_num}}
MyCell(title="实名认证" :isLink='true' to='/realName' icon='buyer-icon-shimingrenzheng' color='#1f8bd6')
p.text_r {{authStatus(userInfo.auth_status)}}
.line
MyCell(title="推广赚钱" :isLink='true' to='/extension' icon='buyer-icon-tuiguang' color='#f88131' size='0.6')
//- van-cell(title="意见反馈" is-link )
MyCell(title="修改地址" :isLink='true' to='/authentication?mode=add' icon='buyer-icon-dizhi' color='#f50')
.line
.propaganda
van-swipe( :autoplay="3000" indicator-color="white")
van-swipe-item(v-for='(item, index) in userInfo.rotation_pic' :key='index')
img( :src='item.upload.path')
</template>
<script lang="ts">
import {Component, Provide, Vue} from 'vue-property-decorator';
import TestComponent from "@/components/test.vue";
import Icons from '@/components/Icons.vue'
import MyCell from '@/components/MyCell.vue'
import { Dialog } from 'vant'
@Component({
components: {
TestComponent,
Icons,
MyCell
}
})
export default class Home extends Vue {
$http: any
$utils: any
private userInfo: any = {
base_info: {},
rotation_pic: [{
upload: {}
}]
}
private orderList: any = []
created(){
this.myAll()
}
private async myAll(): Promise<void> {
let res = await this.$http.UserService.getMemberInfo()
this.userInfo = res
let task: string[] = [],task_stat: any = res.task_stat;
// 获取所有key 并存放到数组中
for (const t in res.task_stat) {
task.push(t)
}
// 循环task_stat并把下标存放进去
Object.values(task_stat).forEach((v:any,i:number)=>{
Object.assign(task_stat[task[i]],{ index: i, key: task[i] })
})
for (const k in task_stat) {
if(k == 'task_order_placed' || k == 'task_has_refunded' || k == 'task_has_received' || k == 'task_in_complain'){
this.orderList.push(task_stat[k])
}
}
}
// 前往订单列表页
private goUrl(item: any): void {
this.$router.push({name:'task',query:{index: item.index, step: item.key}})
}
private extension(): void {
let str: string = `${window.location.origin}${window.location.pathname}#/register?invite=${this.userInfo.refer_code}`
this.$utils.copy(str)
}
// 实名当前的审核状态转换
private authStatus(status: number): string | undefined {
switch (status) {
case -1:
return '未通过'
case 0:
return '审核中'
case 1:
return '已通过'
default:
break;
}
}
/**
* 退出登录
*/
private signOut() :void {
Dialog.confirm({
message: '是否退出登录?'
}).then(() => {
this.$utils.delStorage('access_token')
this.$router.push('/login')
}).catch(()=>{})
}
}
</script>
<style lang="stylus" scoped>
@import "~@assets/stylus/page/my";
</style>

View File

@@ -0,0 +1,179 @@
<template lang="pug">
.news
NavbarComponent(title="消息列表")
.content
van-tabs(:swipe-threshold="4"
@click="onClick"
v-model="OnActive"
animated
title-active-color="#fff"
:border="false"
swipeable)
van-tab(:title='item.title' v-for="(item,index) in NewsList" :key="index")
van-list(v-if="item.type == 0 && showList" @load="onLoad"
:immediate-check="false"
finished-text="没有更多了"
v-model="NewsList[0].loading" :finished="NewsList[0].finished")
//- 防止还没有数据的时候页面就开始渲染
NewsItemComponent(:itemArr="NewsList[OnActive].content")
SystemNoticeItemComponent(:itemArr="NewsList[OnActive].content")
FinanceRecordItemComponent(:itemArr="NewsList[OnActive].content")
van-list(v-if="item.type == 1"
v-model="NewsList[1].loading"
:immediate-check="false"
finished-text="没有更多了"
:finished="NewsList[1].finished"
@load="onLoad")
NewsItemComponent(:itemArr="NewsList[1].content")
van-list(v-if="item.type == 2"
v-model="NewsList[2].loading"
:immediate-check="false"
finished-text="没有更多了"
:finished="NewsList[2].finished"
@load="onLoad")
SystemNoticeItemComponent(:itemArr="NewsList[2].content")
van-list(v-if="item.type == 3"
v-model="NewsList[3].loading"
:immediate-check="false"
finished-text="没有更多了"
:finished="NewsList[3].finished"
@load="onLoad")
FinanceRecordItemComponent(:itemArr="NewsList[3].content")
</template>
<script lang="ts">
import { Component, Provide, Vue } from 'vue-property-decorator';
import NavbarComponent from "@/components/Navbar.vue";
import NewsItemComponent from "@/components/NewsItem.vue";
import SystemNoticeItemComponent from "@/components/SystemNotice.vue";
import FinanceRecordItemComponent from "@/components/FinanceRecord.vue";
import { Action } from 'vuex-class'
@Component({
components: {
NavbarComponent,
NewsItemComponent,
SystemNoticeItemComponent,
FinanceRecordItemComponent
}
})
export default class News extends Vue {
private $http: any;
@Action('NEWSNUM') NEWSNUM: any;
// 保存当前激活tabs的下标
private OnActive: number = 0;
// 有数据后再渲染列表,防止出错
private showList: boolean = false;
// tabs
private NewsList: any[] = [
{ type: 0, title: '全部', loading: false, finished: false, page: 1 ,content: [] },
{ type: 1, title: '任务信息', loading: false, finished: false, page: 1 , content: [] },
{ type: 2, title: '系统通知', loading: false, finished: false, page: 1 ,content: [] },
{ type: 3, title: '资金动态', loading: false, finished: false, page: 1 ,content: [] }
];
async created() {
this.getNewsList();
// this.NEWSNUM(0)
}
public onLoad() {
this.NewsList[this.OnActive].page += 1;
this.getNewsList();
}
public onClick() {
if(this.NewsList[this.OnActive].content.length == 0){
this.getNewsList()
}
}
// TODO 数据量不够,所以滚动加载还未做
public async getNewsList(): Promise<any> {
// 请求数据
let data = await this.$http.NewsService.messageList({
limit: 10,
page: this.NewsList[this.OnActive].page,
type: this.NewsList[this.OnActive].type
});
this.NewsList[this.OnActive].loading = false;
this.NewsList[this.OnActive].content = [...this.NewsList[this.OnActive].content, ...data];
if(data.length < 10){
this.NewsList[this.OnActive].finished = true;
}
this.showList = true
}
private beforeUpdate(): void {
this.$nextTick(function () {
let all = document.querySelectorAll(".van-tab__pane");
all.forEach((val) => (val as any).style.height = `${document.body.clientHeight - 46 - 45.97 - 49.98}px`);
})
}
}
</script>
<style lang="stylus">
.news_item
padding 0.44rem 0.493rem
margin-bottom 0.253rem
border-bottom 10px solid #f6f6f6
.item_title
padding-left 0.28rem
padding-bottom 0.2rem
padding-right 0.28rem
box-sizing border-box
display flex
align-items center
justify-content space-between
border-bottom 1px solid #e5e5e5
h2
color #666
font-size 16px
span
color #adadad
font-size 13px
.item_content
padding-left 0.573rem
padding-right 0.4rem
padding-top 0.187rem
display flex
justify-content space-between
box-sizing border-box
min-height 2rem
.content_left
.name
padding-bottom 0.293rem
img
border-radius 100%
vertical-align middle
span
color #333
font-size 12px
// padding-left 0.147rem
.yj
color #ff5858
font-size 12px
padding-bottom 0.293rem
.df
color #999
font-size 12px
padding-bottom 0.293rem
.content_right
color #20c6c2
font-size 14px
padding 0.147rem 0.28rem
background #e5fffe
border-radius 6px
line-height 0.667rem
box-sizing border-box
align-self center
</style>

View File

@@ -0,0 +1,222 @@
<template lang="pug">
.task
NavbarComponent(title="任务列表")
.content
van-tabs(v-model='active'
:swipe-threshold="4"
@click="onClick"
animated
title-active-color="#fff"
:border="false"
swipeable)
van-tab(v-for="(item,index) in TabsList" :key="index")
div.tab_title(slot='title')
| {{item.title}}
.triangle(v-if='item.count > 0') {{item.count}}
//- 搜索
//- van-search(class="search" v-model='SearchKey',
//- placeholder='请输入刷新关键词',
//- right-icon="search"
//- left-icon=""
//- @search='',
//- @cancel='')
van-list(class="list"
@load="onLoad"
v-model="item.loading"
:immediate-check="false"
:finished="item.finished"
finished-text="没有更多了")
.tabs_items(tag="div" v-for="(it,i) in item.content" :key="i")
.items_title
.title_left
Icons( v-if='it.shop_info.platform_id == 10' name="buyer-icon-taobao_" color='#ff5000' size='0.7')
Icons( v-else name="buyer-icon-tianmaobao" color='#FF0036' size='0.7')
span {{it.shop_info.shop_name}}
.y_1.y(v-for='(li,n) in it.shop_info.flag' :key='n' :style="`background:${li.flag_color}`") {{li.flag_title}}
.title_status {{it.shop_status}}
.item_text
.text_1.t
span.flex_cen 任务编号{{it.base_info.id}}
Icons.fuzhi( name="buyer-icon-fuzhi" color='#ccc' size='0.5' @click='$utils.copy(it.base_info.id)')
span.flex_cen 垫付{{$utils.conversionMoney(it.base_info.capital)}}
.text_2.t
span 任务买号: {{it.account_info.account}}
span 佣金{{$utils.conversionMoney(it.base_info.commission)}}
.text_1.t(v-if='it.cut_down.show')
span 剩余时间
CountDown(:time='it.cut_down.left_time')
.item_action
van-icon(name='ellipsis')
.action_list
van-button(type='default' size="small" v-if='it.buttons.cancel.is_able == 1' @click='cancelTask(it.base_info.id)') {{it.buttons.cancel.title}}
van-button(type='default' size="small" color='#07c160' v-if='it.buttons.comment.is_able == 1') {{it.buttons.comment.title}}
van-button(type='danger' size="small" v-if='it.buttons.detail.is_able == 1' :to='`/taskInfo?id=${it.base_info.id}`') {{it.buttons.detail.title}}
.line(v-if="item.content.length > 0")
</template>
<script lang="ts">
import {Component, Provide, Inject, Vue} from 'vue-property-decorator';
import NavbarComponent from "@/components/Navbar.vue";
import CustomTabsComponent from "@/components/CustomTabs.vue";
import Icons from '@/components/Icons.vue';
import CountDown from '@/components/CountDown.vue'
@Component({
components: {
NavbarComponent,
CustomTabsComponent,
Icons,
CountDown
}
})
export default class Task extends Vue {
@Inject() readonly ShowTabBar!: Function;
private $utils: any;
private $http: any;
// 激活的下标
private active: number = 0;
private SearchKey: String = "";
// 从地址参数中获取的step用于请求对应数据
private step: string = '';
private TabsList: any[] = [];
private created(): void {
this.ShowTabBar();
if(this.$route.query.index !== void 0){
this.active = parseInt(this.$route.query.index as string)
this.step = this.$route.query.step as string
}
this.getTaskList();
}
private beforeUpdate(): void {
this.$nextTick(function () {
let all = document.querySelectorAll(".van-tab__pane");
all.forEach((val) => (val as any).style.height = `${document.body.clientHeight - 46 - 45.97 - 49.98}px`);
})
}
// 分页
private async onLoad(): Promise<void> {
this.TabsList[this.active].page = this.TabsList[this.active].page + 1;
this.getTaskList()
}
// 获取任务列表
private async getTaskList(): Promise<void> {
// 第一次请求默认第一页数据
let data:Object = { page: 1 };
// 第一次请求判断数组是否有active没有不携带step参数
// 如果有,携带 key作为step的数值并且使用数据中的 page字段来继续分页请求数据
if(this.TabsList[this.active]){
Object.assign(data,{step: this.TabsList[this.active].key, page: this.TabsList[this.active].page})
}
// 如果从其他页面带过来step 则请求时加上
if(this.step !== ''){ Object.assign(data,{step: this.step})}
let res = await this.$http.TaskService.getTaskList({...data});
if (this.TabsList.length != 0) {
this.TabsList[this.active].loading = false;
} else {
let task_stat = res.task_stat;
let k;
// 清空防止数据叠加
this.TabsList = [];
for( k in task_stat) {
this.TabsList.push({
title: task_stat[k].title,
count: task_stat[k].count,
key: k,
page: 1,
loading: false,
finished: false,
content: []
})
}
}
if (res.task_list.length == 0) {
this.TabsList[this.active].finished = true;
} else {
this.TabsList[this.active].content = [...this.TabsList[this.active].content, ...res.task_list];
}
}
private onClick(index: number): void {
this.active = index;
this.TabsList[this.active].content = []
this.TabsList[this.active].page = 1;
this.$router.push({
name: 'task',
query: { index: String(index), step: this.TabsList[index].key }
});
this.getTaskList()
}
// 取消任务
private async cancelTask(id: string): Promise<void> {
let res = await this.$http.TaskService.cancelTask(id)
console.log(res);
}
beforeRouteLeave (to: any, from: any, next: any) {
this.ShowTabBar();
next()
}
}
</script>
<style scoped lang="stylus">
@import "~@assets/stylus/page/task"
.tab_title
position relative
.triangle
position absolute
right 0rem
top 0rem
font-size 0.24rem
background-color red
height 0.5rem
width 0.5rem
line-height 0.5rem
border-radius 50%
color #fff !important
text-align center
.tabs_items
width 100%
padding 0.373rem 0.476rem
background #fff
box-sizing border-box
.item_text
padding-bottom 0.28rem
border-bottom 0.02667rem solid #ebedf0
margin-bottom 0.28rem
.t
font-size 0.36rem
color #999
display flex
justify-content space-between
.text_1
margin-top 0.4rem
margin-bottom 0.253rem
.fuzhi
margin-left 0.2rem
.item_action
display flex
justify-content space-between
align-items center
button
margin-right 0.133rem
&:last-child
margin-right 0
</style>

View File

@@ -0,0 +1,136 @@
<template lang="pug">
.Index
NavbarComponent(title='首页')
.content
.pt20
.flex.pd43
.flex1.mr10
.capital.flex_cen
div
.p1 本周奖励
.p2 {{indexData.refer_amount || 0}}
router-link(to='/extension')
span(style='color:#ff5858') 立即推广
van-icon(name="arrow")
.text.mt25 客服QQ: {{indexData.qq_service || '*********'}}
.flex1.ml10
.capital.flex_cen
div
.p1 本周佣金
.p2 {{indexData.commission || 0}}
router-link(to='/fund')
span(style='color:#20c6c2') 资金管理
van-icon(name="arrow")
.text.mt25 工作时间: {{indexData.qq_work_time}}
.line.mt25
.pd43
.task_num.flex.mt40
.flex1.flex_cen
.task_num_li
span {{indexData.accept_task_num||0}}/{{indexData.total_task_num||0}}
p 淘宝任务
router-link.flex1.flex_cen(to='/realName')
.task_num_li
span {{indexData.auth_text||'加载中'}}
p 实名认证
router-link.flex1.flex_cen(to='/authentication')
.task_num_li
span {{indexData.account_num||0}}/{{indexData.total_account_num||0}}
p 绑定买号
.mt.pd43
router-link(to='/taskHall')
.receipt 开始接单
.line.mt36
.advertisement.mt25.pd43
van-swipe( :autoplay="3000" indicator-color="white")
van-swipe-item(v-for='(item, index) in indexData.rotation_pic' :key='index')
img( :src='item.upload.path')
.pd43
.notice
van-tabs(v-model="NoticeActive" @click="NoticeClick" line-height='0' title-active-color='#ffffff')
van-tab(:title="item.title"
v-for="(item,index) in NoticeTabBar"
:key="index")
.news()
.news_cen
router-link(v-for="(li,index) in item.content" :key="index" :to="`/noticeInfo?id=${li.id}`")
p {{li.title}}
//- van-tag.ml20(type="danger" size="medium" v-if="index === 0") 标签
//- .news_end
//- span 查看更多
</template>
<script lang="ts">
import { Component, Provide, Vue, Inject, Watch } from "vue-property-decorator";
import TestComponent from "@/components/test.vue";
import NavbarComponent from "@/components/Navbar.vue";
@Component({
components: {
TestComponent,
NavbarComponent
}
})
export default class Index extends Vue {
@Inject() readonly ShowTabBar!: Function;
private $http: any;
private NoticeActive: number = 0;
private NoticeTabBar: {
type: number;
title: string;
content: Array<any>;
}[] = [
// { type: 1, title: '商家公告', content: [] },
{ type: 2, title: "买家公告", content: [] },
{ type: 3, title: "平台公告", content: [] },
{ type: 4, title: "任务须知", content: [] },
{ type: 5, title: "推广说明", content: [] },
{ type: 6, title: "其他", content: [] }
];
// 首页数据
private indexData: any = {
rotation_pic: []
};
private NoticeConfig: { [key: string]: number } = {
limit: 1,
page: 1
};
public async NoticeClick(): Promise<any> {
this.NoticeConfig.type = this.NoticeTabBar[this.NoticeActive].type;
let data = await this.$http.NewsService.announceList(this.NoticeConfig);
this.NoticeTabBar[this.NoticeActive].content = data;
}
private async getIndex(): Promise<void> {
let res = await this.$http.HomeService.getIndex();
this.indexData = res;
}
async created() {
this.ShowTabBar();
this.NoticeClick();
this.getIndex();
}
beforeRouteLeave(to: any, from: any, next: any) {
this.ShowTabBar();
next();
}
}
</script>
<style scoped lang="stylus">
@import '~@assets/stylus/page/index';
</style>
<style lang="stylus">
.Index {
.van-tab--active {
background: #20c6c2;
}
}
</style>

View File

@@ -0,0 +1,34 @@
<template lang="pug">
//- 项目tabbar页展示
.Subject
//- keep-alive
router-view
</template>
<script lang="ts">
import {Component, Provide, Vue, Watch} from 'vue-property-decorator';
@Component({
components: {
}
})
export default class Subject extends Vue {
created() {
console.log(this.$route.meta.title);
}
@Watch('$route')
private watchRoute(to: any, from: any) {
// 实现keep-alive缓存时 重复点击tabbar使页面刷新
// 暂时未做此功能,此功能待定,因为个人信息变动时
// 页面数据也需要刷新
to.meta.alive = true
from.meta.alive = false
}
}
</script>
<style lang="stylus">
</style>

17
滴滴淘/h5(1)/src/view/shims-tsx.d.ts vendored Normal file
View File

@@ -0,0 +1,17 @@
import Vue, {VNode} from 'vue';
declare global {
namespace JSX {
// tslint:disable no-empty-interface
interface Element extends VNode {
}
// tslint:disable no-empty-interface
interface ElementClass extends Vue {
}
interface IntrinsicElements {
[elem: string]: any
}
}
}

View File

@@ -0,0 +1,5 @@
declare module '*.vue' {
import Vue from 'vue';
export default Vue;
}