hookehuyr

更新配置

Showing 110 changed files with 1202 additions and 10553 deletions
......@@ -12,11 +12,10 @@ module.exports = {
moment: true,
_: true
},
extends: [
'extends': [
'plugin:vue/essential',
'@vue/standard'
],
// extends: 'standard',
rules: {
// allow paren-less arrow functions
'arrow-parens': 0,
......@@ -37,13 +36,10 @@ module.exports = {
'camelcase': 0,
'eqeqeq': 0,
'no-undef': 0,
'no-self-assign': 0,
'no-console': ['error', { allow: ['warn', 'error'] }]
},
parserOptions: {
parser: 'babel-eslint'
},
plugins: ['html', 'vue'],
settings: {
'html/html-extensions': ['.html']
}
};
}
......
# test1
# vant-test
## Project setup
```
......
This diff could not be displayed because it is too large.
{
"name": "test1",
"name": "vant-test",
"version": "0.1.0",
"private": true,
"scripts": {
......@@ -12,32 +12,24 @@
"fastclick": "^1.0.6",
"jquery": "^3.3.1",
"lodash": "^4.17.11",
"register-service-worker": "^1.5.2",
"moment": "^2.23.0",
"vant": "^1.5.2",
"vue": "^2.5.21",
"vue-core-image-upload": "^2.4.11",
"vue-pull-to": "^0.1.6",
"vue-router": "^3.0.1",
"vuex": "^3.0.1",
"vuex-router-sync": "^5.0.0",
"vux": "^2.9.2"
"vuex-router-sync": "^5.0.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "^3.3.0",
"@vue/cli-plugin-eslint": "^3.3.0",
"@vue/cli-plugin-pwa": "^3.3.0",
"@vue/cli-service": "^3.3.0",
"@vue/eslint-config-standard": "^4.0.0",
"babel-eslint": "^10.0.1",
"compression-webpack-plugin": "^2.0.0",
"eslint": "^5.8.0",
"eslint-plugin-html": "^5.0.0",
"eslint-plugin-vue": "^5.0.0",
"less": "^3.0.4",
"less": "^3.9.0",
"less-loader": "^4.1.0",
"lint-staged": "^8.1.0",
"vue-loader": "^14.2.2",
"vue-template-compiler": "^2.5.21",
"vux-loader": "^1.2.9",
"webpack-merge": "^4.2.1",
"yaml-loader": "^0.5.0"
"vue-template-compiler": "^2.5.21"
}
}
......
......@@ -3,15 +3,31 @@
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=0">
<meta name="apple-mobile-web-app-capable" content="yes">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<!-- 使用CDN加速的CSS文件,配置在vue.config.js下 -->
<% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style">
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet">
<% } %>
<!-- 使用CDN加速的JS文件,配置在vue.config.js下 -->
<% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="preload" as="script">
<% } %>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but test1 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
<strong>We're sorry but vant-test doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- 使用CDN加速的JS文件,配置在vue.config.js下 -->
<% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %>
<!-- built files will be auto injected -->
</body>
</html>
......
......@@ -5,6 +5,16 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<!-- 使用CDN加速的CSS文件,配置在vue.config.js下 -->
<% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.css) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="preload" as="style">
<link href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" rel="stylesheet">
<% } %>
<!-- 使用CDN加速的JS文件,配置在vue.config.js下 -->
<% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
<link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="preload" as="script">
<% } %>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
......@@ -12,6 +22,10 @@
<strong>We're sorry but test1 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="login"></div>
<!-- 使用CDN加速的JS文件,配置在vue.config.js下 -->
<% for (var i in htmlWebpackPlugin.options.cdn&&htmlWebpackPlugin.options.cdn.js) { %>
<script src="<%= htmlWebpackPlugin.options.cdn.js[i] %>"></script>
<% } %>
<!-- built files will be auto injected -->
</body>
</html>
......
......@@ -4,11 +4,11 @@
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
<router-view></router-view>
<router-view/>
</div>
</template>
<style lang="less">
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
......@@ -18,12 +18,14 @@
}
#nav {
padding: 30px;
a {
font-weight: bold;
color: #2c3e50;
&.router-link-exact-active {
color: #42b983;
}
}
}
#nav a {
font-weight: bold;
color: #2c3e50;
}
#nav a.router-link-exact-active {
color: #42b983;
}
</style>
......
......@@ -40,7 +40,7 @@ export default {
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped lang="less">
<style scoped>
h3 {
margin: 40px 0 0;
}
......
<template lang="html">
<div v-transfer-dom>
<x-dialog v-model="tmp_show" class="material_dialog" :hide-on-blur="false">
<div class="dialogTitle">录入新/原物料</div>
<div class="material_info">
<ul>
<li>
<label for="">
<span style="margin-top: 0.2rem;">物料类别<em class="red">*</em></span>
</label>
<div class="el-form-item_content">
<!-- <el-select style="width: 100%;" ref="select1" v-model="form.class_id" placeholder="请选择" @blur="blurs('select1')">
<el-option
v-for="item in classList"
:key="item.class_id"
:label="item.name"
:value="item.class_id">
</el-option>
</el-select> -->
<selector placeholder="请选择" v-model="form.class_id" :options="classList" @on-change="changeScroll"></selector>
</div>
</li>
<li>
<label for="">
<span>物料编号<em class="red">*</em></span>
</label>
<div class="el-form-item_content">
<el-input v-model="form.code" placeholder="请输入物料编号"></el-input>
</div>
</li>
<li>
<label for="">
<span>物料名称<em class="red">*</em></span>
</label>
<div class="el-form-item_content">
<el-input v-model="form.name" placeholder="请输入物料名称"></el-input>
</div>
</li>
<li>
<label for="">
<span>适用的品牌<em class="red">*</em></span>
</label>
<div class="el-form-item_content p-right">
<p @click="getBrandList">{{brand_text}}<i class="el-icon-arrow-right"></i></p>
</div>
</li>
<li class="twoLabel">
<label for="">
<span style="font-size: 0.9rem; margin-top: 0.3rem;">订货单位<em class="red">*</em></span>
<div style="width: 5rem;" class="el-form-item">
<selector @on-change="changeScroll" placeholder="请选择" v-model="form.order_unit_name" :options="order_unit_list"></selector>
</div>
</label>
<label>
<span style="font-size: 0.9rem; margin-top: 0.3rem;">盘点单位<em class="red">*</em></span>
<div style="width: 5rem;" class="el-form-item">
<selector @on-change="changeScroll" placeholder="请选择" v-model="form.unit_name" :options="unit_list"></selector>
</div>
</label>
</li>
<li v-if="form.order_unit_name && form.unit_name">
<label>
<span></span>
</label>
<div>
<p>1{{getOrderUnitName(form.order_unit_name)}} = <x-input style="width: 60px;" v-model="form.order_unit_qty" placeholder="请输入"></x-input> {{getUnitName(form.unit_name)}}<em class="red">*</em></p>
</div>
</li>
<li class="twoLabel" v-if="form.order_unit_name && form.unit_name">
<label for="">
<span style="font-size: 0.8rem; margin-top: 0.3rem;">BOM单位<em class="red">*</em></span>
<div class="el-form-item">
<selector placeholder="请选择" v-model="form.bom_unit_name" :options="bom_unit_list" @on-change="bomUnitChange"></selector>
</div>
</label>
<label>
<div class="el-form-item">
<div>1{{getUnitName(form.unit_name)}} = <x-input style="width: 70px;" v-model="form.bom_unit_qty" placeholder="请输入"></x-input> {{bom_unit_name_value}}<em class="red">*</em></div>
</div>
</label>
</li>
</ul>
</div>
<div class="btn" style="padding: 10px;">
<flexbox>
<flexbox-item>
<x-button class="close-btn" @click.native="closeMetrial">取消</x-button>
</flexbox-item>
<flexbox-item>
<x-button class="comfirm-btn" @click.native="addMetrial">完成</x-button>
</flexbox-item>
</flexbox>
</div>
</x-dialog>
<add-select-brand :show="brand_show" :name="'品牌'" :list="brand_list" :checked_list="checked_list" :span="span" @cancel="cancel" @comfirm="comfirm"></add-select-brand>
</div>
</template>
<script>
import { Flexbox, FlexboxItem, XDialog, TransferDomDirective as TransferDom, Badge, XButton, Selector, XInput } from 'vux'
import addSelectBrand from 'components/addSelectBrand/index'
export default {
directives: { TransferDom },
components: { Flexbox, FlexboxItem, XDialog, addSelectBrand, Badge, XButton, Selector, XInput },
props: ['show_dialog', 'add_class_list', 'add_brand_list', 'add_checked_list', 'add_order_unit_list', 'add_units_list', 'add_bom_unit_list'],
data () {
return {
pShow: true,
titleText: '新物料匹配供应商',
leftText: '匹配供应商',
rightText: '完成',
scroller_height: '',
list: [],
form: {
class_id: '',
brand_ids: this.$route.params.checked_list,
code: '',
name: '',
order_unit_name: '',
unit_name: '',
order_unit_qty: '',
bom_unit_name: '',
bom_unit_qty: ''
},
brand_text: '已选全部品牌',
brand_show: false,
span: 3,
checked_list: this.add_checked_list,
classList: this.add_class_list,
brand_list: this.add_brand_list,
order_unit_list: this.add_order_unit_list,
unit_list: this.add_units_list,
bom_unit_list: this.add_bom_unit_list,
tmp_show: false,
bom_unit_name_value: ''
}
},
created () {
this.getList();
},
mounted () {
this.scroller_height = ($('body').height() - 50) + 'px';
this.form = {
class_id: '',
brand_ids: this.$route.params.checked_list,
code: '',
name: '',
order_unit_name: '',
unit_name: '',
order_unit_qty: '',
bom_unit_name: '',
bom_unit_qty: ''
}
$('.vux-x-dialog.material_dialog').click(() => {
this.changeScroll()
})
},
watch: {
show_dialog (val, old) {
if (val !== old) {
this.tmp_show = val
}
}
},
methods: {
// 获取新物料列表
getList () {
axios.get('fi/sku/all?ctrl_status=XP_prov')
.then(res => {
if (res.data.ret === 'OK') {
for (let i = 0; i < res.data.content.length; i++) {
res.data.content[i].checked = false
if (res.data.content[i].XP_prov_status === 'DISABLE') {
res.data.content[i].disabled = true
} else {
res.data.content[i].disabled = false
}
}
this.list = res.data.content
} else {
this.list = []
}
})
},
// 选择品牌弹窗
getBrandList () {
this.brand_show = true
this.tmp_show = false
},
// 品牌弹窗组件关闭
cancel (v) {
this.brand_show = v;
this.tmp_show = true
},
// 品牌弹窗组件确定
comfirm (v) {
// console.warn(v);
this.brand_show = false
this.tmp_show = true
this.form.brand_ids = v
this.checked_list = v
if (v.length === 0) {
this.brand_text = '请选择品牌'
}
if (v.length > 0 && v.length !== this.brand_list.length) {
this.brand_text = '已选' + v.length + '种品牌'
}
if (v.length === this.brand_list.length) {
this.brand_text = '已选全部品牌'
}
},
// 匹配供应商
leftClick () {
let newList = _.filter(this.list, val => {
if (val.checked) {
return val
}
})
// console.warn(newList)
if (newList.length > 0) {
sessionStorage.setItem('newList', JSON.stringify(newList))
this.$router.push({path: '/matchingSuppliers'})
} else {
this.$vux.toast.text('请选择物料')
}
},
// 完成
rightClick () {
axios.get('fi/sku/noMatch?ctrl_status=XP_prov')
.then(res => {
if (res.data.ret === 'OK') {
console.warn(res.data.content.count)
let _this = this
if (res.data.content.count > 0) {
_this.$vux.confirm.show({
title: '温馨提示',
content: '<p style="text-align: left; padding: 1.5em 0 1em">还有' + res.data.content.count + '个新商品没有匹配供应商</p>',
confirmText: '继续设置',
cancelText: '否',
showCancelButton: false,
// onCancel () {
// _this.$vux.confirm.hide()
// },
onConfirm () {
_this.$vux.confirm.hide()
}
})
} else {
_this.$vux.confirm.show({
title: '温馨提示',
content: '<p style="text-align: left; padding: 1.5em 0 1em">您已完成所有新物料的供应商匹配,及门店采购价的设置工作,接下来需要设置新物料的门店盘点规则。</p>',
confirmText: '确定',
cancelText: '否',
showCancelButton: false,
// onCancel () {
// _this.$vux.confirm.hide()
// },
onConfirm () {
_this.$router.push({path: '/newInventoryRule'})
}
})
}
} else {
this.$vux.toast.text(res.data.msg)
}
})
},
// element下拉框失去焦点
blurs (val) {
// console.warn(this.$refs)
this.$refs[val].blur()
},
add () {
this.tmp_show = true
},
addMetrial (e) {
if (this.form.class_id === '') {
this.$vux.toast.text('请选择物料类别');
return false;
} else if (this.form.code === '') {
this.$vux.toast.text('请输入物料编号');
} else if (this.form.name === '') {
this.$vux.toast.text('请输入物料名称');
} else if (this.form.code === '') {
this.$vux.toast.text('请输入物料编号');
} else if (this.form.brand_ids.length === 0) {
this.$vux.toast.text('请选择品牌');
} else if (this.form.order_unit_name === '') {
this.$vux.toast.text('请选择门店订货单位');
} else if (this.form.unit_name === '') {
this.$vux.toast.text('请选择门店盘点单位');
} else if (this.form.order_unit_qty === '') {
this.$vux.toast.text('请输入单位换算量');
} else if (this.form.bom_unit_name === '') {
this.$vux.toast.text('请选择BOM单位');
} else if (this.form.bom_unit_qty === '') {
this.$vux.toast.text('请选择BOM单位数');
} else {
this.form.order_unit_name = this.getOrderUnitName(this.form.order_unit_name);
this.form.unit_name = this.getUnitName(this.form.unit_name);
this.form.bom_unit_name = this.bom_unit_name_value;
axios.post('fi/sku/add', this.form)
.then(res => {
if (res.data.ret === 'OK') {
this.$vux.toast.text(res.data.msg);
let brand_ids = _.map(this.brand_list, val => val.brand_id)
this.brand_text = '已选全部品牌'
this.form = {
class_id: '',
brand_ids: brand_ids,
code: '',
name: '',
order_unit_name: '',
unit_name: '',
order_unit_qty: '',
bom_unit_name: '',
bom_unit_qty: ''
}
this.getList()
this.tmp_show = false;
this.$emit('showDM', true);
} else {
this.$vux.toast.text(res.data.msg);
this.tmp_show = false;
this.$emit('showDM', true);
}
})
.catch(error => {
console.error(error);
this.tmp_show = false;
this.$emit('showDM', true);
})
}
// this.getList()
// this.tmp_show = false;
// this.$emit('showDM', true);
},
closeMetrial () {
this.tmp_show = false;
this.$emit('showDM', true);
},
getOrderUnitName (name) {
// 门店订货单位
let unit = _.filter(this.order_unit_list, v => {
if (v.key === name) {
return v.value
}
});
if (unit.length) {
return unit[0]['value']
}
},
getUnitName (name) {
// 门店盘点单位
let unit = _.filter(this.unit_list, v => {
if (v.key === name) {
return v.value
}
});
if (unit.length) {
return unit[0]['value']
}
},
bomUnitChange (name) {
// 门店盘点单位
let unit = _.filter(this.bom_unit_list, v => {
if (v.key === name) {
return v.value
}
});
if (unit.length) {
this.bom_unit_name_value = unit[0]['value'];
}
this.changeScroll()
},
changeScroll () {
$('html,body').scrollTop(0)
}
}
}
</script>
<style lang="less" scoped>
// 新增物料弹窗
.material_dialog {
font-size: 14px;
.weui-dialog {
width: 100% !important;
max-width: 400px;
text-align: left;
.dialogTitle {
background-color: #8ea9cf;
color: #FFFFFF;
text-align: center;
font-size: 16px;
padding: 0.6rem 0;
}
.material_info {
background-color: #fff;
margin-bottom: 10px;
.red {
font-style: normal;
color: #ff6600;
}
ul {
li {
display: -webkit-flex;
display: flex;
position: relative;
padding: 4px 0 4px 10px;
border-bottom: 1px solid #e5e5e5;
label {
&>span {
display: block;
// float: left;
width: 95px;
height: 36px;
line-height: 36px;
}
}
&.twoLabel {
display: -webkit-flex;
display: flex;
label {
-webkit-flex: 1;
flex: 1;
display: -webkit-flex;
display: flex;
padding-right: 10px;
.el-form-item {
flex: 1;
margin-bottom: 0;
}
}
}
.el-form-item_content{
-webkit-flex: 1;
flex: 1;
float: left!important;
margin-left: 0!important;
line-height: 20px!important;
padding-right: 10px;
&.p-right {
padding-right: 7px;
}
p {
line-height: 36px;
text-align: right;
i {
color: rgb(153, 153, 153);
font-size: 18px;
position: relative;
top: 2px;
}
}
}
}
}
}
.btn {
background-color: #fff;
&>div {
.default-btn {
width: 100%;
height: 38px;
background: #89a9cf!important;
color: #fff!important;
font-size: 16px;
}
.close-btn {
background-color: #ffffff;
color: #8EA8CF;
border: 1px solid #8EA8CF;
width: 100%;
font-size: 16px;
}
.comfirm-btn {
background-color: #8EA8CF;
color: #ffffff;
border: 1px solid #8EA8CF;
width: 100%;
font-size: 16px;
}
}
}
}
}
</style>
<template lang="html">
</template>
<script>
export default {
}
</script>
<style lang="less">
</style>
<template lang="html">
<div class="choose-material-page">
<div v-transfer-dom>
<x-dialog :show.sync="show" class="dialog-demo">
<div class="material-title">请选择{{name}}</div>
<div class="material-wrapper">
<div class="material-classify">
<div>
<check-icon :value.sync="all_checked" @click.native="checkAll(all_checked)">
全部{{name}}
</check-icon>
<div class="material-content">
<checker
v-model="checkList"
type="checkbox"
default-item-class="item"
selected-item-class="item-selected"
disabled-item-class="item-disabled"
>
<checker-item v-for="(item, index) in list" :key="index" :disabled="item.disabled" :value="item.id" @click.native="itemCheck(item.checked, index)">{{item.name}}</checker-item>
</checker>
</div>
</div>
</div>
</div>
<div style="padding: 10px;">
<flexbox>
<flexbox-item>
<x-button @click.native="cancel" mini style="background-color: #ffffff; color: #8EA8CF; border: 1px solid #8EA8CF; width: 100%;">关闭</x-button>
</flexbox-item>
<flexbox-item>
<x-button @click.native="comfirm" mini style="background-color: #8EA8CF; color: #ffffff; border: 1px solid #8EA8CF; width: 100%;">确定</x-button>
</flexbox-item>
</flexbox>
</div>
</x-dialog>
</div>
</div>
</template>
<script>
import { XDialog, TransferDomDirective as TransferDom, Flexbox, FlexboxItem, CheckIcon, XButton, Checker, CheckerItem } from 'vux'
export default {
props: ['show', 'list', 'checked_list', 'span', 'name'],
directives: { TransferDom },
components: { XDialog, Flexbox, FlexboxItem, CheckIcon, XButton, Checker, CheckerItem },
beforeRouteEnter (to, from, next) {
next()
},
mounted () {
// console.warn(this.list)
// console.warn(1)
},
data () {
return {
all_checked: true,
checkList: []
}
},
watch: {
show (val) {
// console.warn(val)
this.checkList = JSON.parse(JSON.stringify(this.checked_list))
if (val) {
let check_list = _.filter(this.list, (val) => {
let tem;
if (val.disabled === false) {
tem = val
}
return tem
});
if (check_list.length > 0 && this.checked_list.length > 0 && check_list.length === this.checked_list.length) {
this.all_checked = true
} else {
this.all_checked = false
}
} else {
this.all_checked = false
}
// this.checkList = val;
}
},
computed: {
// checkList () {
// return JSON.parse(JSON.stringify(this.checked_list));
// }
},
methods: {
checkAll (checked) {
let check_list = _.filter(this.list, (val) => {
let tem;
if (val.disabled === false) {
tem = val
}
return tem
});
// 勾选所有品牌
if (checked) {
// 选中
for (let i = 0; i < check_list.length; i++) {
check_list[i].checked = true;
}
this.checkList = _.map(check_list, val => val.id)
// this.checked_list = id_list;
} else {
// 取消
this.checkList = []
for (let i = 0; i < check_list.length; i++) {
check_list[i].checked = false;
}
}
},
itemCheck (checked, index) {
// console.warn(this.checkList)
let list = _.filter(this.list, (val) => {
let tem;
if (val.disabled === false) {
tem = val
}
return tem
});
if (checked) {
this.list[index].checked = false;
} else {
this.list[index].checked = true;
}
// console.warn(id_list)
if (list.length !== this.checkList.length) {
this.all_checked = false
} else {
this.all_checked = true
}
},
changeCategory () {
},
cancel () {
// 关闭选择框
this.$emit('cancel', !this.show)
},
comfirm () {
// 确认选择框
this.$emit('comfirm', this.checkList)
}
}
}
</script>
<style lang="less" scoped>
.material-classify {
text-align: left;
padding: 10px;
.vux-checker-box {
// display: -webkit-flex;
// display: flex;
// flex-wrap: wrap;
// justify-content: space-between;
}
.vux-check-icon {
margin-bottom: 10px;
}
}
.item {
width: 31%;
// flex-basis: 31%;
line-height: 26px;
text-align: center;
border-radius: 3px;
border: 1px solid #ccc;
background-color: #fff;
margin-bottom: 10px;
margin-right: 2%;
&:nth-child(3n) {
margin-right: 0;
}
}
.item-selected {
color: white;
background-color: #8EA8CF;
}
.item-disabled {
color: #cfcfcf;
background-color: #ebeef7;
}
.weui-dialog {
width: 90% !important;
max-width: 400px;
}
@media screen and (min-width: 1024px) {
.weui-dialog {
width: 35%;
}
}
.weui-btn:after {
border: 0 !important;
}
</style>
<template lang="html">
<div class="">
<alert
:title="title"
:value="show"
:button_text="button_text"
@on-show="onShow"
@on-hide="onHide">
自定义插入内容
</alert>
<group>
<x-switch title="测试开关" v-model="show"></x-switch>
</group>
</div>
</template>
<script>
import alert from 'components/alert/index'
import { Group, XSwitch } from 'vux'
export default {
components: { alert, Group, XSwitch },
data () {
return {
title: '温馨提示',
button_text: '确定',
show: false
}
},
mounted () {
},
methods: {
onHide () {
console.warn('on-hide');
},
onShow () {
console.warn('on-show');
}
}
}
</script>
<style lang="less">
</style>
<template lang="html">
<div v-transfer-dom>
<alert v-model="show"
:title="title"
:button-text="button_text"
@on-show="onShow"
@on-hide="onHide">
<slot></slot>
</alert>
</div>
</template>
<script>
import { TransferDom, Alert } from 'vux'
export default {
components: { Alert },
directives: { TransferDom },
props: ['title', 'value', 'button_text'],
data () {
return {
}
},
mounted () {
},
computed: {
show: {
get () {
return this.value
},
set (val) {}
}
},
methods: {
onHide () {
this.$emit('on-hide');
},
onShow () {
this.$emit('on-show');
}
}
}
</script>
<style lang="less">
.weui-dialog {
width: 90%;
max-width: 50rem;
}
.weui-dialog__btn.weui-dialog__btn_primary {
color: #353535;
}
.weui-dialog__hd {
background-color: #8ea9cf;
color: #FFFFFF;
padding: 0.5em 1.6em 0.5em;
}
</style>
<template>
<div>
<div class="btn">
<div>
<x-button class="default-btn" @click.native="next">{{btnText}}</x-button>
</div>
</div>
</div>
</template>
<script>
import { XButton } from 'vux'
export default {
components: { XButton },
props: ['btnText'],
methods: {
next () {
this.$emit('btnClick')
}
}
}
</script>
<style lang="less" scoped>
.btn {
width: 100%;
background: #fff;
position: fixed;
bottom: 0;
left: 0;
z-index: 100;
&>div {
padding: 6px 10px;
.default-btn {
width: 100%;
height: 38px;
background: #89a9cf!important;
color: #fff!important;
font-size: 16px;
&:after {
border: 1px solid #89a9cf!important;
}
}
}
}
</style>
<template>
<div>
<div class="btn">
<div>
<x-button class="default-btn continue" @click.native="leftClick">{{leftText}}</x-button>
<x-button class="default-btn" @click.native="rightClick">{{rightText}}</x-button>
</div>
</div>
</div>
</template>
<script>
import { XButton } from 'vux'
export default {
props: ['leftText', 'rightText'],
components: {XButton},
methods: {
leftClick () {
this.$emit('leftClick')
},
rightClick () {
this.$emit('rightClick')
}
}
}
</script>
<style lang="less" scoped>
.btn {
width: 100%;
background: #fff;
position: fixed;
bottom: 0;
left: 0;
z-index: 100;
&>div {
display: flex;
display: -webkit-flex;
// align-content: center;
justify-content: space-between;
padding: 6px 10px;
.default-btn {
width: 49%;
height: 38px;
background: #89a9cf!important;
margin: 0;
color: #fff!important;
font-size: 16px;
&.continue {
background-color: #fff!important;
color: #89a9cf!important;
&:after {
width: 199%;
border: 1px solid #89a9cf!important;
}
}
}
}
}
</style>
<template lang="html">
<div style="padding: 20px">
<x-button disabled class="disbaled-btn">确定disabled</x-button>
<x-button class="default-btn">确定default</x-button>
<x-button class="active-btn">确定active</x-button>
<divider> line </divider>
<flexbox>
<flexbox-item><x-button plain class="line-btn">关闭</x-button></flexbox-item>
<flexbox-item><x-button plain class="default-btn">确定</x-button></flexbox-item>
</flexbox>
<divider> line </divider>
<x-button mini plain class="line-btn">选好了</x-button>
</div>
</template>
<script>
import { Flexbox, FlexboxItem, XButton, Divider } from 'vux'
export default {
components: {
Divider,
Flexbox,
FlexboxItem,
XButton
}
}
</script>
<style lang="less">
.disbaled-btn {
border: 1px solid #dbdce0;
background: #ebeef7;
color: #c8cbd0
}
.default-btn {
background: #86aace!important;
border: 1px solid #86aace!important;
color: #fff!important;
}
.active-btn {
border: 1px solid #86aace!important;
background: #697f9f!important;
color: #fff!important;
}
.line-btn {
border: 1px solid #8aa0b4!important;
color: #8298b4!important;
}
</style>
<template lang="html">
<div class="">
<div v-if="type === 'enable'" class="set-enable-btn">
<slot></slot>
</div>
<div v-if="type === 'unable'" class="un-set-btn">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
props: ['type']
}
</script>
<style lang="less">
.set-enable-btn {
color: #8EA8CF;
background-color: #FFFFFF;
text-align: center;
margin: 0.5rem 1rem;
padding: 0.5rem 0;
border-radius: .2rem;
font-size: .85rem;
border: 1px solid #8EA8CF;
}
.un-set-btn {
color: white;
background-color: #8EA8CF;
text-align: center;
margin: 0.5rem 1rem;
padding: 0.5rem 0;
border-radius: .2rem;
font-size: .85rem;
}
</style>
<template lang="html">
<div class="">
<cell-swiper :list="list" @clickItem="clickItem" @editItem="editItem" @deleteItem="deleteItem"></cell-swiper>
</div>
</template>
<script>
import cellSwiper from 'components/cellSwiper/index'
export default {
components: {cellSwiper},
data () {
return {
list: [
{
id: '01',
title: 'item1'
},
{
id: '02',
title: 'item2'
},
{
id: '03',
title: 'item3'
},
{
id: '04',
title: 'item4'
}
]
}
},
methods: {
clickItem (id) {
console.warn(id);
},
editItem (id) {
console.warn(id);
},
deleteItem (id) {
console.warn(id);
}
}
}
</script>
<style lang="less">
</style>
<template lang="html">
<div class="container">
<ul>
<li class="list-item " v-for="(item,index) in list " data-type="0">
<div class="list-box" @touchstart.capture="touchStart" @touchend.capture="touchEnd" @click="clickItem($event, item)" :data-id="item.id">
<div class="list-content">
<p class="title">{{item.title}}</p>
</div>
</div>
<div class="edit" @click="editItem($event, item)" :data-index="index" :data-id="item.id">修 改</div>
<div class="delete" @click="deleteItem" :data-index="index" :data-id="item.id">删 除</div>
</li>
</ul>
</div>
</template>
<script>
/**
* [list 左滑修改删除列表]
* @type {Array}
* @field {id, title}
*
* [clickItem 点击表单项回调, 返回 index]
* @type {Function}
* @callback {index}
*
* [editItem 左滑点击表单编辑回调, 返回 index]]
* @type {Function}
* @callback {index}
*
* [deleteItem 左滑点击表单删除回调, 返回 index]]
* @type {Function}
* @callback {index}
*/
export default{
name: 'index',
props: ['list'],
data () {
return {
startX: 0,
endX: 0
}
},
methods: {
// 跳转
clickItem (e, item) {
if (this.checkSlide()) {
this.restSlide();
} else {
// 当前ID
let id = e.currentTarget.dataset.id;
this.$emit('clickItem', id, item)
}
},
// 滑动开始
touchStart (e) {
// 记录初始位置
this.startX = e.touches[0].clientX;
},
// 滑动结束
touchEnd (e) {
// 当前滑动的父级元素
let parentElement = e.currentTarget.parentElement;
// 记录结束位置
this.endX = e.changedTouches[0].clientX;
// 左滑
if (parentElement.dataset.type == 0 && this.startX - this.endX > 30) {
this.restSlide();
parentElement.dataset.type = 1;
}
// 右滑
if (parentElement.dataset.type == 1 && this.startX - this.endX < -30) {
this.restSlide();
parentElement.dataset.type = 0;
}
this.startX = 0;
this.endX = 0;
},
// 判断当前是否有滑块处于滑动状态
checkSlide () {
let listItems = document.querySelectorAll('.list-item');
for (let i = 0; i < listItems.length; i++) {
if (listItems[i].dataset.type == 1) {
return true;
}
}
return false;
},
// 复位滑动状态
restSlide () {
let listItems = document.querySelectorAll('.list-item');
// 复位
for (let i = 0; i < listItems.length; i++) {
listItems[i].dataset.type = 0;
}
},
// 删除
deleteItem (e) {
// 当前索引
let index = e.currentTarget.dataset.index;
// 复位
this.restSlide();
// 删除
// this.list.splice(index, 1);
// 当前ID
// let id = e.currentTarget.dataset.id;
this.$emit('deleteItem', index)
},
// 修改
editItem (e, item) {
// 当前索引
let id = e.currentTarget.dataset.id;
// 复位
this.restSlide();
// 当前ID
this.$emit('editItem', id, item)
}
}
}
</script>
<style scoped>
.page-title{
text-align: center;
font-size: 17px;
padding: 10px 15px;
position: relative;
}
.page-title:after{
content: " ";
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
border-bottom: 1px solid #ccc;
color: #ccc;
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
z-index: 2;
}
.list-item{
position: relative;
height: 3.5rem;
-webkit-transition: all 0.2s;
transition: all 0.2s;
}
.list-item[data-type="0"]{
transform: translate3d(0,0,0);
}
.list-item[data-type="1"]{
transform: translate3d(-12rem,0,0);
}
.list-item:after{
content: " ";
position: absolute;
/* left: 0.6rem; */
left: 0rem;
bottom: 0;
right: 0;
height: 1px;
border-bottom: 1px solid #ebeaee;
color: #ccc;
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
-webkit-transform: scaleY(0.5);
transform: scaleY(0.5);
z-index: 2;
}
.list-box{
padding: 0.6rem;
background: #fff;
display: flex;
align-items: center;
-webkit-box-sizing: border-box;
box-sizing: border-box;
justify-content: flex-end;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
font-size: 0;
}
.list-item .list-img{
display: block;
width: 3rem;
height: 3rem;
}
.list-item .list-content{
padding: 0.3rem 0 0.3rem 0.6rem;
position: relative;
flex: 1;
flex-direction: column;
align-items: flex-start;
justify-content: center;
overflow: hidden;
}
.list-item .title{
display: block;
color: #333;
overflow: hidden;
font-size: 15px;
font-weight: bold;
text-overflow: ellipsis;
white-space: nowrap;
}
.list-item .tips{
display: block;
overflow: hidden;
font-size: 12px;
color: #999;
line-height: 20px;
text-overflow: ellipsis;
white-space: nowrap;
}
.list-item .time{
display: block;
font-size: 12px;
position: absolute;
right: 0;
top: 0.3rem;
color: #666;
}
.list-item .delete{
width: 6rem;
height: 3.5rem;
background: #fc6621;
font-size: 17px;
color: #fff;
text-align: center;
line-height: 3.5rem;
position: absolute;
top:0;
right: -12rem;
}
.list-item .edit{
width: 6rem;
height: 3.5rem;
background: #f0eff5;
font-size: 17px;
color: #000;
text-align: center;
line-height: 3.5rem;
position: absolute;
top:0;
right: -6.1rem;
border-left: 1px solid #ebeaee;
}
</style>
<template lang="html">
<div class="">
<checker type="checkbox" @on-change="checkerChange" v-model="checkedValue" default-item-class="checklist-item" selected-item-class="checklist-item-selected">
<checker-item :value="item" v-for="(item, index) in options" :key="index"><i></i><span>{{item.value}}</span></checker-item>
</checker>
</div>
</template>
<script>
import { Checker, CheckerItem, TransferDom } from 'vux'
export default {
directives: {
TransferDom
},
components: {
Checker,
CheckerItem
},
data () {
return {
checkedValue: [
{
key: '1',
value: '白'
}
],
options: [
{
key: '1',
value: '白'
},
{
key: '2',
value: '富'
},
{
key: '3',
value: '美'
}
]
}
},
methods: {
checkerChange (val) {
console.warn(val);
}
}
}
</script>
<style lang="less" scoped>
.checklist-item {
margin-right: 15px;
span {
display: inline-block;
vertical-align: middle;
}
i {
display: inline-block;
width: 1rem;
height: 1rem;
background-size: cover;
background-image: url(../../assets/unchecked.png);
vertical-align: middle;
margin-right: 0.5rem;
}
}
.checklist-item-selected {
i {
background-image: url(../../assets/checked.png)
}
}
</style>
<template lang="html">
<div class="">
<checker type="checkbox" @on-change="checkerChange" v-model="checkValue" default-item-class="checklist-item" selected-item-class="checklist-item-selected">
<checker-item :value="item.key" v-for="(item, index) in options" :key="index"><i></i><span>{{item.value}}</span></checker-item>
</checker>
</div>
</template>
<script>
import { Checker, CheckerItem, TransferDom } from 'vux'
export default {
directives: {
TransferDom
},
components: {
Checker,
CheckerItem
},
data () {
return {
checkValue: ''
}
},
methods: {
checkerChange (val) {
this.$emit('change', val)
}
}
}
</script>
<style lang="less" scoped>
.checklist-item {
margin-right: 15px;
span {
display: inline-block;
vertical-align: middle;
}
i {
display: inline-block;
width: 1.2rem;
height: 1.2rem;
background-size: cover;
background-image: url(../../assets/unchecked.png);
vertical-align: middle;
margin-right: 0.5rem;
}
}
.checklist-item-selected {
i {
background-image: url(../../assets/checked.png)
}
}
</style>
<template lang="html">
<div class="">
<div class="check-head" style="margin: 0 0 0 10px">
<check-all :value.sync="isAll" @click.native="selectAll(isAll)">全部商品</check-all>
<p style="display: inline-block">
(<span style="color: #8fb5de">{{currSum}}</span>/<span>{{totalSum}}</span>)
</p>
</div>
<demo
@listChange="listCheckerChange"
v-for="item in data"
:id="item.id"
:name="item.name"
:key="item.id"
:list="item.list"
:isCheckAll="item.isCheck"
:currItemCount="item.currItemCount"
:itemTotal="item.itemTotal"
:listCount="testCount"></demo>
</div>
</template>
<script>
import Demo from 'components/checkBox/index'
import CheckAll from 'components/isCheckAll/index'
export default {
components: { Demo, CheckAll },
data () {
return {
testCount: null,
isAll: false,
currSum: 0,
totalSum: null,
data: [
{
isCheck: true,
id: '123a',
name: '蔬菜类',
currItemCount: 0,
itemTotal: 4,
list: [
{
key: '1',
value: '什锦冷菜'
},
{
key: '2',
value: '经典冷盘甜小菜心太软'
},
{
key: '3',
value: '凉拌黑木耳'
},
{
key: '4',
value: '私房飘香酱牛肉'
}
]
},
{
isCheck: false,
id: '852a',
name: '肉类',
currItemCount: 0,
itemTotal: 5,
list: [
{
key: 'b',
value: '咸水鸭',
isSelected: true
},
{
key: 'c',
value: '酱香牛肉'
},
{
key: 'd',
value: '羊肉'
},
{
key: 'e',
value: '凉拌猪耳朵'
},
{
key: 'g',
value: '海蜇头'
}
]
}
]
}
},
mounted () {
this.totalSum = _.sum(_.map(this.data, 'itemTotal'))
},
methods: {
selectAll (val) {
console.warn(val);
},
listCheckerChange (val) {
this.testCount = val.length
// console.warn(this.testCount);
}
}
}
</script>
<style lang="css">
</style>
<template>
<div>
<div class="dash-line">
<span></span>
</div>
<div class="check-head" style="margin: 0 0 10px 15px">
<check-all :value.sync="checkAll" @click.native="checkAllClick(checkAll)">{{ name }}</check-all>
<p style="display: inline-block">
(<span style="color: #8fb5de">{{currCount}}</span>/<span>{{currTotal}}</span>)
</p>
</div>
<checker
v-model="checkValue"
type="checkbox"
default-item-class="check-item"
disabled-item-class="check-item-disabled"
selected-item-class="check-item-selected"
@on-change="checkerChange"
class="check-item-wrap-self">
<checker-item
v-for="(item, index) in list"
:key="index"
:value="item.key"
v-if="!item.disabled"
:disabled="item.disabled">{{item.value}}</checker-item>
</checker>
</div>
</template>
<script>
import { Checker, CheckerItem, CheckIcon, TransferDom } from 'vux'
import CheckAll from 'components/isCheckAll/index'
export default {
props: ['list', 'id', 'name', 'currItemCount', 'itemTotal', 'isCheckAll', 'listCount'],
directives: {
TransferDom
},
components: {
Checker,
CheckerItem,
CheckIcon,
CheckAll
},
data () {
return {
checkValue: '',
currCount: this.currItemCount,
currTotal: this.itemTotal,
checkAll: this.isCheckAll
}
},
mounted () {
if (this.isCheckAll) {
this.checkValue = _.map(this.list, 'key')
this.checkAll = true;
this.currCount = this.checkValue.length
} else {
this.checkValue = this.filterKeys(this.list)
this.checkAll = false;
this.currCount = 0
}
},
watch: {
currItemCount (val) {
this.currCount = val
},
itemTotal (val) {
this.currTotal = val
},
isCheckAll (val) {
this.checkAll = val
}
},
methods: {
filterKeys (arr) {
let lists = [];
_(arr).each(function (item) {
if (item.isSelected && item.isSelected === true) {
lists.push(item.key)
}
})
return lists
},
checkAllClick (val) {
if (val) {
this.checkValue = _.map(this.list, 'key')
this.checkAll = true;
this.currCount = this.checkValue.length
} else {
this.checkValue = []
this.checkAll = false;
this.currCount = 0
}
},
checkerChange (value) {
let checkedCount = value.length;
this.currCount = checkedCount
this.checkAll = checkedCount === this.list.length;
this.$emit('listChange', value)
}
}
}
</script>
<style lang="less" scoped>
.dash-line {
padding: 0.6rem 0;
span{
display: block;
width: 100%;
border-bottom: 1px dashed #d9d9db;
}
}
.checklist-item {
span {
display: inline-block;
width: 1.2rem;
height: 1.2rem;
background-size: cover;
background-image: url(../../assets/unchecked.png);
vertical-align: middle;
margin-right: 0.5rem;
}
}
.checklist-item-selected {
span {
background-image: url(../../assets/checked.png)
}
}
.check-item {
background: #f6f6f6;
color: #333;
padding: 0.4rem;
border-radius: 0.4rem;
margin: 0.4rem
}
.check-item-disabled {
background: #eaeff7;
color: #ccc;
}
.check-item-selected {
background: #c4d4e7;
color: #2c426b;
}
</style>
<template lang="html">
<div class="">
<checker radio-required @on-change="checkerChange" v-model="checkedValue" default-item-class="radio-item" selected-item-class="radio-item-selected">
<checker-item :value="item.key" v-for="(item, index) in options" :key="index"><i></i><span>{{item.value}}</span></checker-item>
</checker>
</div>
</template>
<script>
import { Checker, CheckerItem, TransferDom } from 'vux'
export default {
directives: {
TransferDom
},
components: {
Checker,
CheckerItem
},
data () {
return {
checkedValue: '1',
options: [
{
key: '1',
value: '白'
},
{
key: '2',
value: '富'
},
{
key: '3',
value: '美'
},
{
key: '4',
value: '潘'
}
]
}
},
methods: {
checkerChange (val) {
console.warn(val);
}
}
}
</script>
<style lang="less" scoped>
.radio-item {
margin-right: 15px;
span {
display: inline-block;
vertical-align: middle;
}
i {
display: inline-block;
width: 1rem;
height: 1rem;
background-size: cover;
background-image: url(../../assets/unradio.png);
vertical-align: middle;
margin-right: 0.5rem;
}
}
.radio-item-selected {
i {
background-image: url(../../assets/radio.png)
}
}
</style>
<template lang="html">
<div class="">
<checker v-model="radioValue" radio-required default-item-class="radio-item" selected-item-class="radio-item-selected">
<checker-item value="1">hehe</checker-item>
<checker-item value="2">haha</checker-item>
</checker>
</div>
</template>
<script>
import { Checker, CheckerItem, TransferDom } from 'vux'
export default {
directives: {
TransferDom
},
components: {
Checker,
CheckerItem
},
data () {
return {
radioValue: ''
}
}
}
</script>
<style lang="less">
.radio-item {
border: 1px solid #ececec;
padding: 5px 15px;
}
.radio-item-selected {
border: 1px solid green;
}
</style>
<template lang="html">
<label>
<input type="checkbox" :checked="shouldBeChecked" :value="value" @change="updateInput">
{{ label }}
</label>
</template>
<script>
export default {
model: {
prop: 'modelValue',
event: 'change'
},
props: {
value: {
type: String
},
modelValue: {
default: false
},
label: {
type: String,
required: true
},
trueValue: {
default: true
},
falseValue: {
default: false
}
},
computed: {
shouldBeChecked () {
if (this.modelValue instanceof Array) {
return this.modelValue.includes(this.value)
}
return this.modelValue === this.trueValue
}
},
methods: {
updateInput (event) {
let isChecked = event.target.checked
if (this.modelValue instanceof Array) {
let newValue = [...this.modelValue]
if (isChecked) {
newValue.push(this.value)
} else {
newValue.splice(newValue.indexOf(this.value), 1)
}
this.$emit('change', newValue)
} else {
this.$emit('change', isChecked ? this.trueValue : this.falseValue)
}
}
}
}
</script>
<template>
<div class="selectbox">
<div class="selectall">
<div class="check-head" style="margin: 0 0 0 10px">
<check-all :value.sync="isAll" @click.native="selectAll(isAll)">全部商品</check-all>
<p style="display: inline-block">
(<span style="color: #8fb5de">{{currSum}}</span>/<span>{{totalSum}}</span>)
</p>
</div>
</div>
<div
class="selectlist"
v-for="(item, index) in data"
:key="item.id">
<div class="dash-line">
<span></span>
</div>
<div class="check-head" style="margin: 0 0 10px 15px">
<check-all :value.sync="item.isCheck" @click.native="checkAllClick(item.isCheck, index)">{{ item.name }}</check-all>
<p style="display: inline-block">
(<span style="color: #8fb5de">{{item.currItemCount}}</span>/<span>{{item.currTotal}}</span>)
</p>
</div>
<checker
v-model="item.selectedList"
type="checkbox"
default-item-class="check-item"
disabled-item-class="check-item-disabled"
selected-item-class="check-item-selected"
@on-change="checkerChange(item.selectedList, index)"
class="check-item-wrap-self">
<checker-item
v-for="(item, index) in item.list"
:key="index"
:value="item.key"
v-if="!item.disabled"
:disabled="item.disabled">{{item.value}}</checker-item>
</checker>
</div>
</div>
</template>
<script>
import { Checker, CheckerItem, CheckIcon, TransferDom } from 'vux'
import CheckAll from 'components/isCheckAll/index'
export default {
directives: {
TransferDom
},
components: {
Checker,
CheckerItem,
CheckIcon,
CheckAll
},
data () {
return {
isAll: false,
currSum: 0,
totalSum: 0,
source: [
{
isCheck: true,
id: '123a',
name: '蔬菜类',
currItemCount: 0,
itemTotal: 4,
list: [
{
key: '1',
value: '什锦冷菜'
},
{
key: '2',
value: '经典冷盘甜小菜心太软'
},
{
key: '3',
value: '凉拌黑木耳'
},
{
key: '4',
value: '私房飘香酱牛肉'
}
]
},
{
isCheck: false,
id: '852a',
name: '肉类',
currItemCount: 0,
itemTotal: 5,
list: [
{
key: 'b',
value: '咸水鸭',
isSelected: true
},
{
key: 'c',
value: '酱香牛肉'
},
{
key: 'd',
value: '羊肉'
},
{
key: 'e',
value: '凉拌猪耳朵'
},
{
key: 'g',
value: '海蜇头'
}
]
}
],
data: [
{
isCheck: false,
id: '123a',
name: '蔬菜类',
currItemCount: 2,
currTotal: 4,
selectedList: ['1', '2'],
list: [
{
key: '1',
value: '什锦冷菜'
},
{
key: '2',
value: '经典冷盘甜小菜心太软'
},
{
key: '3',
value: '凉拌黑木耳'
},
{
key: '4',
value: '私房飘香酱牛肉'
}
]
},
{
isCheck: false,
id: '852a',
name: '肉类',
currItemCount: 1,
currTotal: 5,
selectedList: ['b'],
list: [
{
key: 'b',
value: '咸水鸭'
},
{
key: 'c',
value: '酱香牛肉'
},
{
key: 'd',
value: '羊肉'
},
{
key: 'e',
value: '凉拌猪耳朵'
},
{
key: 'g',
value: '海蜇头'
}
]
}
]
}
},
mounted () {
this.currSum = _.sum(_.map(this.data, 'currItemCount'))
this.totalSum = _.sum(_.map(this.data, 'currTotal'))
},
methods: {
checkAllClick (val, index) {
const selectedKey = _.map(this.data[index].list, 'key')
if (val === true) {
this.data[index].selectedList = selectedKey
this.data[index].currItemCount = this.data[index].currTotal
} else {
this.data[index].selectedList = []
this.data[index].currItemCount = 0
}
this.currSum = _.sum(_.map(this.data, 'currItemCount'))
if (this.currSum === this.totalSum) {
this.isAll = true
} else {
this.isAll = false
}
},
checkerChange (value, index) {
if (value.length === this.data[index].list.length) {
this.data[index].isCheck = true
} else {
this.data[index].isCheck = false
}
this.data[index].selectedList = value
this.data[index].currItemCount = this.data[index].selectedList.length
this.currSum = _.sum(_.map(this.data, 'currItemCount'))
if (this.currSum === this.totalSum) {
this.isAll = true
} else {
this.isAll = false
}
},
selectAll (val) {
const source = this.data
if (val === true) {
_(source).each(function (item, index) {
source[index].selectedList = _.map(item.list, 'key')
source[index].isCheck = true
})
this.currSum = this.totalSum
} else {
_(source).each(function (item, index) {
source[index].selectedList = []
source[index].isCheck = false
})
this.currSum = 0
}
}
}
}
</script>
<style lang="less" scoped>
.dash-line {
padding: 0.6rem 0;
span{
display: block;
width: 100%;
border-bottom: 1px dashed #d9d9db;
}
}
.checklist-item {
span {
display: inline-block;
width: 1.2rem;
height: 1.2rem;
background-size: cover;
background-image: url(../../assets/unchecked.png);
vertical-align: middle;
margin-right: 0.5rem;
}
}
.checklist-item-selected {
span {
background-image: url(../../assets/checked.png)
}
}
.check-item {
background: #f6f6f6;
color: #333;
padding: 0.4rem;
border-radius: 0.4rem;
margin: 0.4rem
}
.check-item-disabled {
background: #eaeff7;
color: #ccc;
}
.check-item-selected {
background: #c4d4e7;
color: #2c426b;
}
</style>
<template lang="html">
<div>
<demo></demo>
</div>
</template>
<script>
import demo from './test-index'
export default {
components: {
demo
},
data ( ) {
return {
}
}
}
</script>
<style lang="less">
</style>
<template lang="html">
<div class="multiSelect">
<div style="height: 16rem; overflow-y: scroll;">
<div style="border-bottom: 1px dashed #d9d9db;">
<div class="check-head" style="margin: 0.8rem 0 0.8rem 2px">
<check-icon :value.sync="checkAll" @click.native="selectAll(checkAll)">{{allName}}</check-icon>
<p style="display: inline-block">
(<span style="color: #8fb5de">{{currCount}}</span>/<span>{{currTotal}}</span>)
</p>
</div>
</div>
<div
class="list"
v-for="(item, index) in items"
:keys="index">
<div class="check-head" style="margin: 0.4rem 0 0.4rem 15px">
<check-icon :value.sync="item.currCheckAll" @click.native="checkItemAll(item.currCheckAll, index)">{{item.name}}</check-icon>
<p style="display: inline-block">
(<span style="color: #8fb5de">{{item.currItemCount}}</span>/<span>{{item.currItemTotal}}</span>)
</p>
</div>
<checker
v-model="item.selectedList"
type="checkbox"
default-item-class="check-item"
disabled-item-class="check-item-disabled"
selected-item-class="check-item-selected"
@on-change="checkerChange(item.selectedList, index)"
class="check-item-wrap-self">
<checker-item
v-for="(list, index) in item.lists"
:key="index"
:value="list.key"
v-if="!list.disabled"
:disabled="list.disabled">{{list.value}}</checker-item>
</checker>
</div>
</div>
<x-button mini class="default-btn" @click.native="getSelected">完成</x-button>
</div>
</template>
<script>
import { Checker, CheckerItem, CheckIcon, TransferDom, XButton } from 'vux'
export default {
name: 'multiCheck',
props: ['items', 'allName'],
components: {
Checker,
CheckerItem,
CheckIcon,
TransferDom,
XButton
},
data () {
return {
currAllSelected: [],
checkAll: false,
currCheckAll: false,
currCount: null,
currTotal: null,
currItemCount: null,
currItemTotal: null
}
},
mounted () {
this.currCount = _.sum(_.map(this.items, 'currItemCount'))
this.currTotal = _.sum(_.map(this.items, 'currItemTotal'))
this.getSelectedF(this.items)
},
methods: {
getSelectedF (arr) {
this.currAllSelected = _.flattenDeep(_.map(arr, 'selectedList'))
},
selectAll (val) {
const source = this.items
if (val === true) {
_(source).each(function (item, index) {
source[index].selectedList = _.map(item.lists, 'key')
source[index].currCheckAll = true
})
this.currCount = this.currTotal
} else {
_(source).each(function (item, index) {
source[index].selectedList = []
source[index].currCheckAll = false
})
this.currCount = 0
}
this.getSelectedF(this.items)
},
checkItemAll (val, index) {
const selectedKey = _.map(this.items[index].lists, 'key')
if (val === true) {
this.items[index].selectedList = selectedKey
this.items[index].currItemCount = this.items[index].currItemTotal
} else {
this.items[index].selectedList = []
this.items[index].currItemCount = 0
}
this.currCount = _.sum(_.map(this.items, 'currItemCount'))
if (this.currCount === this.currTotal) {
this.checkAll = true
} else {
this.checkAll = false
}
this.getSelectedF(this.items)
},
checkerChange (value, index) {
this.$emit('listChange', value)
if (value.length === this.items[index].lists.length) {
this.items[index].currCheckAll = true
} else {
this.items[index].currCheckAll = false
}
this.items[index].selectedList = value
this.items[index].currItemCount = this.items[index].selectedList.length
this.currCount = _.sum(_.map(this.items, 'currItemCount'))
if (this.currCount === this.currTotal) {
this.checkAll = true
} else {
this.checkAll = false
}
this.getSelectedF(this.items)
},
getSelected () {
this.$emit('getSelected', this.currAllSelected)
}
}
}
</script>
<style lang="less">
.multiSelect {
.dash-line {
padding: 0.6rem 0;
span{
display: block;
width: 100%;
border-bottom: 1px dashed #d9d9db;
}
}
.list {
border-bottom: 1px dashed #d9d9db;
padding: 0.3rem 0
}
.check-item {
background: #f6f6f6;
color: #333;
padding: 0.4rem;
border-radius: 0.4rem;
margin: 0.4rem
}
.check-item-disabled {
background: #eaeff7;
color: #ccc;
}
.check-item-selected {
background: #c4d4e7;
color: #2c426b;
}
.default-btn {
display: block;
width: 60%;
margin: 1rem auto 0;
background: #86aace;
border: 1px solid #86aace;
color: #fff;
}
.vux-check-icon > .weui-icon-success:before, .vux-check-icon > .weui-icon-success-circle:before {
color: #c4d4e7
}
}
</style>
<template lang="html">
<div class="">
<confirm
:title="title"
:value="show"
:left_text="left_text"
:right_text="right_text"
@on-cancel="onCancel"
@on-confirm="onConfirm"
@on-show="onShow"
@on-hide="onHide">
自定义插入内容
</confirm>
<group>
<x-switch title="测试开关" v-model="show"></x-switch>
</group>
</div>
</template>
<script>
import confirm from 'components/confirm/index'
import { Group, XSwitch } from 'vux'
export default {
components: { confirm, Group, XSwitch },
data () {
return {
title: '温馨提示',
left_text: '下一步',
right_text: '继续',
show: false
}
},
mounted () {
},
methods: {
onCancel () {
console.warn('on-cancel');
},
onConfirm (msg) {
console.warn('on-confirm', msg);
},
onHide () {
console.warn('on-hide');
},
onShow () {
console.warn('on-show');
}
}
}
</script>
<style lang="less">
</style>
<template lang="html">
<div v-transfer-dom>
<confirm v-model="show"
:title="title"
:confirm-text="right_text"
:cancel-text="left_text"
:close-on-confirm="close_confirm"
ref="confirm"
@on-cancel="onCancel"
@on-confirm="onConfirm"
@on-show="onShow"
@on-hide="onHide">
<slot></slot>
</confirm>
</div>
</template>
<script>
import { TransferDomDirective as TransferDom, Confirm } from 'vux'
export default {
components: { Confirm },
directives: { TransferDom },
props: {
title: {
required: true
},
value: {
required: true
},
left_text: {
required: true
},
right_text: {
required: true
},
close_confirm: {
default: false
}
},
data () {
return {
}
},
mounted () {
},
computed: {
show: {
get () {
return this.value
},
set (val) {}
}
},
methods: {
onCancel () {
this.$emit('on-cancel');
},
onConfirm (msg) {
this.$emit('on-confirm', msg);
},
onHide () {
this.$emit('on-hide');
},
onShow () {
this.$emit('on-show');
}
}
}
</script>
<style lang="less">
.weui-dialog__btn.weui-dialog__btn_primary {
color: #353535;
}
.weui-dialog__hd {
background-color: #8ea9cf;
color: #FFFFFF;
padding: 0.5em 1.6em 0.5em;
}
</style>
<template lang="html">
<div class="circleBtn" @click="onClick">
<i>+</i>
<slot name="text" class="text"></slot>
</div>
</template>
<script>
export default {
data () {
return {
}
},
methods: {
onClick () {
this.$emit('circleClick')
}
}
}
</script>
<style lang="less">
.circleBtn{
display: inline-block;
width: 2rem;
height: 2rem;
border: 1px solid #a2b8d6;
border-radius: 50%;
color: #a2b8d6;
position: relative;
i {
height: 1rem;
line-height: 1rem;
font-size: 1.8rem;
font-weight: 100;
font-style: normal;
position: absolute;
left: 50%;
top: 0;
margin-left: -0.6rem;
}
span{
display: inline-block;
width: 2rem;
font-size: 0.7rem;
text-align: center;
position: absolute;
left: 50%;
bottom: 0;
margin-left: -1rem;
}
}
</style>
<template lang="html">
<div class="">
<demo @circleClick="add"><span slot="text">添加</span></demo>
<demo @circleClick="relative"><span slot="text">关联</span></demo>
</div>
</template>
<script>
import Demo from 'components/customBtn/circleBtn'
export default {
components: {
Demo
},
methods: {
add () {
console.warn('addd');
},
relative () {
console.warn('relative');
}
}
}
</script>
<style lang="css">
</style>
<template>
<div class="">
<datetime
:title="dateTitle"
:show="dateShow"
:confirm_text="confirm_text"
:cancel_text="cancel_text"
@on-cancel="onCancel"
@on-confirm="onConfirm"
@on-hide="onHide"
@on-change="onChange"
></datetime>
</div>
</template>
<script>
import datetime from 'components/datetime/index'
export default {
components: {
datetime
},
data () {
return {
dateTitle: '生日',
dateShow: true,
confirm_text: '确定',
cancel_text: '取消'
}
},
methods: {
onCancel () {
console.warn('on-cancel');
},
onConfirm (msg) {
console.warn('on-confirm', msg);
},
onHide () {
console.warn('on-hide');
},
onShow () {
console.warn('on-show');
},
onChange () {
console.warn('on-show');
}
}
}
</script>
\ No newline at end of file
<template>
<div class="">
<group>
<datetime
v-model="value"
@on-change="onChange"
:title="title"
:confirm-text="confirm_text"
:cancel-text="cancel_text"
:placeholder="placeholder"
@on-cancel="onCancel"
@on-confirm="onConfirm"
@on-hide="onHide"></datetime>
</group>
</div>
</template>
<script>
/*
参考vux文档 datetime
*/
import { Datetime, Group, XButton } from 'vux'
export default {
components: {
Datetime,
Group,
XButton
},
props: ['title', 'confirm_text', 'cancel_text', 'placeholder', 'value'],
data () {
},
mounted () {},
methods: {
onChange (value) {
// console.warn('on-change', value)
},
log (str1, str2 = '') {
console.warn(str1, str2)
},
onConfirm (val) {
this.$emit('on-confirm', val)
},
onCancel () {
this.$emit('on-cancel')
},
onHide () {
this.$emit('on-hide')
}
}
}
</script>
<style lang="less">
.dp-header {
background-color: #89A9CF;
color: #fff;
.dp-item.dp-left, .dp-item.dp-right {
color: #fff!important;
font-size: 14px;
}
}
.dp-item {
.scroller-item {
font-size:14px;
}
.scroller-item-selected {
font-size: 16px;
}
}
</style>
<template lang="html">
<div class="setTimeBox" v-transfer-dom>
<x-dialog v-model="this.$store.state.setTimeBox_show">
<div class="title">设置门店到货时间</div>
<div class="title-prov">{{supplier_name}}</div>
<div class="title-materiel">{{materiel_name}}</div>
<div class="content" v-if="dist_plan.dist_way === 'D'">
<div class="content-title">每天订货</div>
<ul class="list">
<li v-for="(item, index) in store_list" :key="index">
<flexbox>
<flexbox-item :span="4">
<div class="store-name">
<i class="fa fa-minus-circle fa-2x" @click="deleteItem(index)"></i>
<span v-if="item.store_name">{{item.store_name}}</span>
<span v-else>{{item.name}}</span>
</div>
</flexbox-item>
<flexbox-item style="margin-left:2.5rem;" :span="8">
<div>
第<selector class="selector" v-model="item.dist_day" placeholder="请选择" :options="distDay" @on-change="preventS"></selector>天<selector class="selector" v-model="item.dist_time" placeholder="请选择" :options="distTime" @on-change="preventS"></selector>到货
</div>
</flexbox-item>
</flexbox>
</li>
</ul>
</div>
<div class="content" v-if="dist_plan.dist_way === 'W'">
<div class="content-title">每{{getWeek('order')}}订货</div>
<ul class="list">
<li v-for="(item, index) in store_list" :key="index">
<flexbox>
<flexbox-item :span="4">
<div class="store-name">
<i class="fa fa-minus-circle fa-2x" @click="deleteItem(index)"></i>
<span v-if="item.store_name">{{item.store_name}}</span>
<span v-else>{{item.name}}</span>
</div>
</flexbox-item>
<flexbox-item style="margin-left:2.5rem;" :span="8">
<div>
<selector class="selector" v-model="item.dist_day" :placeholder="'请选择'" :options="distWeek" @on-change="preventS"></selector>
<selector class="selector" v-model="item.dist_time" :placeholder="'请选择'" :options="distTime" @on-change="preventS"></selector>
到货
</div>
</flexbox-item>
</flexbox>
</li>
</ul>
</div>
<div class="content" v-if="dist_plan.dist_way === 'M'">
<div class="content-title">每月{{getMonth(dist_plan.order_day)}}订货</div>
<ul class="list">
<li v-for="(item, index) in store_list" :key="index">
<flexbox>
<flexbox-item :span="4">
<div class="store-name">
<i class="fa fa-minus-circle fa-2x" @click="deleteItem(index)"></i>
<span v-if="item.store_name">{{item.store_name}}</span>
<span v-else>{{item.name}}</span>
</div>
</flexbox-item>
<flexbox-item style="margin-left:2.5rem;" :span="8">
<div>
<selector class="selector" v-model="item.dist_day" placeholder="请选择" :options="distMonth" @on-change="preventS"></selector>
<selector class="selector" v-model="item.dist_time" placeholder="请选择" :options="distTime" @on-change="preventS"></selector>
到货
</div>
</flexbox-item>
</flexbox>
</li>
</ul>
</div>
<div class="add" @click="addItem">
<i class="fa fa-plus-circle fa-2x"></i>
<span>添加相同送货线路的门店</span>
</div>
<div class="set-finish">
<div @click="finishSet()" class="set-finish-btn">确定</div>
</div>
<confirm v-model="show"
:title="'操作提示'"
@on-cancel="onCancel"
@on-confirm="onConfirm">
<div style="padding-top:0.8rem;">你确定要放弃修改并退出吗</div>
</confirm>
</x-dialog>
</div>
</template>
<script>
import {
TransferDomDirective as TransferDom,
XDialog,
Flexbox,
FlexboxItem,
Selector,
Confirm
} from 'vux'
import { compat } from 'logistics/static/js/compatibility'
export default {
components: {
TransferDom,
XDialog,
Flexbox,
FlexboxItem,
Selector,
Confirm
},
mixins: [compat],
mounted () {
this.$nextTick(() => {
let mask = document.getElementsByClassName('setTimeBox')[0].getElementsByClassName('weui-mask')[0];
mask.addEventListener('click', () => {
this.show = true;
});
});
},
props: ['supplier_name', 'list', 'materiel_name'],
data () {
return {
distDay: [
{
value: 2,
key: 'DAY+1d'
},
{
value: 3,
key: 'DAY+2d'
},
{
value: 4,
key: 'DAY+3d'
},
{
value: 5,
key: 'DAY+4d'
},
{
value: 6,
key: 'DAY+5d'
},
{
value: 7,
key: 'DAY+6d'
},
{
value: 8,
key: 'DAY+7d'
},
{
value: 9,
key: 'DAY+8d'
},
{
value: 10,
key: 'DAY+9d'
}
],
distWeek: [
{
value: '周一',
key: 'MON'
},
{
value: '周二',
key: 'TUE'
},
{
value: '周三',
key: 'WED'
},
{
value: '周四',
key: 'THU'
},
{
value: '周五',
key: 'FRI'
},
{
value: '周六',
key: 'SAT'
},
{
value: '周日',
key: 'SUN'
},
{
value: '下周一',
key: 'MON+1w'
},
{
value: '下周二',
key: 'TUE+1w'
},
{
value: '下周三',
key: 'WED+1w'
},
{
value: '下周四',
key: 'THU+1w'
},
{
value: '下周五',
key: 'FRI+1w'
},
{
value: '下周六',
key: 'SAT+1w'
},
{
value: '下周日',
key: 'SUN+1w'
}
],
distMonth: [
{
value: '1号',
key: '1'
},
{
value: '2号',
key: '2'
},
{
value: '3号',
key: '3'
},
{
value: '4号',
key: '4'
},
{
value: '5号',
key: '5'
},
{
value: '6号',
key: '6'
},
{
value: '7号',
key: '7'
},
{
value: '8号',
key: '8'
},
{
value: '9号',
key: '9'
},
{
value: '10号',
key: '10'
},
{
value: '11号',
key: '11'
},
{
value: '12号',
key: '12'
},
{
value: '13号',
key: '13'
},
{
value: '14号',
key: '14'
},
{
value: '15号',
key: '15'
},
{
value: '16号',
key: '16'
},
{
value: '17号',
key: '17'
},
{
value: '18号',
key: '18'
},
{
value: '19号',
key: '19'
},
{
value: '20号',
key: '20'
},
{
value: '21号',
key: '21'
},
{
value: '22号',
key: '22'
},
{
value: '23号',
key: '23'
},
{
value: '24号',
key: '24'
},
{
value: '25号',
key: '25'
},
{
value: '26号',
key: '26'
},
{
value: '27号',
key: '27'
},
{
value: '28号',
key: '28'
},
{
value: '29号',
key: '29'
},
{
value: '30号',
key: '30'
},
{
value: '31号',
key: '31'
},
{
value: '月末',
key: 'last'
},
{
value: '次月1号',
key: '1+1m'
},
{
value: '次月2号',
key: '2+1m'
},
{
value: '次月3号',
key: '3+1m'
},
{
value: '次月4号',
key: '4+1m'
},
{
value: '次月5号',
key: '5+1m'
},
{
value: '次月6号',
key: '6+1m'
},
{
value: '次月7号',
key: '7+1m'
},
{
value: '次月8号',
key: '8+1m'
},
{
value: '次月9号',
key: '9+1m'
},
{
value: '次月10号',
key: '10+1m'
},
{
value: '次月11号',
key: '11+1m'
},
{
value: '次月12号',
key: '12+1m'
},
{
value: '次月13号',
key: '13+1m'
},
{
value: '次月14号',
key: '14+1m'
},
{
value: '次月15号',
key: '15+1m'
},
{
value: '次月16号',
key: '16+1m'
},
{
value: '次月17号',
key: '17+1m'
},
{
value: '次月18号',
key: '18+1m'
},
{
value: '次月19号',
key: '19+1m'
},
{
value: '次月20号',
key: '20+1m'
},
{
value: '次月21号',
key: '21+1m'
},
{
value: '次月22号',
key: '22+1m'
},
{
value: '次月23号',
key: '23+1m'
},
{
value: '次月24号',
key: '24+1m'
},
{
value: '次月25号',
key: '25+1m'
},
{
value: '次月26号',
key: '26+1m'
},
{
value: '次月27号',
key: '27+1m'
},
{
value: '次月28号',
key: '28+1m'
},
{
value: '次月29号',
key: '29+1m'
},
{
value: '次月30号',
key: '30+1m'
},
{
value: '次月31号',
key: '31+1m'
},
{
value: '次月月末',
key: 'last+1m'
}
],
distTime: [
{
value: '00:00',
key: '00:00'
},
{
value: '00:30',
key: '00:30'
},
{
value: '01:00',
key: '01:00'
},
{
value: '01:30',
key: '01:30'
},
{
value: '02:00',
key: '02:00'
},
{
value: '02:30',
key: '02:30'
},
{
value: '03:00',
key: '03:00'
},
{
value: '03:30',
key: '03:30'
},
{
value: '04:00',
key: '04:00'
},
{
value: '04:30',
key: '04:30'
},
{
value: '05:00',
key: '05:00'
},
{
value: '05:30',
key: '05:30'
},
{
value: '06:00',
key: '06:00'
},
{
value: '06:30',
key: '06:30'
},
{
value: '07:30',
key: '07:30'
},
{
value: '08:00',
key: '08:00'
},
{
value: '08:30',
key: '08:30'
},
{
value: '09:00',
key: '09:00'
},
{
value: '09:30',
key: '09:30'
},
{
value: '10:00',
key: '10:00'
},
{
value: '10:30',
key: '10:30'
},
{
value: '11:00',
key: '11:00'
},
{
value: '11:30',
key: '11:30'
},
{
value: '12:00',
key: '12:00'
},
{
value: '12:30',
key: '12:30'
},
{
value: '13:00',
key: '13:00'
},
{
value: '13:30',
key: '13:30'
},
{
value: '14:00',
key: '14:00'
},
{
value: '14:30',
key: '14:30'
},
{
value: '15:00',
key: '15:00'
},
{
value: '15:30',
key: '15:30'
},
{
value: '16:00',
key: '16:00'
},
{
value: '16:30',
key: '16:30'
},
{
value: '17:00',
key: '17:00'
},
{
value: '17:30',
key: '17:30'
},
{
value: '18:00',
key: '18:00'
},
{
value: '18:30',
key: '18:30'
},
{
value: '19:00',
key: '19:00'
},
{
value: '19:30',
key: '19:30'
},
{
value: '20:00',
key: '20:00'
},
{
value: '20:30',
key: '20:30'
},
{
value: '21:00',
key: '21:00'
},
{
value: '21:30',
key: '21:30'
},
{
value: '22:00',
key: '22:00'
},
{
value: '22:30',
key: '22:30'
},
{
value: '23:00',
key: '23:00'
},
{
value: '23:30',
key: '23:30'
}
],
dist_plan: {},
store_list: [],
show: false
}
},
/***
* ----------------------------------------------------------------------------
* 父子组件没有嵌套关系,无法获得数组中的index值,需要获得父级当前正在设置的计划
* 并把此计划已设置完的订货计划传到vuex里
* 子组件在从vuex里获得设置到一半的订货计划,在子组件中设置到货计划
* 因为子组件与父组件一起刷新所以mounted不适用
* 需要用watch监听vuex里的stat状态,当父级设置完成订货计划时
* 子组件再设置完到货计划时,将完成的数据一起传给父组件
* ----------------------------------------------------------------------------
* 注意:因为子组件中还可以添加相同线路的门店,已添加的门店若已设置到货时间,那么为了
* 保证已设置的数据不会被清空,需要存到vuex里,当添加完门店回到此组件时,再次展示,并且
* 展示添加的门店。
* ----------------------------------------------------------------------------
*/
computed: {
getOrderDetail () {
return this.$store.state.order_detail;
}
},
watch: {
getOrderDetail (val) {
for (let i in val) {
this.dist_plan[i] = val[i];
};
if (this.dist_plan.dist_way === 'W') {
this.distWeek.forEach((v, i) => {
if (this.dist_plan.order_day === v.key) {
this.distWeek = this.distWeek.slice(i);
}
});
} else if (this.dist_plan.dist_way === 'M') {
this.distMonth.forEach((v, i) => {
if (this.dist_plan.order_day === v.key) {
this.distMonth = this.distMonth.slice(i);
}
});
}
},
list: function (val) {
let list = [];
for (let i = 0; i < val.length; i++) {
list.push(val[i]);
}
this.store_list = _.cloneDeep(list);
}
},
methods: {
finishSet () {
for (let n = 0; n < this.store_list.length; n++) {
if (!this.store_list[n].dist_day || !this.store_list[n].dist_time) {
this.$vux.toast.show({
type: 'warn',
text: '到货日期或到货时间不能为空'
});
return;
}
}
this.$store.commit('emptyOldList');
let arr = [];
let list = this.store_list;
list.map(v => {
if (!v.route_name) {
v.route_name = v.city;
}
return v;
})
let obj = _.groupBy(list, 'route_name');
for (let i in obj) {
let saveData = {
route_name: `${i}${obj[i].length}`,
store_list: obj[i]
}
arr.push(saveData);
}
this.$emit('compelete', _.cloneDeep(arr));
this.$store.commit('checksetTimeBox');
},
getWeek (t) {
let str;
switch (t) {
case 'order':
str = this.dist_plan.order_day;
switch (str) {
case 'MON':
return '周一';
case 'TUE':
return '周二';
case 'WED':
return '周三';
case 'THU':
return '周四';
case 'FRI':
return '周五';
case 'SAT':
return '周六';
case 'SUN':
return '周日';
};
break;
case 'dist':
str = this.dist_plan.store_list[arguments[1]].dist_day;
switch (str) {
case 'MON':
return '周一';
case 'TUE':
return '周二';
case 'WED':
return '周三';
case 'THU':
return '周四';
case 'FRI':
return '周五';
case 'SAT':
return '周六';
case 'SUN':
return '周日';
case 'MON+1w':
return '下周一';
case 'TUE+1w':
return '下周二';
case 'WED+1w':
return '下周三';
case 'THU+1w':
return '下周四';
case 'FRI+1w':
return '下周五';
case 'SAT+1w':
return '下周六';
case 'SUN+1w':
return '下周日';
};
break;
}
},
getMonth (str) {
if (str === 'last') {
return '月末'
} else {
if (str.split('+').length > 1) {
if (str.split('+')[0] === 'last') {
return '次月月末'
} else {
return '次月' + str.split('+')[0] + '号'
}
} else {
return str + '号';
}
}
},
deleteItem (i) {
this.store_list.splice(i, 1);
},
addItem () {
this.$store.commit('checksetTimeBox');
this.$store.commit('saveOldList', this.store_list);
this.$emit('addStoreInChild', this.store_list);
},
onCancel () {
this.show = false;
},
onConfirm () {
this.$store.commit('checksetTimeBox');
this.$store.commit('emptyOldList');
}
}
}
</script>
<style lang="less">
.setTimeBox {
font-size: 14px;
color: #666;
.title {
font-size: 18px;
background: #8ea9cf;
color: #fff;
text-align: center;
padding: 0.6rem 0;
}
.title-prov,
.title-materiel {
padding: 0.2rem 0 0.2rem 0.4rem;
font-size: 16px;
text-align: left;
}
.title-prov {
color: #333;
}
.title-materiel {
color: #8ea9cf;
}
.content {
.content-title {
font-size: 16px;
padding: 0.4rem 0;
text-align: center;
}
.list {
margin: 0;
max-height: 10rem;
overflow-y: auto;
overflow-x: hidden;
li {
list-style: none;
padding: 0.4rem;
border-top: 1px solid #c7c7c7;
.store-name {
i {
color: #8ea9cf;
vertical-align: middle;
}
span {
vertical-align: middle;
}
}
}
}
select {
width: 4rem;
margin: 0 3px;
padding-left: 10px;
background-color: #fff;
border-radius: 4px;
border: 1px solid #dcdfe6;
color: #606266;
height: 40px;
line-height: 40px;
outline: 0;
transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
}
}
.add {
text-align: center;
color: #8ea9cf;
padding: 0.5rem 0;
border-top: 3px solid #c7c7c7;
border-bottom: 3px solid #c7c7c7;
i {
vertical-align: middle;
}
span {
vertical-align: middle;
}
}
.set-finish {
width: 90%;
margin: 0 auto;
margin-top: 1rem;
border-radius: 5px;
color: #fff;
background: #8ea9cf;
padding: 0.4rem 0;
}
}
.vux-selector {
display: inline-block !important;
.weui-select {
padding-right: 0 !important;
}
}
</style>
<!--
复选门店到货时间弹出框
-->
<template>
<div class="setTimeBox" v-transfer-dom>
<x-dialog class="set-bom-prop" v-model="this.$store.state.setTimeBox_show">
<div class="set-bom-prop-title">
<div>设置门店到货时间</div>
</div>
<ul class="title-list">
<li class="supplier">{{supplier_name}}</li>
<li class="materiel">{{materiel_name}}</li>
</ul>
<div v-if="dist_plan.dist_way === 'D'">
<div class="row-title">
每天订货
</div>
<ul class="row-list">
<li v-for="(item, index) in store_list" :key="index">
<flexbox align="center">
<flexbox-item class="store-name" :span="4">
<i class="fa fa-minus-circle fa-2x" @click="deleteItem(index)"></i>
<span>{{item.name}}</span>
</flexbox-item>
<flexbox-item :span="8">
第<select v-model="item.dist_day">
<option v-for="(o, oi) in distDay" :value="o.val" :key="oi">{{o.lab}}</option>
</select>天<select v-model="item.dist_time">
<option v-for="(o, oi) in distTime" :value="o" :key="oi">{{o}}</option>
</select>到货
</flexbox-item>
</flexbox>
</li>
</ul>
<div class="add-store" @click="addItem">
<i class="fa fa-plus-circle fa-2x"></i>
<span>添加相同送货线路的门店</span>
</div>
</div>
<ul class="row-list" v-if="dist_plan.dist_way === 'W'">
<li class="row-title">
每周{{getWeek('order')}}订货
</li>
<li v-for="(item, index) in store_list" :key="index">
<flexbox align="center">
<flexbox-item class="store-name" :span="4">
<i class="fa fa-minus-circle fa-2x" @click="deleteItem(index)"></i>
<span>{{item.name}}</span>
</flexbox-item>
<flexbox-item :span="8">
<select v-model="item.dist_day">
<option v-for="(o, oi) in distWeek" :value="o.val" :key="oi">{{o.lab}}</option>
</select>
<select v-model="item.dist_time">
<option v-for="(o, oi) in distTime" :value="o" :key="oi">{{o}}</option>
</select>
到货
</flexbox-item>
</flexbox>
</li>
<li class="add-store" @click="addItem">
<i class="fa fa-plus-circle fa-2x"></i>
<span>添加相同送货线路的门店</span>
</li>
</ul>
<ul class="row-list" v-if="dist_plan.dist_way === 'M'">
<li class="row-title">
每月{{getMonth(dist_plan.order_day)}}订货
</li>
<li v-for="(item, index) in store_list" :key="index">
<flexbox align="center">
<flexbox-item class="store-name" :span="4">
<i class="fa fa-minus-circle fa-2x" @click="deleteItem(index)"></i>
<span>{{item.name}}</span>
</flexbox-item>
<flexbox-item :span="8">
<select v-model="item.dist_day">
<option v-for="(o, oi) in distMonth" :value="o.val" :key="oi">{{o.lab}}</option>
</select>
<select v-model="item.dist_time">
<option v-for="(o, oi) in distTime" :value="o" :key="oi">{{o}}</option>
</select>
到货
</flexbox-item>
</flexbox>
</li>
<li class="add-store" @click="addItem">
<i class="fa fa-plus-circle fa-2x"></i>
<span>添加相同送货线路的门店</span>
</li>
</ul>
<div class="set-finish">
<div @click="finishSet()" class="set-finish-btn">确定</div>
</div>
</x-dialog>
</div>
</template>
<script>
import { Flexbox, FlexboxItem, XDialog, TransferDomDirective as TransferDom, Popup, Picker } from 'vux'
export default {
components: {
Flexbox, FlexboxItem, XDialog, TransferDom, Popup, Picker
},
mounted () {
this.$nextTick(() => {
let mask = document.getElementsByClassName('setTimeBox')[0].getElementsByClassName('weui-mask')[0];
mask.addEventListener('click', () => {
this.$store.commit('checksetTimeBox');
this.$store.commit('emptyOldList');
});
});
},
props: ['supplier_name', 'list', 'materiel_name'],
data () {
return {
distDay: [
{
lab: 2,
val: 'DAY+1d'
},
{
lab: 3,
val: 'DAY+2d'
},
{
lab: 4,
val: 'DAY+3d'
},
{
lab: 5,
val: 'DAY+4d'
},
{
lab: 6,
val: 'DAY+5d'
},
{
lab: 7,
val: 'DAY+6d'
},
{
lab: 8,
val: 'DAY+7d'
},
{
lab: 9,
val: 'DAY+8d'
},
{
lab: 10,
val: 'DAY+9d'
}
],
distWeek: [
{
lab: '周一',
val: 'MON'
},
{
lab: '周二',
val: 'TUE'
},
{
lab: '周三',
val: 'WED'
},
{
lab: '周四',
val: 'THU'
},
{
lab: '周五',
val: 'FRI'
},
{
lab: '周六',
val: 'SAT'
},
{
lab: '周日',
val: 'SUN'
},
{
lab: '下周一',
val: 'MON+1w'
},
{
lab: '下周二',
val: 'TUE+1w'
},
{
lab: '下周三',
val: 'WED+1w'
},
{
lab: '下周四',
val: 'THU+1w'
},
{
lab: '下周五',
val: 'FRI+1w'
},
{
lab: '下周六',
val: 'SAT+1w'
},
{
lab: '下周日',
val: 'SUN+1w'
}
],
distMonth: [
{
lab: '1号',
val: '1'
},
{
lab: '2号',
val: '2'
},
{
lab: '3号',
val: '3'
},
{
lab: '4号',
val: '4'
},
{
lab: '5号',
val: '5'
},
{
lab: '6号',
val: '6'
},
{
lab: '7号',
val: '7'
},
{
lab: '8号',
val: '8'
},
{
lab: '9号',
val: '9'
},
{
lab: '10号',
val: '10'
},
{
lab: '11号',
val: '11'
},
{
lab: '12号',
val: '12'
},
{
lab: '13号',
val: '13'
},
{
lab: '14号',
val: '14'
},
{
lab: '15号',
val: '15'
},
{
lab: '16号',
val: '16'
},
{
lab: '17号',
val: '17'
},
{
lab: '18号',
val: '18'
},
{
lab: '19号',
val: '19'
},
{
lab: '20号',
val: '20'
},
{
lab: '21号',
val: '21'
},
{
lab: '22号',
val: '22'
},
{
lab: '23号',
val: '23'
},
{
lab: '24号',
val: '24'
},
{
lab: '25号',
val: '25'
},
{
lab: '26号',
val: '26'
},
{
lab: '27号',
val: '27'
},
{
lab: '28号',
val: '28'
},
{
lab: '29号',
val: '29'
},
{
lab: '30号',
val: '30'
},
{
lab: '31号',
val: '31'
},
{
lab: '月末',
val: 'last'
},
{
lab: '次月1号',
val: '1+1m'
},
{
lab: '次月2号',
val: '2+1m'
},
{
lab: '次月3号',
val: '3+1m'
},
{
lab: '次月4号',
val: '4+1m'
},
{
lab: '次月5号',
val: '5+1m'
},
{
lab: '次月6号',
val: '6+1m'
},
{
lab: '次月7号',
val: '7+1m'
},
{
lab: '次月8号',
val: '8+1m'
},
{
lab: '次月9号',
val: '9+1m'
},
{
lab: '次月10号',
val: '10+1m'
},
{
lab: '次月11号',
val: '11+1m'
},
{
lab: '次月12号',
val: '12+1m'
},
{
lab: '次月13号',
val: '13+1m'
},
{
lab: '次月14号',
val: '14+1m'
},
{
lab: '次月15号',
val: '15+1m'
},
{
lab: '次月16号',
val: '16+1m'
},
{
lab: '次月17号',
val: '17+1m'
},
{
lab: '次月18号',
val: '18+1m'
},
{
lab: '次月19号',
val: '19+1m'
},
{
lab: '次月20号',
val: '20+1m'
},
{
lab: '次月21号',
val: '21+1m'
},
{
lab: '次月22号',
val: '22+1m'
},
{
lab: '次月23号',
val: '23+1m'
},
{
lab: '次月24号',
val: '24+1m'
},
{
lab: '次月25号',
val: '25+1m'
},
{
lab: '次月26号',
val: '26+1m'
},
{
lab: '次月27号',
val: '27+1m'
},
{
lab: '次月28号',
val: '28+1m'
},
{
lab: '次月29号',
val: '29+1m'
},
{
lab: '次月30号',
val: '30+1m'
},
{
lab: '次月31号',
val: '31+1m'
},
{
lab: '次月月末',
val: 'last+1m'
}
],
distTime: [
'00:00', '00:30', '01:00', '01:30', '02:00', '02:30', '03:00', '03:30', '04:00', '04:30', '05:00', '05:30', '06:00', '06:30', '07:00', '07:30', '08:00', '08:30', '09:00', '09:30', '10:00', '10:30', '11:00', '11:30', '12:00', '12:30', '13:00', '13:30', '14:00', '14:30', '15:00', '15:30', '16:00', '16:30', '17:00', '17:30', '18:00', '18:30', '19:00', '19:30', '20:00', '20:30', '21:00', '21:30', '22:00', '22:30', '23:00', '23:30'
],
dist_plan: {},
store_line: {
city: '上海3',
store_list: [
{
store_id: '0b805b3a3a9b4d36b5dd9a876592de15',
name: 'XXX门店',
dist_day: '',
dist_time: ''
},
{
store_id: '433f045dba264b6ea5d6bb717589974c',
name: 'XXX门店',
dist_day: '',
dist_time: ''
},
{
store_id: 'd6346c870e384d7ea0d093fc94a82882',
name: 'XXX门店',
dist_day: '',
dist_time: ''
}
]
},
store_list: []
}
},
/***
* ----------------------------------------------------------------------------
* 父子组件没有嵌套关系,无法获得数组中的index值,需要获得父级当前正在设置的计划
* 并把此计划已设置完的订货计划传到vuex里
* 子组件在从vuex里获得设置到一半的订货计划,在子组件中设置到货计划
* 因为子组件与父组件一起刷新所以mounted不适用
* 需要用watch监听vuex里的stat状态,当父级设置完成订货计划时
* 子组件再设置完到货计划时,将完成的数据一起传给父组件
* ----------------------------------------------------------------------------
* 注意:因为子组件中还可以添加相同线路的门店,已添加的门店若已设置到货时间,那么为了
* 保证已设置的数据不会被清空,需要存到vuex里,当添加完门店回到此组件时,再次展示,并且
* 展示添加的门店。
* ----------------------------------------------------------------------------
*/
computed: {
getOrderDetail () {
return this.$store.state.order_detail;
}
},
watch: {
getOrderDetail (val) {
for (let i in val) {
this.dist_plan[i] = val[i];
}
},
list: function (val) {
let list = [];
for (let i = 0; i < val.length; i++) {
list.push(val[i]);
}
this.store_list = _.cloneDeep(list);
}
},
methods: {
finishSet () {
for (let n = 0; n < this.store_list.length; n++) {
if (!this.store_list[n].dist_day || !this.store_list[n].dist_time) {
alert('到货日期或到货时间不能为空');
return;
}
}
this.$store.commit('emptyOldList');
let arr = [];
let obj = {};
let list = this.store_list;
list.forEach((e, i) => {
if (obj.route_name === (e.city || e.route_name)) {
obj.store_list.push(e);
} else if (obj.route_name && obj.route_name !== (e.city || e.route_name)) {
arr.push(obj);
obj = {};
obj.route_name = (e.city || e.route_name);
obj.store_list = [];
obj.store_list.push(e);
} else {
obj.route_name = (e.city || e.route_name);
obj.store_list = [];
obj.store_list.push(e);
}
if (i === list.length - 1) {
arr.push(obj);
}
})
for (let j = 0; j < arr.length; j++) {
arr[j].route_name += arr[j].store_list.length;
}
this.$emit('compelete', _.cloneDeep(arr));
this.$store.commit('checksetTimeBox');
},
getWeek (t) {
let str;
switch (t) {
case 'order':
str = this.dist_plan.order_day;
switch (str) {
case 'MON':
return '周一';
case 'TUE':
return '周二';
case 'WED':
return '周三';
case 'THU':
return '周四';
case 'FRI':
return '周五';
case 'SAT':
return '周六';
case 'SUN':
return '周日';
};
break;
case 'dist':
str = this.dist_plan.store_list[arguments[1]].dist_day;
switch (str) {
case 'MON':
return '周一';
case 'TUE':
return '周二';
case 'WED':
return '周三';
case 'THU':
return '周四';
case 'FRI':
return '周五';
case 'SAT':
return '周六';
case 'SUN':
return '周日';
case 'MON+1w':
return '下周一';
case 'TUE+1w':
return '下周二';
case 'WED+1w':
return '下周三';
case 'THU+1w':
return '下周四';
case 'FRI+1w':
return '下周五';
case 'SAT+1w':
return '下周六';
case 'SUN+1w':
return '下周日';
};
break;
}
},
getMonth (str) {
if (str !== 'last') {
if (str.split('+').length === 1) {
return str + '号';
} else {
return '次月' + str + '号';
}
} else if (str === 'last') {
return '月末';
}
},
deleteItem (i) {
this.store_list.splice(i, 1);
},
addItem () {
this.$store.commit('checksetTimeBox');
this.$store.commit('saveOldList', this.store_list);
this.$emit('addStoreInChild', this.store_list);
}
}
}
</script>
<style lang="less" scoped>
.set-bom-prop {
font-size: 14px;
color: #666;
}
.weui-dialog {
padding-bottom: 1rem !important;
max-width: 800px !important;
}
.red {
color: red;
font-style: normal;
}
.green {
color: green;
}
.title-list {
font-size: 16px;
color: #333;
}
.supplier {
text-align: left;
padding: 0.4rem 0.8rem;
}
.materiel {
text-align: left;
padding: 0.4rem 0.8rem;
color: #8ea8cf;
}
select {
width: 4rem;
margin: 0 3px;
padding-left: 10px;
background-color: #fff;
border-radius: 4px;
border: 1px solid #dcdfe6;
color: #606266;
height: 40px;
line-height: 40px;
outline: 0;
transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
}
.setTimeBox {
ul {
list-style: none;
margin: 0;
padding: 0;
}
.set-bom-prop {
padding: 0;
min-height: 40px;
font-size: 15px;
line-height: 1.3;
word-wrap: break-word;
word-break: break-all;
color: #999999;
touch-action: none;
.set-bom-prop-title {
background-color: #8ea9cf;
color: #FFFFFF;
padding: 0.5em 1.6em 0.5em;
font-size: 18px;
}
.row-title {
text-align: center;
padding: 0.8rem 0;
border-bottom: 1px solid #c7c7c7;
}
.row-list {
max-height: 25rem;
overflow-x: hidden;
overflow-y: auto;
list-style: none;
li {
display: flex;
padding: 0.4rem 0 0.4rem 0.8rem;
border-bottom: 1px solid #c7c7c7;
em {
font-style: normal;
}
.el-input {
width: 4rem;
margin: 0 3px;
}
.el-input__inner {
padding: 0;
padding-left: 10px;
}
}
.store-name {
i {
vertical-align: middle;
color: #8ea8cf;
}
span {
vertical-align: middle;
line-height: 2em;
}
}
}
.add-store {
padding: 0.4rem 0 0.4rem 0 !important;
border-top: 2px solid #c7c7c7;
border-bottom: 2px solid #c7c7c7;
text-align: center;
i {
vertical-align: middle;
color: #8ea8cf;
}
span {
vertical-align: middle;
line-height: 2em;
}
}
.set-finish {
width: 90%;
margin: 0 auto;
margin-top: 1rem;
border-radius: 0.25rem;
color: white;
padding: 0.35rem 0;
background-color: #8ea8cf;
}
}
.el-input__prefix {
display: none;
}
}
</style>
<template lang="html">
<div class="distplan_detail" v-if="dialog.route_index !== null">
<x-dialog :show="show">
<div class="dbox">
<p class="dialog-title">相同送货线路的门店</p>
<p style="text-align:center;">
每<span v-if="dialog.dist_way === 'D'">天</span><span v-if="dialog.dist_way === 'W'">{{getWeek(dialog.order_day)}}</span><span v-if="dialog.dist_way === 'M'">{{getMonth(dialog.order_day)}}</span>订
</p>
<div>
<p class="dialog-subtitle" style="color:#89a9cf">
{{dialog.store_list[dialog.route_index].route_name}}
</p>
<div class="dialog-store-wrap">
<flexbox justify="space-between">
<flexbox-item style="padding-left:2.8rem;text-align:left;">门店名称</flexbox-item>
<flexbox-item style="padding-right:1.2rem;text-align:right;">到货时间</flexbox-item>
</flexbox>
</div>
<div class="dialog-store">
<flexbox justify="space-between" v-for="(ite, i) in dialog.store_list[dialog.route_index].store_list" class="dialog-store-wrap dialog-store-item" :key="i">
<flexbox-item style="padding-left:8px;text-align:left;">{{ite.store_name}}</flexbox-item>
<flexbox-item style="padding-right:8px;text-align:right;" v-if="dialog.dist_way === 'D'">第{{getDay(ite.dist_day)}}天 {{ite.dist_time}} 到货</flexbox-item>
<flexbox-item style="padding-right:8px;text-align:right;" v-if="dialog.dist_way === 'W'">{{getWeek(ite.dist_day)}} {{ite.dist_time}} 到货</flexbox-item>
<flexbox-item style="padding-right:8px;text-align:right;" v-if="dialog.dist_way === 'M'">{{getMonth(ite.dist_day)}} {{ite.dist_time}} 到货</flexbox-item>
</flexbox>
</div>
</div>
<div v-if="type === 'view'" class="close" @click="close" style="margin-bottom:15px;">关闭</div>
<div v-if="type === 'edit'" class="btn-box" style="margin-bottom:15px;">
<div @click="close">关闭</div>
<div @click="edit">修改</div>
</div>
</div>
</x-dialog>
</div>
</template>
<script>
import { XDialog, Flexbox, FlexboxItem } from 'vux'
export default {
props: ['show', 'type', 'dialog'],
components: {
XDialog,
Flexbox,
FlexboxItem
},
methods: {
getDay (str) {
console.warn(str);
return (Number(str.split('+')[1][0]) + 1);
},
getWeek (str) {
switch (str) {
case 'MON':
return '周一';
case 'TUE':
return '周二';
case 'WED':
return '周三';
case 'THU':
return '周四';
case 'FRI':
return '周五';
case 'SAT':
return '周六';
case 'SUN':
return '周日';
case 'MON+1w':
return '下周一';
case 'TUE+1w':
return '下周二';
case 'WED+1w':
return '下周三';
case 'THU+1w':
return '下周四';
case 'FRI+1w':
return '下周五';
case 'SAT+1w':
return '下周六';
case 'SUN+1w':
return '下周日';
}
},
getMonth (str) {
if (str === 'last') {
return '月末'
} else {
if (str.split('+').length > 1) {
if (str.split('+')[0] === 'last') {
return '次月月末'
} else {
return '次月' + str.split('+')[0] + '号'
}
} else {
return str + '号';
}
}
},
close () {
this.$emit('close', 'store')
},
edit () {
this.$emit('edit', 'store')
}
}
}
</script>
<style lang="less">
.weui-dialog {
max-width: 600px;
}
.distplan_detail {
.dialog-title {
text-align: center;
padding: 0.6rem 0;
color: #fff;
background: #8ea8cf;
}
.dialog-content {
max-height: 25rem;
overflow-y: scroll;
}
.dialog-subtitle {
padding: 0.4rem 0.8rem;
text-align: left;
}
.dialog-wrap {
&:after {
display: block;
content: '';
clear: both;
}
.dialog-item {
float: left;
width: 45%;
padding: 0.2rem 0;
margin: 0.2rem 0.4rem;
text-align: center;
background: #F0EFF5;
border-radius: 3px;
}
}
.close {
width: 95%;
margin: 0 auto;
background: #8ea8cf;
text-align: center;
padding: 0.4rem 0;
color: #fff;
margin-top: 1rem;
border-radius: 5px;
}
.btn-box {
display: flex;
justify-content: space-around;
margin-top: 1rem;
div {
width: 46%;
border-radius: 5px;
padding: 0.4rem 0;
&:first-of-type {
background: #fff;
color: #89a9cf;
border: 1px solid #89a9cf;
}
&:last-of-type {
background: #89a9cf;
color: #fff;
}
}
}
.dialog-store {
max-height: 25rem;
overflow-y: auto;
}
.dialog-store-wrap {
border-bottom: 1px solid #d6d7dc;
padding-bottom: 0.6rem;
span {
padding: 0.3rem 0;
}
}
.dialog-store-item {
height: 3rem;
padding: 0.4rem 0;
}
}
</style>
<template lang="html">
<div style="background-color: white;">
<flexbox class="inline-wraper-content">
<flexbox-item :span="8" class="left-wrapper">
{{leftText}}
<slot name="left"></slot>
</flexbox-item>
<flexbox-item :span="4">
<slot name="right"></slot>
</flexbox-item>
</flexbox>
<flexbox-item>
<slot name="bottom"></slot>
</flexbox-item>
</div>
</template>
<script>
import { Flexbox, FlexboxItem } from 'vux'
export default {
props: ['leftText'],
components: { Flexbox, FlexboxItem }
}
</script>
<style lang="less">
.inline-wraper-content {
border-bottom: 1px solid #eee;
.left-wrapper {
text-indent: 0.5rem;
font-size: 0.85rem;
}
}
</style>
<template lang="html">
<inline-wraper :leftText="v.name" v-for="(v, k) in list" :key="k">
<template slot="left">
<div v-if="!v.is_set" class="unset-name">{{v.name}}</div>
<div v-else class="enable-set-name">{{v.name}} (已设置)</div>
</template>
<template slot="right">
<div style="">
<div v-if="!v.is_set" @click="setBom(v, k)" class="un-set-btn">设置BOM{{bom_code}}</div>
<div v-else @click="editBom(v, k)" class="set-enable-btn">设置BOM{{bom_code}}</div>
</div>
</template>
<template slot="bottom">
<div>
<div v-if="!item.data.is_set" @click="setBom(item.data)" class="un-set-btn">设置BOM{{bom_code > 1 ? bom_code : '1'}}</div>
<div v-else class="set-enable-btn" @click="setBom(item.data)">设置BOM{{bom_code > 1 ? bom_code : '1'}}</div>
</div>
</template>
</inline-wraper>
</template>
<script>
import inlineWraper from 'components/inlineWraper/index'
export default {
components: {inlineWraper}
}
</script>
<style lang="less">
</style>
<template lang="html">
<div class="">
<demo :value.sync="demo1" type="all" @update="choose(demo1)">test</demo>
</div>
</template>
<script>
import Demo from 'components/isCheckAll/index'
export default {
components: { Demo },
data () {
return {
demo1: true
}
},
methods: {
choose (val) {
console.warn(val);
}
}
}
</script>
<style lang="css">
</style>
<template>
<div class="checkBox" @click="updateValue">
<span class="checkItem allSelected" v-show="type === 'all' && value"></span>
<span class="checkItem noSelected" v-show="!value"></span>
<font><slot></slot></font>
</div>
</template>
<script>
export default {
name: 'isCheckAll',
methods: {
updateValue () {
this.$emit('update:value', !this.value)
}
},
props: {
value: {
type: Boolean,
default: false
},
type: {
type: String,
default: 'all'
}
}
}
</script>
<style lang="less">
.checkBox {
display: inline-block;
.checkItem {
display: inline-block;
width: 1.3rem;
height: 1.3rem;
text-align: center;
vertical-align: middle;
background-size: cover;
}
.allSelected {
background-image: url(../../assets/all.png);
}
.partSelected {
background-image: url(../../assets/part.png);
}
.noSelected {
background-image: url(../../assets/no.png);
}
font {
font-size: 0.9rem;
vertical-align: middle;
}
}
</style>
<template lang="html">
<div class="materiel_detail">
<x-dialog :show="show">
<div class="dbox">
<p class="dialog-title">同时订货的物料</p>
<div class="dialog-content">
<div v-for="(item, index) in list" :key="index">
<p class="dialog-subtitle">
{{item.class_name}}{{item.sku_list.length}}
</p>
<div class="dialog-wrap">
<p class="dialog-item" v-for="(it, i) in item.sku_list">{{it.sku_name}}</p>
</div>
</div>
</div>
<div v-if="type === 'view'" class="close" @click="close" style="margin-bottom:15px;">关闭</div>
<div v-if="type === 'edit'" class="btn-box" style="margin-bottom:15px;">
<div @click="close">关闭</div>
<div @click="edit">修改</div>
</div>
</div>
</x-dialog>
</div>
</template>
<script>
import { XDialog } from 'vux'
import { setTimeout } from 'timers';
export default {
props: ['type', 'list', 'show'],
components: {
XDialog
},
watch: {
list () {
setTimeout(() => {
let items = document.getElementsByClassName('dialog-item');
console.warn(items);
let leftHeight = 0;
let rightHeight = 0;
for (let i = 0; i < items.length; i++) {
if (!(i % 2)) {
leftHeight = $(items[i]).innerHeight();
} else if (i % 2) {
rightHeight = $(items[i]).innerHeight();
console.warn(leftHeight, rightHeight)
if (leftHeight > rightHeight) {
// items[i].style.height = leftHeight;
items[i].style.paddingBottom = items[i].style.paddingTop = (leftHeight - rightHeight) / 2 + 'px';
} else if (rightHeight > leftHeight) {
// items[i - 1].style.height = rightHeight;
items[i - 1].style.paddingBottom = items[i - 1].style.paddingTop = (rightHeight - leftHeight) / 2 + 'px';
}
}
}
}, 1)
}
},
methods: {
close () {
this.$emit('close', 'materiel')
},
edit () {
this.$emit('edit', 'materiel')
}
}
}
</script>
<style lang="less" scoped>
.materiel_detail {
.dialog-title {
text-align: center;
padding: 0.6rem 0;
color: #fff;
background: #8ea8cf;
}
.dialog-content {
max-height: 25rem;
overflow-y: scroll;
}
.dialog-subtitle {
padding: 0.4rem 0.8rem;
text-align: left;
}
.dialog-wrap {
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: space-between;
&:after {
display: block;
content: '';
clear: both;
}
.dialog-item {
width: 45%;
// padding: 0.2rem 0;
margin: 0.2rem 0.4rem;
text-align: center;
background: #F0EFF5;
border-radius: 3px;
}
}
.close {
width: 95%;
margin: 0 auto;
background: #8ea8cf;
text-align: center;
padding: 0.4rem 0;
color: #fff;
margin-top: 1rem;
border-radius: 5px;
}
.btn-box {
display: flex;
justify-content: space-around;
padding-top: 1rem;
margin-top: 1rem;
border-top: 1px solid #f0eff5;
div {
width: 46%;
padding: 0.4rem 0;
border-radius: 5px;
&:first-of-type {
background: #fff;
color: #89a9cf;
border: 1px solid #89a9cf;
}
&:last-of-type {
background: #89a9cf;
color: #fff;
}
}
}
.dialog-store-wrap {
display: flex;
justify-content: space-between;
padding: 0 0.8rem;
border-bottom: 1px solid #d6d7dc;
span {
padding: 0.3rem 0;
}
}
}
</style>
<!--
添加订货计划弹出框
-->
<template>
<div class="orderPlanBox" v-transfer-dom>
<x-dialog class="set-bom-prop" v-model="this.$store.state.orderPlanBox_show">
<div class="set-bom-prop-title">
<div :title="title">{{title}}</div>
</div>
<ul class="row-list title-list">
<li class="supplier-name">
{{supplier_name}}
</li>
<li class="materiel-name">
{{materiel}}
</li>
<li>
<label for="">
<span>订货频次<em class="red">*</em></span>
</label>
<div class="radioBox">
<el-radio-group v-model="list.dist_way">
<el-radio @change="changeRadio" label="D">每天</el-radio>
<el-radio @change="changeRadio" label="W">每周</el-radio>
<el-radio @change="changeRadio" label="M">每月</el-radio>
</el-radio-group>
</div>
</li>
<li v-if="list.dist_way === 'D' || list.dist_way === 'M'">
设置送货休息日(休息日将顺延送货)
</li>
<li v-if="list.dist_way === 'D' || list.dist_way === 'M'" class="dailyBox">
<el-checkbox-group class="dailyGroup" v-model="list.rest_date">
<el-checkbox label="MON">周一</el-checkbox>
<el-checkbox label="TUE">周二</el-checkbox>
<el-checkbox label="WED">周三</el-checkbox>
<el-checkbox label="THU">周四</el-checkbox>
<el-checkbox label="FRI">周五</el-checkbox>
<el-checkbox label="SAT">周六</el-checkbox>
<el-checkbox label="SUN">周日</el-checkbox>
</el-checkbox-group>
<div class="dailyLine"></div>
</li>
</ul>
<ul class="detailBox" v-if="list.dist_way === 'W'">
<li>
<flexbox>
<flexbox-item :span="3">
<label for="">
<span>订货计划<em class="red">*</em></span>
</label>
</flexbox-item>
<flexbox-item>
<selector @on-change="preventS" v-model="list.order_day" placeholder="请选择" :options="orderWeek"></selector>
订货
</flexbox-item>
</flexbox>
</li>
</ul>
<ul class="detailBox" v-if="list.dist_way === 'M'">
<li>
<flexbox>
<flexbox-item :span="3">
<label for="">
<span>订货计划<em class="red">*</em></span>
</label>
</flexbox-item>
<flexbox-item>
每月
<selector @on-change="preventS" v-model="list.order_day" placeholder="请选择" :options="orderMonth"></selector>
订货
</flexbox-item>
</flexbox>
</li>
</ul>
<div class="set-finish">
<div @click="finishSet()" class="set-finish-btn">确定</div>
</div>
</x-dialog>
</div>
</template>
<script>
import { XDialog, TransferDomDirective as TransferDom, Flexbox, FlexboxItem, Selector } from 'vux'
import { compat } from 'logistics/static/js/compatibility'
export default {
directives: {
TransferDom
},
components: {
XDialog, Flexbox, FlexboxItem, Selector
},
mixins: [compat],
props: ['title', 'supplier_name', 'materiel'],
data () {
return {
orderWeek: [
{
value: '周一',
key: 'MON'
},
{
value: '周二',
key: 'TUE'
},
{
value: '周三',
key: 'WED'
},
{
value: '周四',
key: 'THU'
},
{
value: '周五',
key: 'FRI'
},
{
value: '周六',
key: 'SAT'
},
{
value: '周日',
key: 'SUN'
}
],
orderMonth: [
{
value: '1号',
key: '1'
},
{
value: '2号',
key: '2'
},
{
value: '3号',
key: '3'
},
{
value: '4号',
key: '4'
},
{
value: '5号',
key: '5'
},
{
value: '6号',
key: '6'
},
{
value: '7号',
key: '7'
},
{
value: '8号',
key: '8'
},
{
value: '9号',
key: '9'
},
{
value: '10号',
key: '10'
},
{
value: '11号',
key: '11'
},
{
value: '12号',
key: '12'
},
{
value: '13号',
key: '13'
},
{
value: '14号',
key: '14'
},
{
value: '15号',
key: '15'
},
{
value: '16号',
key: '16'
},
{
value: '17号',
key: '17'
},
{
value: '18号',
key: '18'
},
{
value: '19号',
key: '19'
},
{
value: '20号',
key: '20'
},
{
value: '21号',
key: '21'
},
{
value: '22号',
key: '22'
},
{
value: '23号',
key: '23'
},
{
value: '24号',
key: '24'
},
{
value: '25号',
key: '25'
},
{
value: '26号',
key: '26'
},
{
value: '27号',
key: '27'
},
{
value: '28号',
key: '28'
},
{
value: '29号',
key: '29'
},
{
value: '30号',
key: '30'
},
{
value: '31号',
key: '31'
},
{
value: '月末',
key: 'last'
}
],
list: {
dist_way: '',
rest_date: [],
order_day: '',
order_time: ''
}
}
},
mounted () {
// 点击遮罩层,弹框消失 start
this.$nextTick(() => {
let mask = document.getElementsByClassName('orderPlanBox')[0].getElementsByClassName('weui-mask')[0];
mask.addEventListener('click', () => {
this.$store.commit('checkOrderPlanBox');
});
})
// 点击遮罩层,弹框消失 end
},
methods: {
changeRadio () {
// 切换订货频次
this.list.order_day = '';
this.list.rest_date = [];
},
finishSet () {
/**
* 完成
* 把订货计划数据传给父组件
* 注意:如果按每天订货,需要将对象中的order_day设置为DAY
* 任何频次的order_time都可以为空
* ------------------------------------------------------------------
*/
let obj = {};
for (let i in this.list) {
obj[i] = this.list[i];
}
obj.route_list = [];
if (obj.dist_way === 'D') {
obj.order_day = 'DAY';
} else if (obj.order_day === '') {
this.$vux.toast.show({
type: 'warn',
text: '订货日期不能为空'
});
return;
}
this.$emit('compelete', obj);
this.$store.commit('checkOrderPlanBox')
}
}
}
</script>
<style lang="less">
.weui-dialog {
padding-bottom: 1rem !important;
max-width: 800px !important;
}
.red {
color: red;
font-style: normal;
}
.green {
color: green;
}
.orderPlanBox {
ul {
list-style: none;
margin: 0;
padding: 0;
}
.set-bom-prop {
padding: 0;
min-height: 40px;
font-size: 14px;
line-height: 1.3;
word-wrap: break-word;
word-break: break-all;
color: #666;
touch-action: none;
.set-bom-prop-title {
background-color: #8ea9cf;
font-size: 18px;
color: #FFFFFF;
padding: 0.5em 1.6em 0.5em;
}
.title-list {
color: #333;
font-size: 16px;
}
.row-list {
li {
display: flex;
padding: 0.4rem 0 0.4rem 0.8rem;
border-bottom: 1px solid #C7C7C7;
em {
font-style: normal;
}
label {
text-align: left;
&>span {
display: block;
float: left;
height: 36px;
line-height: 36px;
}
}
.radioBox {
display: flex;
justify-content: space-around;
margin-left: 10px;
span {
display: inline-block;
}
.el-radio__label {
padding-left: 0;
}
}
}
.supplier-name {
border: none;
color: #000;
}
.materiel-name {
color: #8ea9cf;
}
.el-form-item_content{
-webkit-flex: 1;
flex: 1;
float: left!important;
margin-left: 0!important;
line-height: 20px!important;
padding-right: 10px;
&.p-right {
padding-right: 7px;
}
p {
line-height: 36px;
text-align: right;
span {
margin-left: 0.3rem;
}
i {
color: rgb(153, 153, 153);
font-size: 18px;
position: relative;
top: 2px;
}
}
}
}
.detailBox {
max-height: 20rem;
overflow-y: auto;
li {
padding: 0.4rem 0 0.4rem 0.8rem;
border-bottom: 1px solid #C7C7C7;
i {
vertical-align: middle;
color: #8ea8cf;
}
}
.el-input {
width: 4rem;
margin: 0 3px;
}
.el-input__inner {
padding: 0;
padding-left: 10px;
}
select {
width: 4rem;
margin: 0 3px;
padding-left: 10px;
background-color: #fff;
border-radius: 4px;
border: 1px solid #dcdfe6;
color: #606266;
height: 40px;
line-height: 40px;
outline: 0;
transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
}
.el-input__prefix {
display: none;
}
}
.dailyBox {
position: relative;
.dailyGroup {
.el-checkbox {
float: left;
width: 25%;
margin-left: 0;
}
&:after {
clear: both;
display: block;
content: "";
}
}
.dailyLine {
width: 100%;
height: 1px;
background: #C7C7C7;
position: absolute;
top: 50%;
left: 0;
}
}
.set-finish {
width: 90%;
margin: 0 auto;
margin-top: 1rem;
border-radius: 0.25rem;
color: white;
padding: 0.35rem 0;
background-color: #8ea8cf;
}
}
}
.el-picker-panel {
z-index: 9999999 !important;
}
.el-select-dropdown {
z-index: 9999999 !important;
}
.vux-selector {
display: inline-block !important;
.weui-select {
padding-right: 0 !important;
}
}
</style>
<template>
<div class="setTimeBox" v-transfer-dom>
<x-dialog class="set-bom-prop" v-model="this.$store.state.setTimeBox_show">
<div class="set-bom-prop-title">
<div>设置门店到货时间</div>
</div>
<ul class="title-list">
<li class="supplier">{{supplier_name}}</li>
<li class="materiel">{{materiel_name}}</li>
</ul>
<ul class="row-list" v-for="(item, index) in store_list" :key="index" v-if="item.dist_way === 'D'">
<li class="row-title">
每天订货
</li>
<li>
<flexbox justify="space-between">
<flexbox-item :span="4.5" class="store-name">
<span>{{item.store_name}}</span>
</flexbox-item>
<flexbox-item :span="7" style="text-align:right;padding-right:5px;">
<selector @on-change="preventS" class="selector" v-model="item.dist_day" placeholder="请选择" :options="distDay"></selector>
<selector @on-change="preventS" class="selector" v-model="item.dist_time" placeholder="请选择" :options="distTime"></selector>
到货
</flexbox-item>
</flexbox>
</li>
</ul>
<ul class="row-list" v-for="(item, index) in store_list" :key="index" v-if="item.dist_way === 'W'">
<li class="row-title">
每周{{getWeek('order')}}订货
</li>
<li>
<flexbox justify="space-between">
<flexbox-item :span="5.5" class="store-name">
<span>{{item.store_name}}</span>
</flexbox-item>
<flexbox-item :span="6.5" style="text-align:right;padding-right:5px;">
<selector @on-change="preventS" class="selector" v-model="item.dist_day" placeholder="请选择" :options="distWeek"></selector>
<selector @on-change="preventS" class="selector" v-model="item.dist_time" placeholder="请选择" :options="distTime"></selector>
到货
</flexbox-item>
</flexbox>
</li>
</ul>
<ul class="row-list" v-for="(item, index) in store_list" :key="index" v-if="item.dist_way === 'M'">
<li class="row-title">
每月{{getMonth(item.order_day)}}订货
</li>
<li>
<flexbox justify="space-between">
<flexbox-item :span="4.5" class="store-name">
<span>{{item.store_name}}</span>
</flexbox-item>
<flexbox-item :span="7" style="text-align:right;padding-right:5px;">
<selector @on-change="preventS" class="selector" v-model="item.dist_day" placeholder="请选择" :options="distMonth" style="text-align:center;"></selector>
<selector @on-change="preventS" class="selector" v-model="item.dist_time" placeholder="请选择" :options="distTime"></selector>
到货
</flexbox-item>
</flexbox>
</li>
</ul>
<div class="set-finish">
<div @click="finishSet()" class="set-finish-btn">确定</div>
</div>
</x-dialog>
</div>
</template>
<script>
/**
* 订货送货计划总览设置门店到货时间组件
*
* 此组件是否显示的boolean值存在vuex中,无需传入
*
* @param {string} supplier_name 供应商名
* @param {string} materiel_name 物料组名
* @param {array} list 内容
* @returns {object}
*
* @date 2018-08-31
*/
import { Flexbox, FlexboxItem, XDialog, TransferDomDirective as TransferDom, Popup, Picker, Selector } from 'vux'
import { compat } from 'logistics/static/js/compatibility'
export default {
components: {
Flexbox, FlexboxItem, XDialog, TransferDom, Popup, Picker, Selector
},
mixins: [compat],
mounted () {
// 没有关闭按钮的组件,点击遮罩层可以直接关闭此弹框(不保存设置内容)
this.$nextTick(() => {
let mask = document.getElementsByClassName('setTimeBox')[0].getElementsByClassName('weui-mask')[0];
mask.addEventListener('click', () => {
this.$store.commit('checksetTimeBox');
});
});
},
props: ['supplier_name', 'materiel_name', 'list'],
data () {
return {
distDay: [
{
value: 2,
key: 'DAY+1d'
},
{
value: 3,
key: 'DAY+2d'
},
{
value: 4,
key: 'DAY+3d'
},
{
value: 5,
key: 'DAY+4d'
},
{
value: 6,
key: 'DAY+5d'
},
{
value: 7,
key: 'DAY+6d'
},
{
value: 8,
key: 'DAY+7d'
},
{
value: 9,
key: 'DAY+8d'
},
{
value: 10,
key: 'DAY+9d'
}
],
distWeek: [
{
value: '周一',
key: 'MON'
},
{
value: '周二',
key: 'TUE'
},
{
value: '周三',
key: 'WED'
},
{
value: '周四',
key: 'THU'
},
{
value: '周五',
key: 'FRI'
},
{
value: '周六',
key: 'SAT'
},
{
value: '周日',
key: 'SUN'
},
{
value: '下周一',
key: 'MON+1w'
},
{
value: '下周二',
key: 'TUE+1w'
},
{
value: '下周三',
key: 'WED+1w'
},
{
value: '下周四',
key: 'THU+1w'
},
{
value: '下周五',
key: 'FRI+1w'
},
{
value: '下周六',
key: 'SAT+1w'
},
{
value: '下周日',
key: 'SUN+1w'
}
],
distMonth: [
{
value: '1号',
key: '1'
},
{
value: '2号',
key: '2'
},
{
value: '3号',
key: '3'
},
{
value: '4号',
key: '4'
},
{
value: '5号',
key: '5'
},
{
value: '6号',
key: '6'
},
{
value: '7号',
key: '7'
},
{
value: '8号',
key: '8'
},
{
value: '9号',
key: '9'
},
{
value: '10号',
key: '10'
},
{
value: '11号',
key: '11'
},
{
value: '12号',
key: '12'
},
{
value: '13号',
key: '13'
},
{
value: '14号',
key: '14'
},
{
value: '15号',
key: '15'
},
{
value: '16号',
key: '16'
},
{
value: '17号',
key: '17'
},
{
value: '18号',
key: '18'
},
{
value: '19号',
key: '19'
},
{
value: '20号',
key: '20'
},
{
value: '21号',
key: '21'
},
{
value: '22号',
key: '22'
},
{
value: '23号',
key: '23'
},
{
value: '24号',
key: '24'
},
{
value: '25号',
key: '25'
},
{
value: '26号',
key: '26'
},
{
value: '27号',
key: '27'
},
{
value: '28号',
key: '28'
},
{
value: '29号',
key: '29'
},
{
value: '30号',
key: '30'
},
{
value: '31号',
key: '31'
},
{
value: '月末',
key: 'last'
},
{
value: '次月1号',
key: '1+1m'
},
{
value: '次月2号',
key: '2+1m'
},
{
value: '次月3号',
key: '3+1m'
},
{
value: '次月4号',
key: '4+1m'
},
{
value: '次月5号',
key: '5+1m'
},
{
value: '次月6号',
key: '6+1m'
},
{
value: '次月7号',
key: '7+1m'
},
{
value: '次月8号',
key: '8+1m'
},
{
value: '次月9号',
key: '9+1m'
},
{
value: '次月10号',
key: '10+1m'
},
{
value: '次月11号',
key: '11+1m'
},
{
value: '次月12号',
key: '12+1m'
},
{
value: '次月13号',
key: '13+1m'
},
{
value: '次月14号',
key: '14+1m'
},
{
value: '次月15号',
key: '15+1m'
},
{
value: '次月16号',
key: '16+1m'
},
{
value: '次月17号',
key: '17+1m'
},
{
value: '次月18号',
key: '18+1m'
},
{
value: '次月19号',
key: '19+1m'
},
{
value: '次月20号',
key: '20+1m'
},
{
value: '次月21号',
key: '21+1m'
},
{
value: '次月22号',
key: '22+1m'
},
{
value: '次月23号',
key: '23+1m'
},
{
value: '次月24号',
key: '24+1m'
},
{
value: '次月25号',
key: '25+1m'
},
{
value: '次月26号',
key: '26+1m'
},
{
value: '次月27号',
key: '27+1m'
},
{
value: '次月28号',
key: '28+1m'
},
{
value: '次月29号',
key: '29+1m'
},
{
value: '次月30号',
key: '30+1m'
},
{
value: '次月31号',
key: '31+1m'
},
{
value: '次月月末',
key: 'last+1m'
}
],
distTime: [
{
value: '00:00',
key: '00:00'
},
{
value: '00:30',
key: '00:30'
},
{
value: '01:00',
key: '01:00'
},
{
value: '01:30',
key: '01:30'
},
{
value: '02:00',
key: '02:00'
},
{
value: '02:30',
key: '02:30'
},
{
value: '03:00',
key: '03:00'
},
{
value: '03:30',
key: '03:30'
},
{
value: '04:00',
key: '04:00'
},
{
value: '04:30',
key: '04:30'
},
{
value: '05:00',
key: '05:00'
},
{
value: '05:30',
key: '05:30'
},
{
value: '06:00',
key: '06:00'
},
{
value: '06:30',
key: '06:30'
},
{
value: '07:30',
key: '07:30'
},
{
value: '08:00',
key: '08:00'
},
{
value: '08:30',
key: '08:30'
},
{
value: '09:00',
key: '09:00'
},
{
value: '09:30',
key: '09:30'
},
{
value: '10:00',
key: '10:00'
},
{
value: '10:30',
key: '10:30'
},
{
value: '11:00',
key: '11:00'
},
{
value: '11:30',
key: '11:30'
},
{
value: '12:00',
key: '12:00'
},
{
value: '12:30',
key: '12:30'
},
{
value: '13:00',
key: '13:00'
},
{
value: '13:30',
key: '13:30'
},
{
value: '14:00',
key: '14:00'
},
{
value: '14:30',
key: '14:30'
},
{
value: '15:00',
key: '15:00'
},
{
value: '15:30',
key: '15:30'
},
{
value: '16:00',
key: '16:00'
},
{
value: '16:30',
key: '16:30'
},
{
value: '17:00',
key: '17:00'
},
{
value: '17:30',
key: '17:30'
},
{
value: '18:00',
key: '18:00'
},
{
value: '18:30',
key: '18:30'
},
{
value: '19:00',
key: '19:00'
},
{
value: '19:30',
key: '19:30'
},
{
value: '20:00',
key: '20:00'
},
{
value: '20:30',
key: '20:30'
},
{
value: '21:00',
key: '21:00'
},
{
value: '21:30',
key: '21:30'
},
{
value: '22:00',
key: '22:00'
},
{
value: '22:30',
key: '22:30'
},
{
value: '23:00',
key: '23:00'
},
{
value: '23:30',
key: '23:30'
}
],
store_list: [] // 商店列表
}
},
watch: {
/**
* 需要使用watch方法来监听外部传入list是否改变,然后使用数组push方法触发子组件视图更新
* -------------------------
**/
list: function (val) {
let list = [];
for (let i = 0; i < val.length; i++) {
list.push(val[i]);
}
this.store_list = _.cloneDeep(list);
this.store_list.forEach((v, i) => {
if (v.dist_way === 'W') {
this.distWeek.forEach((w, wi) => {
if (v.order_day === w.key) {
this.distWeek = this.distWeek.slice(wi);
}
});
} else if (v.dist_way === 'M') {
this.distWeek.forEach((m, mi) => {
if (v.order_day === m.key) {
this.distMonth = this.distMonth.slice(mi);
}
});
}
});
console.warn(this.store_list);
}
},
methods: {
finishSet () {
/**
* 确定
* -------------------------
**/
this.$store.commit('checksetTimeBox');
this.$emit('compelete', _.cloneDeep(this.store_list));
},
getWeek (t) {
let str;
switch (t) {
case 'order':
str = this.store_list[0].order_day;
switch (str) {
case 'MON':
return '周一';
case 'TUE':
return '周二';
case 'WED':
return '周三';
case 'THU':
return '周四';
case 'FRI':
return '周五';
case 'SAT':
return '周六';
case 'SUN':
return '周日';
};
break;
case 'dist':
str = this.store_list[arguments[1]].dist_day;
switch (str) {
case 'MON':
return '周一';
case 'TUE':
return '周二';
case 'WED':
return '周三';
case 'THU':
return '周四';
case 'FRI':
return '周五';
case 'SAT':
return '周六';
case 'SUN':
return '周日';
case 'MON+1w':
return '下周一';
case 'TUE+1w':
return '下周二';
case 'WED+1w':
return '下周三';
case 'THU+1w':
return '下周四';
case 'FRI+1w':
return '下周五';
case 'SAT+1w':
return '下周六';
case 'SUN+1w':
return '下周日';
};
break;
}
},
getMonth (str) {
if (str === 'last') {
return '月末'
} else {
if (str.split('+').length > 1) {
if (str.split('+')[0] === 'last') {
return '次月月末'
} else {
return '次月' + str.split('+')[0] + '号'
}
} else {
return str + '号';
}
}
}
}
}
</script>
<style lang="less">
.weui-dialog {
padding-bottom: 1rem !important;
width: 90% !important;
max-width: 1000px !important;
}
.red {
color: red;
font-style: normal;
}
.green {
color: green;
}
.supplier {
text-align: left;
padding: 0.4rem 0.8rem;
}
.materiel {
text-align: left;
padding: 0.4rem 0.8rem;
color: #8ea8cf;
}
.setTimeBox {
color: #666;
font-size: 14px;
ul {
list-style: none;
margin: 0;
padding: 0;
}
.set-bom-prop {
padding: 0;
min-height: 40px;
font-size: 15px;
line-height: 1.3;
word-wrap: break-word;
word-break: break-all;
color: #999999;
touch-action: none;
.set-bom-prop-title {
font-size: 18px;
background-color: #8ea9cf;
color: #FFFFFF;
padding: 0.5em 1.6em 0.5em;
}
.title-list {
font-size: 16px;
color: #333;
}
.row-list {
li {
display: flex;
padding: 0.4rem 0 0.4rem 0.8rem;
border-bottom: 1px solid #c7c7c7;
em {
font-style: normal;
}
.el-input {
width: 4rem;
margin: 0 3px;
}
.el-input__inner {
padding: 0;
padding-left: 10px;
}
}
.row-title {
display: block;
text-align: center;
padding: 0.8rem 0;
}
.store-name {
i {
vertical-align: middle;
color: #8ea8cf;
}
span {
vertical-align: middle;
line-height: 2em;
}
}
.add-store {
padding-left: 4.5rem;
border-top: 2px solid #c7c7c7;
border-bottom: 4px solid #c7c7c7;
i {
vertical-align: middle;
color: #8ea8cf;
}
span {
vertical-align: middle;
line-height: 2em;
}
}
}
.set-finish {
width: 90%;
margin: 0 auto;
margin-top: 1rem;
border-radius: 0.25rem;
color: white;
padding: 0.35rem 0;
background-color: #8ea8cf;
}
}
.el-input__prefix {
display: none;
}
}
select {
width: 4rem;
margin: 0 3px;
padding-left: 10px;
background-color: #fff;
border-radius: 4px;
border: 1px solid #dcdfe6;
color: #606266;
height: 40px;
line-height: 40px;
outline: 0;
transition: border-color .2s cubic-bezier(.645, .045, .355, 1);
}
.vux-selector {
display: inline-block !important;
.weui-select {
padding: 0 5px !important;
border-radius: 5px;
border: 1px solid #d6d7dc;
text-align: center !important;
}
}
.weui-cell_select .weui-cell__bd:after {
display: none !important;
}
.weui-cell:before {
display: none;
}
</style>
<template>
<div class="pandect_select" v-transfer-dom>
<x-dialog v-model="show">
<div class="pandect_box">
<h4>{{title}}</h4>
<div class="pandect_content">
<ul v-if="type === 'supplier'">
<li @click="check(index)" v-for="(item, index) in data" :key="index" :class="{'actived': item.checked}">{{item.prov_name}}</li>
</ul>
<ul v-if="type === 'materiel'">
<li @click="check(index)" v-for="(item, index) in data" :key="index" :class="{'actived': item.checked}">{{item.name}}</li>
</ul>
<ul v-if="type === 'route'">
<li @click="check(index)" v-for="(item, index) in data" :key="index" :class="{'actived': item.checked}">{{item.name}}</li>
</ul>
</div>
<div class="btn-box">
<div class="close" @click="close">关闭</div>
<div class="confirm" @click="confirm">确定</div>
</div>
</div>
</x-dialog>
</div>
</template>
<script>
/**
* 订货送货计划总览选择框组件
*
*
* @param {string} title 标题
* @param {array} list 可选择的内容
* @param {boolean} show 是否显示组件
* @param {string} type 类型(根据不同类型,供应商、物料、送货线路,获取到的后端数组字段不同,遍历显示的方式也不同)
* @returns {object}
*
* @date 2018-08-31
*/
import { XDialog, TransferDomDirective as TransferDom } from 'vux'
export default {
components: { XDialog, TransferDom },
props: ['title', 'list', 'show', 'type'],
data () {
return {
data: []
}
},
watch: {
list: function (val) {
/**
* 需要使用watch方法来监听外部传入list是否改变,然后使用数组push方法触发子组件视图更新
* ------------------------------------------------------------------
*/
this.$vux.loading.hide();
this.data = [];
for (let i = 0; i < val.length; i++) {
// 给每条内容添加一个checked属性,是否选择
val[i].checked = false;
this.data.push(val[i])
}
}
},
methods: {
check (index) {
/**
* 选择某一条内容时,将所有内容的checked设false,并将被选择的内容checked设为true,单选效果
* ------------------------------------------------------------------
*/
let arr = []
this.data.forEach(v => {
arr.push(v);
});
this.data = [];
arr.forEach((v, i) => {
v.checked = false;
if (i === index) {
v.checked = true;
}
this.data.push(v);
});
},
close () {
// 关闭
this.$emit('close');
},
confirm () {
/**
* 确认时,返回选中的内容
* ------------------------------------------------------------------
*/
let data = null;
this.data.forEach(v => {
if (v.checked) {
data = v;
}
});
this.$emit('confirm', _.cloneDeep(data));
}
}
}
</script>
<style lang="less" scoped>
.pandect_select {
font-size: 14px;
color: #666;
.pandect_box {
position: relative;
padding-bottom: 3rem;
.pandect_content {
max-height: 20rem;
overflow-y: auto;
}
}
h4 {
font-size: 18px;
color: #333;
padding: 0.4rem 0;
text-align: center;
border-bottom: 1px solid #eee;
}
ul {
margin: 0;
list-style: none;
padding: 0 0.8rem;
li {
padding: 0.4rem 0.6rem;
background: #eee;
margin: 0.6rem 0;
}
.actived {
background: #8ea8cf;
color: #fff;
}
}
.btn-box {
position: absolute;
bottom: 0;
width: 100%;
display: flex;
justify-content: space-around;
div {
width: 48%;
border-radius: 5px;
border: 1px solid #8ea8cf;
text-align: center;
padding: 0.4rem 0;
}
.close {
color: #8ea8cf;
background: #fff;
}
.confirm {
color: #fff;
background: #8ea8cf;
}
}
}
</style>
<template lang="html">
<div class="choose-material-page">
<div v-transfer-dom>
<x-dialog :show.sync="show" class="dialog-demo">
<div class="material-title">
{{title}}
</div>
<div class="wrapper-scroll">
<div v-for="(v, k) in shortcut" :key="k">
<flexbox class="shortcut-title">
<flexbox-item :span="9">
<check-icon @click.native="shortcutCheck(k)" :value.sync="shortcut[k].checked">
<span>{{v.sku_name}}</span>
</check-icon>
</flexbox-item>
<flexbox-item @click.native="shortcutFold(k)" style="margin-left: 0;">
<span style="color: #8EA8CF;">{{v.sku_count}}种物料</span>
<i class="fa fa-chevron-right"></i>
</flexbox-item>
</flexbox>
<div class="shortcut-content fold-content">
<div v-for="(item, index) in v.list" :key="index">{{item.sku_name}}</div>
</div>
</div>
<div class="material-wrapper">
<flexbox>
<flexbox-item :span="7.5">
<check-icon class="material-all-checked" @click.native="checkAll(all_checked)" :value.sync="all_checked">
{{caption}}(<span style="color: #8EA8CF;">{{category_num}}</span>/{{category_sum}})
</check-icon>
</flexbox-item>
<flexbox-item :span="4.5" style="margin-left: 0;">
<div class="add-product-wrapper">
<x-button class="add-btn" @click.native="addProduct" mini>新增原/物料</x-button>
</div>
</flexbox-item>
</flexbox>
<!-- <div class="material-all-checked">
<flexbox>
<flexbox-item :span="7">
{{caption}}(<span style="color: #8EA8CF;">{{category_num}}</span>/{{product_sum}})
</flexbox-item>
<flexbox-item :span="6">
<div class="add-product-wrapper">
<x-button class="add-btn" @click.native="cancel" mini>新增原/物料</x-button>
</div>
</flexbox-item>
</flexbox>
</div> -->
<div class="material-classify">
<div v-for="(item, index) in data_list" :key="index">
<div style="border-top: 1px dashed #eee; width: 100%;"></div>
<flexbox class="material-classify-title">
<flexbox-item :span="10">
<check-icon class="material-classify-checked" @click.native="changeCategory(index)" :value.sync="data_list[index].checked">
{{item.name}}(<span style="color: #8EA8CF;">{{item.num}}</span>/{{item.sku_count}})
</check-icon>
<!-- <div class="material-classify-checked">
{{item.name}}(<span style="color: #8EA8CF;">{{item.num}}</span>/{{item.sku_count}})
</div> -->
</flexbox-item>
<flexbox-item @click.native="fold(index)">
<div style="padding-top: 0.2rem; padding-left: 0.5rem;">
<i class="fa fa-chevron-down" style="font-size: 0.7rem; color: #838383;"></i>
</div>
</flexbox-item>
</flexbox>
<div class="material-content">
<flexbox :gutter="10" class="flexbox-material" v-for="(m, key) in item.sku_list" :key="key">
<flexbox-item v-for="(v, k) in m" :key="k" class="store-item">
<div v-if="!+v.disabled" @click="itemCheck(v, index, 'click')"
:class="[v.checked === true ? 'flex-checked' : '', 'flex-material']">
{{v.sku_name}}
</div>
<div v-else class="flex-material flex-disabled"> {{v.sku_name}} </div>
</flexbox-item>
</flexbox>
</div>
</div>
</div>
</div>
</div>
<div class="control-wrapper">
<flexbox>
<flexbox-item>
<x-button class="close-btn" @click.native="cancel" mini>关闭</x-button>
</flexbox-item>
<flexbox-item>
<x-button class="comfirm-btn" @click.native="comfirm" mini>确定</x-button>
</flexbox-item>
</flexbox>
</div>
</x-dialog>
</div>
</div>
</template>
<script>
import { XDialog, TransferDomDirective as TransferDom, Flexbox, FlexboxItem, CheckIcon, XButton } from 'vux'
export default {
props: ['show', 'title', 'caption', 'list', 'span', 'shortcut'],
directives: { TransferDom },
components: { XDialog, Flexbox, FlexboxItem, CheckIcon, XButton },
mounted () {
},
data () {
return {
all_checked: false,
item_checked: false,
data_list: [],
category_num: 0,
product_num: 0,
checked_list: [],
shortcut_checked_list: [],
add_checked_list: []
}
},
watch: {
list (val, old) {
if (val !== old) {
this.data_list = [];
// 动态生成绑定变量
let foo = val;
for (let i = 0; i < foo.length; i++) {
// 补全物料占位
let remainder = foo[i]['sku_list'].length % this.span;
if (remainder > 0) {
for (let y = 0; y < (this.span - remainder); y++) {
foo[i]['sku_list'].push({
sku_id: '',
sku_name: '',
checked: false,
disabled: '0'
})
}
}
// 分割计算
let tmp = [];
while (foo[i]['sku_list'].length) {
tmp.push(foo[i]['sku_list'].splice(0, this.span));
}
this.data_list.push({
checked: false,
name: foo[i]['name'],
num: 0,
sku_count: foo[i]['sku_count'],
sku_list: tmp
});
}
this.add_checked_list = _.uniq(this.add_checked_list)
_.each(this.add_checked_list, item => {
this.itemCheck(item, item.index)
});
// 模拟选中
_.each(this.data_list, item => {
_.each(item.sku_list, x => {
_.each(x, y => {
_.each(this.add_checked_list, z => {
if (y.sku_id === z.sku_id) {
y.checked = true;
}
})
})
})
});
setTimeout(() => {
for (let i = 0; i < $('.store-item').length; i++) {
if (i % this.span !== 0) {
continue;
}
if ($($('.store-item')[i]).height() > $($('.store-item')[i + 1]).height()) {
$($('.store-item')[i + 1]).css('line-height', $($('.store-item')[i]).height() + 'px')
} else if ($($('.store-item')[i]).height() < $($('.store-item')[i + 1]).height()) {
$($('.store-item')[i]).css('line-height', $($('.store-item')[i + 1]).height() + 'px')
}
}
}, 100);
}
},
category_num (val) {
// 小分类全选状态
if (val === this.category_sum) {
this.all_checked = true;
} else {
this.all_checked = false;
}
}
},
computed: {
category_sum () {
return _.reduce(this.data_list, (sum, n) => {
return sum + n.sku_count;
}, 0);
},
product_sum () {
let foo = _.reduce(this.data_list, (sum, n) => {
return sum + n.sku_count;
}, 0);
return foo;
}
},
methods: {
checkAll (checked) {
// 勾选所有类别
if (checked) {
// 选中
_.each(this.data_list, (item, key) => {
this.data_list[key]['checked'] = true;
this.changeCategory(key)
});
} else {
// 取消
_.each(this.data_list, (item, key) => {
this.data_list[key]['checked'] = false;
this.changeCategory(key)
});
}
},
itemCheck (item, i, method) {
// 选中项
if (method === 'click') {
item.checked = !item.checked;
}
// 选中数量
if (item.checked) {
this.data_list[i]['num'] = this.data_list[i]['num'] < this.data_list[i]['sku_count'] ? this.data_list[i]['num'] + 1 : this.data_list[i]['sku_count'];
// 新增数组内容
this.checked_list.push(item.sku_id);
//
item.index = i;
this.add_checked_list.push(item);
} else {
this.data_list[i]['checked'] = false;
this.data_list[i]['num'] = this.data_list[i]['num'] > 0 ? this.data_list[i]['num'] - 1 : 0;
// 移除数组内容
_.each(this.checked_list, (v, k) => {
if (item.sku_id && v === item.sku_id) {
this.checked_list.splice(k, 1);
}
});
_.each(this.add_checked_list, (v, k) => {
if (v && v.sku_id === item.sku_id) {
this.add_checked_list.splice(k, 1);
}
});
}
// 选中列表项
this.$emit('check', this.add_checked_list);
// 遍历勾选项 全选
// 查询小分类勾选数量
if (this.data_list[i]['num'] === this.data_list[i]['sku_count']) {
this.data_list[i]['checked'] = true;
}
// 小分类勾选状态调整大分类状态
let cat_checked = [];
_.each(this.data_list, item => {
if (item.checked) {
cat_checked.push(item.checked)
}
});
// this.category_num = cat_checked.length < this.data_list.length ? cat_checked.length : this.data_list.length;
this.category_num = this.checked_list.length;
},
changeCategory (i) {
// 勾选分类
if (this.data_list[i]['checked']) {
// 全选
_.each(this.data_list[i]['sku_list'], item => {
_.each(item, v => {
v.checked = true;
// 选中项ID
if (!+v.disabled) {
if (_.indexOf(this.checked_list, v.sku_id) < 0 && v.sku_id) {
this.checked_list.push(v.sku_id);
//
v.index = i;
this.add_checked_list.push(v);
}
}
})
});
// 小分类数量全选
this.data_list[i]['num'] = this.data_list[i]['sku_count'];
// 新增所有分类勾选数量
// this.category_num = this.category_num < this.data_list.length ? this.category_num + 1 : this.data_list.length;
this.category_num = this.checked_list.length;
} else {
// 小分类ID集合
let id_list = [];
// 取消全选
_.each(this.data_list[i]['sku_list'], item => {
_.each(item, v => {
v.checked = false;
// 集合
id_list.push(v.sku_id)
})
});
// 移除数组内容
_.each(id_list, n => {
_.each(this.checked_list, (v, k) => {
if (v === n) {
this.checked_list.splice(k, 1);
}
});
});
this.add_checked_list = _.uniq(this.add_checked_list)
_.each(id_list, n => {
_.each(this.add_checked_list, (v, k) => {
if (v && v.sku_id === n) {
this.add_checked_list.splice(k, 1);
}
});
});
// 小分类数量归零
this.data_list[i]['num'] = 0;
// 减少所有分类勾选数量
// this.category_num = this.category_num > 0 ? this.category_num - 1 : 0;
this.category_num = this.checked_list.length;
}
},
cancel () {
// 关闭选择框
this.$emit('cancel', !this.show);
this.clear();
},
comfirm () {
// 确认选择框
let arr = [];
_.each(this.data_list, x => {
_.each(x.sku_list, y => {
_.each(y, z => {
_.each(this.checked_list, item => {
if (item === z.sku_id) {
z.sku_classname = x.name;
arr.push(z);
}
})
})
})
});
arr = _.uniq(arr);
this.$emit('comfirm', arr);
this.clear();
},
clear () {
// 清空选择项
if (this.all_checked) {
this.all_checked = false;
}
this.category_num = 0;
_.each(this.data_list, (item, key) => {
if (item.checked) {
item.checked = false;
item.num = 0;
}
_.each(item.sku_list, (v, k) => {
_.each(v, x => {
if (x.checked) {
x.checked = false;
item.num = 0;
}
})
})
});
this.checked_list = [];
// 清空快捷
_.each(this.shortcut, item => {
item.checked = false;
});
this.shortcut_checked_list = [];
this.add_checked_list = [];
},
fold (index) {
let has_class = $($('.material-classify-title')[index]).siblings('.material-content').hasClass('fold-content');
if (has_class) {
// 展开
$($('.material-classify-title')[index]).siblings('.material-content').removeClass('fold-content');
$($('.material-classify-title')[index]).find('i').addClass('fa-chevron-down').removeClass('fa-chevron-right');
} else {
// 折叠
$($('.material-classify-title')[index]).siblings('.material-content').addClass('fold-content');
$($('.material-classify-title')[index]).find('i').addClass('fa-chevron-right').removeClass('fa-chevron-down');
}
},
shortcutFold (index) {
let has_class = $($('.shortcut-title')[index]).siblings('.shortcut-content').hasClass('fold-content');
if (has_class) {
// 展开
$($('.shortcut-title')[index]).siblings('.shortcut-content').removeClass('fold-content');
$($('.shortcut-title')[index]).find('i').addClass('fa-chevron-down').removeClass('fa-chevron-right');
} else {
// 折叠
$($('.shortcut-title')[index]).siblings('.shortcut-content').addClass('fold-content');
$($('.shortcut-title')[index]).find('i').addClass('fa-chevron-right').removeClass('fa-chevron-down');
}
},
shortcutCheck (i) {
// 快捷方式选中
let list = _.map(this.shortcut[i].list, item => {
return item.sku_id
});
if (this.shortcut[i]['checked']) {
// 勾选
this.shortcut_checked_list = this.shortcut_checked_list.concat(list);
//
_.each(this.data_list, (item, key) => {
_.each(item.sku_list, (v, k) => {
_.each(v, x => {
// ID在快捷列表中存在
if (_.indexOf(this.shortcut_checked_list, x.sku_id) >= 0 && !+x.disabled) {
x.checked = true;
if (!+x.disabled) {
if (_.indexOf(this.checked_list, x.sku_id) < 0 && x.sku_id) {
this.checked_list.push(x.sku_id);
}
}
this.setCheck()
}
});
})
});
} else {
// 取消
this.shortcut_checked_list = _.difference(this.shortcut_checked_list, list);
this.removeCheck(list)
}
},
setCheck () {
// 勾选取消大小分类
_.each(this.data_list, i => {
_.each(i.sku_list, x => {
let sum = 0;
_.each(x, item => {
if (_.indexOf(this.shortcut_checked_list, item.sku_id) >= 0 && !+item.disabled && item.sku_id) {
sum = sum + 1;
if (i.sku_count === sum) {
i.checked = true;
i.num = sum;
} else {
i.checked = false;
i.num = sum;
}
}
})
});
});
let checked_list = []
_.each(this.data_list, i => {
if (i.checked) {
checked_list.push(i.checked)
}
});
// this.category_num = checked_list.length;
this.category_num = this.checked_list.length;
if (this.data_list.length === checked_list.length) {
this.all_checked = true;
}
},
removeCheck (list) {
// 勾选取消大小分类
_.each(this.data_list, i => {
_.each(i.sku_list, x => {
let sum = i.sku_count;
_.each(x, item => {
if (_.indexOf(list, item.sku_id) >= 0 && !+item.disabled && item.sku_id) {
item.checked = false;
sum = sum - 1;
i.checked = false;
i.num = sum;
}
})
})
});
let checked_list = []
_.each(this.data_list, i => {
if (i.checked) {
checked_list.push(i.checked)
}
});
// this.category_num = checked_list.length;
this.category_num = this.checked_list.length;
if (this.data_list.length !== checked_list.length) {
this.all_checked = false;
}
// 移除数组内容
_.each(list, n => {
_.each(this.checked_list, (v, k) => {
if (v === n) {
this.checked_list.splice(k, 1);
}
});
});
},
addProduct () {
// 打开新增原物料
this.$emit('add', true);
}
}
}
</script>
<style lang="less">
.choose-material-page {
}
.material-title {
padding: 0.5rem;
font-size: 1.1rem;
border-bottom: 1px solid #eee;
}
.wrapper-scroll {
overflow-y: scroll;
max-height: 30rem;
.shortcut-title {
span {
font-size: 0.8rem;
}
i {
font-size: 0.7rem;
color: #838383;
}
}
.shortcut-content {
text-align: left;
padding: 0rem 0 0.5rem 2rem;
div {
font-size: 0.5rem;
border: 1px solid #8EA8CF;
color: #8EA8CF;
padding: 0.2rem 0.4rem;
margin-right: 0.5rem;
margin-top: 0.5rem;
display: inline-block;
}
}
.fold-content {
height: 0;
overflow: hidden;
padding-bottom: 0;
}
}
.material-wrapper {
text-align: left;
.material-all-checked {
font-size: 0.9rem;
padding: 0.5rem 0 0.8rem 0.5rem;
}
.material-classify {
.material-classify-checked {
font-size: 0.9rem;
padding: 0.4rem 0.2rem 0.1rem 0.85rem;
}
.material-classify-title {
margin-bottom: 0.5rem;
}
.material-content {
padding: 0 0.5rem;
border-bottom: 1px dashed #eee;
.flexbox-material {
padding-bottom: 10px;
.flex-material {
text-align: center;
color: #333333;
background-color: #f6f6f6;
}
.flex-checked {
color: #2c426b;
background-color: #C4D4E7;
}
.flex-disabled {
color: #CCCCCC;
background-color: #EAEFF7;
}
}
}
.fold-content {
height: 0;
overflow: hidden;
padding-bottom: 0;
}
}
}
.control-wrapper {
padding: 10px;
.close-btn {
background-color: #ffffff;
color: #8EA8CF;
border: 1px solid #8EA8CF;
width: 100%;
}
.comfirm-btn {
background-color: #8EA8CF;
color: #ffffff;
border: 1px solid #8EA8CF;
width: 100%;
}
}
.add-product-wrapper {
padding: 10px;
display: inline-block;
.add-btn {
background-color: #ffffff;
color: #8EA8CF;
border: 1px solid #8EA8CF;
width: 100%;
}
}
.weui-dialog {
width: 90% !important;
max-width: 400px;
}
@media screen and (min-width: 1024px) {
.weui-dialog {
width: 35%;
}
}
.weui-btn:after {
border: 0 !important;
}
.weui-icon-circle {
font-size: 20px !important;
}
.weui-icon-success {
font-size: 20px !important;
}
.vux-check-icon > .weui-icon-success:before, .vux-check-icon > .weui-icon-success-circle:before {
color: #8EA8CF !important;
}
</style>
<template lang="html">
<div class="">
<select-list :show="show" :title="'请选择物料'" :caption="'所有分类的物料'" :list="list" :shortcut="shortcut_list" :span="2" @cancel="cancel" @comfirm="comfirm"></select-list>
<div @click="showList">
显示
</div>
</div>
</template>
<script>
import selectList from 'components/selectList/index'
export default {
components: { selectList },
data () {
return {
show: false,
list: [{
category: '所有肉类的物料',
sum: 2,
material_list: [{
sku_id: 1,
sku_name: 'XX物料',
checked: false,
disabled: true
}, {
sku_id: 2,
sku_name: 'XX物料',
checked: false,
disabled: false
}]
}, {
category: '所有蔬菜类的物料',
sum: 2,
material_list: [{
sku_id: 11,
sku_name: 'XX物料',
checked: false,
disabled: false
}, {
sku_id: 22,
sku_name: 'XX物料',
checked: false,
disabled: false
}]
}, {
category: '所有蘑菇类的物料',
sum: 2,
material_list: [{
sku_id: 33,
sku_name: 'XX物料',
checked: false,
disabled: false
}, {
sku_id: 44,
sku_name: 'XX物料',
checked: false,
disabled: false
}]
}],
shortcut_list: [{
sku_name: '蔬菜类12+水果8',
sum: 2,
list: [{
sku_id: 1,
sku_name: 'XX物料'
}, {
sku_id: 2,
sku_name: 'XX物料'
}],
checked: false
}, {
sku_name: '肉类10+小器具12',
sum: 2,
list: [{
sku_id: 11,
sku_name: 'XX物料'
}, {
sku_id: 22,
sku_name: 'XX物料'
}],
checked: false
}, {
sku_name: '肉类10+小器具12',
sum: 4,
list: [{
sku_id: 33,
sku_name: 'XX物料'
}, {
sku_id: 44,
sku_name: 'XX物料'
}, {
sku_id: 55,
sku_name: 'XX物料'
}, {
sku_id: 66,
sku_name: 'XXxxxxx物料'
}, {
sku_id: 77,
sku_name: 'XX物料'
}, {
sku_id: 88,
sku_name: 'XX物料'
}, {
sku_id: 99,
sku_name: 'XX物料'
}, {
sku_id: 100,
sku_name: 'XX物料'
}],
checked: false
}]
}
},
methods: {
showList () {
this.show = true;
},
cancel (v) {
this.show = v;
},
comfirm (v) {
console.warn(v);
}
}
}
</script>
<style lang="less">
</style>
<template lang="html">
<div class="choose-material-page">
<div v-transfer-dom>
<x-dialog :show.sync="show" class="dialog-demo">
<div class="material-title">请选择{{name}}</div>
<div class="material-wrapper">
<div class="material-classify">
<div>
<check-icon :value.sync="all_checked" @click.native="checkAll(all_checked)">
全部{{name}}({{checkList.length}}/{{list.length}})
</check-icon>
<div class="material-content">
<checker
v-model="checkList"
type="checkbox"
default-item-class="item"
selected-item-class="item-selected"
disabled-item-class="item-disabled"
>
<checker-item class="brand_select" v-for="(item, index) in list" :key="index" :disabled="item.disabled" :value="item.id" @click.native="itemCheck(item.checked, index)">{{item.name}}</checker-item>
</checker>
</div>
</div>
</div>
</div>
<div style="padding: 10px;">
<flexbox>
<flexbox-item>
<x-button @click.native="cancel" mini style="background-color: #ffffff; color: #8EA8CF; border: 1px solid #8EA8CF; width: 100%;">关闭</x-button>
</flexbox-item>
<flexbox-item>
<x-button @click.native="comfirm" mini style="background-color: #8EA8CF; color: #ffffff; border: 1px solid #8EA8CF; width: 100%;">确定</x-button>
</flexbox-item>
</flexbox>
</div>
</x-dialog>
</div>
</div>
</template>
<script>
import { XDialog, TransferDomDirective as TransferDom, Flexbox, FlexboxItem, CheckIcon, XButton, Checker, CheckerItem } from 'vux'
export default {
props: ['show', 'list', 'checked_list', 'span', 'name'],
directives: { TransferDom },
components: { XDialog, Flexbox, FlexboxItem, CheckIcon, XButton, Checker, CheckerItem },
beforeRouteEnter (to, from, next) {
next()
},
mounted () {
// console.warn(this.list)
// console.warn(1)
},
data () {
return {
all_checked: true,
checkList: []
}
},
watch: {
show (val) {
// console.warn(val)
this.checkList = JSON.parse(JSON.stringify(this.checked_list))
if (val) {
let check_list = _.filter(this.list, (val) => {
let tem;
if (val.disabled === false) {
tem = val
}
return tem
});
// console.warn(check_list, this.checked_list)
if (check_list.length > 0 && this.checked_list.length > 0 && check_list.length === this.checked_list.length) {
this.all_checked = true
} else {
this.all_checked = false
}
} else {
this.all_checked = false
}
// this.checkList = val;
// setTimeout(() => {
// let arr = []
// for (let i = 0; i < $('.brand_select').length; i++) {
// arr.push($('.brand_select').eq(i).height())
// }
// let max = _.max(arr)
// $('.brand_select').height(max)
// }, 100)
}
},
computed: {
// checkList () {
// return JSON.parse(JSON.stringify(this.checked_list));
// }
},
methods: {
checkAll (checked) {
let check_list = _.filter(this.list, (val) => {
let tem;
if (val.disabled === false) {
tem = val
}
return tem
});
// 勾选所有品牌
if (checked) {
// 选中
for (let i = 0; i < check_list.length; i++) {
check_list[i].checked = true;
}
this.checkList = _.map(check_list, val => val.id)
// this.checked_list = id_list;
} else {
// 取消
this.checkList = []
for (let i = 0; i < check_list.length; i++) {
check_list[i].checked = false;
}
}
},
itemCheck (checked, index) {
// console.warn(this.checkList)
let list = _.filter(this.list, (val) => {
let tem;
if (val.disabled === false) {
tem = val
}
return tem
});
if (checked) {
this.list[index].checked = false;
} else {
this.list[index].checked = true;
}
// console.warn(id_list)
if (list.length !== this.checkList.length) {
this.all_checked = false
} else {
this.all_checked = true
}
},
changeCategory () {
},
cancel () {
// 关闭选择框
this.$emit('cancel', !this.show)
},
comfirm () {
// 确认选择框
this.$emit('comfirm', this.checkList)
}
}
}
</script>
<style lang="less">
.material-title {
line-height: 48px;
font-size: 18px;
}
.material-classify {
text-align: left;
padding: 10px;
.vux-checker-box {
display: flex;
flex-wrap: wrap;
}
.vux-check-icon {
margin-bottom: 10px;
}
}
.item {
width: 31%;
// flex-basis: 31%;
line-height: 26px;
text-align: center;
border-radius: 3px;
border: 1px solid #ccc;
background-color: #f6f6f6;
margin-bottom: 10px;
margin-right: 2.5%;
color: #333;
display: flex!important;
align-items: center;
justify-content: center;
&:nth-child(3n) {
margin-right: 0;
}
}
.weui-icon-circle {
font-size: 20px!important;
}
.weui-icon-success {
font-size: 20px!important;
}
.vux-check-icon > .weui-icon-success:before, .vux-check-icon > .weui-icon-success-circle:before {
color: #c4d4e7 !important;
}
.item-selected {
color: #2c426b;
background-color: #c4d4e7;
}
.item-disabled {
color: #cfcfcf;
background-color: #ebeef7;
}
.weui-dialog {
width: 90% !important;
max-width: 400px;
}
@media screen and (min-width: 1024px) {
.weui-dialog {
width: 35%;
}
}
.weui-btn:after {
border: 0 !important;
}
</style>
<template lang="html">
<div class="choose-material-page">
<div v-transfer-dom>
<x-dialog :show.sync="show" class="dialog-demo">
<div class="material-title">{{title}}</div>
<div class="wrapper-scroll">
<div v-for="(v, k) in shortcut" :key="k">
<flexbox class="shortcut-title">
<flexbox-item :span="9">
<check-icon @click.native="shortcutCheck(k)" :value.sync="shortcut[k].checked">
<span>{{v.sku_name}}</span>
</check-icon>
</flexbox-item>
<flexbox-item @click.native="shortcutFold(k)" style="margin-left: 0;">
<span style="color: #8EA8CF;">{{v.sku_count}}种物料</span>
<i class="fa fa-chevron-right"></i>
</flexbox-item>
</flexbox>
<div class="shortcut-content fold-content">
<div v-for="(item, index) in v.list" :key="index">{{item.sku_name}}</div>
</div>
</div>
<div class="material-wrapper">
<check-icon class="material-all-checked" @click.native="checkAll(all_checked)" :value.sync="all_checked">
{{caption}}(<span style="color: #8EA8CF;">{{category_num}}</span>/{{category_sum}})
</check-icon>
<div class="material-classify">
<div class="material-index" v-for="(item, index) in data_list" :key="index">
<div style="border-top: 1px dashed #eee; width: 100%;"></div>
<flexbox class="material-classify-title">
<flexbox-item :span="10">
<check-icon class="material-classify-checked" @click.native="changeCategory(index)" :value.sync="data_list[index].checked">
{{item.name}}(<span style="color: #8EA8CF;">{{item.num}}</span>/{{item.sku_count}})
</check-icon>
</flexbox-item>
<flexbox-item @click.native="fold(index)">
<div style="padding-top: 0.2rem; padding-left: 0.5rem;">
<i class="fa fa-chevron-down" style="font-size: 0.7rem; color: #838383;"></i>
</div>
</flexbox-item>
</flexbox>
<div class="material-content">
<flexbox :gutter="10" class="flexbox-material material-item" v-for="(m, key) in item.sku_list" :key="key">
<flexbox-item v-for="(v, k) in m" :key="k" :class="['material-item' + '-' + k]">
<div v-if="!+v.disabled" @click="itemCheck(v, index, 'click')"
:class="[v.checked === true ? 'flex-checked' : '', 'flex-material']">
{{v.sku_name}}
</div>
<div v-else class="flex-material flex-disabled"> {{v.sku_name}} </div>
</flexbox-item>
</flexbox>
</div>
</div>
</div>
</div>
</div>
<div class="control-wrapper">
<flexbox>
<flexbox-item>
<x-button class="close-btn" @click.native="cancel" mini>关闭</x-button>
</flexbox-item>
<flexbox-item>
<x-button class="comfirm-btn" @click.native="comfirm" mini>确定</x-button>
</flexbox-item>
</flexbox>
</div>
</x-dialog>
</div>
</div>
</template>
<script>
import { XDialog, TransferDomDirective as TransferDom, Flexbox, FlexboxItem, CheckIcon, XButton } from 'vux'
export default {
props: ['show', 'title', 'caption', 'list', 'span', 'shortcut'],
directives: { TransferDom },
components: { XDialog, Flexbox, FlexboxItem, CheckIcon, XButton },
mounted () {
},
data () {
return {
all_checked: false,
item_checked: false,
data_list: [],
category_num: 0,
checked_list: [],
shortcut_checked_list: []
}
},
watch: {
list (val, old) {
if (val !== old) {
this.data_list = [];
// 动态生成绑定变量
let foo = val;
for (let i = 0; i < foo.length; i++) {
// 补全物料占位
let remainder = foo[i]['sku_list'].length % this.span;
if (remainder > 0) {
for (let y = 0; y < (this.span - remainder); y++) {
foo[i]['sku_list'].push({
sku_id: '',
sku_name: '',
checked: false,
disabled: '0'
})
}
}
// 分割计算
let tmp = [];
while (foo[i]['sku_list'].length) {
tmp.push(foo[i]['sku_list'].splice(0, this.span));
}
this.data_list.push({
checked: false,
name: foo[i]['name'],
num: 0,
sku_count: foo[i]['sku_count'],
sku_list: tmp
});
}
}
setTimeout(() => {
let arr = $('.material-item');
function getDom (dom, index) {
return $(dom).children().eq(index)
}
_.each(arr, (v, k) => {
_.each($(v), x => {
if (getDom(x, 0).height() > getDom(x, 1).height()) {
getDom(x, 1).css('line-height', getDom(x, 0).height() + 'px')
getDom(x, 1).css('height', getDom(x, 0).height() + 'px')
} else if (getDom(x, 0).height() < getDom(x, 1).height()) {
getDom(x, 0).css('line-height', getDom(x, 1).height() + 'px')
getDom(x, 0).css('height', getDom(x, 1).height() + 'px')
}
})
});
}, 100);
},
category_num (val) {
// 小分类全选状态
if (val === this.category_sum) {
this.all_checked = true;
} else {
this.all_checked = false;
}
}
},
computed: {
category_sum () {
return _.reduce(this.data_list, (sum, n) => {
return sum + n.sku_count;
}, 0);
}
},
methods: {
checkAll (checked) {
// 勾选所有类别
if (checked) {
// 选中
_.each(this.data_list, (item, key) => {
this.data_list[key]['checked'] = true;
this.changeCategory(key)
});
} else {
// 取消
_.each(this.data_list, (item, key) => {
this.data_list[key]['checked'] = false;
this.changeCategory(key)
});
}
},
itemCheck (item, i, method) {
// 选中项
if (method === 'click') {
item.checked = !item.checked;
}
// 选中数量
if (item.checked) {
this.data_list[i]['num'] = this.data_list[i]['num'] < this.data_list[i]['sku_count'] ? this.data_list[i]['num'] + 1 : this.data_list[i]['sku_count'];
// 新增数组内容
this.checked_list.push(item.sku_id);
} else {
this.data_list[i]['checked'] = false;
this.data_list[i]['num'] = this.data_list[i]['num'] > 0 ? this.data_list[i]['num'] - 1 : 0;
// 移除数组内容
_.each(this.checked_list, (v, k) => {
if (item.sku_id && v === item.sku_id) {
this.checked_list.splice(k, 1);
}
});
}
// 遍历勾选项 全选
// 查询小分类勾选数量
if (this.data_list[i]['num'] === this.data_list[i]['sku_count']) {
this.data_list[i]['checked'] = true;
}
// 小分类勾选状态调整大分类状态
let cat_checked = [];
_.each(this.data_list, item => {
if (item.checked) {
cat_checked.push(item.checked)
}
});
// this.category_num = cat_checked.length < this.data_list.length ? cat_checked.length : this.data_list.length;
this.category_num = this.checked_list.length;
},
changeCategory (i) {
// 勾选分类
if (this.data_list[i]['checked']) {
// 全选
_.each(this.data_list[i]['sku_list'], item => {
_.each(item, v => {
v.checked = true;
// 选中项ID
if (!+v.disabled) {
if (_.indexOf(this.checked_list, v.sku_id) < 0 && v.sku_id) {
this.checked_list.push(v.sku_id);
}
}
})
});
// 小分类数量全选
this.data_list[i]['num'] = this.data_list[i]['sku_count'];
// 新增所有分类勾选数量
// this.category_num = this.category_num < this.data_list.length ? this.category_num + 1 : this.data_list.length;
this.category_num = this.checked_list.length;
} else {
// 小分类ID集合
let id_list = [];
// 取消全选
_.each(this.data_list[i]['sku_list'], item => {
_.each(item, v => {
v.checked = false;
// 集合
id_list.push(v.sku_id)
})
});
// 移除数组内容
_.each(id_list, n => {
_.each(this.checked_list, (v, k) => {
if (v === n) {
this.checked_list.splice(k, 1);
}
});
});
// 小分类数量归零
this.data_list[i]['num'] = 0;
// 减少所有分类勾选数量
// this.category_num = this.category_num > 0 ? this.category_num - 1 : 0;
this.category_num = this.checked_list.length;
}
},
cancel () {
// 关闭选择框
this.$emit('cancel', !this.show);
this.clear();
},
comfirm () {
// 确认选择框
let arr = [];
_.each(this.data_list, x => {
_.each(x.sku_list, y => {
_.each(y, z => {
_.each(this.checked_list, item => {
if (item === z.sku_id) {
z.sku_classname = x.name;
arr.push(z);
}
})
})
})
});
this.$emit('comfirm', arr);
this.clear();
},
clear () {
// 清空选择项
if (this.all_checked) {
this.all_checked = false;
}
this.category_num = 0;
_.each(this.data_list, (item, key) => {
if (item.checked) {
item.checked = false;
item.num = 0;
}
_.each(item.sku_list, (v, k) => {
_.each(v, x => {
if (x.checked) {
x.checked = false;
item.num = 0;
}
})
})
});
this.checked_list = [];
// 清空快捷
_.each(this.shortcut, item => {
item.checked = false;
});
this.shortcut_checked_list = [];
},
fold (index) {
let has_class = $($('.material-classify-title')[index]).siblings('.material-content').hasClass('fold-content');
if (has_class) {
// 展开
$($('.material-classify-title')[index]).siblings('.material-content').removeClass('fold-content');
$($('.material-classify-title')[index]).find('i').addClass('fa-chevron-down').removeClass('fa-chevron-right');
} else {
// 折叠
$($('.material-classify-title')[index]).siblings('.material-content').addClass('fold-content');
$($('.material-classify-title')[index]).find('i').addClass('fa-chevron-right').removeClass('fa-chevron-down');
}
},
shortcutFold (index) {
let has_class = $($('.shortcut-title')[index]).siblings('.shortcut-content').hasClass('fold-content');
if (has_class) {
// 展开
$($('.shortcut-title')[index]).siblings('.shortcut-content').removeClass('fold-content');
$($('.shortcut-title')[index]).find('i').addClass('fa-chevron-down').removeClass('fa-chevron-right');
} else {
// 折叠
$($('.shortcut-title')[index]).siblings('.shortcut-content').addClass('fold-content');
$($('.shortcut-title')[index]).find('i').addClass('fa-chevron-right').removeClass('fa-chevron-down');
}
},
shortcutCheck (i) {
// 快捷方式选中
let list = _.map(this.shortcut[i].list, item => {
return item.sku_id
});
if (this.shortcut[i]['checked']) {
// 勾选
this.shortcut_checked_list = this.shortcut_checked_list.concat(list);
//
_.each(this.data_list, (item, key) => {
_.each(item.sku_list, (v, k) => {
_.each(v, x => {
// ID在快捷列表中存在
if (_.indexOf(this.shortcut_checked_list, x.sku_id) >= 0 && !+x.disabled) {
x.checked = true;
if (!+x.disabled) {
if (_.indexOf(this.checked_list, x.sku_id) < 0 && x.sku_id) {
this.checked_list.push(x.sku_id);
}
}
this.setCheck()
}
});
})
});
} else {
// 取消
this.shortcut_checked_list = _.difference(this.shortcut_checked_list, list);
this.removeCheck(list)
}
},
setCheck () {
// 勾选取消大小分类
_.each(this.data_list, i => {
_.each(i.sku_list, x => {
let sum = 0;
_.each(x, item => {
if (_.indexOf(this.shortcut_checked_list, item.sku_id) >= 0 && !+item.disabled && item.sku_id) {
sum = sum + 1;
if (i.sku_count === sum) {
i.checked = true;
i.num = sum;
} else {
i.checked = false;
i.num = sum;
}
}
})
});
});
let checked_list = []
_.each(this.data_list, i => {
if (i.checked) {
checked_list.push(i.checked)
}
});
// this.category_num = checked_list.length;
this.category_num = this.checked_list.length;
if (this.data_list.length === checked_list.length) {
this.all_checked = true;
}
},
removeCheck (list) {
// 勾选取消大小分类
_.each(this.data_list, i => {
_.each(i.sku_list, x => {
let sum = i.sku_count;
_.each(x, item => {
if (_.indexOf(list, item.sku_id) >= 0 && !+item.disabled && item.sku_id) {
item.checked = false;
sum = sum - 1;
i.checked = false;
i.num = sum;
}
})
})
});
let checked_list = []
_.each(this.data_list, i => {
if (i.checked) {
checked_list.push(i.checked)
}
});
// this.category_num = checked_list.length;
this.category_num = this.checked_list.length;
if (this.data_list.length !== checked_list.length) {
this.all_checked = false;
}
// 移除数组内容
_.each(list, n => {
_.each(this.checked_list, (v, k) => {
if (v === n) {
this.checked_list.splice(k, 1);
}
});
});
}
}
}
</script>
<style lang="less">
.choose-material-page {
}
.material-title {
padding: 0.5rem;
font-size: 1.1rem;
border-bottom: 1px solid #eee;
}
.wrapper-scroll {
overflow-y: scroll;
max-height: 30rem;
.shortcut-title {
span {
font-size: 0.8rem;
}
i {
font-size: 0.7rem;
color: #838383;
}
}
.shortcut-content {
text-align: left;
padding: 0rem 0 0.5rem 2rem;
div {
font-size: 0.5rem;
border: 1px solid #8EA8CF;
color: #8EA8CF;
padding: 0.2rem 0.4rem;
margin-right: 0.5rem;
margin-top: 0.5rem;
display: inline-block;
}
}
.fold-content {
height: 0;
overflow: hidden;
padding-bottom: 0;
}
}
.material-wrapper {
text-align: left;
.material-all-checked {
font-size: 0.9rem;
padding: 0.5rem 0.2rem;
}
.material-classify {
.material-classify-checked {
font-size: 0.9rem;
padding: 0.4rem 0.2rem 0.1rem 0.85rem;
}
.material-classify-title {
margin-bottom: 0.5rem;
}
.material-content {
padding: 0 0.5rem;
border-bottom: 1px dashed #eee;
.flexbox-material {
padding-bottom: 10px;
// align-items: center;
// justify-content: center;
.flex-material {
text-align: center;
color: #333333;
background-color: #f6f6f6;
}
.flex-checked {
color: #2c426b;
background-color: #C4D4E7;
}
.flex-disabled {
color: #CCCCCC;
background-color: #EAEFF7;
}
}
}
.fold-content {
height: 0;
overflow: hidden;
padding-bottom: 0;
}
}
}
.control-wrapper {
padding: 10px;
.close-btn {
background-color: #ffffff;
color: #8EA8CF;
border: 1px solid #8EA8CF;
width: 100%;
}
.comfirm-btn {
background-color: #8EA8CF;
color: #ffffff;
border: 1px solid #8EA8CF;
width: 100%;
}
}
.weui-dialog {
width: 90% !important;
max-width: 400px;
}
@media screen and (min-width: 1024px) {
.weui-dialog {
width: 35%;
}
}
.weui-btn:after {
border: 0 !important;
}
.weui-icon-circle {
font-size: 20px !important;
}
.weui-icon-success {
font-size: 20px !important;
}
.vux-check-icon > .weui-icon-success:before, .vux-check-icon > .weui-icon-success-circle:before {
color: #8EA8CF !important;
}
</style>
<template lang="html">
<div class="">
<select-list :show="show" :title="'请选择物料'" :caption="'所有分类的物料'" :list="list" :shortcut="shortcut_list" :span="2" @cancel="cancel" @comfirm="comfirm"></select-list>
<div @click="showList">
显示
</div>
</div>
</template>
<script>
import selectList from 'components/selectList/index'
export default {
components: { selectList },
data () {
return {
show: false,
list: [{
category: '所有肉类的物料',
sum: 2,
material_list: [{
sku_id: 1,
sku_name: 'XX物料',
checked: false,
disabled: true
}, {
sku_id: 2,
sku_name: 'XX物料',
checked: false,
disabled: false
}]
}, {
category: '所有蔬菜类的物料',
sum: 2,
material_list: [{
sku_id: 11,
sku_name: 'XX物料',
checked: false,
disabled: false
}, {
sku_id: 22,
sku_name: 'XX物料',
checked: false,
disabled: false
}]
}, {
category: '所有蘑菇类的物料',
sum: 2,
material_list: [{
sku_id: 33,
sku_name: 'XX物料',
checked: false,
disabled: false
}, {
sku_id: 44,
sku_name: 'XX物料',
checked: false,
disabled: false
}]
}],
shortcut_list: [{
sku_name: '蔬菜类12+水果8',
sum: 2,
list: [{
sku_id: 1,
sku_name: 'XX物料'
}, {
sku_id: 2,
sku_name: 'XX物料'
}],
checked: false
}, {
sku_name: '肉类10+小器具12',
sum: 2,
list: [{
sku_id: 11,
sku_name: 'XX物料'
}, {
sku_id: 22,
sku_name: 'XX物料'
}],
checked: false
}, {
sku_name: '肉类10+小器具12',
sum: 4,
list: [{
sku_id: 33,
sku_name: 'XX物料'
}, {
sku_id: 44,
sku_name: 'XX物料'
}, {
sku_id: 55,
sku_name: 'XX物料'
}, {
sku_id: 66,
sku_name: 'XXxxxxx物料'
}, {
sku_id: 77,
sku_name: 'XX物料'
}, {
sku_id: 88,
sku_name: 'XX物料'
}, {
sku_id: 99,
sku_name: 'XX物料'
}, {
sku_id: 100,
sku_name: 'XX物料'
}],
checked: false
}]
}
},
methods: {
showList () {
this.show = true;
},
cancel (v) {
this.show = v;
},
comfirm (v) {
console.warn(v);
}
}
}
</script>
<style lang="less">
</style>
<template lang="html">
<div class="financial_manager">
<!-- <p>请选择</p> -->
<selectPage :text="text" :checkedList="checked" :list="list" @change-text="changeText" @change="selected"></selectPage>
</div>
</template>
<script>
import selectPage from './index.vue'
export default {
components: {
selectPage
},
data () {
return {
text: '',
checked: ['002', '003'],
list: [
{
id: '001',
value: '肉'
},
{
id: '002',
value: '青菜'
},
{
id: '003',
value: '啤酒'
},
{
id: '004',
value: '水果'
},
{
id: '005',
value: '水果'
},
{
id: '006',
value: '水果'
},
{
id: '007',
value: '水果'
},
{
id: '008',
value: '水果'
},
{
id: '009',
value: '水果'
},
{
id: '010',
value: '水果'
},
{
id: '011',
value: '水果'
}
]
}
},
methods: {
selected (id) {
console.warn(id);
},
changeText (val) {
this.text = val;
}
}
}
</script>
<style lang="less">
</style>
<template>
<div class="select-check">
<p><span @touchstart.capture="open">{{text}}<icon class="Icon" type="warn"></icon></span></p>
<transition name="component-fade" mode="out-in">
<div class="select-content" v-if="show">
<p class="select-up">请选择<icon class="Icon Icon_up" type="warn"></icon></p>
<div>
<checker
class="checkbox"
v-model="checkList"
type="checkbox"
default-item-class="select-item"
selected-item-class="select-item-selected"
@on-change="selected"
>
<checker-item v-for="item in list" :key="item.id" :value="item.id" >{{item.value}}</checker-item>
</checker>
<x-button class="select-btn" @click.native="submit">确 定</x-button>
</div>
</div>
</transition>
<!-- </transition-group> -->
</div>
</template>
<script>
/*
下拉多选
数据:
checkList: 选中列表集合;
list: 选项列表集合;
方法:
selected: 选项发生改变之后的回调,返回选中项的id;
submit: 点击确定之后的回调;
*/
import { XButton, Checker, CheckerItem, Icon } from 'vux'
export default {
components: {
XButton,
Checker,
CheckerItem,
Icon
},
props: {
text: {
type: String,
default: '请选择'
},
list: {
type: Array,
default: []
},
checkedList: {
type: Array,
default: []
}
},
data () {
return {
show: false,
checkList: []
}
},
created () {
let text;
if (this.checkedList.length != 0) {
text = '已选择' + this.checkedList.length + '个选项';
} else {
text = '请选择'
}
this.$emit('change-text', text)
},
mounted () {
// console.warn(this.checkedList)
this.checkList = this.checkedList
},
methods: {
open () {
this.show = true;
},
selected () {
let text;
if (this.checkList.length != 0) {
text = '已选择' + this.checkList.length + '个选项';
} else {
text = '请选择'
};
this.$emit('change-text', text)
this.$emit('change', this.checkList)
},
submit () {
if (this.checkList.length > 0) {
let text = '已选择' + this.checkList.length + '个选项';
this.$emit('change-text', text)
this.show = false;
} else {
this.$vux.toast.show({
text: '请选择内容',
type: 'text'
})
}
}
}
}
</script>
<style lang="less" scoped>
.select-check {
p {
font-size: 16px;
color: #333;
text-align: right;
padding: 10px 5px 10px 0;
border-bottom: 1px solid #d6d7dc;
.Icon {
position: relative;
font-size: 0;
margin-left: 15px;
}
.Icon:before {
width: 0;
height: 0;
}
.Icon:after {
content: " ";
display: inline-block;
height: 10px;
width: 10px;
border-width: 2px 2px 0 0;
border-color: #C8C8CD;
border-style: solid;
transform: matrix(0.71, 0.71, -0.71, 0.71, 0, 0);
position: relative;
top: -2px;
position: absolute;
top: 50%;
margin-top: -8px;
right: 2px;
}
.Icon_up {
margin-left: 22px;
}
.Icon_up:after {
border-width: 0 2px 2px 0;
margin-top: -11px;
}
}
.checkbox {
padding: 10px 0;
display: flex;
flex-flow: row wrap;
justify-content: space-between;
.select-item {
background-color: #f6f6f6;
color: #999;
font-size: 14px;
text-align: center;
padding: 5px 10px;
margin-bottom: 10px;
line-height: 18px;
border: 1px solid #f6f6f6;
border-radius: 5px;
flex: 0 0 18%;
box-sizing: border-box;
}
.select-item-selected {
background-color: #c4d4e7;
color: #999;
border-color: #c4d4e7;
}
.select-item-disabled {
color: #999;
}
}
.select-btn {
background-color: #c4d4e7;
font-size: 16px;
color: #fff;
&:after{
border: 0;
}
&:not(.weui-btn_disabled):active {
background-color: #89a9cf;
color: #fff;
}
}
}
.component-fade-enter-active, .component-fade-leave-active {
transition: opacity .3s ease;
}
.component-fade-enter, .component-fade-leave-to {
opacity: 0;
}
</style>
<template lang="html">
<div class="choose-material-page">
<div v-transfer-dom>
<x-dialog :show.sync="show" class="dialog-demo">
<div class="material-title">{{title}}</div>
<div class="wrapper-scroll">
<div v-for="(v, k) in shortcut" :key="k">
<flexbox class="shortcut-title">
<flexbox-item :span="9">
<check-icon @click.native="shortcutCheck(k)" :value.sync="shortcut[k].checked">
<span>{{v.store_name}}</span>
</check-icon>
</flexbox-item>
<flexbox-item @click.native="shortcutFold(k)" style="margin-left: 0;">
<span style="color: #8EA8CF;">{{v.store_count}}种物料</span>
<i class="fa fa-chevron-right"></i>
</flexbox-item>
</flexbox>
<div class="shortcut-content fold-content">
<div v-for="(item, index) in v.list" :key="index">{{item.store_name}}</div>
</div>
</div>
<div class="material-wrapper">
<check-icon class="material-all-checked" @click.native="checkAll(all_checked)" :value.sync="all_checked">
{{caption}}(<span style="color: #8EA8CF;">{{category_num}}</span>/{{category_sum}})
</check-icon>
<div class="material-classify">
<div v-for="(item, index) in data_list" :key="index">
<div style="border-top: 1px dashed #eee; width: 100%;"></div>
<flexbox class="material-classify-title">
<flexbox-item :span="10">
<check-icon class="material-classify-checked" @click.native="changeCategory(index)" :value.sync="data_list[index].checked">
{{item.name}}(<span style="color: #8EA8CF;">{{item.num}}</span>/{{item.store_count}})
</check-icon>
</flexbox-item>
<flexbox-item @click.native="fold(index)">
<div style="padding-top: 0.2rem; padding-left: 0.5rem;">
<i class="fa fa-chevron-down" style="font-size: 0.7rem; color: #838383;"></i>
</div>
</flexbox-item>
</flexbox>
<div class="material-content">
<flexbox :gutter="10" class="flexbox-material" v-for="(m, key) in item.store_list" :key="key">
<flexbox-item v-for="(v, k) in m" :key="k">
<div v-if="!+v.disabled" @click="itemCheck(v, index, 'click')"
:class="[v.checked === true ? 'flex-checked' : '', 'flex-material']">
{{v.store_name}}
</div>
<div v-else class="flex-material flex-disabled"> {{v.store_name}} </div>
</flexbox-item>
</flexbox>
</div>
</div>
</div>
</div>
</div>
<div class="control-wrapper">
<flexbox>
<flexbox-item>
<x-button class="close-btn" @click.native="cancel" mini>关闭</x-button>
</flexbox-item>
<flexbox-item>
<x-button class="comfirm-btn" @click.native="comfirm" mini>确定</x-button>
</flexbox-item>
</flexbox>
</div>
</x-dialog>
</div>
</div>
</template>
<script>
import { XDialog, TransferDomDirective as TransferDom, Flexbox, FlexboxItem, CheckIcon, XButton } from 'vux'
export default {
props: ['show', 'title', 'caption', 'list', 'span', 'shortcut', 'checkedList'],
directives: { TransferDom },
components: { XDialog, Flexbox, FlexboxItem, CheckIcon, XButton },
mounted () {
},
data () {
return {
all_checked: false,
item_checked: false,
data_list: [],
category_num: 0,
checked_list: [],
shortcut_checked_list: []
}
},
watch: {
list (val, old) {
if (val !== old) {
this.data_list = [];
// 动态生成绑定变量
let foo = val;
for (let i = 0; i < foo.length; i++) {
// 补全物料占位
let remainder = foo[i]['store_list'].length % this.span;
if (remainder > 0) {
for (let y = 0; y < (this.span - remainder); y++) {
foo[i]['store_list'].push({
store_id: '',
store_name: '',
checked: false,
disabled: '0'
})
}
}
// 分割计算
let tmp = [];
while (foo[i]['store_list'].length) {
tmp.push(foo[i]['store_list'].splice(0, this.span));
}
this.data_list.push({
checked: false,
name: foo[i]['name'],
num: 0,
store_count: foo[i]['store_count'],
store_list: tmp
});
}
}
},
category_num (val) {
// 小分类全选状态
if (val === this.category_sum) {
this.all_checked = true;
} else {
this.all_checked = false;
}
},
checkedList (val) {
if (val.length !== 0) {
val.forEach(element => {
this.data_list.forEach((data, index) => {
data.store_list.forEach(s => {
s.forEach(v => {
if (element.store_id === v.store_id) {
this.itemCheck(v, index, 'click');
}
})
})
})
});
}
}
},
computed: {
category_sum () {
return _.reduce(this.data_list, (sum, n) => {
return sum + n.store_count;
}, 0);
}
},
methods: {
checkAll (checked) {
// 勾选所有类别
if (checked) {
// 选中
_.each(this.data_list, (item, key) => {
this.data_list[key]['checked'] = true;
this.changeCategory(key)
});
} else {
// 取消
_.each(this.data_list, (item, key) => {
this.data_list[key]['checked'] = false;
this.changeCategory(key)
});
}
},
itemCheck (item, i, method) {
// 选中项
if (method === 'click') {
item.checked = !item.checked;
}
// 选中数量
if (item.checked) {
this.data_list[i]['num'] = this.data_list[i]['num'] < this.data_list[i]['store_count'] ? this.data_list[i]['num'] + 1 : this.data_list[i]['store_count'];
// 新增数组内容
this.checked_list.push(item.store_id);
} else {
this.data_list[i]['checked'] = false;
this.data_list[i]['num'] = this.data_list[i]['num'] > 0 ? this.data_list[i]['num'] - 1 : 0;
// 移除数组内容
_.each(this.checked_list, (v, k) => {
if (item.store_id && v === item.store_id) {
this.checked_list.splice(k, 1);
}
});
}
// 遍历勾选项 全选
// 查询小分类勾选数量
if (this.data_list[i]['num'] === this.data_list[i]['store_count']) {
this.data_list[i]['checked'] = true;
}
// 小分类勾选状态调整大分类状态
let cat_checked = [];
_.each(this.data_list, item => {
if (item.checked) {
cat_checked.push(item.checked)
}
});
this.category_num = cat_checked.length < this.data_list.length ? cat_checked.length : this.data_list.length;
},
changeCategory (i) {
// 勾选分类
if (this.data_list[i]['checked']) {
// 全选
_.each(this.data_list[i]['store_list'], item => {
_.each(item, v => {
v.checked = true;
// 选中项ID
if (!+v.disabled) {
if (_.indexOf(this.checked_list, v.store_id) < 0 && v.store_id) {
this.checked_list.push(v.store_id);
}
}
})
});
// 小分类数量全选
this.data_list[i]['num'] = this.data_list[i]['store_count'];
// 新增所有分类勾选数量
this.category_num = this.category_num < this.data_list.length ? this.category_num + 1 : this.data_list.length;
} else {
// 小分类ID集合
let id_list = [];
// 取消全选
_.each(this.data_list[i]['store_list'], item => {
_.each(item, v => {
v.checked = false;
// 集合
id_list.push(v.store_id)
})
});
// 移除数组内容
_.each(id_list, n => {
_.each(this.checked_list, (v, k) => {
if (v === n) {
this.checked_list.splice(k, 1);
}
});
});
// 小分类数量归零
this.data_list[i]['num'] = 0;
// 减少所有分类勾选数量
this.category_num = this.category_num > 0 ? this.category_num - 1 : 0;
}
},
cancel () {
// 关闭选择框
this.$emit('cancel', !this.show);
this.clear();
},
comfirm () {
// 确认选择框
let arr = [];
_.each(this.data_list, x => {
_.each(x.store_list, y => {
_.each(y, z => {
_.each(this.checked_list, item => {
if (item === z.store_id) {
z.route_name = x.name;
arr.push(z);
}
})
})
})
});
this.$emit('comfirm', arr);
this.clear();
},
clear () {
// 清空选择项
if (this.all_checked) {
this.all_checked = false;
}
this.category_num = 0;
_.each(this.data_list, (item, key) => {
if (item.checked) {
item.checked = false;
item.num = 0;
}
_.each(item.store_list, (v, k) => {
_.each(v, x => {
if (x.checked) {
x.checked = false;
item.num = 0;
}
})
})
});
this.checked_list = [];
// 清空快捷
_.each(this.shortcut, item => {
item.checked = false;
});
this.shortcut_checked_list = [];
},
fold (index) {
let has_class = $($('.material-classify-title')[index]).siblings('.material-content').hasClass('fold-content');
if (has_class) {
// 展开
$($('.material-classify-title')[index]).siblings('.material-content').removeClass('fold-content');
$($('.material-classify-title')[index]).find('i').addClass('fa-chevron-down').removeClass('fa-chevron-right');
} else {
// 折叠
$($('.material-classify-title')[index]).siblings('.material-content').addClass('fold-content');
$($('.material-classify-title')[index]).find('i').addClass('fa-chevron-right').removeClass('fa-chevron-down');
}
},
shortcutFold (index) {
let has_class = $($('.shortcut-title')[index]).siblings('.shortcut-content').hasClass('fold-content');
if (has_class) {
// 展开
$($('.shortcut-title')[index]).siblings('.shortcut-content').removeClass('fold-content');
$($('.shortcut-title')[index]).find('i').addClass('fa-chevron-down').removeClass('fa-chevron-right');
} else {
// 折叠
$($('.shortcut-title')[index]).siblings('.shortcut-content').addClass('fold-content');
$($('.shortcut-title')[index]).find('i').addClass('fa-chevron-right').removeClass('fa-chevron-down');
}
},
shortcutCheck (i) {
// 快捷方式选中
let list = _.map(this.shortcut[i].list, item => {
return item.store_id
});
if (this.shortcut[i]['checked']) {
// 勾选
this.shortcut_checked_list = this.shortcut_checked_list.concat(list);
//
_.each(this.data_list, (item, key) => {
_.each(item.store_list, (v, k) => {
_.each(v, x => {
// ID在快捷列表中存在
if (_.indexOf(this.shortcut_checked_list, x.store_id) >= 0 && !+x.disabled) {
x.checked = true;
if (!+x.disabled) {
if (_.indexOf(this.checked_list, x.store_id) < 0 && x.store_id) {
this.checked_list.push(x.store_id);
}
}
this.setCheck()
}
});
})
});
} else {
// 取消
this.shortcut_checked_list = _.difference(this.shortcut_checked_list, list);
this.removeCheck(list)
}
},
setCheck () {
// 勾选取消大小分类
_.each(this.data_list, i => {
_.each(i.store_list, x => {
let sum = 0;
_.each(x, item => {
if (_.indexOf(this.shortcut_checked_list, item.store_id) >= 0 && !+item.disabled && item.store_id) {
sum = sum + 1;
if (i.store_count === sum) {
i.checked = true;
i.num = sum;
} else {
i.checked = false;
i.num = sum;
}
}
})
});
});
let checked_list = []
_.each(this.data_list, i => {
if (i.checked) {
checked_list.push(i.checked)
}
});
this.category_num = checked_list.length;
if (this.data_list.length === checked_list.length) {
this.all_checked = true;
}
},
removeCheck (list) {
// 勾选取消大小分类
_.each(this.data_list, i => {
_.each(i.store_list, x => {
let sum = i.store_count;
_.each(x, item => {
if (_.indexOf(list, item.store_id) >= 0 && !+item.disabled && item.store_id) {
item.checked = false;
sum = sum - 1;
i.checked = false;
i.num = sum;
}
})
})
});
let checked_list = []
_.each(this.data_list, i => {
if (i.checked) {
checked_list.push(i.checked)
}
});
this.category_num = checked_list.length;
if (this.data_list.length !== checked_list.length) {
this.all_checked = false;
}
// 移除数组内容
_.each(list, n => {
_.each(this.checked_list, (v, k) => {
if (v === n) {
this.checked_list.splice(k, 1);
}
});
});
}
}
}
</script>
<style lang="less">
.choose-material-page {
}
.material-title {
padding: 0.5rem;
font-size: 18px;
border-bottom: 1px solid #eee;
}
.wrapper-scroll {
overflow-y: scroll;
max-height: 30rem;
.shortcut-title {
span {
font-size: 0.8rem;
}
i {
font-size: 0.7rem;
color: #838383;
}
}
.shortcut-content {
text-align: left;
padding: 0rem 0 0.5rem 2rem;
div {
font-size: 0.5rem;
border: 1px solid #8EA8CF;
color: #8EA8CF;
padding: 0.2rem 0.4rem;
margin-right: 0.5rem;
margin-top: 0.5rem;
display: inline-block;
}
}
.fold-content {
height: 0;
overflow: hidden;
padding-bottom: 0;
}
}
.material-wrapper {
text-align: left;
.material-all-checked {
font-size: 0.9rem;
padding: 0.5rem 0.2rem;
}
.material-classify {
.material-classify-checked {
font-size: 0.9rem;
padding: 0.4rem 0.2rem 0.1rem 0.85rem;
}
.material-classify-title {
margin-bottom: 0.5rem;
}
.material-content {
padding: 0 0.5rem;
border-bottom: 1px dashed #eee;
.flexbox-material {
padding-bottom: 10px;
.flex-material {
text-align: center;
background-color: #eee;
}
.flex-checked {
color: white;
background-color: #8EA8CF;
}
.flex-disabled {
color: #cfcfcf;
background-color: #ebeef7;
}
}
}
.fold-content {
height: 0;
overflow: hidden;
padding-bottom: 0;
}
}
}
.control-wrapper {
padding: 10px;
.close-btn {
background-color: #ffffff;
color: #8EA8CF;
border: 1px solid #8EA8CF;
width: 100%;
}
.comfirm-btn {
background-color: #8EA8CF;
color: #ffffff;
border: 1px solid #8EA8CF;
width: 100%;
}
}
.weui-dialog {
width: 90% !important;
max-width: 400px;
}
@media screen and (min-width: 1024px) {
.weui-dialog {
width: 35%;
}
}
.weui-btn:after {
border: 0 !important;
}
.weui-icon-circle {
font-size: 20px !important;
}
.weui-icon-success {
font-size: 20px !important;
}
.vux-check-icon > .weui-icon-success:before, .vux-check-icon > .weui-icon-success-circle:before {
color: #8EA8CF !important;
}
</style>
<template>
<div class="choose_store_multi">
<div v-transfer-dom>
<x-dialog :show.sync="show" class="dialog-demo">
<div class="store-title">{{title}}</div>
<div class="wrap-scroll">
<!-- <div class="store-wrapper">
<check-icon class="store-all-checked" :value.sync="category_checked" @click.native="checkAll">
所有品牌的门店(<span style="color: #8EA8CF;">{{category_num}}</span>/{{category_sum}})
</check-icon>
</div> -->
<div class="store-classify">
<div v-for="(b, bi) in data_list" :key="bi">
<div style="border-top: 1px dashed #eee; width: 100%;"></div>
<flexbox class="brand-classify-title">
<flexbox-item :span="10">
<check-icon v-if="b.city_count != 0" class="brand-classify-checked" @click.native="changeCategory(b, 'brand')" :value.sync="b.checked">
所有{{b.name}}门店(<span style="color: #8EA8CF;">{{b.num}}</span>/{{b.city_count}})
</check-icon>
<check-icon v-else class="brand-classify-checked" :value="false">
所有{{b.name}}门店(<span style="color: #8EA8CF;">{{b.num}}</span>/{{b.city_count}})
</check-icon>
</flexbox-item>
<flexbox-item @click.native="fold(bi, 'brand')">
<div style="padding-top: 0.2rem; padding-left: 0.5rem;">
<i class="fa fa-chevron-down" style="font-size: 0.7rem; color: #838383;"></i>
</div>
</flexbox-item>
</flexbox>
<div class="brand-content">
<div class="store-classify">
<div v-for="(c, ci) in b.city_list" :key="ci">
<div style="border-top: 1px dashed #eee; width: 100%;"></div>
<flexbox class="store-classify-title">
<flexbox-item style="text-indent:2px;" :span="10">
<check-icon v-if="c.store_count != 0" class="store-classify-checked" :value.sync="c.checked" @click.native="changeCategory(c, 'city', b)">
所有{{c.name}}{{b.name}}门店(<span style="color: #8EA8CF;">{{c.num}}</span>/{{c.store_count}})
</check-icon>
<check-icon v-else class="store-classify-checked" :value="false">
所有{{c.name}}{{b.name}}门店(<span style="color: #8EA8CF;">{{c.num}}</span>/{{c.store_count}})
</check-icon>
</flexbox-item>
<flexbox-item @click.native="fold(bi, 'store', ci)">
<div style="padding-top: 0.2rem; padding-left: 0.5rem;">
<i class="fa fa-chevron-down" style="font-size: 0.7rem; color: #838383;"></i>
</div>
</flexbox-item>
</flexbox>
<div class="store-content">
<div class="store-list">
<div v-for="(s, si) in c.store_list" :key="si" @click="itemCheck(s, b, ci)" class="store-item">
<div v-if="!s.disabled"
:class="[s.checked ? 'flex-checked' : '', 'flex-store']">
{{s.name}}
</div>
<div v-else class="flex-store flex-disabled"> {{s.name}} </div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="control-wrapper">
<flexbox>
<flexbox-item>
<x-button class="close-btn" @click.native="cancel" mini>关闭</x-button>
</flexbox-item>
<flexbox-item>
<x-button class="confirm-btn" @click.native="confirm" mini>确定</x-button>
</flexbox-item>
</flexbox>
</div>
</x-dialog>
</div>
</div>
</template>
<script>
import { XDialog, TransferDomDirective as TransferDom, Flexbox, FlexboxItem, CheckIcon, XButton } from 'vux'
import { Observable } from 'rxjs/Rx'
export default {
directives: { TransferDom },
components: { XDialog, Flexbox, FlexboxItem, CheckIcon, XButton },
props: ['show', 'list', 'title', 'checkList'],
data () {
return {
data_list: [],
category_num: 0,
category_checked: false
}
},
watch: {
list () {
this.data_list = [];
this.category_num = 0;
this.category_checked = false;
Observable.from([...this.list])
.map(b => {
// 品牌
b.checked = false;
b.num = 0;
b.city_count = 0;
b.city_list.forEach(c => {
// 城市
let cnt = 0;
c.checked = false;
c.num = 0;
// c.store_count = c.store_list.length;
// b.city_count += c.store_count;
c.store_list.forEach(s => {
// 门店
s.checked = false;
if (!s.disabled) {
cnt++;
}
})
c.store_count = cnt;
b.city_count += c.store_count;
})
return b;
}).subscribe(v => {
this.data_list.push(v);
// 判断是否有已选中
if (this.checkList.length) {
v.city_list.forEach((c, ci) => {
c.store_list.forEach(s => {
this.checkList.forEach(checkStore => {
if (checkStore.store_id === s.store_id) {
this.itemCheck(s, v, ci, true)
}
})
})
})
}
// 分别计算已选中的
}).unsubscribe();
setTimeout(() => {
for (let i = 0; i < $('.store-item').length; i++) {
if (i % 2 !== 0) {
continue;
}
if ($($('.store-item')[i]).height() > $($('.store-item')[i + 1]).height() && $($('.store-item')[i + 1]).height() !== 0) {
$($('.store-item')[i + 1]).children('div').css('height', $($('.store-item')[i]).height() + 'px')
} else if ($($('.store-item')[i]).height() < $($('.store-item')[i + 1]).height()) {
$($('.store-item')[i]).children('div').css('height', $($('.store-item')[i + 1]).height() + 'px')
}
}
}, 100);
}
},
computed: {
category_sum () {
// 获取门店总数
let sum = 0;
this.data_list.forEach(b => {
b.city_list.forEach(c => {
sum += c.store_count;
})
})
return sum;
}
},
methods: {
fold (index, str, i) {
let has_class = $($(`.${str}-classify-title`)[index]).siblings(`.${str}-content`).hasClass('fold-content');
if (i && index - 1 >= 0) {
// 不为第一组品牌中的城市
index = this.data_list[index - 1].city_count + i;
} else {
// 不是城市或是第一组品牌中的城市
i ? index = i : '';
}
if (has_class) {
// 展开
$($(`.${str}-classify-title`)[index]).siblings(`.${str}-content`).removeClass('fold-content');
$($(`.${str}-classify-title`)[index]).find('i').addClass('fa-chevron-down').removeClass('fa-chevron-right');
} else {
// 折叠
$($(`.${str}-classify-title`)[index]).siblings(`.${str}-content`).addClass('fold-content');
$($(`.${str}-classify-title`)[index]).find('i').addClass('fa-chevron-right').removeClass('fa-chevron-down');
}
},
itemCheck (item, b, ci, bool) {
// 选中/取消选中单条
// item.checked = !item.checked;
bool ? item.checked = bool : item.checked = !item.checked;
// 计算父类的选中个数
if (item.checked) {
b.num++;
b.city_list[ci].num++;
this.category_num++;
} else {
b.num--;
b.city_list[ci].num--;
this.category_num--;
}
this.checkIcon();
},
/*
* 计算num数量判断逻辑:
* 1、如果点击状态为切换状态时,不等于目标状态的门店为待切换门店。
* 2、待切换门店切换状态时,增加或减少num(根据父类的选择状态判断)。
* 3、切换父类状态时,需要避免计算时累加或累减之前已切换过状态且无需在切换的门店。
* 4、只需要计算待切换状态的门店。
* 5、根据被点击父类的状态判断是增加还是减少,选中为增,取消选中为减。
* 6、最后根据num和count来判断子类被点击选中或取消选中时,切换父类的选中状态。
* ------------------------------------------------------------------------
*/
changeCategory (item, type, brand) {
// 选中分类
// checkicon会自动重置,当用户看到选中时,传入的是false
item.checked ? item.checked = true : item.checked = false;
if (type === 'brand') {
// 品牌分类
Observable.from(item.city_list)
.map(v => {
v.checked = item.checked;
v.store_list.forEach(s => {
if (!s.disabled) {
// 计算选中数量
if (s.checked == !item.checked && item.checked) {
v.num++;
item.num++;
this.category_num++;
} else if (s.checked == !item.checked && !item.checked) {
v.num--;
item.num--;
this.category_num--;
}
s.checked = item.checked;
}
})
return v;
}).subscribe().unsubscribe();
} else if (type === 'city') {
// 城市分类
Observable.from(item.store_list)
.map(v => {
if (!v.disabled) {
// 计算选中数量
if (v.checked == !item.checked && item.checked) {
brand.num++;
item.num++;
this.category_num++;
} else if (v.checked == !item.checked && !item.checked) {
brand.num--;
item.num--;
this.category_num--;
}
v.checked = item.checked;
}
return v;
}).subscribe().unsubscribe();
}
this.checkIcon();
},
checkAll () {
// 全选
let allCheck = this.category_checked;
allCheck ? allCheck = true : allCheck = false;
let arr = [...this.data_list];
this.data_list = [];
Observable.from(arr)
.map(v => {
v.checked = allCheck;
v.city_list.forEach(c => {
c.checked = allCheck;
c.store_list.forEach(s => {
if (!s.disabled) {
if (s.checked == !allCheck && allCheck) {
v.num++;
c.num++;
this.category_num++;
} else if (s.checked == !allCheck && !allCheck) {
v.num--;
c.num--;
this.category_num--;
}
s.checked = allCheck;
}
})
})
return v;
}).subscribe(v => {
this.data_list.push(v);
}).unsubscribe();
},
checkIcon () {
// 根据选中个数和总数来判断是否让父菜单选中
this.data_list.forEach(b => {
b.num === b.city_count ? b.checked = true : b.checked = false;
b.city_list.forEach(c => {
c.num === c.store_count ? c.checked = true : c.checked = false;
})
})
// 总分类数
this.category_sum === this.category_num ? this.category_checked = true : this.category_checked = false;
let arr = [...this.data_list];
this.data_list.splice(0, [...arr]);
},
cancel () {
this.$emit('cancel');
},
confirm () {
// 返回选中
let data = [];
Observable.create(store$ => {
this.data_list.forEach(b => {
b.city_list.forEach(c => {
c.store_list.forEach(s => {
if (s.checked && !s.disabled) {
s.route_name = c.name;
store$.next(s);
}
})
})
})
}).subscribe(v => {
data.push(v);
}).unsubscribe();
if (!data.length) {
this.$vux.toast.show({
type: 'warn',
text: '请至少选择一个!'
});
return;
}
this.$emit('confirm', data);
}
}
}
</script>
<style lang="less">
.choose_store_multi {
}
.store-title {
padding: 0.5rem;
font-size: 18px;
border-bottom: 1px solid #eee;
}
.wrap-scroll {
max-height: 30rem;
overflow-y: auto;
}
.store-wrapper {
text-align: left;
.store-all-checked {
font-size: 0.9rem;
padding: 0.5rem 0.2rem;
}
}
.store-classify {
.store-classify-checked,
.brand-classify-checked {
font-size: 0.9rem;
padding: 0.4rem 0.2rem 0.1rem 0.85rem;
}
.store-classify-title,
.brand-classify-title {
margin-bottom: 0.5rem;
}
.store-content,
.brand-content {
border-bottom: 1px dashed #eee;
.store-list {
&:after {
display: block;
content: "";
clear: both;
}
&>div {
float: left;
margin-left: 2%;
width: 48%;
padding-bottom: 10px;
.flex-store {
text-align: center;
background-color: #f6f6f6;
color: #333;
}
.flex-checked {
color: #2c426b;
background-color: #c4d4e7;
}
.flex-disabled {
color: #ccc;
background-color: #eaeff7;
}
}
}
}
.store-content {
padding: 0 1rem;
}
.fold-content {
height: 0;
overflow: hidden;
padding-bottom: 0;
}
}
.control-wrapper {
padding: 10px;
.close-btn {
background-color: #ffffff;
color: #8EA8CF;
border: 1px solid #8EA8CF;
width: 100%;
}
.confirm-btn {
background-color: #8EA8CF;
color: #ffffff;
border: 1px solid #8EA8CF;
width: 100%;
}
}
.vux-check-icon > .weui-icon-success:before, .vux-check-icon > .weui-icon-success-circle:before {
color: #8ea8cf !important;
}
</style>
<template>
<div class="choose_store_multi">
<div v-transfer-dom>
<x-dialog :show.sync="show" class="dialog-demo">
<div class="store-title">{{title}}</div>
<div class="wrap-scroll">
<div class="store-wrapper">
<check-icon class="store-all-checked">
<!-- {{caption}}(<span style="color: #8EA8CF;">{{category_num}}</span>/{{category_sum}}) -->
所有品牌的门店(<span style="color: #8EA8CF;">{{category_num}}</span>/{{category_sum}})
</check-icon>
</div>
<div class="store-classify">
<div v-for="(b, bi) in data_list" :key="bi">
<div style="border-top: 1px dashed #eee; width: 100%;"></div>
<flexbox class="brand-classify-title">
<flexbox-item style="text-indent:2px;" :span="10">
<check-icon class="brand-classify-checked" :value.sync="b.checked">
{{b.name}}(<span style="color: #8EA8CF;">{{b.num}}</span>/{{b.city_count}})
</check-icon>
</flexbox-item>
<flexbox-item @click.native="fold(bi, 'brand')">
<div style="padding-top: 0.2rem; padding-left: 0.5rem;">
<i class="fa fa-chevron-down" style="font-size: 0.7rem; color: #838383;"></i>
</div>
</flexbox-item>
</flexbox>
<div class="brand-content">
<div class="store-classify">
<div v-for="(c, ci) in b.city_list" :key="ci">
<div style="border-top: 1px dashed #eee; width: 100%;"></div>
<flexbox class="store-classify-title">
<flexbox-item style="text-indent:4px;" :span="10">
<check-icon class="store-classify-checked" :value.sync="c.checked">
{{c.name}}(<span style="color: #8EA8CF;">{{c.num}}</span>/{{c.store_count}})
</check-icon>
</flexbox-item>
<flexbox-item @click.native="fold(bi, 'store', ci)">
<div style="padding-top: 0.2rem; padding-left: 0.5rem;">
<i class="fa fa-chevron-down" style="font-size: 0.7rem; color: #838383;"></i>
</div>
</flexbox-item>
</flexbox>
<div class="store-content">
<div class="store-list">
<div v-for="(s, si) in c.store_list" :key="si" @click="itemCheck(s)">
<div v-if="!+s.disabled"
:class="[s.checked ? 'flex-checked' : '', 'flex-store']">
{{s.name}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="control-wrapper">
<flexbox>
<flexbox-item>
<x-button class="close-btn" @click.native="cancel" mini>关闭</x-button>
</flexbox-item>
<flexbox-item>
<x-button class="confirm-btn" @click.native="confirm" mini>确定</x-button>
</flexbox-item>
</flexbox>
</div>
</x-dialog>
</div>
</div>
</template>
<script>
import { XDialog, TransferDomDirective as TransferDom, Flexbox, FlexboxItem, CheckIcon, XButton } from 'vux'
import { Observable } from 'rxjs/Rx'
export default {
directives: { TransferDom },
components: { XDialog, Flexbox, FlexboxItem, CheckIcon, XButton },
props: ['show', 'list', 'title', 'checkList'],
data () {
return {
data_list: [],
category_num: 0
}
},
watch: {
list () {
this.data_list = [];
Observable.from([...this.list])
.map(b => {
// 品牌
b.checked = false;
b.num = 0;
b.city_count = b.city_list.length;
b.city_list.forEach(c => {
// 城市
c.checked = false;
c.num = 0;
c.store_count = c.store_list.length;
c.store_list.forEach(s => {
// 门店
s.num = 0;
s.checked = false;
})
})
return b;
}).subscribe(v => {
v.city_list.forEach(c => {
c.store_list.forEach(s => {
this.checkList.forEach(checkStore => {
if (checkStore.store_id === s.store_id) {
s.checked = true;
}
})
})
})
this.data_list.push(v);
// 分别计算已选中的
}).unsubscribe();
}
},
computed: {
category_sum () {
// 获取门店总数
let sum = 0;
this.data_list.forEach(b => {
b.city_list.forEach(c => {
sum += c.store_count;
})
})
return sum;
}
},
methods: {
fold (index, str, i) {
let has_class = $($(`.${str}-classify-title`)[index]).siblings(`.${str}-content`).hasClass('fold-content');
if (i && index - 1 >= 0) {
// 不为第一组品牌中的城市
index = this.data_list[index - 1].city_count + i;
} else {
// 不是城市或是第一组品牌中的城市
i ? index = i : '';
}
if (has_class) {
// 展开
$($(`.${str}-classify-title`)[index]).siblings(`.${str}-content`).removeClass('fold-content');
$($(`.${str}-classify-title`)[index]).find('i').addClass('fa-chevron-down').removeClass('fa-chevron-right');
} else {
// 折叠
$($(`.${str}-classify-title`)[index]).siblings(`.${str}-content`).addClass('fold-content');
$($(`.${str}-classify-title`)[index]).find('i').addClass('fa-chevron-right').removeClass('fa-chevron-down');
}
},
itemCheck (item, method) {
// 选中/取消选中单条
item.checked = !item.checked;
let arr = [...this.data_list];
this.data_list.splice(0, [...arr]);
},
cancel () {
this.$emit('cancel');
},
confirm () {
let data = [];
Observable.create(store$ => {
this.data_list.forEach(b => {
b.city_list.forEach(c => {
c.store_list.forEach(s => {
if (s.checked) {
store$.next(s);
}
})
})
})
}).subscribe(v => {
data.push(v);
}).unsubscribe();
this.$emit('confirm', data);
}
}
}
</script>
<style lang="less">
.choose_store_multi {
}
.store-title {
padding: 0.5rem;
font-size: 18px;
border-bottom: 1px solid #eee;
}
.wrap-scroll {
max-height: 30rem;
overflow-y: auto;
}
.store-wrapper {
text-align: left;
.store-all-checked {
font-size: 0.9rem;
padding: 0.5rem 0.2rem;
}
}
.store-classify {
.store-classify-checked,
.brand-classify-checked {
font-size: 0.9rem;
padding: 0.4rem 0.2rem 0.1rem 0.85rem;
}
.store-classify-title,
.brand-classify-title {
margin-bottom: 0.5rem;
}
.store-content,
.brand-content {
border-bottom: 1px dashed #eee;
.store-list {
&:after {
display: block;
content: "";
clear: both;
}
&>div {
float: left;
margin-left: .4rem;
width: 48%;
padding-bottom: 10px;
.flex-store {
text-align: center;
background-color: #eee;
}
.flex-checked {
color: white;
background-color: #8EA8CF;
}
.flex-disabled {
color: #cfcfcf;
background-color: #ebeef7;
}
}
}
}
.store-content {
padding: 0 1rem;
}
.fold-content {
height: 0;
overflow: hidden;
padding-bottom: 0;
}
}
.control-wrapper {
padding: 10px;
.close-btn {
background-color: #ffffff;
color: #8EA8CF;
border: 1px solid #8EA8CF;
width: 100%;
}
.confirm-btn {
background-color: #8EA8CF;
color: #ffffff;
border: 1px solid #8EA8CF;
width: 100%;
}
}
</style>
<template lang="html">
<div class="">
<demo @handle="save"></demo>
</div>
</template>
<script>
import demo from 'components/sms/demo'
export default {
components: { demo },
data () {
return {
}
},
methods: {
save (val) {
console.warn(val)
}
}
}
</script>
<style lang="less">
</style>
<template lang="html">
<div class="SMS">
<!-- 验证码 -->
<flexbox>
<flexbox-item>
<div class="flex-demo" :span="6">
<x-input
class="smsCodeWrap"
v-model="smsCode"
placeholder="请输入验证码"
required
:show-clear="true"
@on-blur="onBlur"
placeholder-align="left"></x-input>
</div>
</flexbox-item>
<flexbox-item :span="6">
<div class="ctl-btn">
<span v-if="!countDownStatus" @click="getCode()">获取验证码</span>
<span v-else :disabled="countDownStatus" @click="getCode()">{{ countDownDuring }}秒后重新获取</span>
<x-button mini :disabled="this.smsCode === ''" @click.native="submitCode()">确定</x-button>
</div>
</flexbox-item>
</flexbox>
<toast v-model="smsCodeMsgShow" :time="1500">{{smsCodeMsg}}</toast>
</div>
</template>
<script>
import { Flexbox, FlexboxItem, XInput, XButton, Alert, TransferDomDirective as TransferDom, Toast } from 'vux'
export default {
directives: {
TransferDom
},
components: {
Flexbox,
FlexboxItem,
XInput,
XButton,
Alert,
Toast
},
props: [ 'TYPE' ],
data () {
return {
smsCode: '',
smsCodeMsg: '验证码发送成功',
smsCodeMsgShow: false,
countDownDuring: 60,
countDownStatus: false
}
},
computed: {
},
methods: {
onBlur () {},
countDown () {
this.countDownStatus = true
// 倒计时 一分钟
if (this.countDownDuring > 0) {
var Timer = setInterval(() => {
this.countDownDuring = this.countDownDuring - 1;
}, 1000);
} else {
this.countDownStatus = true
}
setTimeout(() => {
// 倒计时状态
clearInterval(Timer)
this.countDownStatus = false
this.countDownDuring = 60
}, 60000)
},
getCode () {
// 获取验证码
// axios.post('b/auth/pin', { type: this.TYPE })
// .then(res => {
// if (res.data.ret === 'OK') {
// this.smsCodeMsgShow = true
// // 激活倒计时
// this.countDown()
// } else {
// this.smsCodeMsgShow = true
// this.smsCodeMsg = '出错了'
// console.warn(res);
// }
// })
// .catch(err => {
// console.error(err);
// })
this.countDown()
},
submitCode () {
// 验证验证码
this.$emit('handle', this.smsCode)
this.smsCode = ''
}
}
}
</script>
<style lang="less">
.smsCodeWrap {
font-size: 0.9rem;
/* border: 1px solid #ccc; */
padding: 3px 8px!important;
/* border-radius: 5px */
}
.ctl-btn {
span {
display: inline-block;
padding: 3px 8px;
background: #f2f2f2;
font-size: 0.9rem;
border-radius: 5px;
color: #45547a;
}
}
</style>
<template>
<div class="">
<tabBar @on-change="onIndexChange" :tabList="tabList"></tabBar>
</div>
</template>
<script>
import tabBar from 'components/tabBar/index'
export default {
components: {
tabBar
},
data () {
return {
tabList: [
{
name: '首页',
imgurl: '',
num: '2',
selected: false,
link: ''
},
{
name: '购物车',
imgurl: '',
num: '',
selected: true,
link: ''
}
]
}
},
methods: {
onIndexChange (index) {
console.warn(index)
}
}
}
</script>
\ No newline at end of file
<template>
<div class="tabBar">
<tabbar @on-index-change="onChange">
<tabbar-item v-for="(item, index) in tabList" :key="index" :selected="item.selected" :badge="item.num" :link="item.link">
<img slot="icon" :src="item.imgUrl">
<span slot="label">{{item.name}}</span>
</tabbar-item>
</tabbar>
</div>
</template>
<script>
/*
底部导航栏组件
tablist: {
num: 消息标记数量,传空值则没有标记,
link: 跳转页面链接,
imgUrl: 导航图标,
name: 导航名称
selected: 是否选中当前项
}
onChange:底部导航选中改变时的回调
*/
import { Tabbar, TabbarItem } from 'vux'
export default {
components: {
Tabbar,
TabbarItem
},
props: ['tabList'],
data () {
return {}
},
methods: {
onChange (index) {
this.$emit('on-change', index)
}
}
};
</script>
<style lang="less">
.tabBar {
.weui-tabbar__icon {
position: relative;
.vux-badge-single {
width: auto;
min-width: 16px;
}
}
.weui-tabbar__icon > sup {
position: absolute;
top: 0;
left: 35px;
transform: translateX(-50%);
z-index: 101;
}
.weui-tabbar__item.vux-tabbar-simple {
padding: 0 10px;
height: 50px;
line-height: 50px;
}
.vux-tabbar-simple .weui-tabbar__label {
font-size: 14px;
line-height: 50px;
}
.weui-tabbar__item.weui-bar__item_on .weui-tabbar__label {
color: #89A9CF;
}
}
</style>
<template lang="html">
<div class="">
<tab-swiper :list="list" :default_selected="default_selected" @on-item-click="onItemClick"></tab-swiper>
</div>
</template>
<script>
import tabSwiper from 'components/tabSwiper/index'
export default {
components: { tabSwiper },
data () {
return {
list: ['消息', '通讯录'],
default_selected: '消息'
}
},
methods: {
onItemClick (index) {
console.warn(index);
}
}
}
</script>
<style lang="less" scoped>
</style>
<template lang="html">
<div class="tab-wrapper">
<div class="tab-content">
<tab bar-active-color="#8da9cf" :custom-bar-width="getBarWidth">
<tab-item active-class="active" v-for="(item, index) in list" :key="index" :class="{'vux-1px-r': index+1!==list.length}" :selected="default_selected === item" @on-item-click="onItemClick">{{item}}</tab-item>
</tab>
</div>
</div>
</template>
<script>
/**
* [参考用法 vux tab 组件]
*
* [list tab 显示名称]
* @type {Array}
*
* [default_selected tab 默认显示名称]
* @type {String}
*
* [on-item-click 点击回调返回 index]
*/
import { Tab, TabItem } from 'vux'
export default {
components: { Tab, TabItem },
props: ['list', 'default_selected'],
data () {
return {
getBarWidth: function (index) {
return (index + 1) * 40 + 'px'
}
}
},
methods: {
onItemClick (index) {
this.$emit('on-item-click', index)
}
}
}
</script>
<style lang="less" scoped>
@import '~vux/src/styles/1px.less';
@import '~vux/src/styles/center.less';
.vux-tab .vux-tab-item {
background: none;
}
.vux-1px-r:after {
height: 50%;
top: 30%;
}
.active {
color: #8da9cf !important;
border-color: #8da9cf!important;
}
.tab-wrapper {
padding: 1rem 1rem 0 1rem;
.tab-content {
border-top: 1px solid #dddddf;
border-left: 1px solid #dddddf;
border-right: 1px solid #dddddf;
}
}
</style>
<template>
<div>
<div class="title">
<p>{{text}}</p>
<p class="rightText" v-if="pShow" @click="topClick">{{rightText}}</p>
</div>
</div>
</template>
<script>
export default {
props: ['text', 'pShow', 'rightText'],
data () {
return {}
},
methods: {
topClick () {
this.$emit('topClick')
}
}
}
</script>
<style lang="less" scoped>
.title {
width: 100%;
height: 44px;
background-color: #333;
position: fixed;
top: 0;
left: 0;
color: #fff;
font-size: 16px;
// line-height: 44px;
text-align: center;
z-index: 10;
display: flex;
align-items: center;
&>p:first-child {
line-height: 20px;
flex: 1;
}
.rightText {
position: absolute;
top: 0;
right: 20px;
line-height: 44px;
}
}
</style>
<template>
<div>
<div v-show="multiple">
<label for="file">+</label>
<img v-show="multiple && imgShow" :src="img" alt="">
<input id="file" type="file" multiple @change="selectImg">
</div>
<div v-show="!multiple">
<label for="file1">+</label>
<input id="file1" type="file" @change="selectImg">
</div>
</div>
</template>
<script>
export default {
props: {
multiple: {
type: Boolean,
default: false
},
action: {
type: String,
default: ''
},
img: {
type: String,
default: ''
}
},
data () {
return {
imgShow: false
}
},
mounted () {
console.warn(this.action)
},
methods: {
selectImg (file) {
console.warn(file)
let formData = new FormData()
formData.append('file', file.target.files[0])
formData.append('type', 'test')
this.$vux.loading.show({
text: '正在上传'
})
axios.post(this.action, formData)
.then((res) => {
console.warn(res)
this.imgShow = true;
this.$vux.loading.hide()
this.$emit('success', res.data)
})
}
}
}
</script>
<style lang="less" scoped>
div {
margin-top: 10px;
}
label {
display: inline-block;
width: 48px;
height: 48px;
border: 1px solid #d6d7dc;
text-align: center;
line-height: 46px;
color: #d6d7dc;
font-size: 42px;
cursor: pointer;
vertical-align: top;
}
img {
width: 50px;
height: 50px;
}
input[type="file"] {
display: none;
}
</style>
<template>
<div class="vux-x-input weui-cell">
<div class="weui-cell__bd weui-cell__primary">
<input class="weui-input" style="text-align: center;" type="number" v-on="listeners" v-model="val" ref="input" :placeholder="placeholder" :disabled="disabled" @focus="onFocus">
</div>
</div>
</template>
<script type="text/ecmascript-6">
export default {
mounted () {
this.updateValue(this.value)
},
name: 'vue-pattern-input',
props: {
value: {
required: true,
default: '',
type: [Number, String]
},
regExp: {
type: RegExp,
default: null
},
replacement: {
type: String,
default: ''
},
placeholder: {
type: String,
default: ''
},
disabled: {
type: Boolean,
default: false
}
},
data () {
return {
val: '',
tmp: ''
}
},
computed: {
listeners () {
const listeners = {}
Object.keys(this.$listeners).forEach(fnName => {
listeners[fnName] = (e) => {
let val = e.target.value !== '' ? e.target.value : e.data
// console.warn(val);
this.$listeners[fnName](val)
}
})
listeners.input = (e) => {
let val = e.target.value !== '' ? e.target.value : e.data
// console.warn(val);
this.updateValue(val)
}
return listeners
}
},
methods: {
// format the value of input
formatValue (val) {
let formattedValue = ''
// const formattedValue = val.toString().replace(this.regExp, this.replacement)
val = _.isNull(val) ? '' : val
if (this.regExp.test(val.toString())) {
formattedValue = val.toString();
this.tmp = val.toString()
} else {
formattedValue = this.tmp ? this.tmp : ' '
}
return formattedValue
},
// update the value of input
updateValue (val) {
const formattedValue = this.formatValue(val)
this.val = formattedValue
this.emitInput(formattedValue)
this.emitChange(formattedValue)
},
// emit input event
emitInput (val) {
this.$emit('input', val)
},
// emit change event
emitChange () {
this.$emit('change', this.val)
},
onFocus (e) {
this.$emit('on-focus', e);
}
},
watch: {
// watch value prop
value (val) {
if (val !== this.val) {
this.updateValue(val)
}
}
}
}
</script>
<style lang="less">
.vux-x-input.weui-cell {
border: 1px solid #eee;
padding: 0;
border-radius: .2rem;
}
.weui-cell__bd {
-ms-flex: 1;
flex: 1;
}
.weui-input {
width: 100%;
border: 0;
outline: 0;
-webkit-appearance: none;
background-color: transparent;
font-size: inherit;
color: inherit;
height: 1.41176471em;
line-height: 1.41176471;
}
</style>
/* jshint esversion: 6 */
import Vue from 'vue';
import Vuex from 'vuex';
import VueRouter from 'vue-router';
import App from './App.vue';
import router from './router';
import store from './store';
import axios from './http';
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Vant from 'vant'
import 'vant/lib/index.css'
Vue.use(VueRouter);
Vue.use(Vuex);
Vue.use(Vant)
Vue.config.productionTip = false;
Vue.config.productionTip = false
new Vue({
router,
store,
axios,
render: h => h(App)
}).$mount('#app');
}).$mount('#app')
......
// 多页面测试入口文件
import Vue from 'vue'
import Vuex from 'vuex'
import store from './vuex/store'
import router from './router'
import VueRouter from 'vue-router'
import axios from './http'
import A from './A.vue'
import { sync } from 'vuex-router-sync'
import FastClick from 'fastclick'
import Vant from 'vant'
import 'vant/lib/index.css'
sync(store, router)
Vue.use(VueRouter)
Vue.use(Vuex)
Vue.use(Vant)
Vue.config.productionTip = false
Vue.prototype.method = function () {}
FastClick.attach(document.body)
new Vue({
store,
router,
axios,
render: h => h(A)
}).$mount('#A')
<template lang="html">
<div id="A" style="height:100%;">
<router-view style="margin-top: 3rem"></router-view>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
components: {},
data () {
return {
isIndex: true,
showMore: true
}
},
computed: {
...mapState({
title: state => state.title
})
},
watch: {
$route: 'fetchData'
},
mounted () {
},
methods: {
fetchData () {
if (this.$route.meta.isIndex) {
this.isIndex = true
} else {
this.isIndex = false
}
}
}
}
</script>
<style lang="less">
html, body {
font-family: '微软雅黑', Microsoft YaHei;
height: 100%;
width: 100%;
overflow-x: hidden;
background-color: #F0EFF5;
#login {
}
}
</style>
/* jshint esversion: 6 */
import axios from 'axios';
import router from './router';
import axios from 'axios'
import router from './router'
// 请求拦截器
axios.interceptors.request.use(
config => {
// 发送请求前
return config;
return config
},
error => {
// 请求错误处理
return Promise.reject(error);
});
return Promise.reject(error)
})
// 响应拦截器
axios.interceptors.response.use(
response => {
return response;
return response
},
error => {
if (error.response) {
switch (error.response.status) {
case 401:
router.replace({
path: '/login'
});
break;
path: '/'
})
break
case 404:
router.replace({
path: '/'
});
break;
})
break
}
}
return Promise.reject(error.response.data);
});
return Promise.reject(error.response.data)
})
export default axios;
export default axios
......
/* jshint esversion: 6 */
export default [
{
path: '/',
name: '登录',
component: () => import('./views/login.vue')
}
]
/* jshint esversion: 6 */
import Vue from 'vue'
import VueRouter from 'vue-router'
import ConfigRouter from './route.js'
import store from './vuex/store'
Vue.use(VueRouter)
const router = new VueRouter({
history: false,
hashbang: true,
base: __dirname,
routes: ConfigRouter
})
router.beforeEach((to, from, next) => {
store.commit('updateLoadingStatus', true)
next()
})
router.afterEach((to, from, next) => {
store.commit('updateLoadingStatus', false)
})
export default router
function initFontSize (baseFontSize, baseWidth) {
let clientWidth = document.documentElement.clientWidth || window.innerWidth()
let size = Math.floor(clientWidth / baseWidth * baseFontSize)
document.querySelector('html').style.fontSize = size + 'px'
}
initFontSize(100, 1080)
window.onresize = function () {
initFontSize(100, 1080)
}
<template>
<div>
<!-- <van-password-input
:value="value"
info="密码为6位数字"
@focus="keyboard = 'custom'"
/> -->
<van-field v-model="value" :maxlength="10" @click.native="keyboard = 'custom'" @blur="onBlur" readonly placeholder="请输入用户名" />
<!-- <van-number-keyboard
:show="showKeyboard"
@input="onInput"
@delete="onDelete"
@blur="showKeyboard = false"
/> -->
<van-number-keyboard
:show="keyboard === 'custom'"
close-button-text="完成"
theme="custom"
extra-key="."
@blur="keyboard = ''"
@input="onInput"
@delete="onDelete"
@close="onClose"
/>
</div>
</template>
<script>
export default {
data () {
return {
value: '',
showKeyboard: true,
keyboard: 'default'
}
},
methods: {
onInput (key) {
this.value = (this.value + key).slice(0, 5)
},
onDelete () {
this.value = this.value.slice(0, this.value.length - 1)
},
onBlur () {
// console.warn(this.value);
},
onClose () {
this.keyboard = false
}
}
}
</script>
<style lang="less" scoped>
.login {
position: absolute;
top: 25%;
left: 50%;
transform: translateX(-50%);
padding: 1.8rem 2.5rem;
width: 15rem;
button {
margin-top: 1.2rem;
position: absolute;
right: 2.5rem;
}
input {
display: block;
width: 95%;
padding: 0.8rem 0.4rem;
background: #fff;
border: 1px solid #d6d7dc;
font-size: 0.95rem;
}
}
</style>
export const increment = ({ commit }) => {
commit('INCREMENT')
}
export const decrement = ({ commit }) => {
commit('DECREMENT')
}
export const getCount = state => {
return state.count
}
import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'
Vue.use(Vuex)
// 应用初始状态
const state = {
isLoading: false,
title: '登录',
form: '',
direction: 'forward'
}
// 定义所需的 mutations
const mutations = {
updateLoadingStatus (state, status) {
state.isLoading = status
},
changeTitle (state, title) {
state.title = title
},
savedForm (state, form) {
state.form = form
},
UPDATE_DIRECTION (state, direction) {
state.direction = direction
}
}
// 创建 store 实例
export default new Vuex.Store({
actions,
getters,
state,
mutations
})
// 多页面测试入口文件
import Vue from 'vue'
import Vuex from 'vuex'
import store from './vuex/store'
import router from './router'
import VueRouter from 'vue-router'
import axios from './http'
import B from './B.vue'
import { sync } from 'vuex-router-sync'
import FastClick from 'fastclick'
import Vant from 'vant'
import 'vant/lib/index.css'
sync(store, router)
Vue.use(VueRouter)
Vue.use(Vuex)
Vue.use(Vant)
Vue.config.productionTip = false
Vue.prototype.method = function () {}
FastClick.attach(document.body)
new Vue({
store,
router,
axios,
render: h => h(B)
}).$mount('#B')
<template lang="html">
<div id="B" style="height:100%;">
<router-view style="margin-top: 3rem"></router-view>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
components: {},
data () {
return {
isIndex: true,
showMore: true
}
},
computed: {
...mapState({
title: state => state.title
})
},
watch: {
$route: 'fetchData'
},
mounted () {
},
methods: {
fetchData () {
if (this.$route.meta.isIndex) {
this.isIndex = true
} else {
this.isIndex = false
}
}
}
}
</script>
<style lang="less">
html, body {
font-family: '微软雅黑', Microsoft YaHei;
height: 100%;
width: 100%;
overflow-x: hidden;
background-color: #F0EFF5;
#login {
}
}
</style>
/* jshint esversion: 6 */
import axios from 'axios'
import router from './router'
// 请求拦截器
axios.interceptors.request.use(
config => {
// 发送请求前
return config
},
error => {
// 请求错误处理
return Promise.reject(error)
})
// 响应拦截器
axios.interceptors.response.use(
response => {
return response
},
error => {
if (error.response) {
switch (error.response.status) {
case 401:
router.replace({
path: '/'
})
break
case 404:
router.replace({
path: '/'
})
break
}
}
return Promise.reject(error.response.data)
})
export default axios
/* jshint esversion: 6 */
export default [
{
path: '/',
name: '登录',
component: () => import('./views/login.vue')
}
]
/* jshint esversion: 6 */
import Vue from 'vue'
import VueRouter from 'vue-router'
import ConfigRouter from './route.js'
import store from './vuex/store'
Vue.use(VueRouter)
const router = new VueRouter({
history: false,
hashbang: true,
base: __dirname,
routes: ConfigRouter
})
router.beforeEach((to, from, next) => {
store.commit('updateLoadingStatus', true)
next()
})
router.afterEach((to, from, next) => {
store.commit('updateLoadingStatus', false)
})
export default router
function initFontSize (baseFontSize, baseWidth) {
let clientWidth = document.documentElement.clientWidth || window.innerWidth()
let size = Math.floor(clientWidth / baseWidth * baseFontSize)
document.querySelector('html').style.fontSize = size + 'px'
}
initFontSize(100, 1080)
window.onresize = function () {
initFontSize(100, 1080)
}
<template>
<div>
<!-- <van-password-input
:value="value"
info="密码为6位数字"
@focus="keyboard = 'custom'"
/> -->
<van-field v-model="value" :maxlength="10" @click.native="keyboard = 'custom'" @blur="onBlur" readonly placeholder="请输入用户名" />
<!-- <van-number-keyboard
:show="showKeyboard"
@input="onInput"
@delete="onDelete"
@blur="showKeyboard = false"
/> -->
<van-number-keyboard
:show="keyboard === 'custom'"
close-button-text="完成"
theme="custom"
extra-key="."
@blur="keyboard = ''"
@input="onInput"
@delete="onDelete"
@close="onClose"
/>
</div>
</template>
<script>
export default {
data () {
return {
value: '',
showKeyboard: true,
keyboard: 'default'
}
},
methods: {
onInput (key) {
this.value = (this.value + key).slice(0, 5)
},
onDelete () {
this.value = this.value.slice(0, this.value.length - 1)
},
onBlur () {
// console.warn(this.value);
},
onClose () {
this.keyboard = false
}
}
}
</script>
<style lang="less" scoped>
.login {
position: absolute;
top: 25%;
left: 50%;
transform: translateX(-50%);
padding: 1.8rem 2.5rem;
width: 15rem;
button {
margin-top: 1.2rem;
position: absolute;
right: 2.5rem;
}
input {
display: block;
width: 95%;
padding: 0.8rem 0.4rem;
background: #fff;
border: 1px solid #d6d7dc;
font-size: 0.95rem;
}
}
</style>
export const increment = ({ commit }) => {
commit('INCREMENT')
}
export const decrement = ({ commit }) => {
commit('DECREMENT')
}
export const getCount = state => {
return state.count
}
import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'
Vue.use(Vuex)
// 应用初始状态
const state = {
isLoading: false,
title: '登录',
form: '',
direction: 'forward'
}
// 定义所需的 mutations
const mutations = {
updateLoadingStatus (state, status) {
state.isLoading = status
},
changeTitle (state, title) {
state.title = title
},
savedForm (state, form) {
state.form = form
},
UPDATE_DIRECTION (state, direction) {
state.direction = direction
}
}
// 创建 store 实例
export default new Vuex.Store({
actions,
getters,
state,
mutations
})
// 多页面测试入口文件
import Vue from 'vue'
import Vuex from 'vuex'
import store from './vuex/store'
import router from './router'
import VueRouter from 'vue-router'
import axios from './http'
import C from './C.vue'
import { sync } from 'vuex-router-sync'
import FastClick from 'fastclick'
import Vant from 'vant'
import 'vant/lib/index.css'
sync(store, router)
Vue.use(VueRouter)
Vue.use(Vuex)
Vue.use(Vant)
Vue.config.productionTip = false
Vue.prototype.method = function () {}
FastClick.attach(document.body)
new Vue({
store,
router,
axios,
render: h => h(C)
}).$mount('#C')
<template lang="html">
<div id="C" style="height:100%;">
<router-view style="margin-top: 3rem"></router-view>
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
components: {},
data () {
return {
isIndex: true,
showMore: true
}
},
computed: {
...mapState({
title: state => state.title
})
},
watch: {
$route: 'fetchData'
},
mounted () {
},
methods: {
fetchData () {
if (this.$route.meta.isIndex) {
this.isIndex = true
} else {
this.isIndex = false
}
}
}
}
</script>
<style lang="less">
html, body {
font-family: '微软雅黑', Microsoft YaHei;
height: 100%;
width: 100%;
overflow-x: hidden;
background-color: #F0EFF5;
#login {
}
}
</style>
/* jshint esversion: 6 */
import axios from 'axios'
import router from './router'
// 请求拦截器
axios.interceptors.request.use(
config => {
// 发送请求前
return config
},
error => {
// 请求错误处理
return Promise.reject(error)
})
// 响应拦截器
axios.interceptors.response.use(
response => {
return response
},
error => {
if (error.response) {
switch (error.response.status) {
case 401:
router.replace({
path: '/'
})
break
case 404:
router.replace({
path: '/'
})
break
}
}
return Promise.reject(error.response.data)
})
export default axios
/* jshint esversion: 6 */
export default [
{
path: '/',
name: '登录',
component: () => import('./views/login.vue')
}
]
/* jshint esversion: 6 */
import Vue from 'vue'
import VueRouter from 'vue-router'
import ConfigRouter from './route.js'
import store from './vuex/store'
Vue.use(VueRouter)
const router = new VueRouter({
history: false,
hashbang: true,
base: __dirname,
routes: ConfigRouter
})
router.beforeEach((to, from, next) => {
store.commit('updateLoadingStatus', true)
next()
})
router.afterEach((to, from, next) => {
store.commit('updateLoadingStatus', false)
})
export default router
function initFontSize (baseFontSize, baseWidth) {
let clientWidth = document.documentElement.clientWidth || window.innerWidth()
let size = Math.floor(clientWidth / baseWidth * baseFontSize)
document.querySelector('html').style.fontSize = size + 'px'
}
initFontSize(100, 1080)
window.onresize = function () {
initFontSize(100, 1080)
}
<template>
<div>
<!-- <van-password-input
:value="value"
info="密码为6位数字"
@focus="keyboard = 'custom'"
/> -->
<van-field v-model="value" :maxlength="10" @click.native="keyboard = 'custom'" @blur="onBlur" readonly placeholder="请输入用户名" />
<!-- <van-number-keyboard
:show="showKeyboard"
@input="onInput"
@delete="onDelete"
@blur="showKeyboard = false"
/> -->
<van-number-keyboard
:show="keyboard === 'custom'"
close-button-text="完成"
theme="custom"
extra-key="."
@blur="keyboard = ''"
@input="onInput"
@delete="onDelete"
@close="onClose"
/>
</div>
</template>
<script>
export default {
data () {
return {
value: '',
showKeyboard: true,
keyboard: 'default'
}
},
methods: {
onInput (key) {
this.value = (this.value + key).slice(0, 5)
},
onDelete () {
this.value = this.value.slice(0, this.value.length - 1)
},
onBlur () {
// console.warn(this.value);
},
onClose () {
this.keyboard = false
}
}
}
</script>
<style lang="less" scoped>
.login {
position: absolute;
top: 25%;
left: 50%;
transform: translateX(-50%);
padding: 1.8rem 2.5rem;
width: 15rem;
button {
margin-top: 1.2rem;
position: absolute;
right: 2.5rem;
}
input {
display: block;
width: 95%;
padding: 0.8rem 0.4rem;
background: #fff;
border: 1px solid #d6d7dc;
font-size: 0.95rem;
}
}
</style>
export const increment = ({ commit }) => {
commit('INCREMENT')
}
export const decrement = ({ commit }) => {
commit('DECREMENT')
}
export const getCount = state => {
return state.count
}
import Vue from 'vue'
import Vuex from 'vuex'
import * as actions from './actions'
import * as getters from './getters'
Vue.use(Vuex)
// 应用初始状态
const state = {
isLoading: false,
title: '登录',
form: '',
direction: 'forward'
}
// 定义所需的 mutations
const mutations = {
updateLoadingStatus (state, status) {
state.isLoading = status
},
changeTitle (state, title) {
state.title = title
},
savedForm (state, form) {
state.form = form
},
UPDATE_DIRECTION (state, direction) {
state.direction = direction
}
}
// 创建 store 实例
export default new Vuex.Store({
actions,
getters,
state,
mutations
})
......@@ -6,17 +6,17 @@ import router from './router'
axios.interceptors.request.use(
config => {
// 发送请求前
return config;
return config
},
error => {
// 请求错误处理
return Promise.reject(error);
return Promise.reject(error)
})
// 响应拦截器
axios.interceptors.response.use(
response => {
return response;
return response
},
error => {
if (error.response) {
......@@ -25,15 +25,15 @@ axios.interceptors.response.use(
router.replace({
path: '/'
})
break;
break
case 404:
router.replace({
path: '/'
})
break;
break
}
}
return Promise.reject(error.response.data);
return Promise.reject(error.response.data)
})
export default axios;
export default axios
......
......@@ -8,18 +8,13 @@ import axios from './http'
import login from './login.vue'
import { sync } from 'vuex-router-sync'
import FastClick from 'fastclick'
import { WechatPlugin, LoadingPlugin, ToastPlugin, ConfirmPlugin, TransferDom, AlertPlugin } from 'vux'
// import 'font-awesome/css/font-awesome.css'
import Vant from 'vant'
import 'vant/lib/index.css'
sync(store, router)
Vue.use(VueRouter)
Vue.use(Vuex)
Vue.use(WechatPlugin)
Vue.use(LoadingPlugin)
Vue.use(ToastPlugin)
Vue.use(ConfirmPlugin)
Vue.use(AlertPlugin)
Vue.directive('transfer-dom', TransferDom)
Vue.use(Vant)
Vue.config.productionTip = false
Vue.prototype.method = function () {}
......@@ -27,9 +22,8 @@ Vue.prototype.method = function () {}
FastClick.attach(document.body)
new Vue({
el: '#login',
store,
router,
axios,
render: h => h(login)
})
}).$mount('#login')
......
<template lang="html">
<div id="login" style="height:100%;">
<x-header
:left-options="{showBack: false}"
:title="title">
</x-header>
<router-view style="margin-top: 3rem"></router-view>
</div>
</template>
<script>
import { XHeader } from 'vux'
import { mapState } from 'vuex'
export default {
components: { XHeader },
components: {},
data () {
return {
isIndex: true,
......@@ -42,9 +37,6 @@ export default {
</script>
<style lang="less">
@import '~vux/src/styles/reset.less';
@import '~vux/src/styles/1px.less';
@import '~vux/src/styles/close.less';
html, body {
font-family: '微软雅黑', Microsoft YaHei;
height: 100%;
......@@ -52,17 +44,6 @@ export default {
overflow-x: hidden;
background-color: #F0EFF5;
#login {
.vux-header {
width: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 100;
background: #333;
.vux-header-title {
color: #fff;
}
}
}
}
</style>
......
/* jshint esversion: 6 */
export default [
{
path: '/',
name: '登录',
component: r => {
require(['./views/login'], r)
}
},
{
path: '/function_list',
name: '功能列表',
component: r => {
require(['./views/function_list'], r)
}
component: () => import('./views/login.vue')
}
]
......
/* jshint esversion: 6 */
import Vue from 'vue'
import VueRouter from 'vue-router'
import ConfigRouter from './route.js'
// import NProgress from 'nprogress'
// import 'nprogress/nprogress.css'
import store from './vuex/store'
Vue.use(VueRouter)
// NProgress.configure({ minimum: 0.1, easing: 'ease', speed: 500 });
const router = new VueRouter({
history: false,
......
<template>
<div class="function_list">
<x-header title="功能列表" :left-options="{showBack: false}"></x-header>
<ul class="list">
<li v-for="(item, index) in fun_list" :key="index" @click="goHandler(index)">
<span>{{item.name}}</span>
</li>
</ul>
<bottomBtn :btnText="'返回登录'" @btnClick="btnClick"></bottomBtn>
</div>
</template>
<script>
import { XHeader } from 'vux'
import bottomBtn from 'components/bottomBtn/index'
export default {
components: { XHeader, bottomBtn },
beforeRouteEnter (to, from, next) {
function getFunctionList () {
return axios.get('b/auth/getFunctions')
}
axios.all([getFunctionList()])
.then(axios.spread(fun => {
to.params.fun = fun.data.content
console.warn(fun.data.content);
next();
}))
},
data () {
return {
fun_list: this.$route.params.fun
}
},
mounted () {
let lis = document.getElementsByTagName('li');
for (let i = 0; i < lis.length; i++) {
lis[i].style.height = lis[i].offsetWidth + 'px';
}
},
methods: {
goHandler (i) {
let url = this.$route.params.fun[i].boh_url.split('boh');
let loc = window.location;
console.warn(loc);
if (loc.hostname === 'localhost') {
let res = url[1] ? loc.origin + url[1] : url[0];
window.location.href = res;
} else {
let host = loc.hostname;
if (!isNaN(Number(host.split('.')[0]))) {
let res = url[1] ? loc.origin + url[1] : url[0];
window.location.href = res;
} else {
window.location.href = this.$route.params.fun[i].boh_url;
}
}
},
btnClick () {
this.$router.push('/');
}
}
}
</script>
<style lang="less" scoped>
.function_list {
.list {
margin: 0;
margin-top: 3rem;
list-style: none;
li {
float: left;
text-align: center;
border: 1px solid #ccc;
width: 32.5%;
background: #fff;
position: relative;
span {
position: absolute;
width: 100%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
&:after {
display: block;
content: '';
clear: both;
}
}
}
</style>
<template>
<div class="login">
<p>
<span>用户名</span>
<input v-model="login_data.login_code" @keyup.enter="loginHandler" />
</p>
<p>
<span>密码</span>
<input type="password" v-model="login_data.login_password" @keyup.enter="loginHandler" />
</p>
<el-button type="primary" @click="loginHandler">登录</el-button>
<div>
<!-- <van-password-input
:value="value"
info="密码为6位数字"
@focus="keyboard = 'custom'"
/> -->
<van-field v-model="value" :maxlength="10" @click.native="keyboard = 'custom'" @blur="onBlur" readonly placeholder="请输入用户名" />
<!-- <van-number-keyboard
:show="showKeyboard"
@input="onInput"
@delete="onDelete"
@blur="showKeyboard = false"
/> -->
<van-number-keyboard
:show="keyboard === 'custom'"
close-button-text="完成"
theme="custom"
extra-key="."
@blur="keyboard = ''"
@input="onInput"
@delete="onDelete"
@close="onClose"
/>
</div>
</template>
......@@ -16,45 +29,23 @@
export default {
data () {
return {
login_data: {
login_code: '',
login_password: '1'
}
value: '',
showKeyboard: true,
keyboard: 'default'
}
},
methods: {
loginHandler () {
if (this.login_data.login_code === '') {
this.$vux.toast.show({
type: 'warn',
text: '请输入账号!'
})
return;
}
axios.post('b/auth/syslogin', this.login_data)
.then(res => {
if (res.data.ret === 'OK') {
let user = res.data.content.user;
window.localStorage['user_name'] = user.user_name
window.localStorage['role'] = user.role
window.localStorage['user_id'] = user.user_id
if (user.role === 'PB') {
window.localStorage['prov_id'] = user.parent_id;
}
if (user.role === 'FB') {
window.localStorage['fran_id'] = user.parent_id;
}
if (user.role === 'SM' || user.role === 'SE') {
window.localStorage['store_id'] = user.parent_id;
}
this.$router.push('./function_list')
} else {
this.$vux.toast.text(res.data.msg);
}
})
.catch(err => {
console.error(err);
})
onInput (key) {
this.value = (this.value + key).slice(0, 5)
},
onDelete () {
this.value = this.value.slice(0, this.value.length - 1)
},
onBlur () {
// console.warn(this.value);
},
onClose () {
this.keyboard = false
}
}
}
......
/* jshint esversion: 6 */
export default [
{
path: '/',
name: 'home',
component: () => import('./views/Home.vue')
},
{
path: '/about',
name: 'about',
component: () => import('./views/About.vue')
}
];
/* jshint esversion: 6 */
import Vue from 'vue';
import VueRouter from 'vue-router';
import ConfigRouter from './route.js';
Vue.use(VueRouter);
const router = new VueRouter({
history: false,
hashbang: true,
base: __dirname,
routes: ConfigRouter
});
router.beforeEach((to, from, next) => {
// store.commit('updateLoadingStatus', true)
next();
});
router.afterEach((to, from, next) => {
// store.commit('updateLoadingStatus', false)
});
export default router;
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: Home
}
]
})
......
/* jshint esversion: 6 */
import Vue from 'vue';
import Vuex from 'vuex';
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
Vue.use(Vuex)
export default new Vuex.Store({
state: {
......@@ -14,4 +13,4 @@ export default new Vuex.Store({
actions: {
}
});
})
......
<template>
<div class="about">
<h1>This is an about page</h1>
</div>
</template>
<template>
<div class="home">
<x-header></x-header>
<img alt="Vue logo" src="../assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
<template lang="html">
<div class="">
<van-pull-refresh
v-model="refreshing"
@refresh="onRefresh">
<van-list
v-model="loading"
:finished="finished"
finished-text="没有更多了"
@load="onLoad">
<van-cell
@click.native="onClick()"
v-for="item in list"
:key="item"
:title="item + ''"/>
</van-list>
</van-pull-refresh>
<van-dialog
v-model="show"
show-cancel-button
:before-close="beforeClose"
>
<van-field
v-model="username"
label="用户名"
placeholder="请输入"
/>
<van-field
v-model="password"
type="password"
label="密码"
placeholder="请输入"
/>
<van-field
v-model="username"
label="用户名"
placeholder="请输入"
/>
<van-field
v-model="password"
type="password"
label="密码"
placeholder="请输入"
/>
<van-field
v-model="username"
label="用户名"
placeholder="请输入"
/>
<van-field
v-model="password"
type="password"
label="密码"
placeholder="请输入"
/>
<van-field
v-model="username"
label="用户名"
placeholder="请输入"
/>
<van-field
@blur="onBlur"
v-model="password"
type="password"
label="密码"
placeholder="请输入"
/>
</van-dialog>
</div>
</template>
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
import { XHeader } from 'vux'
import { ImagePreview } from 'vant';
// const images = [
// 'https://img.yzcdn.cn/public_files/2017/09/05/3bd347e44233a868c99cf0fe560232be.jpg',
// 'https://img.yzcdn.cn/public_files/2017/09/05/c0dab461920687911536621b345a0bc9.jpg'
// ];
export default {
name: 'home',
components: {
HelloWorld,
XHeader
data () {
return {
list: [],
refreshing: false,
loading: false,
finished: false,
show: false,
username: '',
password: '',
images: []
}
},
mounted () {
axios.get('b/auth/getFunctions')
.then(res => {
console.warn(res);
})
.catch(error => {
console.error(error);
methods: {
onLoad () {
setTimeout(() => {
for (let i = 0; i < 10; i++) {
const text = this.list.length + 1
this.list.push(text < 10 ? '0' + text : text)
}
this.loading = false
if (this.list.length >= 40) {
this.finished = true
}
}, 500)
},
onRefresh () {
setTimeout(() => {
this.list = []
this.finished = false
this.refreshing = false
window.scrollTo(0, 10)
}, 1000)
},
onClick () {
// this.show = true;
if (_.random(1, true) > 0.5) {
const images = [
'https://img.yzcdn.cn/public_files/2017/09/05/3bd347e44233a868c99cf0fe560232be.jpg'
];
this.showImagePreview(images);
} else {
const images = [
'https://img.yzcdn.cn/public_files/2017/09/05/c0dab461920687911536621b345a0bc9.jpg'
];
this.showImagePreview(images);
}
},
beforeClose (action, done) {
if (action === 'confirm') {
setTimeout(done, 1000);
} else {
done();
}
},
onBlur (e) {
document.body && (document.body.scrollTop = document.body.scrollTop);
},
showImagePreview (images, position, timer) {
const instance = ImagePreview({
images,
asyncClose: !!timer,
startPosition: typeof position === 'number' ? position : 0,
showIndex: false
});
if (timer) {
setTimeout(() => {
instance.close();
}, timer);
}
}
}
}
</script>
<style lang="less" scoped>
</style>
......
/* jshint esversion: 6 */
const vuxLoader = require('vux-loader');
const path = require('path');
const webpack = require('webpack');
const path = require('path')
const webpack = require('webpack')
const CompressionWebpackPlugin = require('compression-webpack-plugin')
// function resolve (dir) {
// return path.join(__dirname, './', dir)
// }
// cdn预加载使用
const externals = {
'vue': 'Vue',
'vue-router': 'VueRouter',
'vuex': 'Vuex',
'axios': 'axios',
'vant': 'Vant',
'$': 'jquery',
'jquery': 'Jquery',
'moment': 'moment'
}
const cdn = {
// 开发环境
dev: {
css: [],
js: []
},
// 生产环境
build: {
css: [
'https://cdn.jsdelivr.net/npm/vant@1.5/lib/index.css'
],
js: [
'https://cdn.jsdelivr.net/npm/vue@2.5.21/dist/vue.min.js',
'https://cdn.jsdelivr.net/npm/vue-router@3.0.1/dist/vue-router.min.js',
'https://cdn.jsdelivr.net/npm/vuex@3.0.1/dist/vuex.min.js',
'https://cdn.jsdelivr.net/npm/axios@0.18.0/dist/axios.min.js',
'https://cdn.jsdelivr.net/npm/vant@1.5/lib/vant.min.js',
'https://cdn.jsdelivr.net/npm/jquery/dist/jquery.min.js',
'https://cdn.jsdelivr.net/npm/moment@2.23.0/moment.min.js'
]
}
}
// 是否使用gzip
const productionGzip = true
// 需要gzip压缩的文件后缀
const productionGzipExtensions = ['js', 'css']
module.exports = {
// 基本路径
......@@ -53,10 +97,6 @@ module.exports = {
// 如果这个值是一个对象,则会通过 webpack-merge 合并到最终的配置中。
// 如果这个值是一个函数,则会接收被解析的配置作为参数。该函数及可以修改配置并不返回任何东西,也可以返回一个被克隆或合并过的配置版本。
configureWebpack: config => {
vuxLoader.merge(config, {
options: {},
plugins: ['vux-ui']
});
config.plugins.push(
new webpack.ProvidePlugin({
$: 'jquery',
......@@ -65,21 +105,59 @@ module.exports = {
'axios': 'axios',
'moment': 'moment'
})
);
config.resolve.extensions.push('.less');
config.resolve.extensions.push('.css');
)
config.resolve.extensions.push('.less')
config.resolve.extensions.push('.css')
//
config.resolve.alias.src = path.resolve(__dirname, './src/src');
config.resolve.alias.assets = path.resolve(__dirname, './src/assets');
config.resolve.alias.components = path.resolve(__dirname, './src/components');
config.resolve.alias.src = path.resolve(__dirname, './src/src')
config.resolve.alias.assets = path.resolve(__dirname, './src/assets')
config.resolve.alias.components = path.resolve(__dirname, './src/components')
// 修改webpack config, 使其不打包externals下的资源
if (process.env.NODE_ENV === 'production') {
// 为生产环境修改配置...
} else {
// 为开发环境修改配置...
// 1. 生产环境npm包转CDN
config.externals = externals
// 2. 构建时开启gzip,降低服务器压缩对CPU资源的占用,服务器也要相应开启gzip
productionGzip && config.plugins.push(
new CompressionWebpackPlugin({
test: new RegExp('\\.(' + productionGzipExtensions.join('|') + ')$'),
threshold: 8192,
minRatio: 0.8
})
)
}
if (process.env.NODE_ENV === 'development') {
}
},
// 是一个函数,会接收一个基于 webpack-chain 的 ChainableConfig 实例。允许对内部的 webpack 配置进行更细粒度的修改。
chainWebpack: () => {},
chainWebpack: (config) => {
/**
* 添加CDN参数到htmlWebpackPlugin配置中, 详见public/index.html 修改
* vue inspect --plugins 查询插件 使用pages会有多个html实例
*/
config
.plugin('html-index')
.tap(args => {
if (process.env.NODE_ENV === 'production') {
args[0].cdn = cdn.build
}
if (process.env.NODE_ENV === 'development') {
args[0].cdn = cdn.dev
}
return args
})
.end()
.plugin('html-login')
.tap(args => {
if (process.env.NODE_ENV === 'production') {
args[0].cdn = cdn.build
}
if (process.env.NODE_ENV === 'development') {
args[0].cdn = cdn.dev
}
return args
})
.end()
},
// css相关配置
css: {
// 是否使用css分离插件 ExtractTextPlugin
......@@ -106,7 +184,8 @@ module.exports = {
pwa: {},
// webpack-dev-server 相关配置
devServer: {
open: process.platform === 'darwin',
open: false,
// open: process.platform === 'darwin',
host: '0.0.0.0',
port: 8080,
https: false,
......@@ -122,8 +201,8 @@ module.exports = {
'^/(.*)': '/$1'
},
onProxyReq: function (proxyReq, req, res, options) {
proxyReq.setHeader('X-Proxy-Host', req.header('host'));
proxyReq.setHeader('X-Proxy-Request-URI', req.url);
proxyReq.setHeader('X-Proxy-Host', req.header('host'))
proxyReq.setHeader('X-Proxy-Request-URI', req.url)
}
}
},
......@@ -137,4 +216,4 @@ module.exports = {
pluginOptions: {
// ...
}
};
}
......