新增门店管理店员管理营销推广码

This commit is contained in:
唐明明
2021-09-25 17:17:08 +08:00
parent ce16270b75
commit 63b16b2802
30 changed files with 4935 additions and 220 deletions

311
pages/employees/add.vue Normal file
View File

@@ -0,0 +1,311 @@
<template>
<view class="content" v-if="!loging">
<!-- 基础信息 -->
<view class="info-card">
<view class="cover">
<view class="cover-add vertical" @click="updCover">
<block v-if="cover.showpath != ''">
<image :src="cover.showpath" mode="aspectFill"></image>
</block>
<block v-else>
<image class="cover-default" src="@/static/icons/add-icon.png" mode="widthFix"></image>
<view>员工寸照</view>
</block>
</view>
</view>
<view class="info-text">
<view class="info-inputs">
<input type="text" v-model="name" placeholder="姓名"/>
</view>
<view class="info-inputs">
<input type="number" v-model="phone" placeholder="手机号码"/>
</view>
<view class="info-inputs">
<input type="text" v-model="job" placeholder="职业"/>
</view>
<view class="info-inputs">
<picker :range="section" range-key="name" :value="sectionIndex" @change="pickerChange">
<view class="picker-text">
{{section[sectionIndex].name}}
<uni-icons class="icon" type="arrowdown" color="#555"></uni-icons>
</view>
</picker>
</view>
</view>
</view>
<view class="jurisdiction switch">
<view class="item">
<label>
<view class="item-title">设为推荐</view>
<view class="item-info">设为推荐员工将在企业自媒体中优先展示</view>
<switch class="item-switch" :checked="isPosition" color="#e93340" @change="switchChange" />
</label>
</view>
</view>
<!-- 权限设置 -->
<view class="title">权限设置</view>
<view class="jurisdiction">
<checkbox-group @change="permissionChange">
<view class="item" v-for="(item, index) in permissions" :key="index">
<label>
<view class="item-title">{{item.title}}</view>
<view class="item-info">{{item.description}}</view>
<checkbox class="item-checkbox" :checked="item.check" color="#e93340" :value="item.permission_id" />
</label>
</view>
</checkbox-group>
</view>
<!-- 按钮 -->
<view class="add-btns">
<button size="default" @click="onAddEmployees">{{type === 'PUT' ? '修改': '添加'}}</button>
</view>
</view>
</template>
<script>
import { employeesConfig, addEmployees, employeesInfo, employeesPut } from '@/apis/interfaces/employees'
import { uploads } from '@/apis/interfaces/uploading'
export default {
data() {
return {
type : '',
loging : true,
section : [],
permissions : [],
permissionIds: [],
sectionIndex : 0,
cover : {
showpath : '',
path : ''
},
name : '',
phone : '',
job : '',
isPosition : false
};
},
created() {
if(this.$Route.query.type === 'PUT'){
this.type = 'PUT'
uni.setNavigationBarTitle({
title: '编辑员工'
})
}
employeesConfig().then(res => {
this.section = res.store
if(this.$Route.query.type === 'PUT'){
employeesInfo(this.$Route.query.id || 4).then(res => {
let permissionIds = []
for(let val of res.permission){
if(val.check){
permissionIds.push(val.permission_id)
}
}
this.permissions = res.permission
this.sectionIndex = this.section.findIndex(val => val.store_id == res.store.store_id)
this.permissionIds= permissionIds
this.name = res.name
this.phone = res.mobile
this.job = res.job
this.cover = res.cover
this.isPosition = res.is_position
this.loging = false
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}else{
this.permissions = res.permissions
this.loging = false
}
})
},
methods:{
// 设为推荐
switchChange(e){
this.isPosition = e.detail.value
},
// 选择部门
pickerChange(e){
this.sectionIndex = e.detail.value
},
// 权限选择
permissionChange(e){
this.permissionIds = e.detail.value
},
// 上传照片
updCover(){
uni.chooseImage({
crop: {width: 229, height: 320},
success: path=> {
uploads([{
uri : path.tempFilePaths[0]
}]).then(res => {
this.cover = {
showpath: res.url[0],
path : res.path[0]
}
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
})
},
// 添加员工
onAddEmployees(){
let data = {
name : this.name,
mobileNo : this.phone,
job : this.job,
cover : this.cover.path,
position : this.isPosition ? 1: 0,
order : 0,
store_id : this.section[this.sectionIndex].store_id,
permission : this.permissionIds
}
let submitAdd = this.type == 'PUT' ? employeesPut(this.$Route.query.id, data) : addEmployees(data)
submitAdd.then(res => {
uni.showModal({
title : '提示',
content : res,
showCancel : false,
success : () => {
this.$Router.back()
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
}
}
</script>
<style lang="scss" scoped>
.content{
min-height: 100vh;
@extend .ios-bottom;
.title{
padding: ($padding/2) $padding;
color: $text-gray;
}
.jurisdiction{
background: white;
&.switch{
margin-top: $margin;
}
.item{
position: relative;
padding: $padding 150rpx $padding $padding;
&::after{
position: absolute;
left: $padding;
right: 0;
bottom: 0;
height: 1rpx;
content: " ";
background: $border-color;
}
&:last-child::after{
display: none;
}
.item-checkbox{
position: absolute;
right: $padding;
top: 50%;
height: 40rpx;
margin-top: -27rpx;
}
.item-switch{
position: absolute;
right: $padding;
top: 50%;
height: 40rpx;
margin-top: -27rpx;
}
.item-title{
font-size: $title-size;
padding-bottom: $margin/3;
}
.item-info{
font-size: $title-size-m;
color: $text-gray;
}
}
}
// 基础信息
.info-card{
background: white;
padding: $padding;
position: relative;
min-height: 238rpx;
.cover{
position: absolute;
top: $padding;
left: $padding;
background: #f8f8f8;
width: 229rpx;
height: 320rpx;
.cover-add{
position: absolute;
width: 100%;
height: 100%;
text-align: center;
image{
width: 229rpx;
height: 320rpx;
}
image.cover-default{
width: 128rpx;
}
color: $text-gray-m;
font-size: $title-size-m;
}
}
.info-text{
padding-left: $padding + 229;
.info-inputs{
height: 80rpx;
line-height: 80rpx;
border-bottom: solid 1rpx $border-color;
input{
height: 80rpx;
}
.picker-text{
position: relative;
padding-right: 80rpx;
.icon{
position: absolute;
right: 0;
top: 0;
}
}
}
}
}
// 添加按钮
.add-btns{
padding: $padding;
button[size='default']{
height: 90rpx;
line-height: 90rpx;
padding: 0;
margin: 0;
background: $text-price;
font-size: $title-size;
font-weight: bold;
color: white;
border-radius: 0;
}
}
}
</style>

260
pages/employees/list.vue Normal file
View File

@@ -0,0 +1,260 @@
<template>
<view class="ios-bottom" v-if="!loding">
<view class="header-flex">
员工数量 {{total}}
<view class="add-btn" @click="addEmployees">添加员工</view>
</view>
<!-- 员工列表 -->
<uni-collapse v-if="lists.length > 0">
<block v-for="(listItem, listIndex) in lists" :key="listIndex">
<uni-collapse-item :show-animation="true" :open="listIndex === 0">
<template v-slot:title>
<view class="collapse-title">{{listItem.name}}</view>
</template>
<block v-if="listItem.data.length > 0">
<view class="employees-border" v-for="(item, index) in listItem.data" :key="index">
<uni-swipe-action>
<uni-swipe-action-item :rightOptions="options" @click="onEmployees($event, listIndex, index)">
<view class="employees-item">
<view class="cover">
<block v-if="item.user.avatar === ''">{{item.name.slice(0,1)}}</block>
<block v-else>
<image class="cover-img" :src="item.user.avatar" mode="aspectFill"></image>
</block>
</view>
<view class="content">
<view class="nickname nowrap">{{item.name}}<text>{{item.job}}</text></view>
<view class="job nowrap">
<text v-for="(permissionItem, permissionIndex) in item.permission" :key="permissionIndex">{{permissionItem}}</text>
</view>
</view>
</view>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
</block>
<block v-else>
<view class="employees-null">店铺暂无员工</view>
</block>
</uni-collapse-item>
</block>
</uni-collapse>
<view v-else class="list-null">
<image class="icon" src="@/static/icons/listnull-icon.png" mode="widthFix" />
<view class="sub-title">暂未添加员工</view>
<view class="sub-btn" @click="$Router.push({name: 'employeesAdd'})">添加员工</view>
</view>
</view>
</template>
<script>
import { employees, employeesDelete } from '@/apis/interfaces/employees'
export default {
data() {
return {
loding : true,
lists : [],
total : 0,
options : [{
text : '编辑',
type : 'PUT',
style : {
backgroundColor: '#3688ee'
}
},{
text : '删除',
type : 'DELETE',
style : {
backgroundColor: '#e93340'
}
}]
};
},
onShow(){
employees().then(res => {
this.lists = res.data
this.total = res.total
this.loding = false
})
},
methods:{
// 编辑,删除
onEmployees(e, upIndex, index){
let type = e.content.type,
val = this.lists[upIndex].data[index]
if(type == 'PUT'){
this.$Router.push({name: 'addEmployees', params: {type: 'PUT', id: val.employee_id}})
return
}
uni.showModal({
title : '提示',
content : '删除后无法恢复,确定删除员工[' + val.name + ']吗?',
cancelText : '取消',
cancelColor : '#555',
confirmText : '确认',
confirmColor: '#e93340',
success : res => {
if(res.confirm) {
employeesDelete(val.employee_id).then(res => {
uni.showToast({
title: res,
icon : 'none'
})
this.lists[upIndex].data.splice(index, 1)
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
}
})
},
// 添加员工
addEmployees(){
if(this.lists.length <= 0){
uni.showModal({
title : '提示',
content : '暂未创建门店,无法添加员工',
cancelText : '稍后创建',
cancelColor : '#555',
confirmText : '立即创建',
confirmColor: '#e93340',
success : res => {
if(res.confirm) {
this.$Router.push({name: 'shopCreate'})
}
}
})
return
}
this.$Router.push({name: 'employeesAdd'})
}
}
};
</script>
<style lang="scss" scoped>
.collapse-title{
padding: 0 $padding;
line-height: 90rpx;
font-weight: bold;
font-size: $title-size-lg;
}
.employees-item {
background: white;
padding: ($padding - 10) $padding;
position: relative;
&::before {
position: absolute;
bottom: 0;
left: $padding + 98;
right: 0;
content: ' ';
height: 1rpx;
background: $border-color;
}
.cover {
position: absolute;
top: $padding - 10;
left: $padding;
background: $text-price;
color: white;
height: 88rpx;
width: 88rpx;
line-height: 88rpx;
text-align: center;
border-radius: 50%;
overflow: hidden;
font-size: $title-size-lg;
.cover-img {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
}
.content {
height: 88rpx;
padding-left: 108rpx;
.nickname{
line-height: 40rpx;
font-size: $title-size;
padding-bottom: 10rpx;
text{
font-size: $title-size-sm;
color: $text-gray-m;
padding-left: 10rpx;
}
}
.job{
line-height: 38rpx;
text{
background-color: $border-color-lg;
color: $text-gray;
padding: 0 10rpx;
line-height: 38rpx;
margin-left: $margin/2;
display: inline-block;
&:first-child{
margin-left: 0;
}
}
}
}
}
// 空提示
.list-null{
width: 100vw;
height: 100vh;
box-sizing: border-box;
text-align: center;
background: white;
padding-bottom: 20vh;
@extend .vertical;
.sub-title{
color: $text-gray;
font-size: $title-size-m;
}
.icon{
width: 288rpx;
}
.sub-btn{
width: 200rpx;
height: 70rpx;
line-height: 70rpx;
text-align: center;
background: $mian-color;
color: white;
display: inline-block;
margin-top: $margin*2;
}
}
.employees-null{
text-align: center;
line-height: 10vh;
padding-bottom: $padding;
font-size: $title-size-m;
color: $text-gray;
}
// 添加员工header
.header-flex{
background: white;
padding: ($padding/2) $padding;
display: flex;
justify-content: space-between;
margin-bottom: $margin - 10;
line-height: 60rpx;
color: $text-gray;
.add-btn{
background: $mian-color;
color: white;
width: 150rpx;
text-align: center;
font-size: $title-size-m;
}
}
</style>

View File

@@ -34,16 +34,243 @@
<view class="title">{{ item.title }}</view>
</view>
</scroll-view>
<!-- 平台概况 -->
<view class="situation">
<view class="header">
<view class="header-item">
<view class="title">平台原石余量<uni-icons class="help-icon" @click="showHelp('occBalance')" type="help-filled" size="18" color="rgba(255,255,255,.3)" /></view>
<view class="number ellipsis">{{ occBalance }}</view>
</view>
<view class="header-item">
<view class="title">昨日瓜分水晶<uni-icons class="help-icon" @click="showHelp('yesterdayCrystal')" type="help-filled" size="18" color="rgba(255,255,255,.3)" /></view>
<view class="number ellipsis">{{ yesterdayCrystal }}</view>
</view>
<view class="header-item">
<view class="title">区块链高度<uni-icons class="help-icon" @click="showHelp('blockHeight')" type="help-filled" size="18" color="rgba(255,255,255,.3)" /></view>
<view class="number ellipsis">{{ blockHeight }}</view>
</view>
<view class="header-item">
<view class="title">平台累计盈利额<uni-icons class="help-icon" @click="showHelp('gain')" type="help-filled" size="18" color="rgba(255,255,255,.3)" /></view>
<view class="number ellipsis">{{ gain }}</view>
</view>
<view class="header-item">
<view class="title">已开通节点数<uni-icons class="help-icon" @click="showHelp('nodeNumber')" type="help-filled" size="18" color="rgba(255,255,255,.3)" /></view>
<view class="number ellipsis">{{ nodeNumber }}</view>
</view>
</view>
<!-- 节点信息 -->
<view class="node-info">
<view class="node-item">
<view class="title">轻节点</view>
<view class="number ellipsis">{{occs.light || '-'}}</view>
</view>
<view class="node-item">
<view class="title">合作节点</view>
<view class="number ellipsis">{{occs.cooperation || '-'}}</view>
</view>
<view class="node-item">
<view class="title">主节点</view>
<view class="number ellipsis">{{occs.main || '-'}}</view>
</view>
<view class="node-item">
<view class="title">超级节点</view>
<view class="number ellipsis">{{occs.super || '-'}}</view>
</view>
<view class="node-item">
<view class="title">运营节点</view>
<view class="number ellipsis">{{occs.operating || '-'}}</view>
</view>
<view class="node-item">
<view class="title">技术节点</view>
<view class="number ellipsis">{{occs.technology || '-'}}</view>
</view>
</view>
<!-- 平台盈利额原石数量 -->
<view class="chart">
<view class="title">平台累计营业额和原石价值走势图</view>
<view class="chart-f2">
<l-f2 ref="chartChange"></l-f2>
</view>
</view>
</view>
</view>
</template>
<script>
import { occ } from '@/apis/interfaces/chain'
import { certified, security } from '@/apis/interfaces/index'
import F2 from '@/uni_modules/lime-f2/components/lime-f2/f2.min.js'
import lF2 from '@/uni_modules/lime-f2/components/lime-f2/'
export default {
data() {
return {
crystalArr : [],
categoryArr : [],
occs: {},
blockHeight: 0,
occBalance: 0,
occ: 0,
yesterdayCrystal: 0,
gain: 0,
nodeNumber: 0,
notice: [],
isAuth: false,
helpToast: {
occ: '恒量发行原石量',
occBalance: '平台原石量',
yesterdayCrystal: '昨日瓜分水晶',
blockHeight: '区块链高度',
gain: '平台累计盈利额',
nodeNumber: '已开通节点数'
}
};
},
onShow() {
if(this.$store.state.token != '') this.isAuth = true
this.getOcc()
},
methods:{
// 求助信息
showHelp(type) {
uni.showModal({
title: '提示',
content: this.helpToast[type],
showCancel: false
})
},
// 原石钱包
openWallet(){
Promise.all([certified(), security()]).then(res=> {
let certified = res[0],
security = res[1]
if(!certified){
uni.showModal({
title: '提示',
content: '您还为完成个人认证,无法激活您的钱包',
confirmText: '去认证',
confirmColor: '#009B69',
cancelColor: '#666666',
cancelText: '稍后再说',
success: res=> {
if(res.confirm) {
uni.navigateTo({
url: '/pages/certification/personal'
})
}
}
})
return
}
if(!security) {
uni.showModal({
title: '激活提示',
content: '您的钱包未激活,是否立即导出助记词并激活您的钱包?',
confirmText: '去激活',
confirmColor: '#009B69',
cancelColor: '#666666',
cancelText: '稍后再说',
success: res=> {
if(res.confirm) {
uni.navigateTo({
url: '/pages/wallet/add'
})
}
}
})
return
}
uni.navigateTo({
url: '/pages/wallet/property'
})
})
},
// occ信息
getOcc(){
occ().then(res => {
console.log(res)
this.occs = res.occs
this.yesterdayCrystal = res.yesterday_crystal
this.occ = res.occ
this.occBalance = res.occ_balance
this.blockHeight = res.block_height
this.gain = res.gain
this.nodeNumber = res.node_number
this.notice = res.notice
if(res.help_toast) this.helpToast = res.help_toast
this.showCartc(res.movements)
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 绘制图表
showCartc(data){
// 图表信息
this.$refs.chartChange.init(config => {
config.appendPadding = [10, 15, 10, 15]
const chart = new F2.Chart(config);
chart.source(data, {
date: {
range: [0, 1],
type: 'timeCat',
mask: 'MM-DD'
},
value: {
tickCount: 5
}
});
chart.axis('time', {
line: null,
label: function label(text, index, total) {
const textCfg = {};
if (index === 0) {
textCfg.textAlign = 'left';
} else if (index === total - 1) {
textCfg.textAlign = 'right';
}
return textCfg;
}
});
chart.axis('tem', {
grid: function grid(text) {
if (text === '0%') {
return {
lineDash: null,
lineWidth: 1
};
}
}
});
chart.tooltip({
showCrosshairs: true
});
chart.legend({
position: 'bottom',
offsetY: 0,
offsetX: 30
});
chart.area()
.position('date*value')
.color('name', [ '#009b69', '#9f8052' ])
.shape('smooth')
chart.line()
.position('date*value')
.color('name', [ '#009b69', '#9f8052' ])
.shape('smooth', name=> {
if (name === '预期收益率') {
return 'line';
}
if (name === '实际收益率') {
return 'dash';
}
});
chart.render();
return chart;
})
}
}
}
</script>
@@ -137,10 +364,83 @@
background: #1f1922;
overflow: hidden;
}
// 平台概况
.situation{
margin: 0 $margin;
background-image: linear-gradient(to bottom, $block-color, #1f1922);
border-radius: $radius;
padding: $padding $padding/2 $padding*2;
// 平台统计
.header{
display: flex;
flex-wrap: wrap;
margin-bottom: $margin*2;
.number{
color: white;
font-size: $title-size;
padding-top: $padding/2;
font-weight: bold;
}
.title{
color: rgba($color: white, $alpha: .4);
font-size: $title-size-sm;
}
.header-item{
width: 50%;
padding: $padding / 2;
box-sizing: border-box;
&:first-child{
width: 100%;
.number{
font-size: $title-size;
}
}
}
}
// 节点信息
.node-info{
display: flex;
flex-wrap: wrap;
margin: 0 -$margin / 2;
.node-item{
background: rgba($color: $block-color, $alpha: .8);
width: calc(50% - #{$margin});
margin: $margin / 2;
padding: $padding;
box-sizing: border-box;
border-radius: $radius/2;
}
.number{
font-size: $title-size + 4;
font-weight: bold;
color: white;
}
.title{
font-size: $title-size-sm;
color: white;
}
}
// 图表
.chart{
background: rgba($color: $block-color, $alpha: .8);
padding: $padding;
border-radius: $radius/2;
margin-top: $margin;
.title{
text-align: center;
line-height: 80rpx;
color: white;
font-size: $title-size-m;
}
.chart-f2{
height: 200px;
}
}
}
// 数据统计
.total {
position: relative;
margin: $margin ($margin + $margin/2);
margin: $margin;
background: #2b2449;
padding: 0;
display: flex;
@@ -171,6 +471,12 @@
background: linear-gradient(to bottom, transparent, rgba(255, 255, 255, .7), transparent);
}
}
// 求助icon
.help-icon{
vertical-align: middle;
margin-left: $margin/3;
opacity: .7;
}
// 矿石
.ore {
position: relative;

249
pages/instrument/Spread.vue Normal file
View File

@@ -0,0 +1,249 @@
<template>
<view class="content">
<view class="codeContent">
<image class="codeContent-back" src="../../static/icons/store_codeBack.png" mode="widthFix"></image>
<image class="codeContent-cont" src="../../static/icons/store_contBack.png" mode="widthFix"></image>
<view class="textContent">
<view class="company">
<image class="company-logo" :src="companyInfo.cover" mode="aspectFill"></image>
<view class="company-cont">
<view class="nowrap company-name">{{companyInfo.name}}</view>
<view class="company-tips">易货平台</view>
</view>
</view>
<view class="code">
<image class="code-img" :src="companyInfo.code" mode="aspectFit"></image>
<!-- <view class="code-text">简单扫一扫即可进入平台</view> -->
</view>
<!-- @click="shareCanvas" -->
<view class="codeBnt">
扫码推广
</view>
</view>
</view>
<canvas class="codeImg" canvas-id="qrcodeCard"></canvas>
</view>
</template>
<script>
import { companiesCode } from '@/apis/interfaces/store'
export default {
data() {
return {
companyInfo : ''
}
},
created() {
companiesCode().then(res=>{
this.companyInfo = res
})
},
methods: {
// 绘制图片
shareCanvas(e){
uni.showLoading({
title: '加载中',
})
// 下载头像
let avatarImg = new Promise(success=>{
uni.getImageInfo({
src : this.companyInfo.cover,
success : res => {
success(res.path)
}
})
})
// 下载二维码
let codeImg = new Promise(success => {
uni.getImageInfo({
src : this.companyInfo.code,
success : res => {
success(res.path)
}
})
})
Promise.all([avatarImg, codeImg]).then(res => {
// 绘制海报
const ctx = uni.createCanvasContext('qrcodeCard')
ctx.save()
// 绘制背景图片
ctx.drawImage('../../static/icons/store_downBack', 0, 0, 375, 603)
// 绘制头像
ctx.drawImage(res[0], 0, 0, 60, 60)
// 绘制二维码
ctx.drawImage(res[1], 140, 250, 110, 110)
// 文字
ctx.setFontSize(16)
ctx.fillText(this.companyInfo.name, 194, 180 , 270)
ctx.setFontSize(16)
ctx.fillText('邀请你加入易货平台', 194, 180 , 270)
ctx.save();
ctx.beginPath(); //开始绘制
ctx.arc(50 / 2 + 170, 50 / 2 + 110, 50 / 2, 0, Math.PI * 2, false);
ctx.clip();
// 保存图片
ctx.draw(true, () => {
uni.hideLoading()
uni.canvasToTempFilePath({
canvasId: 'qrcodeCard',
x: 0,
y: 0,
success: res => {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success : res=>{
if (res.errMsg == "saveImageToPhotosAlbum:ok"){
uni.showToast({
title: '分享海报已保存至相册',
icon : 'none'
})
}else{
uni.hideLoading()
}
},
fail : err=>{
if (err.errMsg == "saveImageToPhotosAlbum:fail auth deny"){
uni.showModal({
title : '提示',
content : '暂未授权小程序写入您的相册,无法存储二维码海报',
confirmColor: '#d82526',
confirmText : '去设置',
success : res=>{
if (res.confirm){
uni.openSetting()
}
}
})
}
}
})
}
})
})
}).catch(err=>{
uni.showToast({
title: '海报下载,请检查网络',
icon : 'none'
})
})
}
}
}
</script>
<style lang="scss" scoped>
.content {
background-color: #e93340;
height: 100vh;
width: 100vw;
}
.codeContent {
position: relative;
width: 100%;
height: 100vh;
.codeContent-back {
width: 100%;
height: 100%;
z-index: 1;
position: absolute;
}
.codeContent-cont {
left: 5%;
width: 90%;
top: 100px;
z-index: 2;
position: absolute;
}
.codeContent-tips {
position: absolute;
top: 0;
right: 20rpx;
width: 200rpx;
z-index: 2;
}
.textContent {
position: absolute;
padding: 20rpx 20rpx 0 40rpx;
box-sizing: border-box;
width: 70%;
z-index: 3;
left: 15%;
right: 15%;
top: 140px;
}
.company {
width: 100%;
.company-logo {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
}
.company-cont {
position: absolute;
width: 100%;
height: 230rpx;
left: 0;
top: 0;
padding: 20rpx 20rpx 30rpx 210rpx;
font-size: $title-size;
.company-name {
font-weight: 600;
margin: 10rpx 0;
}
.company-tips {
font-size: 26rpx;
color: #787878;
}
}
}
.code {
text-align: center;
width: 100%;
box-sizing: border-box;
margin-bottom: $margin;
.code-img {
width: 90%;
}
.code-text {
color: #787878;
margin-top: $margin - 10;
font-size: $title-size;
}
}
}
.codeBnt {
background-color: #e1293f;
text-align: center;
border-radius: 10rpx;
line-height: 90rpx;
font-weight: 600;
font-size: $title-size;
color: #FFFFFF;
box-shadow: 4rpx 0 10rpx rgba(155,0,19,.5);
position: relative;
}
/* canvas */
.codeImg {
position: absolute;
left: -1000%;
height: 603px;
width: 375px;
background: white;
}
</style>

View File

@@ -1,6 +1,6 @@
<template>
<view class="News-detail" v-if="loaded">
<view class="item" v-for="(item,index) in items" v-if="items.length>0"
<view class="item" v-for="(item,index) in items" :key="index" v-if="items.length>0"
@click="item.read_at === ''?read(index,item):noread(item)">
<view class="top">
<image src="/static/images/news_2_1.png" mode="widthFix"></image>

327
pages/shop/create.vue Normal file
View File

@@ -0,0 +1,327 @@
<template>
<view>
<view class="create-form">
<view class="header">
<view @click="updLogo">
<image class="logo" style="border: none;" v-if="cover.showpath" :src="cover.showpath" mode="aspectFill" />
<image class="logo" v-else src="@/static/icons/add-icon.png" mode="aspectFill" />
</view>
<view class="inputs">
<input type="text" v-model="name" placeholder="门店/部门名称" />
</view>
<view class="inputs">
<input type="number" v-model="mobile" placeholder="门店联系电话" />
</view>
</view>
<view class="info">
<view class="inputs">
<label class="inputs-label">开店时间</label>
<picker mode="time" @change="pickerTime" :value="startTime" data-key="startTime">
<view class="time-text">
{{startTime || '选择开店时间'}}
<uni-icons class="time-icon" type="arrowdown" size="18" color="#999"></uni-icons>
</view>
</picker>
</view>
<view class="inputs">
<label class="inputs-label">闭店时间</label>
<picker mode="time" @change="pickerTime" :value="endTime" data-key="endTime">
<view class="time-text">
{{endTime || '选择闭店时间'}}
<uni-icons class="time-icon" type="arrowdown" size="18" color="#999"></uni-icons>
</view>
</picker>
</view>
<view class="inputs addrss-input">
<label class="inputs-label">门店地址</label>
<textarea class="inputs-textarea" v-model="address" placeholder="输入门店地址" auto-height/>
<view class="addrss-icon" @click="onLocation">
<uni-icons type="location-filled" size="20" color="#c82626"></uni-icons>
</view>
</view>
</view>
<view class="info">
<view class="inputs">
<label class="inputs-label">门店简介</label>
<textarea class="inputs-textarea" v-model="description" placeholder="门店简介..." />
</view>
</view>
</view>
<view class="create-btns">
<button class="item-btn btn-submit" type="default" @click="createShop">{{type === 'add' ? '创建': '保存'}}</button>
<button class="item-btn btn-delete" type="default" @click="onDeleteShop" v-if="type === 'edit'">删除</button>
</view>
</view>
</template>
<script>
import { create, putShop, deleteShop, editInfo } from '@/apis/interfaces/shop'
import { uploads } from '@/apis/interfaces/uploading'
export default {
data() {
return {
type : 'add',
id : '',
cover : {
showpath: '',
path : '',
},
name : '',
mobile : '',
address : '',
startTime : '',
endTime : '',
description : '',
latitude : '',
longitude : ''
};
},
onLoad() {
if(this.$Route.query.id){
this.type = 'edit'
this.getInfo()
}
},
methods:{
// 获取编辑信息
getInfo(){
editInfo(this.$Route.query.id).then(res => {
this.id = res.store_id
this.cover = res.cover
this.name = res.name
this.mobile = res.mobile
this.address = res.address
this.startTime = res.start_time
this.endTime = res.end_time
this.description= res.description
this.latitude = res.latitude
this.longitude = res.longitude
})
},
// 获取地址
onLocation(){
uni.chooseLocation({
success: res => {
this.address = res.address
this.longitude = res.longitude
this.latitude = res.latitude
},
fail: err => {
uni.showToast({
title: err,
icon : 'none'
})
}
})
},
// 选择营业时间
pickerTime(e){
this[e.target.dataset.key] = e.detail.value
},
// 编辑创建
createShop(){
let data = {
cover : this.cover.path,
name : this.name,
mobile : this.mobile,
address : this.address,
latitude : this.latitude,
longitude : this.longitude,
description : this.description,
start_time : this.startTime,
end_time : this.endTime
}
if(this.type === 'edit'){
putShop(this.id, {...data}).then(res => {
uni.showModal({
title : '提示',
content : res,
showCancel : false,
success : modalRes => {
this.$Router.back()
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
return
}
create({...data}).then(res => {
uni.showModal({
title : '提示',
content : res,
showCancel : false,
success : modalRes => {
this.$Router.back()
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 删除门店
onDeleteShop(){
deleteShop(this.id).then(res => {
uni.showModal({
title : '提示',
content : res,
showCancel : false,
success : modalRes => {
this.$Router.back()
}
})
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
},
// 上传logo
updLogo(){
uni.chooseImage({
crop: { width: 188, height: 188 },
success: path => {
uploads([{
name: 'logo',
uri : path.tempFilePaths[0]
}]).then(res => {
this.cover = {
showpath: res.url[0],
path: res.path[0]
}
}).catch(err => {
uni.showToast({
title: err.message,
icon : 'none'
})
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
// 门店信息
.create-form{
.header{
position: relative;
background: white;
padding-left: $padding + 150;
.logo{
width: 108rpx;
height: 108rpx;
border-radius: 50%;
position: absolute;
left: $padding;
top: 26rpx;
border: dashed 2rpx $border-color;
box-sizing: border-box;
}
.inputs{
position: relative;
padding-right: $padding;
input,
.time-text{
line-height: 80rpx;
height: 80rpx;
font-size: $title-size-lg;
}
&::after{
position: absolute;
left: 0;
bottom: 0;
right: 0;
content: " ";
height: 1rpx;
background: $border-color;
}
&:last-child::after{
display: none;
}
.time-text{
padding-right: 80rpx;
.time-icon{
position: absolute;
height: 80rpx;
line-height: 80rpx;
text-align: right;
width: 80rpx;
right: $padding;
top: 0;
}
}
}
}
.info{
@extend .header;
margin-top: $margin;
padding-left: 0;
background: white;
.inputs{
padding-left: $padding + 150;
.inputs-label{
position: absolute;
left: $padding;
top: 0;
font-size: $title-size-lg;
line-height: 80rpx;
height: 80rpx;
width: 150rpx;
}
.inputs-textarea{
width: 100%;
padding: 20rpx 0;
height: 160rpx;
font-size: $title-size-lg;
line-height: 40rpx;
}
&.addrss-input{
padding-right: $padding + 100;
.addrss-icon{
position: absolute;
height: 80rpx;
line-height: 80rpx;
text-align: right;
width: 80rpx;
right: $padding;
top: 0;
}
}
}
}
}
// 按钮组
.create-btns{
padding: $padding;
.item-btn{
border-radius: 0;
background: white;
font-size: $title-size;
line-height: 90rpx;
height: 90rpx;
&::after{
border: none;
}
}
.btn-submit{
background: $text-price;
color: white;
font-weight: bold;
margin-bottom: $margin;
}
.btn-delete{
border: solid 1rpx $border-color;
color: $text-gray;
}
}
</style>

120
pages/shop/lists.vue Normal file
View File

@@ -0,0 +1,120 @@
<template>
<view class="lists">
<block v-if="lists.length > 0">
<view class="lists-item" v-for="(item, index) in lists" :key="index" @click="$Router.push({name: 'shopCreate', params: { id: item.store_id }})">
<view class="header">
<image class="logo" :src="item.cover" mode="aspectFill"></image>
<view class="title">{{item.name}}</view>
<view class="time"><text>营业时间{{item.start_time}} {{item.end_time}}</text></view>
<view class="icons">
<uni-icons type="arrowright" color="#999" size="18"></uni-icons>
</view>
</view>
<view class="address">店铺地址{{item.address}}</view>
</view>
</block>
<block v-else>
<view class="list-null">
<image class="icon" src="@/static/icons/approve-icon.png" mode="widthFix"></image>
<view class="sub-title">暂未创建店铺/部门</view>
<view class="sub-btn" @click="$Router.push({name: 'shopCreate'})">创建</view>
</view>
</block>
</view>
</template>
<script>
import { shops } from '@/apis/interfaces/shop'
export default {
data() {
return {
lists: []
};
},
onShow(){
shops().then(res => {
console.log(res)
this.lists = res.data
})
}
}
</script>
<style lang="scss">
// 空提示
.list-null{
width: 100vw;
height: 100vh;
padding-bottom: 20vh;
box-sizing: border-box;
background: white;
text-align: center;
@extend .vertical;
.sub-title{
color: $text-gray;
font-size: $title-size-m;
}
.icon{
width: 288rpx;
}
.sub-btn{
width: 200rpx;
height: 70rpx;
line-height: 70rpx;
text-align: center;
background: $mian-color;
color: white;
display: inline-block;
margin-top: $margin*2;
}
}
// 列表
.lists-item{
background: white;
margin: $margin;
border-radius: $radius/2;
padding: $padding;
.header{
position: relative;
padding-left: 128rpx;
padding-right: 100rpx;
min-height: 108rpx;
padding-bottom: $padding - 10;
.logo{
position: absolute;
top: 0;
left: 0;
width: 108rpx;
height: 108rpx;
border-radius: 50%;
}
.title{
line-height: 60rpx;
font-size: $title-size;
font-weight: bold;
}
.time{
line-height: 40rpx;
font-size: $title-size-sm;
text{
background-color: $border-color-lg;
color: $text-gray;
padding: 0 $padding/2;
}
}
.icons{
position: absolute;
right: 0;
top: 0;
line-height: 108rpx;
}
}
.address{
border-top: solid 1rpx $border-color;
padding-top: $padding - 10;
font-size: $title-size-m;
color: $text-gray;
left: 50rpx;
}
}
</style>

View File

@@ -178,7 +178,7 @@
<image class="tool-label-img" src="/static/user/userTool-01.png" mode=""></image>
<view class="tool-label-name">优惠券管理</view>
</view>
<view class="tool-label">
<view class="tool-label" @click="$Router.push({name: 'instrumentSpread'})">
<image class="tool-label-img" src="/static/user/userTool-02.png" mode=""></image>
<view class="tool-label-name">营销推广码</view>
</view>
@@ -186,14 +186,18 @@
<image class="tool-label-img" src="/static/user/userTool-03.png" mode=""></image>
<view class="tool-label-name">基础信息</view>
</view>
<view class="tool-label">
<view class="tool-label" @click="$Router.push({name: 'shopLists'})">
<image class="tool-label-img" src="/static/user/userTool-04.png" mode=""></image>
<view class="tool-label-name">部门门店</view>
</view>
<view class="tool-label" @click="$Router.push({name: 'instrumentBasics'})">
<view class="tool-label" @click="$Router.push({name: 'employeesList'})">
<image class="tool-label-img" src="/static/user/userTool-05.png" mode=""></image>
<view class="tool-label-name">店员管理</view>
</view>
<!-- <view class="tool-label" @click="$Router.push({name: 'verificationIndex'})">
<image class="tool-label-img" src="/static/user/userTool-05.png" mode=""></image>
<view class="tool-label-name">扫码核销</view>
</view> -->
</view>
</view>

View File

@@ -270,7 +270,7 @@
width: calc(100% - 60rpx);
height: 360rpx;
background-image: linear-gradient(to left, #076cff, #076cff);
box-shadow: 0 10rpx 20rpx 0rpx rgba($color: $main-color, $alpha: 0.4);
box-shadow: 0 10rpx 20rpx 0rpx rgba($color: $mian-color, $alpha: 0.4);
margin: 0 30rpx;
border-radius: 20rpx;
box-sizing: border-box;