Authored by 王水玲

微信群控制

... ... @@ -6,6 +6,7 @@ module.exports = yo(yoBase)
port: 8001,
host: '0.0.0.0',
hot: true,
disableHostCheck: true,
proxy: {
'/api': 'http://localhost:8887'
}
... ...
... ... @@ -5,6 +5,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title></title>
<script>
(function(d,c){var e=d.documentElement,a="orientationchange" in window?"orientationchange":"resize",b=function(){var f=e.clientWidth;if(!f){return}if(f>=750){e.style.fontSize="40px"}else{e.style.fontSize=40*(f/750)+"px"}};if(!d.addEventListener){return}b();c.addEventListener(a,b,false);d.addEventListener("DOMContentLoaded",b,false)})(document,window);
</script>
</head>
<body>
<div id="app">
... ...
This diff could not be displayed because it is too large.
... ... @@ -54,6 +54,7 @@
"babel-eslint": "^8.2.6",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-preset-es2015": "^6.24.1",
"clipboard": "^2.0.1",
"eslint": "^5.1.0",
"eslint-config-standard": "^11.0.0",
"eslint-config-yoho": "^1.1.0",
... ...
... ... @@ -31,7 +31,7 @@ const request = async(options) => {
}
};
export default {
module.exports = {
async get(url, params, options) {
return await request(Object.assign({
url,
... ...
let api = require('../common/create-api');
module.exports = {
queryHelper(param) {
return api.get('helper/queryHelper', param, {
defaults: {
baseURL: 'imApi'
}
});
},
queryAllCommonPhrase(param) {
return api.get('commonphrase/queryAllCommonPhrase', param, {
defaults: {
baseURL: 'imApi'
}
});
},
queryAllCommonLink(param) {
return api.get('/commonlink/queryAllCommonLink', param, {
defaults: {
baseURL: 'imApi'
}
});
}
}
... ...
<template>
<div class="coupon-container">
<NavTitle :more="more">
<template slot="title">最近10张优惠券</template>
</NavTitle>
</div>
</template>
<script>
import NavTitle from './nav-title';
import homeModel from '../../../models/home';
export default {
name: 'coupon',
data() {
return {
more: 'http://www.baidu.com'
};
},
mounted() {
},
methods: {
},
components: {
NavTitle
}
}
</script>
<style lang="scss" scoped>
.exchange-container {
.original-order-code {
float: left;
}
.order-code {
float: right;
}
.lg {
float: left;
}
.goods-info {
height: 66px;
display: flex;
img {
width: 56px;
height: 66px;
}
.right {
flex: 1;
margin-left: 10px;
}
.goods-name {
word-break: break-all;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.number {
span {
width: 50%;
text-align: left;
float: left;
}
}
.remark {
width: 100%;
}
}
.user-info {
height: auto;
overflow: hidden;
span {
width: 50%;
float: left;
line-height: 30px;
}
.address {
width: 100%;
}
}
}
</style>
... ...
<template>
<div class="exchange-container">
<Tabs :tabs="tabs" @change-tabs="changeTabs"></Tabs>
<NavTitle :more="more">
<template slot="title">{{getTitleCont}}</template>
</NavTitle>
<Modal>
<template slot="label">
<div class="original-order-code" v-if="curTabs === '换货'">原订单号:<span class="red">2222</span></div>
<div class="order-code" :class="{lg: curTabs === '退货'}">订单号:<span class="red">11111</span></div>
</template>
<template slot="cont">
<div class="order-cont" >
<div class="goods-info">
<img src="//img11.static.yhbimg.com/goodsimg/2018/10/22/18/012502918a8149f76a74ebcab5971437c6.jpg?imageMogr2/thumbnail/750x750/background/d2hpdGU=/position/center/quality/80">
<div class="right">
<div class="goods-name">AIR JORDAN 1 x OFF-WHITE CHICAGO THE TEN 芝加哥</div>
<div class="number">
<span class="skn">SKN:</span>
<span class="sku">SKU:</span>
</div>
<div class="remark">备注:</div>
</div>
</div>
<div class="user-info">
<span>收货人:</span>
<span>手机号:</span>
<span v-if="curTabs === '退货'">退款金额:</span>
<span v-if="curTabs === '退货'">退款方式:</span>
<span>申请类型:</span>
<span>申请人:</span>
<span>当前状态:</span>
<span class="address">地址:</span>
</div>
</div>
</template>
</Modal>
</div>
</template>
<script>
import Tabs from './tabs';
import Modal from './modal';
import NavTitle from './nav-title';
import homeModel from '../../../models/home';
export default {
name: 'exchange',
data() {
return {
tabs: ['换货', '退货'],
curTabs: '换货',
more: 'http://www.baidu.com'
};
},
mounted() {
},
computed: {
getTitleCont() {
return this.curTabs === '换货' ? '最近10笔换货订单' : '最近10笔退货订单';
}
},
methods: {
changeTabs(item) {
this.curTabs = item;
}
},
components: {
Tabs,
Modal,
NavTitle
}
}
</script>
<style lang="scss" scoped>
.exchange-container {
.original-order-code {
float: left;
}
.order-code {
float: right;
}
.lg {
float: left;
}
.goods-info {
height: 66px;
display: flex;
img {
width: 56px;
height: 66px;
}
.right {
flex: 1;
margin-left: 10px;
}
.goods-name {
word-break: break-all;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
.number {
span {
width: 50%;
text-align: left;
float: left;
}
}
.remark {
width: 100%;
}
}
.user-info {
height: auto;
overflow: hidden;
span {
width: 50%;
float: left;
line-height: 30px;
}
.address {
width: 100%;
}
}
}
</style>
... ...
<template>
<div class="knowledge-container">
<Tabs :tabs="tabs" @change-tabs="changeTabs"></Tabs>
<div class="knowledge-search">
<input value="" class="search-key" @input="changeSearchKey"/>
<div class="search-btn" @click="getListData"><span class="search-icon"></span></div>
</div>
<div class="problem" v-if="curTabs === '问题库'">
<Modal v-for="(item, index) in problemList" :key="index"></Modal>
</div>
<div class="phrase" v-if="curTabs === '常用语'">
<Modal v-for="(item, index) in phraseList" :key="index"></Modal>
</div>
<div class="link" v-if="curTabs === '常用链接'">
<Modal v-for="(item, index) in linkList" :key="index"></Modal>
</div>
</div>
</template>
<script>
import Tabs from './tabs';
import Modal from './modal';
import homeModel from '../../../models/home';
export default {
name: 'knowledge',
data() {
return {
tabs: ['问题库', '常用语', '常用链接'],
searchKey: '',
curTabs: '',
problemList: [],
phraseList: [],
linkList: []
};
},
mounted() {
},
methods: {
getListData() {
homeModel.queryHelper({
keyword: this.searchKey
}).then(ret => {
console.log(ret)
});
},
getPhraseData() {
console.log('getPhraseData')
homeModel.queryAllCommonPhrase().then(ret => {
console.log(ret)
});
},
getLinkData() {
console.log('queryAllCommonLink')
homeModel.queryAllCommonLink().then(ret => {
console.log(ret)
});
},
changeSearchKey(e) {
this.searchKey = e.target.value;
this.getListData();
},
changeTabs(item) {
this.curTabs = item;
switch(item) {
case '常用语':
if (this.phraseList.length === 0) {
this.getPhraseData();
}
break;
case '常用链接':
if (this.linkList.length === 0) {
this.getLinkData();
}
break;
default:
break;
}
}
},
components: {
Tabs,
Modal
}
}
</script>
<style lang="scss" scoped>
.knowledge-search {
width: 90%;
border: 1px solid #3a3a3a;
height: 24px;
margin: 20px auto 0;
display: flex;
input {
height: 24px;
padding: 0 5px;
box-sizing: border-box;
flex: 1;
outline: none;
}
.search-btn {
background: #3a3a3a;
width: 72px;
display: flex;
align-items: center;
justify-content: center;
}
.search-icon {
width: 20px;
height: 20px;
background: url(../../../static/images/search.png) no-repeat;
background-size: contain;
display: inline-block;
}
}
</style>
... ...
<template>
<div class="modal">
<div class="label">
<slot name="label"></slot>
</div>
<div class="cont">
<slot name="cont"></slot>
</div>
</div>
</template>
<script>
export default {
name: 'modal'
}
</script>
<style lang="scss" scoped>
.modal {
width: 90%;
margin: 20px auto 0;
.label {
background: #e0e0e0;
border-radius: 5px 5px 0 0;
height: 30px;
line-height: 30px;
padding: 0 20px;
}
.cont {
background: #eee;
padding: 10px 20px;
}
}
</style>
... ...
<template>
<div class="title-container">
<span class="title">
<slot name="title"></slot>
</span>
<a :href="more" class="more" v-if="more != ''">MORE></a>
</div>
</template>
<script>
export default {
name: 'nav-title',
props: {
more: {
type: String,
default: ''
}
}
}
</script>
<style lang="scss" scoped>
.title-container {
width: 90%;
text-align: center;
position: relative;
margin: 15px auto 0;
.title {
border: 1px solid #ddd;
padding: 3px 20px;
}
.more {
position: absolute;
right: 0;
}
}
</style>
... ...
<template>
<div class="order-list-container">
<NavTitle :more="more">
<template slot="title">最近10笔订单</template>
</NavTitle>
<Modal>
<template slot="label">
<div class="time">2018-10-31 16:51:22</div>
<div class="order-code">订单号:<span class="red">11111</span></div>
</template>
<template slot="cont">
<div class="order-cont" >
<div class="goods-info">
<img src="//img11.static.yhbimg.com/goodsimg/2018/10/22/18/012502918a8149f76a74ebcab5971437c6.jpg?imageMogr2/thumbnail/750x750/background/d2hpdGU=/position/center/quality/80">
<div class="right">
<div class="goods-name">AIR JORDAN 1 x OFF-WHITE CHICAGO THE TEN 芝加哥</div>
<div class="number">
<span class="goods-price red">¥859</span>
<span class="goods-num">数量:1</span>
</div>
</div>
</div>
<div class="order-info">
<div class="order-price">订单金额:</div>
<div class="order-dec">
<div>订单状态:</div>
<div>订单来源:</div>
</div>
</div>
</div>
</template>
</Modal>
</div>
</template>
<script>
import Modal from './modal';
import NavTitle from './nav-title';
import homeModel from '../../../models/home';
export default {
name: 'order-list',
data() {
return {
more: 'http://www.baidu.com'
};
},
mounted() {
},
methods: {
},
components: {
Modal,
NavTitle
}
}
</script>
<style lang="scss" scoped>
.order-list-container {
.time {
float: left;
}
.order-code {
float: right;
}
.goods-info {
height: 66px;
display: flex;
img {
width: 56px;
height: 66px;
}
.right {
flex: 1;
margin-left: 10px;
}
.goods-name {
word-break: break-all;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
}
.order-info {
border-top: 1px solid #ddd;
margin-top: 10px;
padding-top: 10px;
}
.order-dec {
display: flex;
justify-content: space-between;
}
}
</style>
... ...
<template>
<div class="tabs">
<div
v-for="(item, index) in tabs"
:key="index"
class="tabs-item"
:class="{start: index === 0, end: index === tabs.length - 1, actived: item === curTabs}"
@click="changeTabs(item)">{{item}}</div>
</div>
</template>
<script>
export default {
name: 'Knowledge',
props: {
tabs: {
type: Array,
default: []
}
},
data() {
return {
curTabs: ''
};
},
created() {
if (this.tabs.length > 0) {
this.curTabs = this.tabs[0];
}
},
methods: {
changeTabs(item) {
this.curTabs = item;
this.$emit('change-tabs', item)
}
}
}
</script>
<style lang="scss" scoped>
.tabs {
display: flex;
margin: 20px auto 0;
width: 80%;
.tabs-item {
border-top: 1px solid #3a3a3a;
border-bottom: 1px solid #3a3a3a;
height: 26px;
line-height: 26px;
text-align: center;
flex: 1;
border-right: 1px solid #3a3a3a;
&:last-child {
border-right: none;
}
&.actived {
background: #3a3a3a;
color: #fff;
}
&.start {
border-left: 1px solid #3a3a3a;
border-radius: 5px 0 0 5px;
}
&.end {
border-right: 1px solid #3a3a3a;
border-radius: 0 5px 5px 0;
}
}
}
</style>
... ...
<template>
<div class="user-info-container">
<div class="notes">
<h5>用户备忘录</h5>
<textarea name="" id="" rows="5"></textarea>
<div class="update-note-btn">更新备忘录</div>
</div>
<div class="bind-user">
<h5>绑定用户</h5>
<div>用户微信号:</div>
<div class="search">
<input type="text" value="" placeholder="用户UID查询(请输入有货手机号/订单编号)">
<span class="search-btn"></span>
</div>
<div>用户UID:</div>
<textarea name="" id="" rows="6" placeholder="备注(非必填)"></textarea>
<div class="update-note-btn">绑定用户</div>
</div>
</div>
</template>
<script>
import homeModel from '../../../models/home';
export default {
name: 'user-info',
data() {
return {
};
},
mounted() {
},
methods: {
},
components: {
}
}
</script>
<style lang="scss" scoped>
.user-info-container {
.notes {
width: 90%;
margin: 10px auto 0;
background: #eee;
border-radius: 5px;
padding: 10px;
box-sizing: border-box;
h5 {
text-align: center;
padding: 0;
margin: 0;
}
textarea {
width: 100%;
margin: 10px 0 0;
box-sizing: border-box;
resize: none;
}
.update-note-btn {
width: 100%;
background: #000;
color: #fff;
text-align: center;
line-height: 24px;
border-radius: 5px;
margin-top: 10px;
}
}
.bind-user {
width: 90%;
margin: 10px auto 0;
background: #eee;
border-radius: 5px;
padding: 10px;
box-sizing: border-box;
h5 {
text-align: center;
padding: 0;
margin: 0;
}
.search {
width: 100%;
background: #fff;
margin: 10px 0;
}
textarea {
width: 100%;
margin: 10px 0 0;
resize: none;
}
.update-note-btn {
width: 100%;
background: #000;
color: #fff;
text-align: center;
line-height: 24px;
border-radius: 5px;
margin-top: 10px;
}
}
}
</style>
... ...
<template>
<div class="home-page">
<div>
<p class="home-title">
Home
</p>
</div>
</div>
<div class="home-page">
<div class="base-info">
<h5>顾问基本信息</h5>
<ul class="info-list">
<li><span class="lable">微信号:</span></li>
<li><span class="lable">微信昵称:</span></li>
<li><span class="lable">微信手机号:</span></li>
<li><span class="lable">机器码:</span></li>
<li><span class="lable">有货账号:</span></li>
<li><span class="lable">有货UID:</span></li>
<li><span class="lable">所属分组:</span></li>
<li><span class="lable">运营人员:</span></li>
</ul>
<button class="copy-link-btn">复制活动链接</button>
</div>
<div class="home-menu">
<span
v-for="(item, index) in homeMenu"
:key="index" class="menu-item"
:class="{actived: item.text === curMenu}"
@click="changeMenu(item.text)">{{item.text}}</span>
</div>
<Knowledge v-if="curMenu === '知识库'"></Knowledge>
<OrderList v-if="curMenu === '订单信息'"></OrderList>
<Exchange v-if="curMenu === '退换货'"></Exchange>
<Coupon v-if="curMenu === '优惠券'"></Coupon>
<UserInfo v-if="curMenu === '用户信息'"></UserInfo>
</div>
</template>
<script>
import Knowledge from './components/knowledge';
import OrderList from './components/orderList';
import Exchange from './components/exchange';
import Coupon from './components/coupon';
import UserInfo from './components/user-info';
export default {
name: 'Home'
name: 'Home',
data() {
return {
homeMenu: [
{text: '用户信息'},
{text: '订单信息'},
{text: '退换货'},
{text: '优惠券'},
{text: '知识库'}
],
curMenu: '用户信息'
};
},
methods: {
changeMenu(item) {
this.curMenu = item;
}
},
components: {
Knowledge,
OrderList,
Exchange,
Coupon,
UserInfo
}
};
</script>
<style lang="scss">
html, body {
width: 100%;
margin: 0;
padding: 0;
font-size: 12px;
max-width: 750px;
margin: 0 auto;
}
a {
color: #000;
text-decoration: none;
}
ul, li {
list-style: none;
margin: 0;
padding: 0;
}
.red {
color: #d8021a;
}
.base-info {
width: 90%;
background: #efefef;
border-radius: 5px;
margin: 20px auto 0;
padding: 10px;
box-sizing: border-box;
h5 {
text-align: center;
padding: 0;
margin: 0;
}
.copy-link-btn {
width: 100%;
margin: 0 auto;
background: #000;
color: #fff;
text-align: center;
border: none;
outline: none;
margin: 0 auto;
display: block;
height: 24px;
line-height: 24px;
border-radius: 5px;
}
.info-list {
li {
width: 50%;
float: left;
height: 24px;
line-height: 24px;
}
}
}
.home-menu {
display: flex;
justify-content: space-evenly;
margin-top: 20px;
.menu-item {
background: #efefef;
padding: 5px;
border-radius: 5px;
&.actived {
background: #d8021a;
color: #fff;
}
}
}
</style>
... ...
... ... @@ -1916,6 +1916,14 @@ cli-width@^2.0.0:
version "2.2.0"
resolved "http://npm.yohops.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639"
clipboard@^2.0.1:
version "2.0.1"
resolved "http://npm.yohops.com/clipboard/-/clipboard-2.0.1.tgz#a12481e1c13d8a50f5f036b0560fe5d16d74e46a"
dependencies:
good-listener "^1.2.2"
select "^1.1.2"
tiny-emitter "^2.0.0"
cliui@^3.0.3, cliui@^3.2.0:
version "3.2.0"
resolved "http://npm.yohops.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d"
... ... @@ -2730,6 +2738,10 @@ delayed-stream@~1.0.0:
version "1.0.0"
resolved "http://npm.yohops.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
delegate@^3.1.2:
version "3.2.0"
resolved "http://npm.yohops.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
delegates@^1.0.0:
version "1.0.0"
resolved "http://npm.yohops.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
... ... @@ -4057,6 +4069,12 @@ gonzales-pe@^4.0.3, gonzales-pe@^4.2.3:
dependencies:
minimist "1.1.x"
good-listener@^1.2.2:
version "1.2.2"
resolved "http://npm.yohops.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
dependencies:
delegate "^3.1.2"
graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6:
version "4.1.11"
resolved "http://npm.yohops.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
... ... @@ -7940,6 +7958,10 @@ select-hose@^2.0.0:
version "2.0.0"
resolved "http://npm.yohops.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
select@^1.1.2:
version "1.1.2"
resolved "http://npm.yohops.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
selfsigned@^1.9.1:
version "1.10.4"
resolved "http://npm.yohops.com/selfsigned/-/selfsigned-1.10.4.tgz#cdd7eccfca4ed7635d47a08bf2d5d3074092e2cd"
... ... @@ -8828,6 +8850,10 @@ timsort@^0.3.0:
version "0.3.0"
resolved "http://npm.yohops.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
tiny-emitter@^2.0.0:
version "2.0.2"
resolved "http://npm.yohops.com/tiny-emitter/-/tiny-emitter-2.0.2.tgz#82d27468aca5ade8e5fd1e6d22b57dd43ebdfb7c"
tmp@^0.0.33:
version "0.0.33"
resolved "http://npm.yohops.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9"
... ... @@ -9299,7 +9325,7 @@ vue-style-loader@^4.1.0:
hash-sum "^1.0.2"
loader-utils "^1.0.2"
vue-template-compiler@^2.5.16, vue-template-compiler@^2.5.17:
vue-template-compiler@^2.5.17:
version "2.5.17"
resolved "http://npm.yohops.com/vue-template-compiler/-/vue-template-compiler-2.5.17.tgz#52a4a078c327deb937482a509ae85c06f346c3cb"
dependencies:
... ...