소스 검색

【抖音小程序发布平台】

master
chenshengle 2 년 전
커밋
8434b6b911
70개의 변경된 파일26192개의 추가작업 그리고 0개의 파일을 삭제
  1. +15
    -0
      .babelrc
  2. +15
    -0
      .gitignore
  3. +3
    -0
      README.md
  4. +17036
    -0
      package-lock.json
  5. +80
    -0
      package.json
  6. +123
    -0
      src/App.vue
  7. +399
    -0
      src/components/audit/list.vue
  8. +33
    -0
      src/components/authHOC/authHoc.js
  9. +284
    -0
      src/components/basicSettings/list.vue
  10. +313
    -0
      src/components/codesubmit/list.vue
  11. +353
    -0
      src/components/draft/list.vue
  12. +34
    -0
      src/components/help.vue
  13. +114
    -0
      src/components/input.vue
  14. +697
    -0
      src/components/layout/homePage.vue
  15. +60
    -0
      src/components/layout/layout.vue
  16. +175
    -0
      src/components/layout/topLayout.vue
  17. +265
    -0
      src/components/login/login.vue
  18. +379
    -0
      src/components/marketing/businessComp/chooseApp.vue
  19. +234
    -0
      src/components/marketing/businessComp/chooseVersion.vue
  20. +181
    -0
      src/components/marketing/businessComp/chooseVersionRelease.vue
  21. +181
    -0
      src/components/marketing/businessComp/chooseVersioncheck.vue
  22. +320
    -0
      src/components/marketing/businessComp/extend.vue
  23. +154
    -0
      src/components/marketing/businessComp/getcategory.vue
  24. +312
    -0
      src/components/marketing/businessComp/member.vue
  25. +93
    -0
      src/components/marketing/businessComp/templateMsg.vue
  26. +175
    -0
      src/components/marketing/businessComp/versionWithdraw.vue
  27. +230
    -0
      src/components/member/list.vue
  28. +379
    -0
      src/components/release/list.vue
  29. +69
    -0
      src/components/tools/baiduMap.vue
  30. +38
    -0
      src/components/tools/uploadImg.vue
  31. +105
    -0
      src/core/comps/input/alertDialog.vue
  32. +86
    -0
      src/core/comps/input/vInput.vue
  33. +32
    -0
      src/core/comps/input/正则表达式
  34. +101
    -0
      src/core/comps/select/bottom.vue
  35. +106
    -0
      src/core/comps/select/left.vue
  36. +171
    -0
      src/core/comps/select/localSelect.vue
  37. +174
    -0
      src/core/comps/table/body.vue
  38. +102
    -0
      src/core/comps/table/header.vue
  39. +105
    -0
      src/core/comps/table/paging.vue
  40. +198
    -0
      src/core/comps/table/tableList.vue
  41. +118
    -0
      src/core/comps/upload/coverImg.vue
  42. +256
    -0
      src/core/comps/upload/coverUpload.vue
  43. +166
    -0
      src/core/comps/upload/upload.vue
  44. +264
    -0
      src/core/tool/ajaxService.js
  45. +28
    -0
      src/core/tool/alert.js
  46. +460
    -0
      src/core/tool/commonUtil.js
  47. +16
    -0
      src/core/tool/dataCache.js
  48. +104
    -0
      src/core/tool/report.js
  49. +101
    -0
      src/core/tool/validator.js
  50. +30
    -0
      src/index.html
  51. +35
    -0
      src/main.js
  52. +83
    -0
      src/router/index.js
  53. +55
    -0
      src/service/couponData/data.js
  54. +59
    -0
      src/static/css/app.css
  55. BIN
      src/static/font/iconfont.eot
  56. +87
    -0
      src/static/font/iconfont.svg
  57. BIN
      src/static/font/iconfont.ttf
  58. BIN
      src/static/font/iconfont.woff
  59. BIN
      src/static/images/login-bg.png
  60. BIN
      src/static/images/logout.png
  61. +24
    -0
      src/static/js/event.js
  62. +11
    -0
      src/store/coupon/game.js
  63. +17
    -0
      src/store/coupon/store.js
  64. +10
    -0
      src/store/index.js
  65. +17
    -0
      src/store/member/store.js
  66. +40
    -0
      src/store/topNav/store.js
  67. +116
    -0
      src/utils/config.js
  68. +11
    -0
      src/utils/validate.js
  69. +5
    -0
      typings.json
  70. +155
    -0
      webpack.config.js

+ 15
- 0
.babelrc 파일 보기

@@ -0,0 +1,15 @@

{
"presets": [
["env", { "modules": false }],
"stage-2"
],
"plugins": ["transform-runtime"],
"comments": false,
"env": {
"test": {
"presets": ["env", "stage-2"],
"plugins": ["istanbul"]
}
}
}

+ 15
- 0
.gitignore 파일 보기

@@ -0,0 +1,15 @@
node_modules
logs/*
dataCenter/build/*
!.gitkeep
node_modules/
bower_components/
tmp
.DS_Store
.idea/*
.project
dist/*
.vscode/*
dist
*.zip
debug.log

+ 3
- 0
README.md 파일 보기

@@ -0,0 +1,3 @@
git config --global http.sslVerify false

Path Intellisense

+ 17036
- 0
package-lock.json
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
파일 보기


+ 80
- 0
package.json 파일 보기

@@ -0,0 +1,80 @@
{
"name": "vue-pro",
"version": "1.7.6",
"description": "A Vue.js project",
"author": "damon05 <damon05@163.com>",
"private": true,
"scripts": {
"dev": "webpack-dev-server --open",
"build": "webpack --progress --env.Generative=true"
},
"dependencies": {
"clean-webpack-plugin": "^0.1.18",
"echarts": "^4.1.0",
"element-ui": "~2.4.8",
"moment": "^2.24.0",
"popper.js": "^1.14.1",
"q": "^1.5.1",
"vue": "^2.5.2",
"vue-baidu-map": "^0.21.11",
"vue-cropper": "^0.4.0",
"vue-router": "^3.0.1"
},
"devDependencies": {
"autoprefixer": "^7.1.2",
"babel-core": "^6.22.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-loader": "^7.1.1",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-plugin-transform-runtime": "^6.22.0",
"babel-plugin-transform-vue-jsx": "^3.5.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.3.2",
"babel-preset-stage-2": "^6.22.0",
"bootstrap": "^3.3.1",
"chalk": "^2.0.1",
"compression-webpack-plugin": "^1.1.12",
"copy-webpack-plugin": "^4.0.1",
"cross-env": "^5.1.3",
"css-loader": "^0.28.0",
"extract-text-webpack-plugin": "^3.0.0",
"file-loader": "^1.1.4",
"friendly-errors-webpack-plugin": "^1.6.1",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^2.30.1",
"install": "^0.10.4",
"jquery": "^3.3.1",
"node-notifier": "^5.1.2",
"npm": "^6.4.0",
"optimize-css-assets-webpack-plugin": "^3.2.0",
"ora": "^1.2.0",
"portfinder": "^1.0.13",
"postcss-import": "^11.0.0",
"postcss-loader": "^2.0.8",
"postcss-url": "^7.2.1",
"rimraf": "^2.6.0",
"semver": "^5.3.0",
"shelljs": "^0.7.6",
"style-loader": "^0.22.0",
"uglifyjs-webpack-plugin": "^1.1.1",
"url-loader": "^1.1.1",
"vue-loader": "^13.3.0",
"vue-style-loader": "^3.0.1",
"vue-template-compiler": "^2.5.2",
"vuex": "^3.0.1",
"webpack": "^3.6.0",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-dev-server": "^2.9.1",
"webpack-merge": "^4.1.0"
},
"engines": {
"node": ">= 6.0.0",
"npm": ">= 3.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8"
]
}

+ 123
- 0
src/App.vue 파일 보기

@@ -0,0 +1,123 @@
<template>
<div id="app">
<router-view v-if="isRouterAlive"></router-view>
</div>
</template>

<script>
import { mapState, mapActions } from "vuex";
export default {

name: 'App',
provide(){
return{
reload: this.reload
}
},
data () {
return {
isRouterAlive:true
}
},
methods:{
...mapActions(["setIndex"]),
reload () {
this.isRouterAlive = false
this.$nextTick(function(){
this.isRouterAlive =true
})
}
},
computed: {
//当前导航状态
...mapState({
topNav: state => state.topNav.data, //将 this.topNav 映射为 this.$store.topNav.data
index: state => state.topNav.index,
})
},
// created() {
// //在页面加载时读取sessionStorage里的状态信息
// if (sessionStorage.getItem("index")) {
// this.setIndex(JSON.parse(sessionStorage.getItem("index")))
// }
// //在页面刷新时将vuex里的信息保存到sessionStorage里
// window.addEventListener("beforeunload", () => {
// sessionStorage.setItem("index", JSON.stringify(this.index));
// })
// },
}

</script>

<style>

@import url('../node_modules/bootstrap/dist/css/bootstrap.min.css');
.fl{float: left;}
.fr{float: right;}
.clearfix:after {
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
text-decoration: none;
}
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
position: relative;
}
body::-webkit-scrollbar {
width: 8px;
height: 8px;
}
/*正常情况下滑块的样式*/
body::-webkit-scrollbar-thumb {
background-color: rgba(0,0,0,.05);
border-radius: 10px;
-webkit-box-shadow: inset 1px 1px 0 rgba(0,0,0,.3);
}
/*鼠标悬浮在该类指向的控件上时滑块的样式*/
body:hover::-webkit-scrollbar-thumb {
background-color: rgba(0,0,0,.2);
border-radius: 10px;
-webkit-box-shadow: inset 1px 1px 0 rgba(0,0,0,.1);
}
/*鼠标悬浮在滑块上时滑块的样式*/
body::-webkit-scrollbar-thumb:hover {
background-color: rgba(0,0,0,.4);
-webkit-box-shadow: inset 1px 1px 0 rgba(0,0,0,.1);
}
/*正常时候的主干部分*/
body::-webkit-scrollbar-track {
border-radius: 10px;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,0);
background-color: white;
}
/*鼠标悬浮在滚动条上的主干部分*/
body::-webkit-scrollbar-track:hover {
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.4);
background-color: rgba(0,0,0,.01);
}
.insight,.production,.server,.about,.case,.partner,.copy{
width: 100%;
position: relative;
}
</style>

+ 399
- 0
src/components/audit/list.vue 파일 보기

@@ -0,0 +1,399 @@
<template>
<div class="layout">
<div class="title">
<h3>审核列表</h3>
</div>
<div class="layout-content">
<el-form :inline="true" :model="ruleForm" ref="ruleForm" class="demo-form-inline" label-position="right">
<el-form-item label="审核状态" prop="auditStatus" class="fx_send">
<el-select v-model="ruleForm.auditStatus" placeholder="请选择" clearable>
<el-option v-for="(item,index) in auditStatus" :key="index" :value="item.value" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="小程序类型" prop="type" class="fx_send">
<el-select v-model="ruleForm.type" placeholder="请选择" clearable>
<el-option v-for="(item,index) in appType" :key="index" :value="item.value" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="小程序名称" prop="name" class="fx_title">
<el-input v-model="ruleForm.name" placeholder="请输入" clearable></el-input>
</el-form-item>
<el-form-item label="小程序版本号" class="fx_send">
<el-select v-model="ruleForm.userVersion" placeholder="请选择" clearable>
<el-option v-for="(item,index) in version" :key="index" :value="item.version" :label="item.version"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button class="hoverBtn" type="primary" icon="el-icon-search" size="medium" @click.stop="search"></el-button>
</el-form-item>
<div></div>
<el-form-item>
<el-button class="hoverBtn" type="primary" @click.stop="batchRelease">批量发布(8)</el-button>
</el-form-item>
<el-form-item>
<el-button class="hoverBtn" type="primary" @click.stop="batchrevertStatus">批量撤回审核</el-button>
</el-form-item>
<el-form-item>
<el-button class="hoverBtn" type="primary" @click.stop="batchsearchStatus">批量查询审核状态</el-button>
</el-form-item>
<el-form-item>
<el-button class="hoverBtn" type="primary" @click.stop="refresh">刷新</el-button>
</el-form-item>
</el-form>
</div>
<p class="lip">*注:小程序<span>撤回审核按钮</span>需要慎重使用,<span>单个帐号每天审核撤回次数最多不超过1次,一个月不超过10次。</span></p>
<table-list :ref="tk" :options="optionsTable"></table-list>
<!-- 批量发布小程序版本列表 -->
<choose-version-release :ref="tKey1" :t-key="tKey1" :cb="getShopCb"></choose-version-release>
<!-- 撤回审核版本列表 -->
<version-withdraw :ref="tKey2" :t-key="tKey2" :cb="getShopCb"></version-withdraw>
<!-- 批量查询小程序的审核状态 -->
<choose-versioncheck :ref="tKey3" :t-key="tKey2" :cb="getShopCb"></choose-versioncheck>
</div>
</template>

<script>
import alertDialog from "../../core/comps/input/alertDialog.vue";
import {mapState, mapActions} from "vuex";
import TableList from "../../core/comps/table/tableList.vue";
import { CacheData } from "./../../service/couponData/data.js";
import { configUrl } from "./../../utils/config.js";
import versionWithdraw from "./../../components/marketing/businessComp/versionWithdraw.vue";
import chooseVersionRelease from "./../../components/marketing/businessComp/chooseVersionRelease.vue";
import chooseVersioncheck from "./../../components/marketing/businessComp/chooseVersioncheck.vue";
export default {
name: 'audit',
components: {TableList,versionWithdraw,chooseVersionRelease,chooseVersioncheck},
data(){
return {
listNavKey:"checkNavKey",
tk:"checkKey",
params:"",
src: '',
version:[],
tKey2:"versionWithdraw",
tKey1:"chooseVersionRelease",
tKey3:"chooseVersioncheck",
ruleForm:{
auditStatus:"",
releaseStatus:"",
codeStatus:"",
type:"",
appId:"",
name:"",
userVersion:"",
},
optionsTable:{
actions :[
{key:"edit",val:"体验二维码(6)",action:this.goErCode,show:(item)=>{
if(item.codeStatus == 0){
return true;
}
return false;
}},
{key:"edit",val:"查询",action:this.checkStatus,show:(item)=>{
return true;
}},
{key:"edit",val:"发布(8)",action:this.goSubmit,show:(item)=>{
if(item.auditStatus == 0){
return true;
}
return false;
}},
{key:"edit",val:"撤回",action:this.auditCancel,show:(item)=>{
if((item.auditStatus == 2||item.auditStatus == 0)){
return true;
}
return false;
}}
],
map: [
{ key: "name", val: "小程序名称"},
{ key: "appId", val: "授权方appid"},
{ key:"type", val:"类型",convert:this.cAppType},
{ key:"userVersion", val:"版本号"},
{ key:"versionDesc", val:"版本描述"},
{ key:"auditStatus", val:"审核状态",convert:this.cAuditStatus},
{ key:"auditTime", val:"提交审核时间",type:"dateTime"},
{ key:"auditErrCode", val:"错误码"}
],
getUrl:()=>{
let auditStatus = this.ruleForm.auditStatus;
let type = this.ruleForm.type;
let name = this.ruleForm.name;
let userVersion = this.ruleForm.userVersion;
if(userVersion){
return configUrl.auditStatusList+"?auditStatus="+auditStatus+"&type="+type+"&name="+name+"&userVersion="+userVersion;
}else{
return configUrl.auditStatusList+"?auditStatus="+auditStatus+"&type="+type+"&name="+name;
}
},
pageOption:{
sizeKey:"pageSize",
indexKey:"pageNum",
index:1,
size:10
},
analysis:(data)=>{
return {
data:data.data.list,
count:data.data.total
};
}
}
}
},
computed:{
appType:()=>{
return CacheData.appType;
},
auditStatus:()=>{
return CacheData.auditStatus;
},
...mapState({
topNav:state=>state.topNav.data, //将 this.topNav 映射为 this.$store.topNav.data
channels:state=>state.couponStore.channels,
navigationInfo:state=>state.topNav.navigationInfo
})
},
created() {
this.setIndex("6");
},
mounted(){
//获得小程序的版本号
this.getFetch(configUrl.auditVersionList).then(res=>{
console.log(res)
this.version = res.data;
}).catch(error=>{
console.log(error);
})
},
methods:{
...mapActions([
"setIndex"
]),
//选择版本号或者小程序
getShopCb(items) {
this.shopTableData = [];
items.data.map((item, index) => {
let haveIf = false;
this.shopTableData.map((item01, index01) => {
if(item.id == item01.id) {
haveIf = true
}
})
if (haveIf == false) {
item.merchantName = item.name;
item.merchantLinkPhone = item.linkPhone
this.shopTableData.push(item);
}
})
},
//批量撤回小程序
batchrevertStatus() {
this.$refs[this.tKey2].openDialog();
},
//批量发布小程序
batchRelease(){
this.$refs[this.tKey1].openDialog();
},
//批量查询审核状态
batchsearchStatus(){
this.$refs[this.tKey3].openDialog();
},
//撤回审核
auditCancel(item){
this.getFetch(configUrl.undoCodeAudit+"?appId="+item.appId).then(res=>{
this.search();
this.$message({
type:"success",
message:"撤回审核成功"
})
}).catch(err=>{
console.log(err)
if(typeof(err.data)=="string"){
var errcode = JSON.parse(err.data).errcode;
}else{
var errcode = err.data.errcode;
console.log(typeof(err.data))
}
if(errcode == 0){
this.$message({
type: "error",
message: "系统繁忙"
});
}else if(errcode == -1){
this.$message({
type: "error",
message: "系统繁忙"
});
}else if(errcode == 87013){
this.$message({
type: "error",
message: "撤回次数达到上限(每天一次,每个月10次)"
});
}else if(errcode == 45009){
this.$message({
type: "error",
message: "公众号接口访问次数到达了上限"
});
}
})
},
//发布单个小程序
goSubmit(item){
this.getFetch(configUrl.releaseAudited+"?appId="+item.appId).then(res=>{
console.log(res);
this.$message({
type: "success",
message: "小程序发布成功"
});
this.search();
}).catch(err=>{
console.log(err)
this.$message({
type: "error",
message: err.data
});
})
},
//查看审核状态
checkStatus(item){
this.getFetch(configUrl.getLatestAuditstatus+"?appId="+item.appId).then(res=>{
console.log(res);
this.$message({
type: "success",
message: "查询状态成功"
});
this.search();
}).catch(err=>{
console.log(err)
this.$message({
type: "error",
message: err.data
});
})
},
//刷新
refresh(){
this.search();
},
search:function(){
let tk = this.$refs[this.tk];
tk.search(tk.getParams().index);
},
//小程序提交审核
submitcheck: function (item) {
let parmer = {
apps:item.appId,
userVersion:item.userVersion
}
this.postFetch(configUrl.batchCodeAudit,parmer).then(res=>{
this.$message({
type: "success",
message:"提交审核成功"
})
}).catch(error=>{
console.log(error)
this.$message({
type: "error",
message:error.data
})
})
},
//小程序的类型
cAppType(col, item) {
console.log(item)
let res = CacheData.appType.filter(e => {
return e.value == item.type;
})[0];
console.log(res)
if (res) {
return res.name;
} else {
console.log("error:异常券id:", item.id);
return "";
}
return res.name;
},
//小程序审核状态
cAuditStatus(col, item){
console.log(item)
let res = CacheData.auditStatus.filter(e => {
return e.value == item.auditStatus;
})[0];
console.log(res)
if (res) {
return res.name;
} else {
return "";
}
return res.name;
},
},
}
</script>
<style scoped>
.lip{
padding-top: 30px;
}
.lip span{
color: red;
}
.title{
margin-bottom: 10px;
}
.title h3{
font-size: 18px;
font-weight: bold;
}
.content span{
font-size: 15px;
}
.content span:nth-of-type(1){
color: #19ce00;
font-weight:bold;
margin-right: 20px;
}
.content span:nth-of-type(2){
margin-right: 20px;
cursor: pointer;
}
.layout-content{
margin-top: 20px;
background: #f6f6f6;
padding: 29px 20px 0;
border-radius:6px;
}
.el-select-dropdown__item{
display: block;
}
.tableContainer{
width: 100%;
margin-top: 23px;
}
</style>
<style>
.el-message-box{
width:300px;
padding:0 0 20px;
}
.el-message-box img{
width:200px;
height: 200px;
display:block;
margin:0 auto;
}
.el-message-box__header{
text-align:center;
font-size:14px!important;
}
.el-message-box__btns button{
width:100px!important;
}
.el-message-box__title{
font-size:16px;
}
</style>


+ 33
- 0
src/components/authHOC/authHoc.js 파일 보기

@@ -0,0 +1,33 @@

import Util from "../../core/tool/commonUtil.js";

function AuthHOC(Component){
return {
mounted (){
},
props:Component.props,
render(h){
let uname = Util.cookie.getCookie("uname");
if(!uname){
this.$router.push({path:"/login"});
return h();
}
const slots = Object.keys(this.$slots);
slots.reduce((arr, key) => arr.concat(this.$slots[key]), [])
.map(vnode => {
vnode.context = this._self
return vnode
})
return h(Component,{
on: this.$listeners,
props: this.$props,
scopedSlots: this.$scopedSlots,
attrs: this.$attrs
},slots)
}
}
}

export default AuthHOC

+ 284
- 0
src/components/basicSettings/list.vue 파일 보기

@@ -0,0 +1,284 @@
<template>
<div class="layout server">
<div class="title">
<h3>基础设置</h3>
</div>
<div class="content" v-for="(item, index) in set" :key="index">
<el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="162px" class="demo-ruleForm sever" label-position="right">
<h3 v-if="item.type == 1">B端</h3>
<h3 v-if="item.type == 2">C端</h3>
<div>
<div class="sever">
<h3>服务器域名配置</h3>
<div class="layout-content wdbFormBox wdbFormBox1">
<el-form-item label="request 合法域名" prop="subTitle">
<span>{{item.domainUrl.url.requestdomain}}</span>
</el-form-item>
<el-form-item label="socket 合法域名" prop="subTitle">
<span>{{item.domainUrl.url.wsrequestdomain}}</span>
</el-form-item>
<el-form-item label="uploadFile 合法域名" prop="subTitle">
<span>{{item.domainUrl.url.uploaddomain}}</span>
</el-form-item>
<el-form-item label="downloadFile 合法域名" prop="subTitle">
<span>{{item.domainUrl.url.downloaddomain}}</span>
</el-form-item>
</div>
</div>
<div class="sever">
<h3>业务域名配置</h3>
<div class="layout-content wdbFormBox wdbFormBox1">
<div class="edit-item" v-for="(yewuitemUrl,index) in item.domainUrl.web" :key="index">
<el-form-item label="合法业务域名" prop="subTitle">
<span>{{yewuitemUrl}}</span>
</el-form-item>
</div>
</div>
</div>
<div class="sever">
<h3>版本号</h3>
<div class="layout-content wdbFormBox wdbFormBox1">
<div class="edit-item">
<el-form-item label="基础库版本号" prop="subTitle">
<span>{{item.version}}</span>
</el-form-item>
</div>
</div>
</div>
</div>
</el-form>
</div>
</div>
</template>
<script>
import TableList from "./../../core/comps/table/tableList.vue";
import commonUtil from './../../core/tool/commonUtil';
import { configUrl } from "./../../utils/config.js";
import { mapState, mapActions } from "vuex";

export default {
name: 'server',
components: {TableList},
data () {
return {
data:[],
set:[],
ruleForm: {
version: "",
},
rules:{
subTitle: [
{
min: 1,
max: 50,
message: "副标题最大50个字符!",
trigger: "blur"
}
],
}
}
},
computed:{
sendMethods:()=>{
return CouponCacheData.sendMethods;
},
...mapState({
topNav:state=>state.topNav.data, //将 this.topNav 映射为 this.$store.topNav.data
channels:state=>state.couponStore.channels,
index:state=>state.topNav.index
})
},
methods:{
...mapActions([
"setIndex"
]),
addCol(){
this.data.push({points:"",level:"",description:"",discountEnable:0});
},
delItem(item){
if(item.points == "" && item.level == "" ){
this.data = commonUtil.arrayServer.removeItems(this.data,[item]);
return;
}
this.showConfirm("是否删除?",(d)=>{
this.postFetch(MemberUrl.CZZ.LEVEL.DELETE,{id:item.id}).then(d=>{
this.showAlertMsg();
this.data = commonUtil.arrayServer.removeItems(this.data,[item]);
})
})
},
},
mounted(){
this.getFetch(configUrl.weappBasicSetList+"?pageNum=1&pageSize=100").then(res=>{
this.set = res.data.list;
this.set.map(file=>{
file.domainUrl = JSON.parse(file.domainUrl);
console.log(file.domainUrl)
})
}).catch(err=>{
console.log(err);
})
},
created() {
this.setIndex("2");
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.sever{
border-radius: 4px;
border:1px solid #e7e7eb;
padding: 0 20px 10px;
margin-bottom: 20px;
}
.content{
width: 630px;
margin: 30px 0;
}
.title{
margin-bottom: 10px;
}
.title h3{
font-size: 18px;
font-weight: bold;
}
.layout-content{
background: #fff;
overflow: hidden;
}
.btn-group{
text-align: center;
margin-top: 26px;
}
.layout-content table{
width:100%;
}
.layout-content table tr td{
padding:17px 0;
text-align:left;
}
.layout-content table tr td:nth-child(1){
padding:17px 0 17px 18px;
width:200px;
text-align:center;
}
.layout-content table tr td:nth-child(2){
padding:17px 15px;
width:10px;
text-align:center;
}
.layout-content table tr td:nth-child(3){
padding:17px 10px 17px 0;
width:180px;
text-align:center;
}
.layout-content table tr td:nth-child(4){
padding:17px 10px;
width:240px;
text-align:center;
}
.layout-content table tr td:nth-child(5){
padding:17px 10px;
text-align:left;
}
.layout-content table tr:hover{
cursor:pointer;
background:#F4F7F9;
}

.editBox,.delBox{
width:40px;
height:40px;
text-align:center;
line-height:40px;
display:inline-block;
color:#fff;
font-size:14px;
border-radius:3px;
margin-right:20px;
display:none;
}
.editBox{
background:#51A9C9;
}
.delBox{
background:#EE7653;
}
.layout-content table tr:hover .editBox{
display:inline-block;
}
.layout-content table tr:hover .delBox{
display:inline-block;
}
.btnGroupBox{
margin-top:20px;
}
.addBox{
width:146px;
height:40px;
text-align:center;
line-height:40px;
display:inline-block;
color:#fff;
font-size:14px;
border-radius:3px;
margin-right:20px;
background:#6B5EC9;
cursor:pointer;
}

.addBox i{
margin-right:5px;
}
.saveBox{
width:91px;
height:40px;
text-align:center;
line-height:40px;
display:block;
color:#fff;
font-size:14px;
border-radius:3px;
background:#409EFF;
margin: 0 auto!important;
cursor:pointer;
}
.addBox:hover{
background:#7A6CE1;
}
.addBox:active{
background:#6357BB;
}
.editBox:hover{
background:#5DC1E5;
}
.editBox:active{
background:#4490AB;
}
.saveBox:hover{
background:#5DC1E5;
}
.saveBox:active{
background:#4490AB;
}
.delBox:hover{
background:#FF8460;
}
.delBox:active{
background:#DF6F4E;
}
</style>
<style>

.save{
display: block;
width:90px;
margin:0 auto;
}
.tips{
color:red;
text-align:center;
margin-top:10px;
}
</style>

+ 313
- 0
src/components/codesubmit/list.vue 파일 보기

@@ -0,0 +1,313 @@
<template>
<div class="layout">
<div class="title">
<h3>code提交列表</h3>
</div>
<div class="layout-content">
<el-form :inline="true" :model="ruleForm" ref="ruleForm" class="demo-form-inline" label-position="right">
<el-form-item label="提交状态" prop="codeStatus" class="fx_send">
<el-select v-model="ruleForm.codeStatus" placeholder="请选择" clearable>
<el-option v-for="(item,index) in codestate" :key="index" :value="item.value" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="小程序类型" prop="type" class="fx_send">
<el-select v-model="ruleForm.type" placeholder="请选择" clearable>
<el-option v-for="(item,index) in appType" :key="index" :value="item.value" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="小程序名称" prop="name" class="fx_title">
<el-input v-model="ruleForm.name" placeholder="请输入" clearable></el-input>
</el-form-item>
<el-form-item label="小程序版本号" class="fx_send">
<el-select v-model="ruleForm.userVersion" placeholder="请选择" clearable>
<el-option v-for="(item,index) in version" :key="index" :value="item.version" :label="item.version"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button class="hoverBtn" type="primary" icon="el-icon-search" size="medium" @click.stop="search"></el-button>
</el-form-item>
<el-form-item>
<el-button class="hoverBtn" type="primary" @click.stop="reviewApp('reviewApp')">批量提交小程序审核(7)</el-button>
</el-form-item>
<el-form-item>
<el-button class="hoverBtn" type="primary" @click.stop="refresh">刷新</el-button>
</el-form-item>
</el-form>
</div>
<table-list :ref="tk" :options="optionsTable"></table-list>
<choose-app :params="params" :ref="tKey" :t-key="tKey" :cb="getShopCb"></choose-app>
</div>
</template>

<script>
import {mapState, mapActions} from "vuex";
import TableList from "../../core/comps/table/tableList.vue";
import { CacheData } from "./../../service/couponData/data.js";
import { configUrl } from "./../../utils/config.js";
import chooseApp from "./../../components/marketing/businessComp/chooseApp.vue";
export default {
name: 'codesubmit',
components: {TableList,chooseApp},
data(){
return {
listNavKey:"codesubmitNavKey",
tk:"codesubmitKey",
paramers:"",
params:"",
src: '',
version:[],
tKey: "chooseApp",
ruleForm:{
auditStatus:"",
releaseStatus:"",
codeStatus:"",
type:"",
appId:"",
name:"",
userVersion:"",
},
optionsTable:{
actions :[
{key:"edit",val:"体验版二维码(6)",action:this.goErCode,show:(item)=>{
if(item.codeStatus == 0){
return true;
}
return false;
}},
{key:"edit",val:"提交审核(7)",action:this.submitcheck,show:(item)=>{
if(item.codeStatus == 0){
return true;
}
return false;
}},
],
map: [
{ key: "name", val: "小程序名称"},
{ key: "appId", val: "授权方appid"},
{ key:"type", val:"小程序类型",convert:this.cAppType},
{ key:"userVersion", val:"版本号"},
{ key:"versionDesc", val:"版本描述"},
{ key:"codeStatus", val:"code提交状态",convert:this.codeStatus},
{ key:"codeTime", val:"code提交时间",type:"dateTime"},
{ key:"codeErrCode", val:"错误码"}
],
getUrl:()=>{
let codeStatus = this.ruleForm.codeStatus;
let type = this.ruleForm.type;
let name = this.ruleForm.name;
let userVersion = this.ruleForm.userVersion;
if(this.ruleForm.userVersion){
return configUrl.codeStatusList+"?codeStatus="+codeStatus+"&type="+type+"&name="+name+"&userVersion="+userVersion;
}else if(this.ruleForm.userVersion == ""){
return configUrl.codeStatusList+"?codeStatus="+codeStatus+"&type="+type+"&name="+name;
}
},
pageOption:{
sizeKey:"pageSize",
indexKey:"pageNum",
index:1,
size:10
},
analysis:(data)=>{
// data.data.list.map(file=>{
// if(file.codeErrCode=='{"errcode":"0","errmsg":"ok"}'){
// file.codeErrCode =""
// }
// })
return {
data:data.data.list,
count:data.data.total
};
}
}
}
},
computed:{
appType:()=>{
return CacheData.appType;
},
codestate:()=>{
return CacheData.codeStatus;
},
...mapState({
topNav:state=>state.topNav.data, //将 this.topNav 映射为 this.$store.topNav.data
channels:state=>state.couponStore.channels,
navigationInfo:state=>state.topNav.navigationInfo
})
},
created() {
this.setIndex("7");
},
mounted(){
//获得小程序的版本号
this.getFetch(configUrl.codeVersionList).then(res=>{
console.log(res)
this.version = res.data;
}).catch(error=>{
console.log(error);
})
},
methods:{
...mapActions([
"setIndex"
]),
//选择小程序
getShopCb(items) {
this.shopTableData = [];
items.data.map((item, index) => {
let haveIf = false;
this.shopTableData.map((item01, index01) => {
if(item.id == item01.id) {
haveIf = true
}
})
if (haveIf == false) {
item.merchantName = item.name;
item.merchantLinkPhone = item.linkPhone
this.shopTableData.push(item);
}
})
},
//批量提交小程序审核
reviewApp(item) {
let items = {
from:item
}
console.log(items)
this.$refs[this.tKey].openDialog(JSON.stringify(items));
},
//刷新
refresh(){
this.search();
},
search:function(){
let tk = this.$refs[this.tk];
tk.search(tk.getParams().index);
},
goErCode: function (item) {
let weiXinUrl = configUrl.getQrcode+"?appId="+item.appId+'&pagePath='+'pages/index/index';
        this.$alert("<strong><img src="+ weiXinUrl + " width=100px height=100px></strong>", item.name+'体验版', {
          dangerouslyUseHTMLString: true,
closeOnClickModal:true,
showConfirmButton:true,
showClose:false,
center:true
        })
},
//小程序提交审核
submitcheck: function (item) {
let parmer = {
apps:item.appId,
userVersion:item.userVersion
}
this.postFetch(configUrl.batchCodeAudit,parmer).then(res=>{
console.log(res)
this.search();
this.$message({
type: "success",
message:"提交审核成功"
})
}).catch(error=>{
console.log(error)
this.search();
this.$message({
type: "error",
message:error.data
})
})
},
//小程序的类型
cAppType(col, item) {
console.log(item)
let res = CacheData.appType.filter(e => {
return e.value == item.type;
})[0];
console.log(res)
if (res) {
return res.name;
} else {
console.log("error:异常券id:", item.id);
return "";
}
return res.name;
},
//code提交状态
codeStatus(col, item){
console.log(item)
let res = CacheData.codeStatus.filter(e => {
return e.value == item.codeStatus;
})[0];
console.log(res)
if (res) {
return res.name;
} else {
return "";
}
return res.name;
},
},
}
</script>
<style scoped>
.lip{
padding-top: 30px;
}
.lip span{
color: red;
}
.title{
margin-bottom: 10px;
}
.title h3{
font-size: 18px;
font-weight: bold;
}
.content span{
font-size: 15px;
}
.content span:nth-of-type(1){
color: #19ce00;
font-weight:bold;
margin-right: 20px;
}
.content span:nth-of-type(2){
margin-right: 20px;
cursor: pointer;
}
.layout-content{
margin-top: 20px;
background: #f6f6f6;
padding: 29px 20px 0;
border-radius:6px;
}
.el-select-dropdown__item{
display: block;
}
.tableContainer{
width: 100%;
margin-top: 23px;
}
</style>
<style>
.el-message-box{
width:300px;
padding:0 0 20px;
}
.el-message-box img{
width:200px;
height: 200px;
display:block;
margin:0 auto;
}
.el-message-box__header{
text-align:center;
font-size:14px!important;
}
.el-message-box__btns button{
width:100px!important;
}
.el-message-box__title{
font-size:16px;
}
</style>


+ 353
- 0
src/components/draft/list.vue 파일 보기

@@ -0,0 +1,353 @@
<template>
<div class="layout server">
<div class="title">
<h3>草稿/模板</h3>
</div>
<el-button type="primary" @click="refresh">刷新</el-button>
<div class="content">
<div>
<h3 class="h3">草稿</h3>
<table-list :ref="tk1" :options="optionsTable1"></table-list>
<alert-dialog ref="alertDialogKey"></alert-dialog>
</div>
<div>
<h3 class="h3">模板</h3>
<table-list :ref="tk2" :options="optionsTable2"></table-list>
<alert-dialog ref="alertDialogKey"></alert-dialog>
</div>
</div>
<choose-app :params="params" :ref="tKey" :t-key="tKey" :cb="getShopCb"></choose-app>
</div>
</template>
<script>

import TableList from "./../../core/comps/table/tableList.vue";
import { configUrl } from "./../../utils/config.js";
import { mapState, mapActions } from "vuex";
import moment from 'moment';
import alertDialog from "../../core/comps/input/alertDialog.vue";
import commonUtil from './../../core/tool/commonUtil';
import chooseApp from "./../../components/marketing/businessComp/chooseApp.vue";
export default {
name: 'draft',
components: {TableList,alertDialog,chooseApp},
data () {
return {
data:[],
tk1:"draftTableKey1",
tk2:"draftTableKey2",
tKey: "chooseApp",
params:"",
draft:"draft",
ruleForm: {
//副标题
subTitle: "",
},
rules:{
subTitle: [
{
min: 1,
max: 50,
message: "副标题最大50个字符!",
trigger: "blur"
}
],
},
optionsTable1:{
actions :[
{key:"edit",val:"转为模板(4)",action:this.addToTemplate}
],
map:[
{key:"draftId",val:"草稿ID"},
{key:"userVersion",val:"版本号"},
{key:"createTime",val:"创建时间",type:'dateTime'},
{key:"userDesc",val:"版本描述"},
],
getUrl:()=>{
return configUrl.tempDraftList;
},
pageOption:{
showIf:false,
sizeKey:"pageSize",
indexKey:"pageNum",
index:1,
size:10
},
analysis:(res)=>{
res.data.map((item,index)=>{
item.createTime=Number(item.createTime)*1000
})
return {
data:res.data,
count:res.data.total
};
}
},
optionsTable2:{
actions :[
{key:"edit",val:"删除",action:this.goDelete},
{key:"edit",val:"提交(5)",action:this.choseAPP},
],
map:[
{key:"templateId",val:"模板ID"},
{key:"userVersion",val:"版本号"},
{key:"createTime",val:"创建时间",type:'dateTime'},
{key:"userDesc",val:"版本描述"}
],
getUrl:()=>{
return configUrl.getTempList;
},
pageOption:{
showIf:false,
sizeKey:"pageSize",
indexKey:"pageNum",
index:1,
size:10,
},
analysis:(res)=>{
res.data.map((item,index)=>{
item.createTime=Number(item.createTime)*1000
})
return {
data:res.data,
count:res.data.total
};
}
}
}
},
computed:{
...mapState({
topNav:state=>state.topNav.data, //将 this.topNav 映射为 this.$store.topNav.data
channels:state=>state.couponStore.channels,
index:state=>state.topNav.index
})
},
methods:{
...mapActions([
"setIndex"
]),
//选择小程序
choseAPP(item) {
console.log(item)
this.params = JSON.stringify(item);
this.$refs[this.tKey].openDialog(this.params);
},
//选择小程序
getShopCb(items) {
this.shopTableData = [];
items.data.map((item, index) => {
let haveIf = false;
this.shopTableData.map((item01, index01) => {
if(item.id == item01.id) {
haveIf = true
}
})
if (haveIf == false) {
item.merchantName = item.name;
item.merchantLinkPhone = item.linkPhone
this.shopTableData.push(item);
}
})
},
//删除模板
goDelete(item) {
this.$refs['alertDialogKey'].openDialog("此操作会删除草稿, 是否继续?",() => {
let params = { templateId: item.templateId}
this.postFetch(configUrl.deleteTemplate, params).then(d => {
this.showAlertMsg("success", '操作成功!');
this.search();
})
});
},
//将草稿转为模板
addToTemplate(item) {
this.$refs['alertDialogKey'].openDialog("此操作会将草稿转为模板, 是否继续?",() => {
let params = { draftId: item.draftId};
this.postFetch(configUrl.addToTemplate, params).then(d => {
this.showAlertMsg("success", '操作成功!');
this.search();
})
})
},
search:function(){
let tk1 = this.$refs[this.tk1];
let tk2 = this.$refs[this.tk2];
tk1.search(tk1.getParams().index);
tk2.search(tk2.getParams().index);
},
//刷新
refresh(){
//更新草稿列表
//更新模板列表
this.search();
}
},
mounted(){
},
created() {
this.setIndex("3");
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.tableContainer{
width: 100%;
margin-top: 30px;
}
.h3{
font-size: 16px;
}
.sever{
border-radius: 4px;
border:1px solid #e7e7eb;
padding: 0 20px 10px;
margin-bottom: 20px;
}
.title{
margin-bottom: 10px;
}
.title h3{
font-size: 18px;
font-weight: bold;
}
.layout-content{
background: #fff;
overflow: hidden;
}
.btn-group{
text-align: center;
margin-top: 26px;
}
.layout-content table{
width:100%;
}
.layout-content table tr td{
padding:17px 0;
text-align:left;
}
.layout-content table tr td:nth-child(1){
padding:17px 0 17px 18px;
width:200px;
text-align:center;
}
.layout-content table tr td:nth-child(2){
padding:17px 15px;
width:10px;
text-align:center;
}
.layout-content table tr td:nth-child(3){
padding:17px 10px 17px 0;
width:180px;
text-align:center;
}
.layout-content table tr td:nth-child(4){
padding:17px 10px;
width:240px;
text-align:center;
}
.layout-content table tr td:nth-child(5){
padding:17px 10px;
text-align:left;
}
.layout-content table tr:hover{
cursor:pointer;
background:#F4F7F9;
}

.editBox,.delBox{
width:40px;
height:40px;
text-align:center;
line-height:40px;
display:inline-block;
color:#fff;
font-size:14px;
border-radius:3px;
margin-right:20px;
display:none;
}
.editBox{
background:#51A9C9;
}
.delBox{
background:#EE7653;
}
.layout-content table tr:hover .editBox{
display:inline-block;
}
.layout-content table tr:hover .delBox{
display:inline-block;
}
.btnGroupBox{
margin-top:20px;
}
.addBox{
width:146px;
height:40px;
text-align:center;
line-height:40px;
display:inline-block;
color:#fff;
font-size:14px;
border-radius:3px;
margin-right:20px;
background:#6B5EC9;
cursor:pointer;
}

.addBox i{
margin-right:5px;
}
.saveBox{
width:91px;
height:40px;
text-align:center;
line-height:40px;
display:block;
color:#fff;
font-size:14px;
border-radius:3px;
background:#51A9C9;
margin: 0 auto!important;
cursor:pointer;
}
.addBox:hover{
background:#7A6CE1;
}
.addBox:active{
background:#6357BB;
}
.editBox:hover{
background:#5DC1E5;
}
.editBox:active{
background:#4490AB;
}
.saveBox:hover{
background:#5DC1E5;
}
.saveBox:active{
background:#4490AB;
}
.delBox:hover{
background:#FF8460;
}
.delBox:active{
background:#DF6F4E;
}
</style>
<style>
.save{
display: block;
width:90px;
margin:0 auto;
}
.tips{
color:red;
text-align:center;
margin-top:10px;
}
</style>

+ 34
- 0
src/components/help.vue 파일 보기

@@ -0,0 +1,34 @@
<template>
<el-popover
placement="top-start"
:title="title"
width="200"
trigger="hover"
:content="content">
<i class="el-icon-question" slot="reference"></i>
</el-popover>
</template>

<script>
export default {
name: 'help',
props:['title','content'],
data () {
return {
}
},
methods:{

},
mounted:function () {
},
created(){
}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

+ 114
- 0
src/components/input.vue 파일 보기

@@ -0,0 +1,114 @@
<template>
<div>
<div class="second-level">
<h1>满减券</h1>
<ul class="tab-list">
<li>全部</li>
<li class="active">草稿箱</li>
<li>待生效</li>
<li>已生效</li>
<li>已失效</li>
<li>已作废</li>
</ul>
</div>
<!-- <v-input :ref="name" error-msg="请输入数字" :v-type="num"></v-input>
<button @click="submit">提交</button>
<div>
<local-select ref='localSelectId' :data="selectData" :analysis="analysis"></local-select>
<input type="button" value="getSelectedItems" @click="getSelectedItems" />
</div> -->
</div>
</template>
<script>
import AjaxUtil from "../core/tool/ajaxService";
import Util from "../core/tool/commonUtil";
import LocalSelect from "../core/comps/select/localSelect.vue";
import VInput from "../core/comps/input/vInput.vue"

export default {
extends:AjaxUtil,
components: {LocalSelect,VInput},
name: "Login",
data(){
return {
selectData:[],
num:"number",
name:"name"
}
},
methods:{
analysis:function(data){
let res = [];
data.forEach(item => {
res.push({name:item.name,code:item._id});
});
return res;
},
getSelectData:function(){
this.getFetch("/api/person/list").then(d=>{
this.selectData = d.data.data;
})
},
getSelectedItems:function(){
console.log(this.$refs['localSelectId'].getSelectedItems());
},
submit(){
console.log(this.$refs[this.name].getResult());
}
},
mounted:function () {
this.getSelectData();
},
created(){

}
}
</script>
<style scoped>
.inputRedIcon input{border-right: 0;border-color: red;outline: none;}
.inputRedIcon div span.icon{background: #fff;border-color: red;color: red;}
.inputRedIcon p{color: red;}


.inputGreenIcon input{border-right: 0;}
.inputGreenIcon div span.icon{background: #fff;font-size: 16px;color: rgb(72, 255, 0);}
.inputGreenIcon p{display: none}

.inputIcon{border-right: 0;}

.second-level{
min-height: 60px;
background: #fff;
padding: 0 32px;
box-sizing: border-box;
}
.second-level h1{
color:rgba(0,0,0,0.85);
font-size: 20px;
text-align: left;
line-height: 60px;
margin: 0;
padding: 0;
}

.second-level .tab-list{
list-style: none;
line-height: 42px;
overflow: hidden;
padding: 0;
margin: 0;
}
.second-level .tab-list li{
float: left;
font-size: 14px;
color:rgba(0,0,0,0.65);
padding:0 10px;
margin: 0 10px
}

.second-level .tab-list .active{
color: rgba(24,144,255,1);
border-bottom: 2px solid rgba(24,144,255,1);
}
</style>

+ 697
- 0
src/components/layout/homePage.vue 파일 보기

@@ -0,0 +1,697 @@
<template>
<div class="layout">
<div class="title">
<h3>授权链接</h3>
</div>
<div class="content">
<a href="/O/wt_auth/goto_auth_url" target="_blank">获取授权(1)</a>
</div>
<div class="layout-content">
<el-form :inline="true" :model="ruleForm" ref="ruleForm" class="demo-form-inline" label-position="right">
<el-form-item label="授权状态" prop="authorizationStatus" class="fx_send">
<el-select v-model="ruleForm.authorizationStatus" placeholder="请选择" clearable>
<el-option v-for="(item,index) in authorizationStatus" :key="index" :value="item.value" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="小程序名称" prop="name" class="fx_title">
<el-input v-model="ruleForm.name" placeholder="请输入" clearable></el-input>
</el-form-item>
<el-form-item label="小程序类型" prop="type" class="fx_send">
<el-select v-model="ruleForm.type" placeholder="请选择" clearable>
<el-option v-for="(item,index) in appType" :key="index" :value="item.value" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button class="hoverBtn" type="primary" icon="el-icon-search" size="medium" @click.stop="search"></el-button>
</el-form-item>
<el-form-item>
<el-button class="hoverBtn" type="primary" @click.stop="batchBasicSet">批量基础配置(2)</el-button>
</el-form-item>
<el-form-item>
<el-button class="hoverBtn" type="primary" @click.stop="batchExtendSet">批量扩展配置</el-button>
</el-form-item>
<el-form-item>
<el-button class="hoverBtn" type="primary" @click.stop="getAuthorizerList">拉取已授权帐号信息</el-button>
</el-form-item>
</el-form>
</div>
<table-list :ref="tk" :options="optionsTable"></table-list>
<choose-app :ref="tKey" :t-key="tKey" :cb="getShopCb"></choose-app>
<extend :ref="tKey1" :t-key="tKey1"></extend>
<getcategory :ref="tKey2" :t-key="tKey2"></getcategory>
<template-msg :ref="tKey3" :t-key="tKey3"></template-msg>
</div>
</template>
<script>
import { mapState, mapActions } from "vuex";
import TableList from "../../core/comps/table/tableList.vue";
import { CacheData } from "./../../service/couponData/data.js";
import { configUrl } from "./../../utils/config.js";
import alertDialog from "../../core/comps/input/alertDialog.vue";
import extend from "./../../components/marketing/businessComp/extend.vue";
import templateMsg from "./../../components/marketing/businessComp/templateMsg.vue";
import chooseApp from "./../../components/marketing/businessComp/chooseApp.vue";
import getcategory from "./../../components/marketing/businessComp/getcategory.vue";
export default {
name: "HomePage",
components: {
TableList,
alertDialog,
extend,
chooseApp,
getcategory,
templateMsg
},
data() {
return {
listNavKey: "homePageNavKey",
tk: "homePageKey",
tKey: "extendApp",
tKey1: "extend",
tKey2: "getcategory",
tKey3: "templateMsgList",
dialogVisible: false,
privacySetting:"",
latestAuditstatus:"",
ruleForm: {
authorizationStatus: "",
type: "",
name: ""
},
optionsTable: {
actions: [
{
key: "edit",
val: "配置隐私保护指引",
action: this.setprivacysetting,
show: item => {
return (item.type == 1 || item.type == 2)&&item.privacySettingStatus!=0 ? true : false;
}
},
{
key: "edit",
val: "查询隐私保护指引",
action: this.getPrivacySetting,
show: item => {
return (item.type == 1 || item.type == 2)&&item.privacySettingStatus==0 ? true : false;
}
},
// {
// key: "edit",
// val: "查询最新审核状态",
// action: this.getLatestAuditstatus,
// },
{
key: "edit",
val: "基础",
action: this.searchFigure,
show: item => {
return item.type == 1 || item.type == 2 ? true : false;
}
},
{
key: "edit",
val: "扩展(3)",
action: this.conFigure,
show: item => {
return item.type == 1 || item.type == 2 ? true : false;
}
},
{
key: "edit",
val: "类目",
action: this.getCategory,
show: item => {
return item.type == 1 || item.type == 2 ? true : false;
}
},
{
key: "delete",
val: "模板列表",
action: this.templateList,
show: item => {
return item.type == 1 || item.type == 2 ? true : false;
}
},
{
key: "edit",
val: "创建O",
action: this.createPlatform,
show: item => {
return (item.type == 3)&&(!item.openAppid) || (item.type == 4)&&(!item.openAppid) ? true : false;
}
},
{
key: "bind",
val: "绑定O",
action: this.bindPlatform,
show: item => {
return (item.type == 1)&&(!item.openAppid) || (item.type == 2)&&(!item.openAppid) ? true : false;
}
},
{
key: "unbind",
val: "解绑O",
action: this.unbindPlatform,
show: item => {
return item.type == 1 || item.type == 2 ? true : false;
}
},
{
key: "edit",
val: "获取O",
action: this.getPlatform,
show: item => {
return (item.type == 1)&&(!item.openAppid) || (item.type == 2)&&(!item.openAppid) ? true : false;
}
},
{
key: "edit",
val: "重置Quota",
action: this.clearQuota,
show: item => {
return item.type == 3 || item.type == 4 ? true : false;
}
}
],
map: [
{ key: "headImg", val: "小程序图标", etype: "img" },
{ key: "name", val: "小程序名称" },
{ key: "type", val: "类型", convert: this.cAppType },
{ key: "currentVersion", val: "当前发布版本" },
{ key: "authorizerAppid", val: "appid" },
{
key: "authorizationStatus",
val: "授权状态",
convert: this.authStatus
},
{ key: "baseStatus", val: "基础版本状态", convert: this.baseStatus },
{
key: "domainStatus",
val: "服务器域名状态",
convert: this.domainStatus
},
{
key: "webdomainStatus",
val: "业务域名状态",
convert: this.webdomainStatus
},
{
key: "templateStatus",
val: "模板消息状态",
convert: this.templateStatus
},
{
key: "privacySettingStatus",
val: "用户隐私状态",
convert: this.setPrivacySettingStatus
},
{
key: "openAppid",
val: "开放平台AppId"
}
],
getUrl: () => {
let type = this.ruleForm.type;
let authorizationStatus = this.ruleForm.authorizationStatus;
let name = this.ruleForm.name;
return (
configUrl.weappList +
"?type=" +
type +
"&authorizationStatus=" +
authorizationStatus +
"&name=" +
name
);
},
pageOption: {
sizeKey: "pageSize",
indexKey: "pageNum",
index: 1,
size: 10
},
analysis: res => {
return {
data: res.data.list,
count: res.data.total
};
}
}
};
},
computed: {
appType: () => {
return CacheData.appType;
},
authorizationStatus: () => {
return CacheData.authorizationStatus;
},
...mapState({
topNav: state => state.topNav.data, //将 this.topNav 映射为 this.$store.topNav.data
channels: state => state.couponStore.channels,
navigationInfo: state => state.topNav.navigationInfo
})
},
methods: {
//
setprivacysetting(item){
console.log(item);
this.postFetch("/O/weappSet/setprivacysetting",{appId:item.authorizerAppid}).then(res=>{
console.log(res,"res");
this.search()
}).catch(error => {
this.$message({
type: "error",
message: error.data
});
});
},
getPrivacySetting(item){
this.getFetch(`/O/weappSet/getPrivacySetting?appId=${item.authorizerAppid}`).then(res=>{
this.privacySetting = JSON.stringify(res.data)

this.$confirm( this.privacySetting,"查询隐私保护指引",{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$message({
type: 'success',
message: '确定'
});
}).catch(() => {
this.$message({
type: 'info',
message: '取消'
});
});
}).catch(error => {
this.$message({
type: "error",
message: error.data
});
});
},
getLatestAuditstatus(item){
this.getFetch(`/O/weappCode/getLatestAuditstatus?appId=${item.authorizerAppid}`).then(res=>{
this.latestAuditstatus = JSON.stringify(res.data)
this.$confirm( this.latestAuditstatus,"查询隐私保护指引",{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$message({
type: 'success',
message: '确定'
});
}).catch(() => {
this.$message({
type: 'info',
message: '取消'
});
});
}).catch(error => {
this.$message({
type: "error",
message: error.data
});
});
},
//拉取当前所有已授权的帐号基本信息
getAuthorizerList: function() {
this.getFetch(configUrl.getAuthorizerList)
.then(res => {
console.log(res);
this.$message({
type: "success",
message: "拉取当前所有已授权的帐号基本信息成功"
});
})
.catch(error => {
this.$message({
type: "error",
message: error.data
});
});
},

//获得模板列表
templateList(item) {
console.log(item);
let parmers = JSON.stringify({
appId: item.authorizerAppid
});
this.$refs[this.tKey3].openDialog(parmers);
},

//批量扩展配置
batchExtendSet() {
let parmers = JSON.stringify({
flag: "extendJSON"
});
this.$refs[this.tKey1].openDialog(parmers);
},
//小程序的类型
cAppType(col, item) {
let res = CacheData.appType.filter(e => {
return e.value == item.type;
})[0];
if (res) {
return res.name;
} else {
return "小程序类型无效";
}
return res.name;
},
search: function() {
let tk = this.$refs[this.tk];
tk.search(tk.getParams().index);
},

/***
* createPlatform 创建开放平台
* bindPlatform 绑定开放平台
* unbindPlatform 解绑开放平台
*/

createPlatform(item) {
let appId = item.authorizerAppid;
this.getFetch(configUrl.createOpenPlatform + "?appId=" + appId)
.then(res => {
console.log(res);
this.$message({
type: "success",
message: "创建微信开放平台成功"
});
})
.catch(error => {
this.$message({
type: "error",
message: error.data
});
});
},
// 绑定开放平台
bindPlatform(item) {
console.log(item);
this.$prompt("请输入openAppId", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
inputPattern: /\S/,
inputErrorMessage: "openAppId不能为空"
})
.then(({ value }) => {
console.log(value);
let appId = item.authorizerAppid;
let openAppId = value;
this.getFetch(
configUrl.bindOpenPlatform +
"?appId=" +
appId +
"&openAppId=" +
openAppId
)
.then(res => {
console.log(res);
this.$message({
type: "success",
message: "绑定微信开放平台成功"
});
})
.catch(error => {
console.log(error);
this.$message({
type: "error",
message: error.data
});
});
})
.catch(() => {
this.$message({
type: "error",
message: "取消输入"
});
});
},
//解绑开放平台
unbindPlatform(item) {
console.log(item);
this.$prompt("请输入openAppId", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
inputPattern: /\S/,
inputErrorMessage: "openAppId不能为空"
})
.then(({ value }) => {
console.log(value);
let appId = item.authorizerAppid;
let openAppId = value;
this.getFetch(
configUrl.unbindOpenPlatform +
"?appId=" +
appId +
"&openAppId=" +
openAppId
)
.then(res => {
console.log(res);
this.$message({
type: "success",
message: "解绑微信开放平台成功"
});
})
.catch(error => {
console.log(error);
this.$message({
type: "error",
message: error.data
});
});
})
.catch(() => {
this.$message({
type: "error",
message: "取消输入"
});
});
},
getPlatform(item) {
let appId = item.authorizerAppid;
let openAppId = "";
this.getFetch(configUrl.getOpenPlatform + "?appId=" + appId)
.then(res => {
console.log(res);
this.$message({
type: "success",
message: "获取微信开放平台Appid成功"
});
})
.catch(error => {
this.$message({
type: "error",
message: error.data
});
});
},
clearQuota(item) {
let appId = item.authorizerAppid;
let openAppId = "";
this.getFetch(configUrl.clearQuota + "?appId=" + appId)
.then(res => {
console.log(res);
this.$message({
type: "success",
message: "重置公众号Quota成功"
});
})
.catch(error => {
this.$message({
type: "error",
message: error.data
});
});
},
//选择小程序
batchBasicSet(item) {
let parmers = {
type: this.ruleForm.type,
from: "fromHomePage"
};
this.$refs[this.tKey].openDialog(JSON.stringify(parmers));
},
//选择小程序
getShopCb(items) {
this.shopTableData = [];
items.data.map((item, index) => {
let haveIf = false;
this.shopTableData.map((item01, index01) => {
if (item.id == item01.id) {
haveIf = true;
}
});
if (haveIf == false) {
item.merchantName = item.name;
item.merchantLinkPhone = item.linkPhone;
this.shopTableData.push(item);
}
});
},
//小程序授权状态
authStatus(col, item) {
let res = CacheData.authorizationStatus.filter(e => {
return e.value == item.authorizationStatus;
})[0];
if (res) {
return res.name;
} else {
return "小程序授权状态无效";
}
return res.name;
},
//基础配置
baseStatus(col, item) {
let res = CacheData.baseStatus.filter(e => {
return e.value == item.baseStatus;
})[0];
if (res) {
return res.name;
} else {
return "暂无基础配置";
}
return res.name;
},
//服务器域名配置
domainStatus(col, item) {
let res = CacheData.domainStatus.filter(e => {
return e.value == item.domainStatus;
})[0];
if (res) {
return res.name;
} else {
return "暂无配置服务器域名";
}
return res.name;
},
//配置业务域名
webdomainStatus(col, item) {
let res = CacheData.webdomainStatus.filter(e => {
return e.value == item.webdomainStatus;
})[0];
if (res) {
return res.name;
} else {
return "暂无配置业务域名";
}
return res.name;
},
//小程序用户隐私状态
setPrivacySettingStatus(col,item){
let sing = ""
if(!item.privacySettingStatus&&item.privacySettingStatus!=0){
sing = "暂无配置信息"
}else if(item.privacySettingStatus===0){
sing = "已设置"
}else{
sing = "设置失败"
};
return sing
},
//小程序模板消息
templateStatus(col, item) {
let res = CacheData.templateStatus.filter(e => {
return e.value == item.templateStatus;
})[0];
if (res) {
return res.name;
} else {
return "暂无配置模板消息";
}
return res.name;
},
//查看基础配置
searchFigure(item) {
let parmers = JSON.stringify({
flag: "basicFigure",
appId: item.authorizerAppid
});
this.$refs[this.tKey1].openDialog(parmers);
},
//查看小程序类目
getCategory(item) {
console.log(item);
let parmers = JSON.stringify({
appId: item.authorizerAppid
});
this.$refs[this.tKey2].openDialog(parmers);
},
//扩展配置
conFigure(item) {
let parmers = JSON.stringify({
flag: "conFigure",
appId: item.authorizerAppid
});
this.$refs[this.tKey1].openDialog(parmers);
}
}
};
</script>
<style scoped>
.tableContainer {
width: 100%;
margin-top: 30px;
}
.title {
margin-bottom: 10px;
}
.title h3 {
font-size: 18px;
font-weight: bold;
}
.content span {
font-size: 15px;
}
.content span:nth-of-type(1) {
color: #19ce00;
font-weight: bold;
margin-right: 20px;
}
.content span:nth-of-type(2) {
margin-right: 20px;
cursor: pointer;
}
.layout-content {
margin-top: 20px;
background: #f6f6f6;
padding: 29px 20px 0;
border-radius: 6px;
}
.el-select-dropdown__item {
display: block;
}
</style>
<style>
.el-message-box {
width: 1000px;
padding: 0 0 20px;
}
.el-message-box img {
width: 200px;
display: block;
margin: 0 auto;
}
.el-message-box__header {
text-align: center;
font-size: 14px !important;
}
.el-message-box__btns button {
width: 100px !important;
}
.el-message-box__title {
font-size: 16px;
}
</style>


+ 60
- 0
src/components/layout/layout.vue 파일 보기

@@ -0,0 +1,60 @@
<template>
<div class="layout">
<top-layout></top-layout>
<div class="layout-box">
<router-view></router-view>
</div>
</div>
</template>
<script>
import TopLayout from "./topLayout.vue";
import commonUtil from "../../core/tool/commonUtil.js";
import {mapState, mapActions} from "vuex";

export default {
name: 'Layout',
components: {TopLayout},
methods:{
...mapActions([
"setIndex"
]),
},
created() {
this.setIndex("1");
}
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.layout{
position: relative;
}
.red{
color:red;
}
h1, h2 {
font-weight: normal;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}

.layout-box{
min-height: 200px;
padding: 0 20px;
text-align: left;
margin-top: 90px;
}
.layout-box .widget-box{
padding: 24px;
}
</style>

+ 175
- 0
src/components/layout/topLayout.vue 파일 보기

@@ -0,0 +1,175 @@
<template>
<div class="layout-top">
<div><img class="logo fl" src="https://iformall-net.s3.cn-northwest-1.amazonaws.com.cn/456/e32b123d-d762-4d8d-a89b-dd7e4380a25f.png" alt=""></div>
<el-menu
:default-active="index"
class="el-menu-demo"
mode="horizontal"
@select="handleSelect"
background-color="#000"
text-color="#fff"
active-text-color="#ffd04b">
<el-menu-item index="1">首页</el-menu-item>
<el-menu-item index="3">草稿/模板</el-menu-item>
<el-menu-item index="7">code提交列表</el-menu-item>
<el-menu-item index="6">审核列表</el-menu-item>
<el-menu-item index="4">发布列表</el-menu-item>
<el-menu-item index="5">成员管理</el-menu-item>
<el-menu-item index="2">基础设置</el-menu-item>
</el-menu>
<img class="logout" src="./../../static/images/logout.png" @click="logout" alt="">
</div>
</template>

<script>
import {mapState, mapActions} from "vuex";
import commonUtil from "../../core/tool/commonUtil.js";
export default {
name: "TopLayout",
data(){
return {
}
},
methods:{
...mapActions([
"setNavData", // 将this.setNavData 映射为 this.$store.dispatch('setNavData')
"setIndex"
]),
handleSelect(key, keyPath) {
console.log(key);
if(key == 1){
this.$router.push({
path: "/layout"
});
}else if(key == 2){
this.$router.push({
path: "/basicSettings"
});
}else if(key == 3){
this.$router.push({
path: "/draft"
});
}
else if(key == 4){
this.$router.push({
path: "/release"
});
}else if(key == 5){
this.$router.push({
path: "/member"
});
}else if(key == 6){
this.$router.push({
path: "/audit"
});
}else if(key == 7){
this.$router.push({
path: "/codesubmit"
});
}
},
logout(){
this.getFetch("/O/logout").then(d=>{
this.$message.success("退出成功");
this.$router.push({path:"/login"});
commonUtil.cookie.removeCookie("uname");
})
}
},
computed:{
...mapState({
topNav:state=>state.topNav.data, //将 this.topNav 映射为 this.$store.topNav.data
index:state=>state.topNav.index
})
}
}
</script>
<style scoped>
.logout{
width: 20px;
float: right;
margin-top: 20px;
cursor: pointer;
}
.el-menu-demo{
margin-left: 20px;
}
.layout-top .logo{
width: 100px;
margin-top: 15px;
margin-right: 20px;
}
.layout-top{
position: fixed;
right: 0;
top: 0;
left: 0;
background: #141e29;
padding: 0 20px;
text-align: left;
box-shadow: 0 1px 4px 0px rgba(0,21,41,0.12);
color: rgba(0,0,0,0.45);
font-size: 14px;
overflow: hidden;
z-index: 10;
background:#000;
height: 60px;
line-height: 60px;
}

.layout-top ul{
float: left;
list-style: none;
margin: 0;
padding: 0;
overflow: hidden;
background: #000!important;
color: #fff;
}
.el-menu--horizontal>.el-menu-item.is-active {
border-bottom: 2px solid #409EFF;
color: #fff;
}
.layout-top ul li{
float: left;
text-align: center!important;
}

.layout-top ul li::after{
content: '';
display: inline-block;
}

.layout-top ul li:last-child::after{
content: '';
}

.layout-top ul li:last-child{
color: rgba(0,0,0,0.65);
}

.layout-top .layout-top-right{
position: absolute;
right: 25px;
text-align: right;
top:0;
}

.layout-top .portrait{
width: 24px;
height: 24px;
background: rgba(166,219,255,1);
display: inline-block;
border-radius: 50%;
overflow: hidden;
vertical-align: middle;
margin-top: -4px;
}

.layout-top .logout-icon{
margin-left: 14px;
cursor: pointer;
vertical-align: middle;
}
</style>

+ 265
- 0
src/components/login/login.vue 파일 보기

@@ -0,0 +1,265 @@
<template>
<div class="bg">
<div class="login">
<el-form :model="ruleForm2" status-icon :rules="rules2" ref="ruleForm2" class="demo-ruleForm login_form">
<h1>小程序第三方管理平台</h1>
<el-form-item class="inputs" label="" prop="username">
<el-input v-model.number="ruleForm2.username" placeholder="请输入账号"></el-input>
</el-form-item>
<el-form-item class="inputs" label="" prop="password">
<el-input type="password" v-model="ruleForm2.password" auto-complete="off" placeholder="请输入密码"></el-input>
</el-form-item>
<el-form-item class="inputs" label="" prop="captcha">
<el-input v-model="ruleForm2.captcha" auto-complete="off" placeholder="看不清?点击图片刷新">
</el-input>
<div class="refreImg">
<img alt="" :src="src" @click="refreshCode">
</div>
</el-form-item>
<el-form-item>
<el-button class="login-btn" :loading="submitButton" type="primary" @click="login('ruleForm2')">登录</el-button>
</el-form-item>
</el-form>
<div style="position: absolute;top: 96%;right: 2%;color: #fff;" id="_version"></div>
</div>
</div>
</template>
<script>
import AjaxUtil from "../../core/tool/ajaxService";
import Util from "../../core/tool/commonUtil";
import { configUrl } from "./../../utils/config.js";
export default {
extends: AjaxUtil,
name: "Login",
data() {
return {
submitButton:false,
src: '',
ruleForm2: {
username: '',
password: '',
captcha: ''
},
rules2: {
username: [{
required: true,
message: '抱歉,不能识别您输入的账号',
trigger: 'blur'
}],
password: [{
required: true,
message: '抱歉,不能识别您输入的密码',
trigger: 'blur'
}],
captcha: [{
required: true,
message: '抱歉,不能识别您输入的验证码',
trigger: 'blur'
}],
}
};
},
methods: {
login: function () {
this.submitButton = true
let name = this.ruleForm2.username;
let pwd = this.ruleForm2.password;
let captcha = this.ruleForm2.captcha;
this.postFetch(configUrl.doLogin, {
username: name,
password: pwd,
captcha: captcha,
})
.then(d => {
console.log(d)
this.submitButton = false
this.showNotify("success", "欢迎进入小程序第三方管理平台", "登录成功");
Util.cookie.setCookie("uname", d.data.username);
this.$router.push({
path: "/layout"
});
})
.catch((err) => {
this.submitButton = false
this.refreshCode();
this.$message.error(err.data);
});
},
refreshCode: function () {
this.src = configUrl.captcha+"?t=" + Date();
console.log(this.src);
}
},
created() {
this.refreshCode();
},
mounted() {
let metas = document.getElementsByTagName("meta");
let version = "";
for (let index = 0; index < metas.length; index++) {
if (metas[index].getAttribute("name") == "version") {
version = metas[index].getAttribute("content");
break;
}
}
console.log(configUrl.getversion,"configUrl.getversion");
this.getFetch(configUrl.getversion).then(d=>{
console.log(d,22222)
document.getElementById("_version").innerHTML = "version:"+ version.substr(4) + "." + d.data.split('_')[1] ;
}).catch(e=>{
document.getElementById("_version").innerHTML = "version:"+ version.substr(4);
})
},
}
</script>

<style scoped>
.qrcode{
width: 36px;
position: absolute;
right: 7px;
top: 5px;
z-index: 1000;
}
#login_container{
position: absolute;
left: 0;
right: 0;
margin: auto;
top: 0;
bottom:0;
}
.inputs{
width: 315px;
height: 44px;
margin: 0 auto 22px;
line-height: 44px;
}
.el-input__inner {
font-size: 16px !important;
color: rgb(0, 0, 0, 0.25) !important;
padding: 0 35px !important;
}

.refreImg img {
width: 100%;
height: 100%;
border-radius: 2px;
cursor: pointer;
}

a {
text-decoration: none;
}

.frechBox {
display: block;
margin-top: -10px;
}

.refreImg {
width: 38.2%;
height: 40px;
/* line-height: 20px; */
position: absolute;
z-index: 1000;
right: 0;
top: -1px;
background-color: #ededed;
}

.bg {
background: url(../../static/images/login-bg.png) no-repeat;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-size: cover;
}

.login h1 {
font-size: 22px;
font-weight:400;
color:rgba(85,85,85,1);
line-height: 24px;
margin-bottom: 28px;
}

.login-item {
width: 368px;
margin: 0 auto;
height: 40px;
margin-bottom: 16px;
border: 1px solid #D9D9D9;
border-radius: 4px;
box-sizing: border-box;
overflow: hidden;
position: relative;
}

.login-item input {
width: 100%;
line-height: 38px;
background: #fff;
font-size: 16px;
color: rgba(0, 0, 0, 0.25);
padding: 0 0 0 36px;
display: block;
border: none;
outline: none;
}

.login-btn {
width: 315px;
line-height: 44px;
background: #3FC497;
text-align: center;
border-radius: 4px;
font-size: 16px;
color: #fff;
padding: 0;
border: none;
cursor: pointer;
margin: 0 auto;
}

.forgot-password {
color: rgba(24, 144, 255, 1);
width: 368px;
margin: 0 auto;
text-align: right;
line-height: 22px;
margin-bottom: 4px;
}

.forgot-password label {
font-weight: 400 !important;
font-size: 14px;
cursor: pointer;
margin-right: 26px;
color:#555;

}

.el-input__inner {
font-size: 16px !important;
color: rgb(0, 0, 0, 0.25) !important;
padding: 0 35px !important;
}
.login {
background: #f9fafc;
border-radius:6px;
overflow: hidden;
width: 375px;
position: relative;
left: 50%;
top: 50%;
height: 340px;
transform: translate(-50%,-50%);
-webkit-transform:translate(-50%,-50%);
box-shadow:0px 3px 24px 0px rgba(0, 0, 0, 0.24);
}
</style>

+ 379
- 0
src/components/marketing/businessComp/chooseApp.vue 파일 보기

@@ -0,0 +1,379 @@
<template>
<div>
<el-dialog
:title="title"
:visible="dialogVisible"
width="800px"
:before-close="closeDialog"
:modal-append-to-body="false"
class="fx_dialog_list_chooseSH"
>
<div class="search">
<el-form :inline="true" :model="ruleForm" ref="ruleForm" class="demo-form-inline" label-position="right">
<el-form-item label="小程序类型" prop="type" class="fx_send">
<el-select v-model="ruleForm.type" placeholder="请选择" @change="selectValue" >
<el-option v-for="(item,index) in appType" :disabled="disabled" :key="index" :value="item.value" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="小程序名称" prop="name" class="fx_title">
<el-input v-model="ruleForm.name" placeholder="请输入" clearable></el-input>
</el-form-item>
<el-form-item>
<el-button
class="hoverBtn"
type="primary"
icon="el-icon-search"
size="medium"
@click="search"
></el-button>
</el-form-item>
<h4 v-if="formwhere == 'reviewApp'" style="color:red;padding-top: 18px;margin-top:2px!important;line-height:40px;">1.请选择小程序的版本号: <el-form-item prop="type" class="fx_send">
<el-select v-model="ruleForm.version" placeholder="请选择" >
<el-option v-for="(item,index) in version" :disabled="disabled" :key="index" :value="item.version" :label="item.version"></el-option>
</el-select>
</el-form-item></h4>
</el-form>
<h4 style="color:red;margin-bottom:10px!important;" v-if="formwhere == 'reviewApp'">2.请选择需要提交审核的小程序</h4>
</div>
<table-list :ref="tKey" :options="optionsTable"></table-list>
<span slot="footer" class="dialog-footer">
<el-button class="draftBtn" @click="dialogVisible = false">取 消</el-button>
<el-button class="putinBtn" @click="getSelected()">确 定</el-button>
</span>
</el-dialog>
</div>
</template>

<script>
import TableList from "../../../core/comps/table/tableList.vue";
import commonUtil from "../../../core/tool/commonUtil.js";
import { configUrl } from "./../../../utils/config.js";
import { CacheData } from "./../../../service/couponData/data.js"
export default {
inject: ["reload"],
name: "chooseApp",
props: ["cb","params"],
components: { TableList},
data() {
return {
dialogVisible: false,
title:"",
version:[],
realversion:this.childversion,
disabled:false,
formwhere:"",
tKey: "chooseApp",
ruleForm: {
name: '',
type:1,
version:""
},
businessData:[],
optionsTable: {
singleSelected: false,
showCk: true,
map: [
{ key: "id", val: "编号"},
{ key: "headImg", val: "小程序图标",etype:"img"},
{ key: "name", val: "小程序名称"},
{ key: "authorizerAppid", val: "授权方appid"},
{key:"authorizationStatus",val:"授权状态",convert:this.authStatus},
{key:"type",val:"小程序类型",convert:this.cAppType},
],
getUrl:() => {
return configUrl.weappList + "?type=" + this.ruleForm.type+"&name="+this.ruleForm.name;
},
pageOption: {
sizeKey: "pageSize",
indexKey: "pageNum",
index: 1,
size: 10
},
analysis: data => {
console.log(data)
return {
data: data.data.list,
count: data.data.total
};
}
}
};
},
computed:{
appType:()=>{
return CacheData.appType;
},
},
methods: {
//批量状态查询
searchAudit(flag) {
console.log(flag)
this.paramers = flag;
this.$refs[this.tKey].openDialog(flag);
},
selectValue(value){
console.log(value);
this.$refs[this.tKey].search(value);
console.log(value);
/**
* 点击批量提交小程序审核按钮进来的
*/
if(this.formwhere == 'reviewApp'){
this.version = [];
this.ruleForm.version = "";
this.getFetch(configUrl.codeVersionList+"?type="+value).then(res=>{
console.log(res)
this.version = res.data;
}).catch(err=>{
console.log(err);
})
}
},
//小程序类型转换
cAppType(col,item,flag) {
console.log(flag)
let res = CacheData.appType.filter(e => {
return e.value == item.type;
})[0];
console.log(res)
if (res) {
return res.name;
} else {
return "小程序类型无效";
}
return res.name;
},
//小程序授权状态
authStatus(col, item){
console.log(item)
let res = CacheData.authorizationStatus.filter(e => {
return e.value == item.authorizationStatus.toString();
})[0];
console.log(res)
if (res) {
return res.name;
} else {
return "小程序授权状态无效";
}
return res.name;
},
openDialog(from) {
this.dialogVisible = true;
if(from!=undefined){
let froms = JSON.parse(from);
if(froms.from=='fromHomePage'){
this.formwhere = froms.from;
if(this.formwhere == 'fromHomePage'){
this.title = "批量基础配置";
}
}else if(froms.from=='reviewApp'){
this.formwhere = froms.from;
if(this.formwhere == 'reviewApp'){
this.title = "批量提交小程序审核";
}
this.getFetch(configUrl.codeVersionList+"?type="+this.ruleForm.type).then(res=>{
console.log(res)
this.version = res.data;
}).catch(err=>{
console.log(err);
})
}else{
this.title = "版本号:"+JSON.parse(from).userVersion;
console.log(JSON.parse(from).userVersion.charAt(0))
if(JSON.parse(from).userVersion.charAt(0)=='B'){
this.ruleForm.type = 1;
this.disabled = true;
}else if(JSON.parse(from).userVersion.charAt(0)=='C'){
this.ruleForm.type = 2;
this.disabled = true;
}
if(this.$refs[this.tKey]){
this.search()
}
}
}
},
closeDialog() {
this.dialogVisible = false;
},
search: function() {
let tKey = this.$refs[this.tKey];
tKey.search(tKey.getParams().index);
},
//确定
getSelected() {
let items = this.$refs[this.tKey].getCheckedItems("authorizerAppid");
if (items.data.length == 0) {
if(this.formwhere == 'fromHomePage'){
this.title = "批量基础配置"
this.$message({
type: "error",
message: "请选择需要配置的小程序"
});
}else if(this.formwhere == 'reviewApp'){
this.title = "批量提交小程序审核"
this.$message({
type: "error",
message: "请选择需要提交审核的小程序"
});
}else if(this.ruleForm.type == ""){
this.$message({
type: "error",
message: "请选择小程序的类型"
});
}else{
this.$message({
type: "error",
message: "请选择需要发布的小程序"
});
}
return;
}else if(this.ruleForm.version==""&&this.formwhere == 'reviewApp'){
this.$message({
type: "error",
message: "请选择小程序的版本号"
});
return;
}else {
let apps = JSON.stringify(items.vals).replace(/\[|]/g,'').replace(/\"/g, "");
if(this.formwhere == 'fromHomePage'){
let parmer = {
apps:apps,
type:this.ruleForm.type,
}
this.postFetch(configUrl.batchBasicSet,parmer).then(res=>{
console.log(res)
this.$message({
type: "success",
message: "配置成功"
});
this.dialogVisible = false;
}).catch(err=>{
this.$message({
type: "error",
message: err.data
});
this.dialogVisible = true;
})
}
else if(this.formwhere == 'reviewApp'){
let parmer = {
apps:apps,
userVersion:this.ruleForm.version,
}
this.postFetch(configUrl.batchCodeAudit,parmer).then(res=>{
console.log(res)
this.$message({
type: "success",
message: "提交审核成功"
});
this.dialogVisible = false;
this.search();
}).catch(err=>{
console.log(err)
this.$message({
type: "error",
message: err.data
});
this.dialogVisible = true;
})
}else{
let paramers = JSON.parse(this.params);
let params = {
apps:apps,
templateId:paramers.templateId,
userVersion:paramers.userVersion,
userDesc:paramers.userDesc,
}
console.log(params.apps)
this.postFetch(configUrl.batchCodeCommit,params).then(res=>{
console.log(res)
this.$message({
type: "success",
message: "提交代码成功"
});
}).catch(err=>{
this.$message({
type: "error",
message: err.data
});
})
this.dialogVisible = false;
}
}
}
},
};
</script>

<style scoped>
.version{
color: red;
font-size: 16px;
}
.fx_dialog_list_chooseSH .el-dialog .el-dialog__footer .dialog-footer .draftBtn,
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
width: 76px;
height: 35px;
font-size: 14px;
padding: 10px 20px;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn {
margin-right: 7.5px;
background: #ffffff;
color: #555555;
border: 1px solid #e1e6ea;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
margin-left: 7.5px;
background: #c85963;
color: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:hover {
background: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:hover {
background: #e26972;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:active {
background: #e1e2e2;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:active {
background: #bf585f;
}
.search{
width: 100%;
text-align: left;
}
.search .el-form-item{
margin-bottom: 0;
}
</style>

+ 234
- 0
src/components/marketing/businessComp/chooseVersion.vue 파일 보기

@@ -0,0 +1,234 @@
<template>
<div>
<el-dialog
:title="title"
:visible="dialogVisible"
width="800px"
:before-close="closeDialog"
:modal-append-to-body="false"
class="fx_dialog_list_chooseSH">
<div style="width:100%">
<table-list :ref="tKey" :options="optionsTable"></table-list>
</div>
<span slot="footer" class="dialog-footer">
<el-button class="draftBtn" @click="dialogVisible = false">取 消</el-button>
<el-button class="putinBtn" @click="childversion">确 定</el-button>
</span>
</el-dialog>
</div>
</template>

<script>
import TableList from "../../../core/comps/table/tableList.vue";
import commonUtil from "../../../core/tool/commonUtil.js";
import { configUrl } from "./../../../utils/config.js";
import { CacheData } from "./../../../service/couponData/data.js";

export default {
inject: ["reload"],
name: "chooseVersion",
props: ["tKey", "cb"],
components: { TableList },
data() {
return {
dialogVisible: false,
title:"",
brands:[],
flag:"",
ruleForm: {
authorizerAppid: '',
type:""
},
businessData:[],
optionsTable: {
singleSelected: true,
showCk: true,
map: [
{ key: "version", val: "小程序版本号"}
],
getUrl:() => {
//批量撤回审核
if(this.flag == 'batchrevertStatus'){
return configUrl.auditVersionList;
}else if(this.flag == 'batchsearchStatus'){
return configUrl.codeVersionList;
}else if(this.flag == 'batchRelease'){
return configUrl.auditVersionList+"?status=0";
}
},
pageOption: {
showIf:false,
sizeKey: "pageSize",
indexKey: "pageNum",
index: 1,
size: 10
},
analysis: data => {
console.log(data.data);
return {
data: data.data
};
}
}
};
},
computed:{
appType:()=>{
return CacheData.appType;
},
},
methods: {
//小程序类型转换
cAppType(col, item) {
console.log(item)
let res = CacheData.appType.filter(e => {
return e.value == item.type;
})[0];
console.log(res)
if (res) {
return res.name;
} else {
return "小程序类型无效";
}
return res.name;
},
search: function() {
let tKey = this.$refs[this.tKey];
tKey.search(tKey.getParams().index);
},
openDialog(flag) {
this.flag = flag;
this.data = [];
if(this.flag == 'batchrevertStatus'){
this.title ='批量撤回小程序审核';
}else if(this.flag == 'batchsearchStatus'){
this.title ='批量查询小程序审核状态';
}else if(this.flag == 'batchRelease'){
this.title ='批量发布小程序';
}
this.dialogVisible = true;
},
closeDialog() {
this.dialogVisible = false;
},
//请选择小程序的版本
childversion() {
let items = this.$refs[this.tKey].getCheckedItems("version");
if (items.data.length != 1) {
this.$message({
type: "error",
message: "请选择小程序的版本号!"
});
return;
} else {
let params = {
version:JSON.stringify(items.vals).replace(/\[|]/g,'').replace(/\"/g, "")
};
let postUrl = "";
if(this.flag == 'batchsearchStatus'){
//批量查询审核状态
postUrl = configUrl.batchAuditQuery;
}else if(this.flag == 'batchrevertStatus'){
//批量撤回审核
postUrl = configUrl.batchAuditCancel;
}else if(this.flag == 'batchRelease'){
//批量发布小程序
postUrl = configUrl.batchRelease;
}
if(this.flag == 'batchsearchStatus'||this.flag == 'batchrevertStatus'||this.flag == 'batchRelease'){
this.postFetch(postUrl,params).then(res=>{
if(this.flag == 'batchsearchStatus'){
this.$message({
type: "success",
message: "批量查询审核状态成功!"
})
}else if(this.flag == 'batchrevertStatus'){
this.$message({
type: "success",
message: "批量撤回审核成功!"
})
}else if(this.flag == 'batchRelease'){
this.$message({
type: "success",
message: "批量发布小程序成功!"
})
}
}).catch(err=>{
this.$message({
type: "error",
message: err.data,
});
})
}
}
this.dialogVisible = false;
}
}
};
</script>
<style scoped>
.fx_dialog_list_chooseSH .el-dialog .el-dialog__footer .dialog-footer .draftBtn,
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
width: 76px;
height: 35px;
font-size: 14px;
padding: 10px 20px;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn {
margin-right: 7.5px;
background: #ffffff;
color: #555555;
border: 1px solid #e1e6ea;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
margin-left: 7.5px;
background: #c85963;
color: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:hover {
background: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:hover {
background: #e26972;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:active {
background: #e1e2e2;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:active {
background: #bf585f;
}
.search{
width: 100%;
height: 50px;
text-align: left;
margin-left: 20px;
}
</style>

+ 181
- 0
src/components/marketing/businessComp/chooseVersionRelease.vue 파일 보기

@@ -0,0 +1,181 @@
<template>
<div>
<el-dialog
title="批量发布小程序"
:visible="dialogVisible"
width="800px"
:before-close="closeDialog"
:modal-append-to-body="false"
class="fx_dialog_list_chooseSH">
<div style="width:100%">
<table-list :ref="tKey" :options="optionsTable"></table-list>
</div>
<span slot="footer" class="dialog-footer">
<el-button class="draftBtn" @click="dialogVisible = false">取 消</el-button>
<el-button class="putinBtn" @click="childversion">确 定</el-button>
</span>
</el-dialog>
</div>
</template>

<script>
import TableList from "../../../core/comps/table/tableList.vue";
import commonUtil from "../../../core/tool/commonUtil.js";
import { configUrl } from "./../../../utils/config.js";
import { CacheData } from "./../../../service/couponData/data.js";

export default {
inject: ["reload"],
name: "chooseVersionRelease",
props: ["tKey", "cb"],
components: { TableList },
data() {
return {
dialogVisible: false,
title:"",
brands:[],
flag:"",
ruleForm: {
authorizerAppid: '',
type:""
},
businessData:[],
optionsTable: {
singleSelected: true,
showCk: true,
map: [
{ key: "version", val: "小程序版本号"}
],
getUrl:() => {
//批量撤回审核
return configUrl.auditVersionList+"?status=0";
},
pageOption: {
showIf:false,
sizeKey: "pageSize",
indexKey: "pageNum",
index: 1,
size: 10
},
analysis: data => {
console.log(data.data);
return {
data: data.data
};
}
}
};
},
computed:{
appType:()=>{
return CacheData.appType;
},
},
methods: {
search: function() {
let tKey = this.$refs[this.tKey];
tKey.search(tKey.getParams().index);
},
openDialog() {
this.dialogVisible = true;
},
closeDialog() {
this.dialogVisible = false;
},
//请选择小程序的版本
childversion() {
let items = this.$refs[this.tKey].getCheckedItems("version");
if (items.data.length != 1) {
this.$message({
type: "error",
message: "请选择小程序的版本号!"
});
return;
} else {
let params = {
version:JSON.stringify(items.vals).replace(/\[|]/g,'').replace(/\"/g, "")
};
let postUrl = configUrl.batchRelease;
this.postFetch(postUrl,params).then(res=>{
this.$message({
type: "success",
message: "批量发布小程序成功!"
})
}).catch(err=>{
this.$message({
type: "error",
message: err.data,
});
})
}
this.dialogVisible = false;
}
}
};
</script>
<style scoped>
.fx_dialog_list_chooseSH .el-dialog .el-dialog__footer .dialog-footer .draftBtn,
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
width: 76px;
height: 35px;
font-size: 14px;
padding: 10px 20px;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn {
margin-right: 7.5px;
background: #ffffff;
color: #555555;
border: 1px solid #e1e6ea;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
margin-left: 7.5px;
background: #c85963;
color: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:hover {
background: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:hover {
background: #e26972;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:active {
background: #e1e2e2;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:active {
background: #bf585f;
}
.search{
width: 100%;
height: 50px;
text-align: left;
margin-left: 20px;
}
</style>

+ 181
- 0
src/components/marketing/businessComp/chooseVersioncheck.vue 파일 보기

@@ -0,0 +1,181 @@
<template>
<div>
<el-dialog
title="批量查询小程序审核状态"
:visible="dialogVisible"
width="800px"
:before-close="closeDialog"
:modal-append-to-body="false"
class="fx_dialog_list_chooseSH">
<div style="width:100%">
<table-list :ref="tKey" :options="optionsTable"></table-list>
</div>
<span slot="footer" class="dialog-footer">
<el-button class="draftBtn" @click="dialogVisible = false">取 消</el-button>
<el-button class="putinBtn" @click="childversion">确 定</el-button>
</span>
</el-dialog>
</div>
</template>

<script>
import TableList from "../../../core/comps/table/tableList.vue";
import commonUtil from "../../../core/tool/commonUtil.js";
import { configUrl } from "./../../../utils/config.js";
import { CacheData } from "./../../../service/couponData/data.js";

export default {
inject: ["reload"],
name: "chooseVersioncheck",
props: ["tKey", "cb"],
components: { TableList },
data() {
return {
dialogVisible: false,
title:"",
brands:[],
flag:"",
ruleForm: {
authorizerAppid: '',
type:""
},
businessData:[],
optionsTable: {
singleSelected: true,
showCk: true,
map: [
{ key: "version", val: "小程序版本号"}
],
getUrl:() => {
//批量撤回审核
return configUrl.auditVersionList;
},
pageOption: {
showIf:false,
sizeKey: "pageSize",
indexKey: "pageNum",
index: 1,
size: 10
},
analysis: data => {
console.log(data.data);
return {
data: data.data
};
}
}
};
},
computed:{
appType:()=>{
return CacheData.appType;
},
},
methods: {
search: function() {
let tKey = this.$refs[this.tKey];
tKey.search(tKey.getParams().index);
},
openDialog() {
this.dialogVisible = true;
},
closeDialog() {
this.dialogVisible = false;
},
//请选择小程序的版本
childversion() {
let items = this.$refs[this.tKey].getCheckedItems("version");
if (items.data.length != 1) {
this.$message({
type: "error",
message: "请选择小程序的版本号!"
});
return;
} else {
let params = {
version:JSON.stringify(items.vals).replace(/\[|]/g,'').replace(/\"/g, "")
};
let postUrl = configUrl.batchAuditQuery;
this.postFetch(postUrl,params).then(res=>{
this.$message({
type: "success",
message: "批量查询审核状态成功!"
})
}).catch(err=>{
this.$message({
type: "error",
message: err.data,
});
})
}
this.dialogVisible = false;
}
}
};
</script>
<style scoped>
.fx_dialog_list_chooseSH .el-dialog .el-dialog__footer .dialog-footer .draftBtn,
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
width: 76px;
height: 35px;
font-size: 14px;
padding: 10px 20px;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn {
margin-right: 7.5px;
background: #ffffff;
color: #555555;
border: 1px solid #e1e6ea;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
margin-left: 7.5px;
background: #c85963;
color: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:hover {
background: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:hover {
background: #e26972;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:active {
background: #e1e2e2;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:active {
background: #bf585f;
}
.search{
width: 100%;
height: 50px;
text-align: left;
margin-left: 20px;
}
</style>

+ 320
- 0
src/components/marketing/businessComp/extend.vue 파일 보기

@@ -0,0 +1,320 @@
<template>
<div class="basicConfig">
<el-dialog
:title="title"
:visible="dialogVisible"
width="800px"
:before-close="closeDialog"
:modal-append-to-body="false"
class="fx_dialog_list_chooseSH">
<!-- 查询基础配置 -->
<div class="search" v-if="configFlag=='basicFigure'">
<h3>服务器域名</h3>
<p>request 合法域名:<span v-for="(item,index) in basicData.requestdomainList" :key="index">{{item}}</span></p>
<p>socket 合法域名:<span v-for="(item,index) in basicData.wsrequestdomainList" :key="index">{{item}}</span></p>
<p>uploadFile 合法域名:<span v-for="(item,index) in basicData.uploaddomainList" :key="index">{{item}}</span></p>
<p>downloadFile 合法域名:<span v-for="(item,index) in basicData.downloaddomainList" :key="index">{{item}}</span></p>
<h3>业务域名</h3>
<p><span v-for="(item,index) in webviewdomain" :key="index">{{item}}</span></p>
</div>
<!-- 扩展配置 -->
<div class="search extend" v-if="configFlag=='conFigure'">
<el-form :inline="false" :model="ruleForm" ref="ruleForm" class="demo-form-inline" label-position="right">
<el-form-item label="扩展配置" prop="extJson" class="fx_send">
<el-input
@click.ctrl.alt.native="show('extend')"
type="textarea"
:rows="12"
placeholder="请输入内容"
:disabled="ruleForm.disable"
v-model="ruleForm.extJson">
</el-input>
</el-form-item>
<el-form-item label="发布配置" prop="releaseJson" class="fx_title">
<el-input
@click.ctrl.alt.native="show('release')"
type="textarea"
:rows="4"
placeholder="请输入内容"
:disabled="ruleForm.disable1"
v-model="ruleForm.releaseJson">
</el-input>
</el-form-item>
<el-form-item label="停车配置" v-if="ruleForm.carSupport" prop="carSupport" class="fx_title">
<el-input
@click.ctrl.alt.native="show('carFlag')"
type="text"
placeholder=""
:disabled="ruleForm.disable2"
v-model="ruleForm.carSupport">
</el-input>
</el-form-item>
</el-form>
</div>
<div class="search extend" v-if="configFlag=='extendJSON'">
<el-form :inline="false" :model="ruleForm" ref="ruleForm" class="demo-form-inline" label-position="right">
<el-form-item label="小程序类型" class="fx_send">
<el-select v-model="ruleForm.type" placeholder="请选择" clearable>
<el-option v-for="(item,index) in appType" :key="index" :value="item.value" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="扩展配置" prop="extJson " class="fx_send">
<el-input
type="textarea"
:rows="12"
:disabled="ruleForm.disable3"
placeholder="请输入内容"
v-model="ruleForm.extJson ">
</el-input>
</el-form-item>
</el-form>
</div>
<div slot="footer" class="dialog-footer">
<el-button class="draftBtn" @click="dialogVisible = false">取 消</el-button>
<el-button class="putinBtn" @click="submit()" v-if="!ruleForm.disable||!ruleForm.disable1||!ruleForm.disable2||!ruleForm.disable3">确 定</el-button>
</div>
</el-dialog>
</div>
</template>

<script>
import commonUtil from "../../../core/tool/commonUtil.js";
import { configUrl } from "./../../../utils/config.js";
import { CacheData } from "./../../../service/couponData/data.js";
export default {
inject: ["reload"],
name: "extend",
props: ["tKey", "cb"],
data() {
return {
configFlag:"",
title:"",
appType:[],
basicData:"",
webviewdomain:"",
dialogVisible: false,
releaseJson:"",
extJson:"",
ruleForm: {
extJson: "",
releaseJson:"",
carSupport:false,
id:"",
appId:"",
disable:true,
disable1:true,
disable2:true,
disable3:false
}
};
},
computed:{
appType: () => {
return CacheData.appType;
},
},
methods: {
show(flag){
if(flag == 'release'){
if(this.ruleForm.disable1){
this.ruleForm.disable1 = false
}else{
this.ruleForm.disable1 = true;
}
}else if(flag == 'extend'){
if(this.ruleForm.disable){
this.ruleForm.disable = false
}else{
this.ruleForm.disable = true
}
}else if(flag == 'carFlag'){
if(this.ruleForm.disable2){
this.ruleForm.disable2 = false
}else{
this.ruleForm.disable2 = true
}
}
},
search: function() {
let tKey = this.$refs[this.tKey];
tKey.search(tKey.getParams().index);
},
openDialog(flag) {
this.ruleForm.disable = true;
this.ruleForm.disable1 = true;
this.basicData = [];
this.webviewdomain = [];
if(flag){
let flags = JSON.parse(flag);
this.configFlag= flags.flag;
this.ruleForm.appId = flags.appId;
if(flags.flag == 'basicFigure'){
this.title = '查看基础配置';
this.getFetch(configUrl.getDomain+"?appId="+flags.appId).then(res=>{
console.log(res)
this.basicData = res.data;
}).catch(err=>{
this.$message({
type:"error",
message:"暂无基础配置信息"
})
})
this.getFetch(configUrl.getWebDomain+"?appId="+flags.appId).then(res=>{
if(res.data){
this.webviewdomain = JSON.parse(res.data).webviewdomain;
}
}).catch(err=>{
this.$message({
type:"error",
message:"暂无基础配置信息"
})
})
}else if(flags.flag == 'conFigure'){
this.title = '扩展配置';
this.getFetch(configUrl.weappExtSetList+"?pageNum=1&pageSize=10&appId="+flags.appId).then(res=>{
this.ruleForm.extJson = res.data.list[0].extJson;
this.ruleForm.releaseJson = res.data.list[0].releaseJson;
this.ruleForm.carSupport = res.data.list[0].carSupport;
this.ruleForm.id = res.data.list[0].id;
}).catch(err=>{
this.$message({
type:"error",
message:"扩展配置失败"
})
})
}
}
this.dialogVisible = true;
},
closeDialog() {
this.dialogVisible = false;
},
//小程序扩展配置配置
submit(){
this.dialogVisible = false;
let parmers = {}
let url = ""
if(this.configFlag == 'extendJSON'){
url = configUrl.batchExtendSet;
parmers = {
type:this.ruleForm.type,
extJson:this.ruleForm.extJson
}
if(!parmers.type){
this.$message({
type:"error",
message:"请选择小程序类型"
})
return;
}
if(!parmers.extJson){
this.$message({
type:"error",
message:"提交的extJson不能为空"
})
return;
}
}else{
url = configUrl.weappExtSetupdate;
parmers = {
appId:this.ruleForm.appId,
id:this.ruleForm.id,
extJson:this.ruleForm.extJson,
releaseJson:this.ruleForm.releaseJson
}
}
this.postFetch(url,parmers).then(res=>{
this.$message({
type:"success",
message:"保存成功"
})
}).catch(error=>{
this.$message({
type:"error",
message:error.data
})
this.ruleForm.disable1 = true;
this.ruleForm.disable = true;
})
}
}
};
</script>


<style scoped>
.search span{
display: block;
}
.extend{
width: 400px;
}
.fx_dialog_list_chooseSH .el-dialog .el-dialog__footer .dialog-footer .draftBtn,
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
width: 76px;
height: 35px;
font-size: 14px;
padding: 10px 20px;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn {
margin-right: 7.5px;
background: #ffffff;
color: #555555;
border: 1px solid #e1e6ea;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
margin-left: 7.5px;
background: #c85963;
color: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:hover {
background: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:hover {
background: #e26972;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:active {
background: #e1e2e2;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:active {
background: #bf585f;
}
.search{
width: 60%;
text-align: left;
margin-left: 20px;
}
</style>
<style>
.basicConfig .el-dialog__body{
padding: 0 18px 30px;
}
</style>

+ 154
- 0
src/components/marketing/businessComp/getcategory.vue 파일 보기

@@ -0,0 +1,154 @@
<template>
<div class="basicConfig">
<el-dialog
title="小程序类目列表"
:visible="dialogVisible"
width="800px"
:before-close="closeDialog"
:modal-append-to-body="false"
class="fx_dialog_list_chooseSH">
<!-- 扩展配置 -->
<div class="search extend">
<div v-for="(item,index) in categoryList" :key="index" class="model">
<span>firstClass:{{item.firstClass}}</span>
<span>firstId:{{item.firstId}}</span>
<span>secondClass:{{item.secondClass}}</span>
<span>secondId:{{item.secondId}}</span>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button class="draftBtn" @click="dialogVisible = false">取 消</el-button>
<el-button class="putinBtn" @click="submit()">确 定</el-button>
</div>
</el-dialog>
</div>
</template>

<script>
import commonUtil from "../../../core/tool/commonUtil.js";
import { configUrl } from "./../../../utils/config.js";
export default {
inject: ["reload"],
name: "getcategory",
props: ["tKey", "cb"],
data() {
return {
dialogVisible:false,
categoryList: []
};
},
methods: {
openDialog(flag) {
if(flag){
let appId = JSON.parse(flag).appId;
this.getFetch(configUrl.getCategory+"?appId="+appId).then(res=>{
if(res.data.categoryList){
this.categoryList = res.data.categoryList;
}
console.log(res.data.categoryList)
}).catch(err=>{
this.$message({
type:"error",
message:"扩展配置失败"
})
})
}
this.dialogVisible = true;
},
closeDialog() {
this.dialogVisible = false;
},
//确定
submit(){
this.dialogVisible = false;
}
},
mounted: function() {},
created() {
}
};
</script>

<style scoped>
.model{
border: 1px solid #eee;
border-radius:6px;
padding: 10px;
margin-bottom: 10px;
}
.search span{
display: block;
}
.extend{
width: 400px;
}
.fx_dialog_list_chooseSH .el-dialog .el-dialog__footer .dialog-footer .draftBtn,
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
width: 76px;
height: 35px;
font-size: 14px;
padding: 10px 20px;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn {
margin-right: 7.5px;
background: #ffffff;
color: #555555;
border: 1px solid #e1e6ea;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
margin-left: 7.5px;
background: #c85963;
color: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:hover {
background: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:hover {
background: #e26972;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:active {
background: #e1e2e2;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:active {
background: #bf585f;
}
.search{
width: 60%;
text-align: left;
margin-left: 20px;
}
</style>
<style>
.basicConfig .el-dialog__body{
padding: 0 18px 30px;
}
</style>

+ 312
- 0
src/components/marketing/businessComp/member.vue 파일 보기

@@ -0,0 +1,312 @@
<template>
<div>
<el-dialog
:title="title"
:visible="dialogVisible"
width="1105px"
:before-close="closeDialog"
:modal-append-to-body="false"
class="fx_dialog_list_chooseSH">
<div class="search">
<el-form :inline="true" :model="ruleForm" ref="ruleForm" class="demo-form-inline" label-position="right">
<el-form-item label="小程序类型" prop="type" class="fx_send">
<el-select v-model="ruleForm.type" placeholder="请选择" clearable>
<el-option v-for="(item,index) in appType" :key="index" :value="item.value" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="小程序名称" prop="name" class="fx_title">
<el-input v-model="ruleForm.name" placeholder="请输入" clearable></el-input>
</el-form-item>
<el-form-item>
<el-button
class="hoverBtn"
type="primary"
icon="el-icon-search"
size="medium"
@click="search"
></el-button>
</el-form-item>
<div></div>
<h4 style="color:red;line-height:40px;margin:0!important;">1.请输入微信号:
<el-form-item prop="wechatId" class="fx_title">
<el-input v-model="ruleForm.wechatId" placeholder="请输入" clearable></el-input>
</el-form-item>
</h4>
<h4 style="color:red;line-height:40px;margin:0!important;">2.请选择小程序</h4>
</el-form>
</div>
<div style="width:100%">
<table-list :ref="tKey" :options="optionsTable"></table-list>
</div>
<span slot="footer" class="dialog-footer">
<el-button class="draftBtn" @click="dialogVisible = false">取 消</el-button>
<el-button class="putinBtn" @click="getSelected(tKey)">{{button}}</el-button>
</span>
</el-dialog>
</div>
</template>

<script>
import TableList from "../../../core/comps/table/tableList.vue";
import commonUtil from "../../../core/tool/commonUtil.js";
import { configUrl } from "./../../../utils/config.js";
import { CacheData } from "./../../../service/couponData/data.js";

export default {
inject: ["reload"],
name: "member",
props: ["tKey", "cb","params"],
components: { TableList },
data() {
return {
dialogVisible: false,
ruleForm: {
name: '',
wechatId:"",
type:"",
},
title:"",
flag:"",
button:"",
businessData:[],
optionsTable: {
singleSelected: true,
showCk: true,
map: [
{ key: "id", val: "编号"},
{ key: "headImg", val: "小程序图标",etype:"img"},
{ key: "name", val: "小程序名称"},
{ key: "authorizerAppid", val: "授权方appid"},
{key:"authorizationStatus",val:"授权状态",convert:this.authStatus},
{key:"type",val:"小程序类型",convert:this.cAppType},
],
getUrl:() => {
return configUrl.weappList + "?type=" + this.ruleForm.type+"&name="+this.ruleForm.name;
},
pageOption: {
sizeKey: "pageSize",
indexKey: "pageNum",
index: 1,
size: 10
},
analysis: data => {
console.log(data)
return {
data: data.data.list,
count: data.data.total
};
}
}
};
},
computed:{
appType:()=>{
return CacheData.appType;
},
},
methods: {
//小程序类型转换
cAppType(col, item) {
console.log(item)
let res = CacheData.appType.filter(e => {
return e.value == item.type;
})[0];
if (res) {
return res.name;
} else {
return "小程序类型无效";
}
return res.name;
},
//小程序授权状态
authStatus(col, item){
console.log(item)
let res = CacheData.authorizationStatus.filter(e => {
return e.value == item.authorizationStatus.toString();
})[0];
console.log(res)
if (res) {
return res.name;
} else {
return "小程序授权状态无效";
}
return res.name;
},
search: function() {
let tKey = this.$refs[this.tKey];
tKey.search(tKey.getParams().index);
},
openDialog(item) {
console.log(item)
if(item == 'add'){
this.title = '添加体验者权限'
this.flag = 'add';
this.button = '添 加';
}else if(item == 'delete'){
this.title = '删除体验者权限'
this.flag = 'delete';
this.button = '删 除';
}
this.dialogVisible = true;
},
closeDialog() {
this.dialogVisible = false;
},
//确定选择的需要添加权限的小程序
getSelected(pamer) {
console.log(pamer)
let items = this.$refs[this.tKey].getCheckedItems("authorizerAppid");
console.log(items)
if (items.data.length == 0) {
this.$message({
type: "error",
message: "请选择小程序"
});
return;
}else if(this.ruleForm.wechatId == ""){
this.$message({
type: "error",
message: "请输入需要添加体验权限的微信号"
});
return;
} else {
let params = {
appId:JSON.stringify(items.vals).replace(/\[|]/g,'').replace(/\"/g, ""),
wechatId:this.ruleForm.wechatId,
}
let postUrl = this.flag == 'add'?configUrl.bindTester:configUrl.unbindTester;
this.postFetch(postUrl,params).then(res=>{
console.log(typeof(res.data))
//错误提示的判断
if(typeof(res.data)=="string"){
var errcode = JSON.parse(res.data).errcode;
}else{
var errcode = res.data.errcode;
console.log(typeof(res.data))
}
//绑定体验者
if(postUrl == configUrl.bindTester){
if(errcode == -1){
this.$message({
type: "error",
message: "系统繁忙"
});
}else if(errcode == 85001){
this.$message({
type: "error",
message: "微信号不存在或微信号设置为不可搜索"
});
}else if(errcode == 85002){
this.$message({
type: "error",
message: "小程序绑定的体验者数量达到上限"
});
}else if(errcode == 85003){
this.$message({
type: "error",
message: "微信号绑定的小程序体验者达到上限"
});
}else if(errcode == 85004){
this.$message({
type: "error",
message: "微信号已经绑定"
});
}else if(errcode == "0"){
this.$message({
type: "success",
message: "添加小程序体验者成功"
});
}
}
//解除体验者
else if(postUrl == configUrl.unbindTester){
if(errcode == -1){
this.$message({
type: "error",
message: "系统繁忙"
});
}else if(errcode == "0"){
this.$message({
type: "success",
message: "解除绑定成功"
});
}
}
}).catch(err=>{
console.log(err)
this.$message({
type: "error",
message: err.data
});
})
}
this.dialogVisible = false;
}
}
};
</script>

<style scoped>
.fx_dialog_list_chooseSH .el-dialog .el-dialog__footer .dialog-footer .draftBtn,
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
width: 76px;
height: 35px;
font-size: 14px;
padding: 10px 20px;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn {
margin-right: 7.5px;
background: #ffffff;
color: #555555;
border: 1px solid #e1e6ea;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
margin-left: 7.5px;
background: #c85963;
color: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:hover {
background: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:hover {
background: #e26972;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:active {
background: #e1e2e2;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:active {
background: #bf585f;
}
.search{
width: 100%;
text-align: left;
}
</style>

+ 93
- 0
src/components/marketing/businessComp/templateMsg.vue 파일 보기

@@ -0,0 +1,93 @@
<template>
<div>
<el-dialog title="小程序模板列表" :visible="dialogVisible" width="800px" :before-close="closeDialog" :modal-append-to-body="false" class="fx_dialog_list_chooseSH">
<table-list v-if="showAlert" :ref="tKey" :options="optionsTable"></table-list>
</el-dialog>
</div>
</template>

<script>
import TableList from "../../../core/comps/table/tableList.vue";
import commonUtil from "../../../core/tool/commonUtil.js";
import { configUrl } from "./../../../utils/config.js";
import { CacheData } from "./../../../service/couponData/data.js";
export default {
inject: ["reload"],
name: "templateMsg",
props: ["cb", "params"],
components: { TableList },
data() {
return {
showAlert:false,
dialogVisible: false,
appId:"",
disabled: false,
tKey: "chooseApp",
optionsTable: {
actions: [
{
key: "delete",
val: "删除",
action: this.deleteTemplate
}
],
map: [
{ key: "title", val: "标题" },
{ key: "templateId", val: "模板消息Id" }
],
getUrl: () => {},
pageOption: {
sizeKey: "pageSize",
indexKey: "pageNum",
index: 1,
size: 10
},
analysis: data => {
return {
data: data.data.list,
count: data.data.total
};
}
}
};
},
methods: {
openDialog(from) {
let appId = JSON.parse(from).appId;
this.appId = appId;
this.optionsTable.getUrl=()=>{
return configUrl.getTemplateList +"?type=2"+"&appId="+appId
}
this.showAlert=true;
this.dialogVisible = true;
},
closeDialog() {
this.showAlert=false;
this.dialogVisible = false;
},
deleteTemplate(item){
let pamars = {
appId:this.appId,
templateId:item.templateId
};
this.postFetch(configUrl.delTemplate,pamars).then(res=>{
this.$message({
type: "success",
message: "删除成功"
});
this.search();
}).catch(error=>{
this.$message({
type: "error",
message: error.data
});
})
},
search: function() {
let tKey = this.$refs[this.tKey];
tKey.search(tKey.getParams().index);
},
}
};
</script>


+ 175
- 0
src/components/marketing/businessComp/versionWithdraw.vue 파일 보기

@@ -0,0 +1,175 @@
<template>
<div>
<el-dialog
title="批量撤回审核"
:visible="dialogVisible"
width="800px"
:before-close="closeDialog"
:modal-append-to-body="false"
class="fx_dialog_list_chooseSH">
<div style="width:100%">
<table-list :ref="tKey" :options="optionsTable"></table-list>
</div>
<span slot="footer" class="dialog-footer">
<el-button class="draftBtn" @click="dialogVisible = false">取 消</el-button>
<el-button class="putinBtn" @click="childversion">确 定</el-button>
</span>
</el-dialog>
</div>
</template>

<script>
import TableList from "../../../core/comps/table/tableList.vue";
import commonUtil from "../../../core/tool/commonUtil.js";
import { configUrl } from "./../../../utils/config.js";
import { CacheData } from "./../../../service/couponData/data.js";

export default {
inject: ["reload"],
name: "versionWithdraw",
props: ["tKey", "cb"],
components: { TableList },
data() {
return {
dialogVisible: false,
title:"",
brands:[],
flag:"",
ruleForm: {
authorizerAppid: '',
type:""
},
businessData:[],
optionsTable: {
singleSelected: true,
showCk: true,
map: [
{ key: "version", val: "小程序版本号"}
],
getUrl:() => {
//批量撤回审核
return configUrl.auditVersionList;
},
pageOption: {
showIf:false,
sizeKey: "pageSize",
indexKey: "pageNum",
index: 1,
size: 10
},
analysis: data => {
return {
data: data.data
};
}
}
};
},
methods: {
openDialog() {
this.dialogVisible = true;
},
search: function() {
let tKey = this.$refs[this.tKey];
tKey.search(tKey.getParams().index);
},
closeDialog() {
this.dialogVisible = false;
},
//请选择小程序的版本
childversion() {
let items = this.$refs[this.tKey].getCheckedItems("version");
if (items.data.length != 1) {
this.$message({
type: "error",
message: "请选择小程序的版本号!"
});
return;
} else {
let params = {
version:JSON.stringify(items.vals).replace(/\[|]/g,'').replace(/\"/g, "")
};
let postUrl = configUrl.batchAuditCancel;
this.postFetch(postUrl,params).then(res=>{
ithis.$message({
type: "success",
message: "批量撤回审核成功!"
})
}).catch(err=>{
this.$message({
type: "error",
message: err.data,
});
})
}
this.dialogVisible = false;
}
}
};
</script>
<style scoped>
.fx_dialog_list_chooseSH .el-dialog .el-dialog__footer .dialog-footer .draftBtn,
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
width: 76px;
height: 35px;
font-size: 14px;
padding: 10px 20px;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn {
margin-right: 7.5px;
background: #ffffff;
color: #555555;
border: 1px solid #e1e6ea;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn {
margin-left: 7.5px;
background: #c85963;
color: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:hover {
background: #ffffff;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:hover {
background: #e26972;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.draftBtn:active {
background: #e1e2e2;
}
.fx_dialog_list_chooseSH
.el-dialog
.el-dialog__footer
.dialog-footer
.putinBtn:active {
background: #bf585f;
}
.search{
width: 100%;
height: 50px;
text-align: left;
margin-left: 20px;
}
</style>

+ 230
- 0
src/components/member/list.vue 파일 보기

@@ -0,0 +1,230 @@
<template>
<div class="layout server">
<div class="title">
<h3>成员管理</h3>
</div>
<el-button type="primary" @click="addMember('add')">添加体验者</el-button>
<el-button type="primary" @click="addMember('delete')">删除体验者</el-button>
<member :params="params" :ref="tKey" :t-key="tKey" :cb="addMember"></member>
</div>
</template>
<script>

import { configUrl } from "./../../utils/config.js";
import { mapState, mapActions } from "vuex";
import moment from 'moment';
import alertDialog from "../../core/comps/input/alertDialog.vue";
import commonUtil from './../../core/tool/commonUtil';
import member from "./../../components/marketing/businessComp/member.vue";
export default {
name: 'draft',
components: {alertDialog,member},
data () {
return {
data:[],
tk:"memberTableKey",
tKey: "member",
params:"",
ruleForm: {
appId: "",
},
rules:{
appId: [
{
min: 1,
max: 50,
message: "副标题最大50个字符!",
trigger: "blur"
}
],
},
}
},
computed:{
...mapState({
topNav:state=>state.topNav.data, //将 this.topNav 映射为 this.$store.topNav.data
channels:state=>state.couponStore.channels,
index:state=>state.topNav.index
})
},
methods:{
...mapActions([
"setIndex"
]),
//选择小程序
addMember(item) {
console.log(item);
this.params = item;
this.$refs[this.tKey].openDialog(item);
},
search:function(){
let tk = this.$refs[this.tk];
tk.search(tk.getParams().index);
},
},
created() {
this.setIndex("5");
}
}
</script>
<style scoped>
.content{
margin-top: 30px;
}
.tableContainer{
width: 100%;
}
.h3{
font-size: 16px;
}
.sever{
border-radius: 4px;
border:1px solid #e7e7eb;
padding: 0 20px 10px;
margin-bottom: 20px;
}
.title{
margin-bottom: 10px;
}
.title h3{
font-size: 18px;
font-weight: bold;
}
.layout-content{
background: #fff;
overflow: hidden;
}
.btn-group{
text-align: center;
margin-top: 26px;
}
.layout-content table{
width:100%;
}
.layout-content table tr td{
padding:17px 0;
text-align:left;
}
.layout-content table tr td:nth-child(1){
padding:17px 0 17px 18px;
width:200px;
text-align:center;
}
.layout-content table tr td:nth-child(2){
padding:17px 15px;
width:10px;
text-align:center;
}
.layout-content table tr td:nth-child(3){
padding:17px 10px 17px 0;
width:180px;
text-align:center;
}
.layout-content table tr td:nth-child(4){
padding:17px 10px;
width:240px;
text-align:center;
}
.layout-content table tr td:nth-child(5){
padding:17px 10px;
text-align:left;
}
.layout-content table tr:hover{
cursor:pointer;
background:#F4F7F9;
}

.editBox,.delBox{
width:40px;
height:40px;
text-align:center;
line-height:40px;
display:inline-block;
color:#fff;
font-size:14px;
border-radius:3px;
margin-right:20px;
display:none;
}
.editBox{
background:#51A9C9;
}
.delBox{
background:#EE7653;
}
.layout-content table tr:hover .editBox{
display:inline-block;
}
.layout-content table tr:hover .delBox{
display:inline-block;
}
.btnGroupBox{
margin-top:20px;
}
.addBox{
width:146px;
height:40px;
text-align:center;
line-height:40px;
display:inline-block;
color:#fff;
font-size:14px;
border-radius:3px;
margin-right:20px;
background:#6B5EC9;
cursor:pointer;
}

.addBox i{
margin-right:5px;
}
.saveBox{
width:91px;
height:40px;
text-align:center;
line-height:40px;
display:block;
color:#fff;
font-size:14px;
border-radius:3px;
background:#51A9C9;
margin: 0 auto!important;
cursor:pointer;
}
.addBox:hover{
background:#7A6CE1;
}
.addBox:active{
background:#6357BB;
}
.editBox:hover{
background:#5DC1E5;
}
.editBox:active{
background:#4490AB;
}
.saveBox:hover{
background:#5DC1E5;
}
.saveBox:active{
background:#4490AB;
}
.delBox:hover{
background:#FF8460;
}
.delBox:active{
background:#DF6F4E;
}
</style>
<style>
.save{
display: block;
width:90px;
margin:0 auto;
}
.tips{
color:red;
text-align:center;
margin-top:10px;
}
</style>

+ 379
- 0
src/components/release/list.vue 파일 보기

@@ -0,0 +1,379 @@
<template>
<div class="layout">
<div class="title">
<h3>发布列表</h3>
</div>
<div class="layout-content">
<el-form :inline="true" :model="ruleForm" ref="ruleForm" class="demo-form-inline" label-position="right">
<el-form-item label="发布状态" prop="releaseStatus" class="fx_send">
<el-select v-model="ruleForm.releaseStatus" placeholder="请选择" clearable>
<el-option v-for="(item,index) in releaseStatus" :key="index" :value="item.value" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="小程序类型" prop="type" class="fx_send">
<el-select v-model="ruleForm.type" placeholder="请选择" clearable>
<el-option v-for="(item,index) in appType" :key="index" :value="item.value" :label="item.name"></el-option>
</el-select>
</el-form-item>
<el-form-item label="小程序名称" prop="name" class="fx_title">
<el-input v-model="ruleForm.name" placeholder="请输入" clearable></el-input>
</el-form-item>
<el-form-item label="小程序版本号" class="fx_send">
<el-select v-model="ruleForm.userVersion" placeholder="请选择" clearable>
<el-option v-for="(item,index) in version" :key="index" :value="item.version" :label="item.version"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button class="hoverBtn" type="primary" icon="el-icon-search" size="medium" @click.stop="search"></el-button>
</el-form-item>
<el-form-item>
<el-button class="hoverBtn" type="primary" @click.stop="refresh">刷新</el-button>
</el-form-item>
</el-form>
</div>
<table-list :ref="tk" :options="optionsTable"></table-list>
<choose-version :paramers="paramers" :ref="tKey" :t-key="tKey" :cb="getShopCb"></choose-version>
</div>
</template>
<script>
import {mapState, mapActions} from "vuex";
import TableList from "../../core/comps/table/tableList.vue";
import { CacheData } from "./../../service/couponData/data.js";
import { configUrl } from "./../../utils/config.js";
import chooseVersion from "./../../components/marketing/businessComp/chooseVersion.vue";
export default {
name: 'release',
components: {TableList,chooseVersion},
data(){
return {
listNavKey:"releaseNavKey",
tk:"releaseKey",
paramers:"",
params:"",
src: '',
version:[],
tKey: "chooseVersion",
ruleForm:{
auditStatus:"",
releaseStatus:"",
codeStatus:"",
type:"",
appId:"",
name:"",
userVersion:"",
},
optionsTable:{
actions :[
{key:"edit",val:"版本回退",action:this.revertCodeRelease,show:(item)=>{
if(item.releaseStatus == 0){
return true;
}
return false;
}},
],
map: [
{ key: "name", val: "小程序名称"},
{ key: "appId", val: "授权方appid"},
{ key:"type", val:"小程序类型",convert:this.cAppType},
{ key:"userVersion", val:"版本号"},
{ key:"versionDesc", val:"版本描述"},
{ key:"releaseStatus", val:"发布状态",convert:this.cReleaseStatus},
{ key:"releaseTime", val:"发布时间",type:"dateTime"},
{ key:"releaseErrCode", val:"错误码"}
],
getUrl:()=>{
let releaseStatus = this.ruleForm.releaseStatus;
let type = this.ruleForm.type;
let name = this.ruleForm.name;
let userVersion = this.ruleForm.userVersion;
if(userVersion){
return configUrl.releaseStatusList+"?releaseStatus="+releaseStatus+"&type="+type+"&name="+name+"&userVersion="+userVersion;
}else{
return configUrl.releaseStatusList+"?releaseStatus="+releaseStatus+"&type="+type+"&name="+name;
}
},
pageOption:{
sizeKey:"pageSize",
indexKey:"pageNum",
index:1,
size:10
},
analysis:(data)=>{
// data.data.list.map(file=>{
// if(file.releaseErrCode=='{"errcode":"0","errmsg":"ok"}'){
// file.releaseErrCode =""
// }
// })
return {
data:data.data.list,
count:data.data.total
};
}
}
}
},
computed:{
appType:()=>{
return CacheData.appType;
},
releaseStatus:()=>{
return CacheData.releaseStatus;
},
...mapState({
topNav:state=>state.topNav.data, //将 this.topNav 映射为 this.$store.topNav.data
channels:state=>state.couponStore.channels,
navigationInfo:state=>state.topNav.navigationInfo
})
},
created() {
this.setIndex("4");
},
mounted(){
//获得小程序的版本号
this.getFetch(configUrl.releaseVersionList).then(res=>{
console.log(res)
this.version = res.data;
}).catch(error=>{
console.log(error);
})
},
methods:{
...mapActions([
"setIndex"
]),
//小程序版本回退
revertCodeRelease(item){
console.log(item);
this.getFetch(configUrl.revertCodeRelease+"?appId="+item.appId).then(res=>{
console.log(res);
this.search();
}).catch(err=>{
this.$message({
type: "error",
message: err.data
});
})
},
//选择版本号或者小程序
getShopCb(items) {
this.shopTableData = [];
items.data.map((item, index) => {
let haveIf = false;
this.shopTableData.map((item01, index01) => {
if(item.id == item01.id) {
haveIf = true
}
})
if (haveIf == false) {
item.merchantName = item.name;
item.merchantLinkPhone = item.linkPhone
this.shopTableData.push(item);
}
})
},
//批量撤回小程序
searchAudit(flag) {
console.log(flag)
this.paramers = flag;
this.$refs[this.tKey].openDialog(flag);
},
//撤回审核
auditCancel(item){
this.getFetch(configUrl.undoCodeAudit+"?appId="+item.appId).then(res=>{
this.search();
this.$message({
type:"success",
message:"撤回审核成功"
})
}).catch(err=>{
console.log(err)
if(typeof(err.data)=="string"){
var errcode = JSON.parse(err.data).errcode;
}else{
var errcode = err.data.errcode;
console.log(typeof(err.data))
}
if(errcode == 0){
this.$message({
type: "error",
message: "系统繁忙"
});
}else if(errcode == -1){
this.$message({
type: "error",
message: "系统繁忙"
});
}else if(errcode == 87013){
this.$message({
type: "error",
message: "撤回次数达到上限(每天一次,每个月10次)"
});
}else if(errcode == 45009){
this.$message({
type: "error",
message: "公众号接口访问次数到达了上限"
});
}
})
},
//发布单个小程序
goSubmit(item){
let paramer = {
apps:item.appId
};
this.postFetch(configUrl.batchRelease,paramer).then(res=>{
console.log(res);
this.$message({
type: "success",
message: "批量发布小程序成功"
});
this.search();
}).catch(err=>{
console.log(err)
this.$message({
type: "error",
message: err.data
});
})
},
//批量提交小程序审核
reviewApp(item) {
let items = {
from:item
}
console.log(items)
this.$refs[this.tKey1].openDialog(JSON.stringify(items));
},
//刷新
refresh(){
this.search();
},
search:function(){
let tk = this.$refs[this.tk];
tk.search(tk.getParams().index);
},
goErCode: function (item) {
let weiXinUrl = configUrl.getQrcode+"?appId="+item.appId+'&pagePath='+'pages/index/index';
        this.$alert("<strong><img src="+ weiXinUrl + " width=100px height=100px></strong>", item.name+'体验版', {
          dangerouslyUseHTMLString: true,
closeOnClickModal:true,
showConfirmButton:true,
showClose:false,
center:true
        })
},
//小程序提交审核
submitcheck: function (item) {
let parmer = {
apps:item.appId,
userVersion:item.userVersion
}
this.postFetch(configUrl.batchCodeAudit,parmer).then(res=>{
console.log(res)
this.$message({
type: "success",
message:"提交审核成功"
})
}).catch(error=>{
console.log(error)
this.$message({
type: "error",
message:error.data
})
})
},
//小程序的类型
cAppType(col, item) {
console.log(item)
let res = CacheData.appType.filter(e => {
return e.value == item.type;
})[0];
console.log(res)
if (res) {
return res.name;
} else {
console.log("error:异常券id:", item.id);
return "";
}
return res.name;
},
//小程序审核状态
cReleaseStatus(col, item){
console.log(item)
let res = CacheData.releaseStatus.filter(e => {
return e.value == item.releaseStatus;
})[0];
console.log(res)
if (res) {
return res.name;
} else {
return "";
}
return res.name;
},
},
}
</script>
<style scoped>
.lip{
padding-top: 30px;
}
.lip span{
color: red;
}
.title{
margin-bottom: 10px;
}
.title h3{
font-size: 18px;
font-weight: bold;
}
.content span{
font-size: 15px;
}
.content span:nth-of-type(1){
color: #19ce00;
font-weight:bold;
margin-right: 20px;
}
.content span:nth-of-type(2){
margin-right: 20px;
cursor: pointer;
}
.layout-content{
margin-top: 20px;
background: #f6f6f6;
padding: 29px 20px 0;
border-radius:6px;
}
.el-select-dropdown__item{
display: block;
}
.tableContainer{
width: 100%;
margin-top: 23px;
}
</style>
<style>
.el-message-box{
width:300px;
padding:0 0 20px;
}
.el-message-box img{
width:200px;
height: 200px;
display:block;
margin:0 auto;
}
.el-message-box__header{
text-align:center;
font-size:14px!important;
}
.el-message-box__btns button{
width:100px!important;
}
.el-message-box__title{
font-size:16px;
}
</style>


+ 69
- 0
src/components/tools/baiduMap.vue 파일 보기

@@ -0,0 +1,69 @@
<template>
<el-dialog
title='搜索定位您的详细地址'
:visible="dialogVisible"
width="500px" :show-close=true :before-close="handleClose">
<baidu-map sytle="height:280px;width:100%;" :map-click=false :center="center" :zoom="zoom" @ready="handler">
<bm-view style="height:280px;width:100%"></bm-view>
<bm-control :offset="{width: '10px', height: '10px'}">
<bm-auto-complete v-model="keyword" :sugStyle="{zIndex: 9999}">
<input style="height:5vh;width:30vw;font-size:12px;text-indent: 1em;
border: 1px solid #eee;
border-radius: 6px;" placeholder="请输入关键字"/> <!-- 这里指代一个自定义搜索框组件 -->
</bm-auto-complete>
</bm-control>
<bm-local-search :pageCapacity="3" :keyword="keyword" @infohtmlset="getpoi" :auto-viewport="true"></bm-local-search>
</baidu-map>
</el-dialog>
</template>

<script>
export default {
name: 'baidumap',
props:['setpoi'],
data () {
return {
center: {lng: 0, lat: 0},
zoom: 3,
dialogVisible:false,
location: '',
keyword: ''
}
},
methods:{
openDialog(){
this.dialogVisible = true;
},
handler ({BMap, map}) {
console.log(BMap, map)
this.center.lng = 116.404
this.center.lat = 39.915
this.zoom = 15
},
getpoi(info){
this.dialogVisible = false;
this.setpoi(info);
},
handleClose(done) {
this.$confirm('确认关闭?')
.then(_ => {
this.keyword='';
this.dialogVisible=false;
})
.catch(_ => {});
},
syncCenterAndZoom (e) {
const {lng, lat} = e.target.getCenter()
}

}
}
</script>

<style scoped>
.el-dialog__body{
padding-top: 0;
}
</style>

+ 38
- 0
src/components/tools/uploadImg.vue 파일 보기

@@ -0,0 +1,38 @@
<template>
<div>
<file-upload fname="file" :url="imageUploadUrl" :completed-callback="uploadCb"></file-upload>
{{filePath}}
</div>
</template>

<script>
import commonUtil from '../../core/tool/commonUtil';
import FileUpload from "../../core/comps/upload/upload.vue";

export default {
name: 'ImgUpload',
components: {FileUpload},
data () {
return {
imageUploadUrl:"/api/upload/awsFileUpload",
filePath:""
}
},
methods:{
uploadCb(d){
if(d.success){
this.filePath = d.data.data.url;
}
}
},
mounted(){
}

}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

+ 105
- 0
src/core/comps/input/alertDialog.vue 파일 보기

@@ -0,0 +1,105 @@
<template>
<div>
<el-dialog class="alertDialog" top="40vh" :visible="dialogVisible" :before-close="closeDialog" width="443px" :append-to-body='true'>
<div class="contentBox">
<i :class="icon"></i><span v-html="title"></span>
</div>
<div class="btnGroupBox">
<span class="cancelBtn" @click="dialogVisible = false;">取消</span>
<span class="sureBtn" @click="clickSure">确定</span>
</div>
</el-dialog>
</div>
</template>
<script>
import commonUtil from '../../tool/commonUtil.js';
import {CouponCacheData} from "../../../service/couponData/data.js";
import {mapState, mapActions} from "vuex";
export default {
name: 'alertDialog',
components: {},
data() {
return {
dialogVisible: false,
title: '',
icon: 'el-icon-warning',
cb:function(){
}
}
},
computed:{
...mapState({
topNav:state=>state.topNav.data,//将 this.topNav 映射为 this.$store.topNav.data
navigationInfo:state=>state.topNav.navigationInfo
}),
},
methods: {
openDialog(title,cb,icon) {
this.dialogVisible = true;
this.title = title;
if(cb){
this.cb=cb;
}
if (icon) {
this.icon = icon;
}
},
closeDialog() {
this.dialogVisible = false;
},
clickSure(){
this.cb()
this.dialogVisible = false;
}
},
mounted: function() {

}
}
</script>
<style scoped>
.contentBox {
text-align: left;
padding: 25px 15px;
}

.contentBox i {
font-size: 24px;
color: #e6a23c;
margin-right: 12px;
vertical-align: middle;
}

.contentBox span {
color: #606266;
font-size: 14px;
line-height: 24px;
}

.btnGroupBox{
text-align: right;
}
.btnGroupBox span {
width: 76px;
height: 35px;
display: inline-block;
line-height: 35px;
text-align: center;
border-radius: 3px;
font-size: 14px;
margin-left: 15px;
cursor: pointer;
}

.cancelBtn {
background: rgba(255, 255, 255, 1);
border: 1px solid rgba(225, 230, 234, 1);
}

.sureBtn {
border: 1px solid rgba(200, 89, 98, 1);
background: rgba(200, 89, 98, 1);
color: #fff;
}
</style>

+ 86
- 0
src/core/comps/input/vInput.vue 파일 보기

@@ -0,0 +1,86 @@
<template>
<div>
<div v-bind:class="state.borderCls">
<div class="input-group mb-3">
<input type="text" class="form-control" v-model="vValue" aria-label="Amount (to the nearest dollar)" v-on:input="changeEvent()">
<div class="input-group-append">
<span class="input-group-text icon" v-bind:class="state.successIcon"></span>
</div>
</div>
<p class="text-left" v-show="state.showError">{{errorMsg}}</p>
</div>
</div>
</template>

<script>
import Util from "../../../core/tool/commonUtil";
export default{
name:"VInput",
props:["errorMsg","vType"],
data(){
return {
vValue:"",
state:{
flag:false,
showError:false,
borderCls:"inputIcon",//inputRedIcon inputGreenIcon inputIcon
successIcon:""//icon-cuo,icon-duihao
}
}
},
methods:{
setIsSuccess(flag){
if(flag){
this.state = {
borderCls:"inputGreenIcon",
successIcon:"icon-duihao",
showError:false,
flag:true
}
}else{
this.state = {
borderCls:"inputRedIcon",
successIcon:"icon-cuo",
showError:true,
flag:false
}
}
},
changeEvent(e){
this.setIsSuccess(this.verify(this.vValue));
},
verify(val){
var reg = /^[0-9]*$/;
if (!reg.test(val)) {
return false;
}
return true;
},
getResult(){
return {
success:this.state.flag,
value:this.vValue
}
}
},
mounted () {
},
created () {
}
}
</script>

<style scoped>
.inputRedIcon input{border-right: 0;border-color: red;outline: none;}
.inputRedIcon div span.icon{background: #fff;border-color: red;color: red;}
.inputRedIcon p{color: red;}


.inputGreenIcon input{border-right: 0;}
.inputGreenIcon div span.icon{background: #fff;font-size: 16px;color: rgb(72, 255, 0);}
.inputGreenIcon p{display: none}

.inputIcon{border-right: 0;}
</style>

+ 32
- 0
src/core/comps/input/正则表达式 파일 보기

@@ -0,0 +1,32 @@
验证数字:^[0-9]*$
验证n位的数字:^\d{n}$
验证至少n位数字:^\d{n,}$
验证m-n位的数字:^\d{m,n}$
验证零和非零开头的数字:^(0|[1-9][0-9]*)$
验证有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
验证有1-3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
验证非零的正整数:^\+?[1-9][0-9]*$
验证非零的负整数:^\-[1-9][0-9]*$
验证非负整数(正整数 + 0) ^\d+$
验证非正整数(负整数 + 0) ^((-\d+)|(0+))$
验证长度为3的字符:^.{3}$
验证由26个英文字母组成的字符串:^[A-Za-z]+$
验证由26个大写英文字母组成的字符串:^[A-Z]+$
验证由26个小写英文字母组成的字符串:^[a-z]+$
验证由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
验证由数字、26个英文字母或者下划线组成的字符串:^\w+$
验证用户密码:^[a-zA-Z]\w{5,17}$ 正确格式为:以字母开头,长度在6-18之间,只能包含字符、数字和下划线。
验证是否含有 ^%&',;=?$\" 等字符:[^%&',;=?$\x22]+
验证汉字:^[\u4e00-\u9fa5],{0,}$
验证Email地址:/^([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\_|\.]?)*[a-zA-Z0-9]+\.[a-zA-Z]{2,3}$/
验证InternetURL:^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$ ;^[a-zA-z]+://(w+(-w+)*)(.(w+(-w+)*))*(?S*)?$
验证电话号码:^(\(\d{3,4}\)|\d{3,4}-)?\d{7,8}$:--正确格式为:XXXX-XXXXXXX,XXXX-XXXXXXXX,XXX-XXXXXXX,XXX-XXXXXXXX,XXXXXXX,XXXXXXXX。
验证身份证号(15位或18位数字):^\d{15}|\d{}18$
验证一年的12个月:^(0?[1-9]|1[0-2])$ 正确格式为:“01”-“09”和“1”“12”
验证一个月的31天:^((0?[1-9])|((1|2)[0-9])|30|31)$ 正确格式为:01、09和1、31。
整数:^-?\d+$
非负浮点数(正浮点数 + 0):^\d+(\.\d+)?$
正浮点数 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
非正浮点数(负浮点数 + 0) ^((-\d+(\.\d+)?)|(0+(\.0+)?))$
负浮点数 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮点数 ^(-?\d+)(\.\d+)?$

+ 101
- 0
src/core/comps/select/bottom.vue 파일 보기

@@ -0,0 +1,101 @@
<template>
<div class="pullItem">
<p :class="item.cls" @click.stop="selectItem(item)" v-for="(item,index) in data" :key="index">{{item.name}}<span class="icon icon-duihaocheckmark17"></span></p>
</div>
</template>

<script>

export default {
name: 'BottomSection',
props:['data','noticeParent'],
data () {
return {
}
},
methods:{
selectItem:function(item){
this.noticeParent(item);
}
}
}
</script>

<style scoped>
.chooseZh {padding-top:30px;}
.right {
width:80%;
border:1px solid #e6e6e6;
border-radius:5px;
padding:5px 0 0;
margin:auto;
}
.defaultSpan {
display:inline-block;
height:26px;
line-height:26px;
margin-bottom:5px;
margin-left:5px;
}
.groupSpan {
float:left;
/* width:90%; */
margin-left:5px;
overflow-x:hidden;
overflow-y:auto;
max-height:150px;
}
.groupSpan span.icon{font-size:12px;}
.item {
background:aliceblue;
border-radius:5px;
padding:5px;
margin-right:5px;
margin-bottom:5px;
}
.delG {
width:15px;
height:15px;
margin-left:3px;
border:1px solid #e6e6e6;
border-radius:50%;
background-color:#f2f2f2;
}
.clear {
width:15px;
height:15px;
margin-right:5px;
margin-top:6px;
}
.pull {
width:15px;
height:15px;
margin-top:6px;
margin-right:5px;
}
.pullItem p {text-align: left}
.pullItem p span{float: right}
.pullItem {
overflow-x:hidden;
overflow-y:auto;
width:80%;
margin:auto;
max-height:150px;
margin-bottom:10px;
border:1px solid #e6e6e6;
border-top:none;
border-radius:0 0 5px 5px;
}
.pullItem p {
height:30px;
line-height:30px;
padding:0 5px;
}
.pullItem p:HOVER {background-color:cornflowerblue;color:white;}
.pullItemCkBgc {background-color:cornflowerblue;}
.over {overflow:hidden;}
.fl {float:left;}
.fr {float:right;}
.input{height: 30px;width: 200px;border:none;outline: none}
</style>

+ 106
- 0
src/core/comps/select/left.vue 파일 보기

@@ -0,0 +1,106 @@
<template>
<div>
<span class="groupSpan over" v-for="(item,index) in data" :key="index">
<div class="item over fl">
<span class="fl">{{item.name}}</span>
<span class="icon icon-cuo" @click.stop="removeItem(item)"></span>
</div>
</span>
</div>
</template>

<script>
export default {
name: 'LeftSection',
components: {},
props:["data","noticeParent"],
data () {
return {

}
},
methods:{
removeItem:function(item){
this.noticeParent(item);
}
}
}
</script>

<style scoped>
.chooseZh {padding-top:30px;}
.right {
width:80%;
border:1px solid #e6e6e6;
border-radius:5px;
padding:5px 0 0;
margin:auto;
}
.defaultSpan {
display:inline-block;
height:26px;
line-height:26px;
margin-bottom:5px;
margin-left:5px;
}
.groupSpan {
float:left;
/* width:90%; */
margin-left:5px;
overflow-x:hidden;
overflow-y:auto;
max-height:150px;
}
.groupSpan span.icon{font-size:12px;}
.item {
background:aliceblue;
border-radius:5px;
padding:5px;
margin-right:5px;
margin-bottom:5px;
}
.delG {
width:15px;
height:15px;
margin-left:3px;
border:1px solid #e6e6e6;
border-radius:50%;
background-color:#f2f2f2;
}
.clear {
width:15px;
height:15px;
margin-right:5px;
margin-top:6px;
}
.pull {
width:15px;
height:15px;
margin-top:6px;
margin-right:5px;
}
.pullItem p {text-align: left}
.pullItem p span{float: right}
.pullItem {
overflow-x:hidden;
overflow-y:auto;
width:80%;
margin:auto;
max-height:150px;
margin-bottom:10px;
border:1px solid #e6e6e6;
border-top:none;
border-radius:0 0 5px 5px;
}
.pullItem p {
height:30px;
line-height:30px;
padding:0 5px;
}
.pullItem p:HOVER {background-color:cornflowerblue;color:white;}
.over {overflow:hidden;}
.fl {float:left;}
.fr {float:right;}
.input{height: 30px;width: 200px;border:none;outline: none}
</style>

+ 171
- 0
src/core/comps/select/localSelect.vue 파일 보기

@@ -0,0 +1,171 @@
<template>
<div class="chooseZh">
<div class="right" id="zhPull">
<div class="over" style="text-align: left;">
<left-section :data="datas.leftArray" :notice-parent="noticeFromLeft"></left-section>
<input @click.stop="clickInput" type="text" class="input" v-model="datas.searchName" @input="inputChange" />
{{datas.searchName}}
</div>
<bottom-section :data="datas.bottomArray" :notice-parent="noticeFromBottom"></bottom-section>
</div>
</div>
</template>

<script>
import CommonUtil from '../../tool/commonUtil.js';
import LeftSection from "./left.vue";
import BottomSection from "./bottom.vue";

export default {
name: 'LocalSelect',
props:["data","analysis"],
components: {LeftSection,BottomSection},
data () {
return {
datas:{
searchName:"",
bottomArray:[],
leftArray:[],
}
}
},
computed:{
originData:function(){
let tmp = CommonUtil.object.cloneObj(this.analysis(this.data));
if(tmp && tmp instanceof Array){
tmp.forEach(item=>{
item.ck = false;
item.__tmpId = Math.ceil(Math.random()*10000000000000000);
item.cls = "";
})
return CommonUtil.object.addPrimaryAndCk(tmp);
}
return [];
}
},
methods:{
clickInput:function(){
if(this.datas.searchName != ""){
this.datas = {
searchName:"",
bottomArray:[],
leftArray:this.datas.leftArray
}
}else{
this.datas.bottomArray = this.fliterOriginData();
}
},
inputChange:function(){
this.datas.bottomArray = this.fliterOriginData();
},
fliterOriginData:function(){
let res = this.originData.filter(item=>{
return item.name.indexOf(this.datas.searchName) != -1;
})
return res;
},
init:function(data){
this.data = data;
},
updateLeftBottom:function(item){
this.datas = {
searchName:"",
bottomArray:this.originData,
leftArray:CommonUtil.object.getCheckedItems(this.originData).items
}
},
noticeFromBottom:function(item){
if(item.ck){
item.ck = false;
item.cls = "";
}else{
item.ck = true;
item.cls = "pullItemCkBgc";
}
this.updateLeftBottom(item);
},
noticeFromLeft:function(item){
item.ck = false;
item.cls = "";
this.updateLeftBottom(item);
},
bodyClick:function(){
this.datas = {
searchName:"",
bottomArray:[],
leftArray:CommonUtil.object.getCheckedItems(this.originData).items
}
},
getSelectedItems:function(){
return CommonUtil.object.cloneObj(CommonUtil.object.getCheckedItems(this.originData,"code"));
}
},
created () {
document.body.addEventListener("click",this.bodyClick,false);
},
beforeDestroy () {
document.body.removeEventListener("click",this.bodyClick)
}
}
</script>

<style scoped>
.chooseZh {padding-top:30px;}
.right {
width:80%;
border:1px solid #e6e6e6;
border-radius:5px;
padding:5px 0 0;
margin:auto;
}
.defaultSpan {
display:inline-block;
height:26px;
line-height:26px;
margin-bottom:5px;
margin-left:5px;
}
.groupSpan {
float:left;
/* width:90%; */
margin-left:5px;
overflow-x:hidden;
overflow-y:auto;
max-height:150px;
}
.groupSpan span.icon{font-size:12px;}
.item {
background:aliceblue;
border-radius:5px;
padding:5px;
margin-right:5px;
margin-bottom:5px;
}
.delG {
width:15px;
height:15px;
margin-left:3px;
border:1px solid #e6e6e6;
border-radius:50%;
background-color:#f2f2f2;
}
.clear {
width:15px;
height:15px;
margin-right:5px;
margin-top:6px;
}
.pull {
width:15px;
height:15px;
margin-top:6px;
margin-right:5px;
}
.over {overflow:hidden;}
.fl {float:left;}
.fr {float:right;}
.input{height: 30px;width: 200px;border:none;outline: none}
</style>

+ 174
- 0
src/core/comps/table/body.vue 파일 보기

@@ -0,0 +1,174 @@
<template>
<tbody>
<tr v-for="(row,index) in data" @click="e=>selectRow(row,e)" :key="index" v-if="data && data.length>0">
<td v-if="showCk">
<div v-if="singleSelected">
<input :name="radioKey" type="radio" :checked="row.ck" />
</div>
<div v-else>
<input type="checkbox" :checked="row.ck" />
</div>
</td>
<td v-for="(item,idx) in cols" :key="idx" :style="item.key=='title'&&textAlignKey==true?'text-align:left;':''">
<div v-if="item.etype == 'img'">
<img style="width:100px;height:75px;border-radius:5px;" v-bind:src="row[item.key]" />
</div>
<div v-else style="position:relative;">
<a v-if="item.convert && item.action" @click.prevent="e=>item.action(row,item)">
{{item.convert(item,row)}}
</a>
<span v-if="item.convert && !item.action">
{{item.convert(item,row)}}
</span>
<a v-if="!item.convert && item.action" @click.prevent="e=>item.action(row,item)">
{{getValByFieldInRow(item,row)}}
</a>
<span v-if="!item.convert && !item.action">
{{getValByFieldInRow(item,row)}}
</span>
<img v-if="item.img && item.img(item, row)" style="display:block;position:absolute;top:0;right:0;" :src="item.img(item, row)"/>
</div>
</td>
<td v-if="actions && actions.length != 0" class="operationButtonBox">
<span class="tableBtn" style="color:rgb(200, 89, 99);" v-if="actionShowFn(x,row)" v-for="(x,i) in actions" @click.prevent="e=>{x.action(row)}" :key="i">
<i class="iconfont" v-if="x.val=='编辑'"></i><i class="iconfont" v-if="x.val=='复制'"></i><i class="iconfont" v-if="x.val=='投放'"></i><i class="iconfont" v-if="x.val=='上线'"></i><i class="iconfont" v-if="x.val=='查看'" style="font-size:12px !important;"></i><i class="iconfont" v-if="x.val=='修改'"></i><i class="iconfont" v-if="x.val=='退款'"></i><i class="iconfont" v-if="x.val=='下线'"></i><i class="" v-if="x.val=='作废'"></i><i class="" v-if="x.val=='停用'"></i><i class="" v-if="x.val=='删除'"></i><i class="iconfont" v-if="x.val=='终止'"></i><i class="iconfont" v-if="x.val=='周期'"></i><i class="" v-if="x.val=='结单'"></i>{{x.val}}
</span>
</td>
</tr>
<tr v-if="!data||data.length==0">
<td :colspan="[actions && actions.length != 0?cols.length:(cols.length+1)]" style="text-align:center !important;">暂无数据</td>
</tr>
</tbody>
</template>
<script>
import Util from "../../tool/commonUtil.js";
import { mapState, mapActions } from "vuex";

export default {
name: "BodySection",
props: ["actions", "data", "cols", "accpetHBNotice", "showCk", "singleSelected"],
data() {
return {
radioKey: Math.ceil(Math.random() * 10000000),
textAlignKey:false,
}
},
computed: {
...mapState({
topNav: state => state.topNav.data, //将 this.topNav 映射为 this.$store.topNav.data
navigationInfo: state => state.topNav.navigationInfo
}),
},
created() {
this.cols.forEach(s => {
if (s.etype == 'img') {
this.textAlignKey = true;
}
});
},
methods: {
actionShowFn(action, row) {
if (action.show) {
return action.show(row);
} else {
return true;
}
return;
},
selectRow: function(row, e) {
if (this.singleSelected) {
this.data.forEach(el => {
el.ck = false;
});
}
row.ck = !row.ck;
this.accpetHBNotice(null, { data: this.data });
},
getValByFieldInRow: function(item, row) {
let key = item.key;
let val = "";
if (typeof row[key] == "boolean") {
val = row[key].toString();
} else {
let v = "row." + item.key;
let tmp = eval("(" + v + ")");
if (tmp == undefined) {
val = "";
} else {
let type = item.type;
if (type) {
type = type.toLowerCase();
switch (type) {
case "date":
val = Util.date.date(tmp);
break;
case "datetime":
val = Util.date.dateTime(tmp);
break;
case "time":
val = Util.date.time(tmp);
break;
default:
val = tmp;
}
} else {
val = tmp;
}
}
}
return val;
}
}
}
</script>
<style scoped>
.tableList .relative {
position: relative;
}

.tableList .maskLayer {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
}

.btnCls {
margin: 0 5px;
}

tbody tr:hover {
background: #f5f7f8 !important;
}

tbody tr td {
color: rgba(0, 0, 0, 0.65);
border-bottom: 1px solid #ddd;
vertical-align: middle;
text-align: center;
}

.operationButtonBox {
width: 160px !important;
overflow: hidden;
}

.tableBtn {
display: inline-block;
font-size: 14px !important;
margin: 5px 7px !important;
cursor: pointer;
/* display: inline-block; */
}

.tableBtn i {
font-size: 14px !important;
margin-right: 6px !important;
font-weight: bolder;
}

.btn-sm {
padding: 0 10px;
}
</style>

+ 102
- 0
src/core/comps/table/header.vue 파일 보기

@@ -0,0 +1,102 @@
<template>
<thead>
<tr>
<th v-if="showCk">
<div v-if="!singleSelected">
<input type="checkbox" :checked="ck" @click="setAll" />
</div>
</th>
<th v-for="(item,index) in cols" :key="index" class="thCols">
{{item.val}}
<i v-if="false" class="icon icon-caidan menu" @click.stop="showChangeColsDialog"></i>
<!-- <i v-if="index == 0 ? true : false" class="icon icon-caidan menu" @click.stop="showChangeColsDialog"></i> -->
<div class="colsModal" v-if="index == 0 && colsModalShow ? true : false" @click.stop>
<div v-for="(item,index) in defaultCols" :key="index">
<p>
<input type="checkbox" :checked="item.ck" @click.stop="e=>{itemCheckChange(item,e)}" />
<span>{{item.val}}</span>
</p>
</div>
</div>
</th>
<th v-if="actions && actions.length != 0">
操作
</th>
</tr>
</thead>
</template>

<script>
import Util from "../../tool/commonUtil.js";
export default {
props:["originCols","accpetHBNotice","noticeChangeCols","ck","actions","cols","showCk","singleSelected"],
name: "HeaderSection",
data(){
return {
colsModalShow:false
}
},
computed:{
defaultCols:function(){
return Util.object.addPrimaryAndCk(Util.object.deepArrayClone(this.originCols),true);
}
},
methods:{
setAll:function(){
this.accpetHBNotice({ck:!this.ck},null);
},
itemCheckChange:function(item,e){
item.ck = !item.ck;
e.target.checked = item.ck;

this.reSetCols();
},
reSetCols:function(){
let cols = Util.object.getCheckedItems(this.defaultCols).items;
if(cols.length == 0){
this.noticeChangeCols(this.defaultCols);
this.defaultCols.forEach(item => {
item.ck = true;
});
}else{
this.noticeChangeCols(cols);
}
},
showChangeColsDialog:function(){
this.colsModalShow = this.colsModalShow ? false : true;
},
bodyClick:function(){
console.log("body click");
this.colsModalShow = false;
}
},
updated(a,b) {
},
mounted(){
},
created () {
document.body.addEventListener("click",this.bodyClick,false);
},
beforeDestroy () {
document.body.removeEventListener("click",this.bodyClick)
}
}
</script>

<style scoped>
.enterIndexCls{width: 50px;display: inline-block;}
.colsModal{border:1px solid #ddd;padding:10px;border-radius: 3px;position: absolute;left:30px;top:0;background: #fff;color: #000;z-index: 999;}
.colsModal p {text-align: left;}
.colsModal p input{float: left;margin-left: 15px;margin-right: 15px;}
.thCols {position: relative;}
/* .thCols:nth-of-type(2){
width:100px;
} */
.colsModal .bot input{width: 50px;line-height: 15px;margin: 0 5px;}
.menu{position: absolute;left:10px;top:0;font-size: 20px;}
thead tr th{border-bottom:1px solid rgba(0,0,0,0.09);font-weight: 400;text-align: center;
color:#fff;font-size: 14px;}
</style>

+ 105
- 0
src/core/comps/table/paging.vue 파일 보기

@@ -0,0 +1,105 @@
<template>
<div class="pageNumCls" >
<nav aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item"><a class="page-link span">总条数:{{count}}</a></li>
<li class="page-item" @click="this.prev"><a class="page-link button" >上一页</a></li>
<li class="page-item" @click="this.next"><a class="page-link button" >下一页</a></li>
<li class="page-item"><a class="page-link span">当前页</a></li>
<li class="page-item"><a class="page-link span">{{index}}/{{total}}</a></li>
<li class="page-item"><span class="page-link span">跳至</span></li>
<li class="page-item"><input type="text" :ref="this.goIndexKey" class="enter-number" placeholder=''/></li>
<li class="page-item"><span class="page-link span">页</span></li>
<li class="page-item" @click="this.goToIndex"><a class="page-link button">跳至此页</a></li>
</ul>
</nav>
</div>
</template>

<script>
export default {
props:["options","goNext","goPrev","goIndex"],
name: "PagingSection",
data(){
return {
goIndexKey:Math.ceil(Math.random()*10000000000)
}
},
computed:{
index:function(){
return this.options.index;
},
count:function(){
return this.options.count;
},
total:function(){
return this.options.total;
}
},
methods:{
next:function () {
if(this.index >= this.total){
return;
}
this.goNext();
},
prev:function () {
if(this.index <=1){
return;
}
this.goPrev();
},
goToIndex:function () {
let eIndex = this.$refs[this.goIndexKey].value;
if( eIndex > this.total || eIndex< 1 || isNaN(eIndex)){
this.$refs[this.goIndexKey].value = "";
return;
}
this.goIndex(eIndex);
}
},
updated(a,b) {
},
created(){
}
}
</script>

<style scoped>
.button{
cursor: pointer;
}
.paging{height: 26px; margin: 30px 0; line-height: 26px;}
.paging input[type=button]{
height: 26px;
min-width: 26px;
padding: 0 5px;
border: 1px solid #dfdfdf;
box-sizing: border-box;
background: none;
margin-right: 4px;
border-radius: 5px;}
.paging input[type=text]{width: 30px; height: 20px; border: 1px solid #797979; text-align: center;}
.paging span{padding: 0 5px;}
.pageNumCls{margin-right: 20px;}
.pagination{
list-style: none;overflow: hidden;
}
.pagination>li{
display: block;float: left;margin-left: 8px;
}
.pagination>li>a, .pagination>li>span{
border-radius: 6px;padding: 0 10px;line-height: 30px;color: rgba(0,0,0,0.65);
}
.pagination .enter-number{
border: 1px solid rgba(217,217,217,1);line-height: 30px;width: 54px;
padding: 0 5px;border-radius: 6px;outline: none;
}
</style>
<style>
.span{ border:1px #fff solid!important; }
.span:hover{
background-color:#fff!important;
}

</style>

+ 198
- 0
src/core/comps/table/tableList.vue 파일 보기

@@ -0,0 +1,198 @@
<template>
<div class="tableContainer">
<table class="table">
<header-section :singleSelected="singleSelected" :show-ck="showCk" :origin-cols="originCols" :accpet-h-b-notice="accpetHBNotice" :notice-change-cols="noticeChangeCols" :ck="state.ck" :actions="actions" :cols="state.cols"></header-section>

<body-section :singleSelected="singleSelected" :show-ck="showCk" :actions="actions" :cols="state.cols" :accpet-h-b-notice="accpetHBNotice" :data="state.data"></body-section>
</table>
<div v-if="showIf">

<paging-section :options="state.pageOption" :go-index="gIndex" :go-prev="prev" :go-next="next"></paging-section>
</div>
</div>
</template>

<script>
import HeaderSection from "./header.vue";
import BodySection from "./body.vue";
import PagingSection from "./paging.vue";
import Util from "../../tool/commonUtil.js";
import CommonUtil from '../../tool/commonUtil.js';
export default {
components: {HeaderSection,BodySection,PagingSection},
props:["options"],
name: "TableList",
data(){
return {
showIf:this.options.pageOption.showIf==false?false:true,
state:{
data:[],
cols:this.options.map,
ck:false,
pageOption:{
index:this.options.pageOption.index?this.options.pageOption.index:1,
size:this.options.pageOption.size?this.options.pageOption.size:10,
count:0,
total:0,
showIf:true
}
}
}
},
computed:{
originCols:function(){
return Util.object.deepArrayClone(this.options.map);
},
showCk:function(){
return this.options.showCk;
},
actions:function(){
return this.options.actions;
},
getUrl:function(){
return this.options.getUrl;
},
singleSelected:function(){
return this.options.singleSelected;
}
},
methods:{
getData:function(index){
if(!index){
index = 1;
}
let url = this.options.getUrl();
if( url === ""){
return;
}
let suffix = url.indexOf('?') === -1?"?":"&";
let size = this.state.pageOption.size;
url += suffix + this.options.pageOption.indexKey + "=" + index + "&"+ this.options.pageOption.sizeKey + "=" + size;
this.getFetch(url).then(data=>{
let res = {};
if(this.options.analysis){
res = this.options.analysis(data);
}else{
res = data;

}
if(res.data && res.data instanceof Array && res.data.length != 0){
let arr = Util.object.addPrimaryAndCk(res.data);
let total = -1;
if(parseInt(res.count)%size == 0){
total = parseInt(res.count)/size;
}else{
total = parseInt(parseInt(res.count)/size) + 1;
}

this.state = {
data:arr,
cols:this.state.cols,
ck:false,
pageOption:{
index:index,
count:res.count,
total:total,
size:size
}
}
}else{
this.state = {
data:[],
cols:this.state.cols,
ck:false,
pageOption:{
index:1,
count:0,
total:0,
size:size
}
}
Util.throwError("检查analysis, getUrl, pageOption参数!");
}
})
},
accpetHBNotice:function(hData,bData){
//如果data有参数,说明是从head过来的通知,如果没有就说明是body过来的通知
if(hData){
this.state.data.map(item=>{
item.ck = hData.ck;
})
this.state = {
data:this.state.data,
ck:hData.ck,
cols:this.state.cols,
pageOption:this.state.pageOption
}
}
if(bData){
let items = Util.object.getCheckedItems(bData.data);
let flag = items.items.length == this.state.data.length?true:false;
this.state = {
data:bData.data,
ck:flag,
cols:this.state.cols,
pageOption:this.state.pageOption
}
}
},
noticeChangeCols:function(map){
this.state.cols = map;
},
prev:function(){
let index = this.state.pageOption.index;
index--;
this.getData(index);
},
next:function(){
let index = this.state.pageOption.index;
index++;
this.getData(index);
},
gIndex:function(index){
this.getData(index);
},
getCheckedItems(field){
let res = {data:[],vals:[]};
if(this.state.data && this.state.data instanceof Array){
this.state.data.forEach(x=>{
if(x.ck){
res.data.push(x);
if(field){
res.vals.push(x[field]);
}
}
})
}
return res;
},
getParams(){
return {index:this.state.pageOption.index,data:this.state.data};
},
search(index){
if(!index){
this.getData();
}else{
this.getData(this.state.pageOption.index);
}
},
// removeItems(items){
// this.state.data = CommonUtil.arrayServer.removeItems(items);
// }
},
created(){
console.log(this.state.pageOption,22222)
},
mounted () {
this.getData(this.state.pageOption.index);
console.log(this.state.pageOption);
},
destroyed(){
}
}
</script>

<style scoped>
table thead{background:#409EFF;}
</style>

+ 118
- 0
src/core/comps/upload/coverImg.vue 파일 보기

@@ -0,0 +1,118 @@
<template>
<div class="upaload">
<span class="input-file">请选择
<input @change="change" type="file" :ref="fkey" class="imgFile"></span>
<img v-show="showLoading" src="https://p2.lefile.cn/product/adminweb/2018/05/28/6f7b5572-8693-4f6c-a041-cf6f32b367ac.gif" class="loading">
<span style="margin-left:10px;" >{{msg}}</span>
<!-- <input type="button" style="margin-left:10px;" class="btn btn-info" @click="upload" value="上传" /> -->
</div>
</template>

<script>
export default {
components: {},
props:["fname","url","completedCallback","vtype"],
name: "FileUpload",
data(){
return {
fkey:Math.ceil(Math.random()*1000000000),
showLoading:false,
msg:""
}
},
computed:{
},
methods:{
change:function(){
let val = this.$refs[this.fkey].value;
this.msg = val.substring(val.lastIndexOf('\\') + 1);
this.upload();
},
resetFileInput:function(){
this.$refs[this.fkey].value = "";
},
upload:function(){
let dom = this.$refs[this.fkey];
let val = dom.value;
if(val){
let formData = new FormData();
formData.append(this.fname,dom.files[0]);
if(this.vtype){
let fileName = dom.files[0].name;
var suffix = fileName.substring(fileName.lastIndexOf('.')+1);
if(this.vtype.indexOf(',') == -1){
if(this.vtype != suffix){
this.msg = "后缀名必须为:"+ this.vtype;
return;
}
}else{
let res = this.vtype.split(',').filter(item=>{
return item.toLowerCase() == suffix.toLowerCase();
})
if(res.length == 0){
this.msg = "后缀名必须为:"+ this.vtype;
return;
}
}
}
this.showLoading = true;
this.uploadFetch(this.url,formData).then((result) => {
this.msg = "上传成功";
this.showLoading = false;
this.completedCallback({success:true,data:result});
}).catch((err) => {
this.showLoading = false;
this.msg = "上传异常";
this.resetFileInput();
this.completedCallback({success:false,data:err});
});
}else{
this.msg = "请选择文件";
}
}
},
created(){
},
mounted () {
}
}
</script>

<style scoped>
.imgFile{
cursor:pointer;
}
.input-file {
position: relative;
overflow: hidden;
text-align: center;
width: 100%;
background-color: #2c7;
border-radius: 4px;
padding: 7px 10px;
font-size: 12px;
font-weight: normal;
line-height: 18px;
color: #fff;
text-decoration: none;
}
.input-file input[type="file"] {
cursor:pointer;
position: absolute;
display: block;
top: 0;
right: 0;
font-size: 14px;
background-color: #f00;
/*transform: translate(-300px, 0px) scale(4);*/
/* height: 100%;
width: 100%; */
opacity: 0;
filter: alpha(opacity=0);
}
.loading{width:24px;}
</style>

+ 256
- 0
src/core/comps/upload/coverUpload.vue 파일 보기

@@ -0,0 +1,256 @@
<template>
<div style="margin-top:10px">
<div class="coverText">1.裁剪图片,图片大小需在2M以内.</div>
<div class="coverText">2.鼠标滚轮可以伸缩图片展示区大小.</div>
<div class="coverText" style="margin-bottom:5px;">{{information}}</div>
<div class="contianer">
<vueCropper ref="cropper" :img="option.img" :autoCrop="option.autoCrop" :autoCropWidth="option.autoCropWidth"
:autoCropHeight="option.autoCropHeight" :canScale="option.canScale" :outputSize="option.size"
:outputType="option.outputType" :info="true" :full="option.full" :canMove="option.canMove" :canMoveBox="option.canMoveBox"
:fixedBox="option.fixedBox" :original="option.original" :fixed="option.fixed" :fixedNumber="option.fixedNumber"
@realTime="realTime">
</vueCropper>
</div>
<div class="buttonBox"></div>
<span class="input-file">请选择
<input class="choiceImg" type="file" name="file" @change="changeEt" value="1" />
</span>
<!-- <div class="finish" @click="finish('blob')">保存图片</div> -->
<el-button class="finish" :loading="submitButton" type="primary" @click="finish('blob')">保存图片</el-button>
<span class="msg">{{msg}}</span>
</div>
</template>

<script>
import AjaxUtil from "../../../core/tool/ajaxService";
import vueCropper from 'vue-cropper'
export default {
components: {
vueCropper
},
props: ["fname", "url", "completedCallback", "vtype", "option"],
name: "FileUpload",
// props: {
// viewImg: {
// url: {
// type: String,
// default: ''
// },
// scale: {
// type: Number,
// default: 1 / 1
// },
// label: {
// type: String,
// default: ''
// }
// }
// },
data() {
return {
submitButton:false,
msg:"",
information:'',
imgUrl: '',
// option: {
// img: '',
// size: 1,
// full: false,
// outputType: 'png',
// canMove: true,
// fixedBox: false,
// original: false,
// canMoveBox: false,
// canScale: false,
// autoCrop: true,
// autoCropWidth: 200,
// autoCropHeight: 200,
// // // 开启宽度和高度比例
// fixed: true,
// fixedNumber: [1, 1]
// },
crap: false,
previews: {},
files: ''
}
},
methods: {
changeEt: function (e) {
var file = e.target.files[0]
if (!file) return;
if (/^image\/\w+$/.test(file.type)) {
let uploadedImageURL = URL.createObjectURL(file);
this.files = file
this.option.img = uploadedImageURL;
}
},
// 实时预览函数
realTime(data) {
this.previews = data
console.log( JSON.stringify(this.option))
if(this.option.propertion=='4/3'){
this.information = '3.宽高比约4:3效果最佳(例:宽800px,高600px)'
}else if(this.option.propertion=='1/1'){
this.information = '3.宽高比约1:1效果最佳(例:宽400px,高400px)'
}else if(this.option.propertion=='8/3'){
this.information = '3.宽高比约8:3效果最佳(例:宽800px,高300px)'
}
},
changeImg() {
this.option.img = this.lists[~~(Math.random() * this.lists.length)].img
},
startCrop() {
// start
this.crap = true
this.$refs.cropper.startCrop()
},
stopCrop() {
// stop
this.crap = false
this.$refs.cropper.stopCrop()
},
clearCrop() {
// clear
this.$refs.cropper.clearCrop()
},
finish(type) {
this.$refs.cropper.getCropBlob((data) => {
let blob = data
let formData = new FormData()
formData.append('file', blob, this.files.name)
this.msg = '',
this.submitButton = true;
this.uploadFetch(this.url, formData).then((result) => {
this.submitButton = false;
this.$message.success('保存成功');
this.showLoading = false;
this.completedCallback({
success: true,
data: result
});
}).catch((err) => {
this.submitButton = false;
this.msg = "上传失败,图片超2M或上传超时";
this.completedCallback({
success: false,
data: err
});
});
})
}
},
mounted() {

}

}
</script>
<style scoped>
.msg{
margin-top: 38px;
display: block;
color: red;
font-size: 12px;
}
img{
max-width: 100%;
}
.buttonBox{
overflow: hidden;
}
.contianer {
width: 375px;
height: 200px;
position: relative;
border-radius: 4px;
}

.show-preview {
position: absolute;
left: 405px;
bottom: 0px;
background-color: white;
border-radius: 4px;
color: #2c7;
}

.show-text {
position: absolute;
left: 0;
top: -30px;
font-size: 14px;
color: #333;
width: 200px;
}

.imgFile {
cursor: pointer;
}

.input-file {
float: left;
position: relative;
overflow: hidden;
text-align: center;
border: 1px #999 solid;
background-color: #fff;
border-radius: 4px;
padding: 7px 10px;
font-size: 12px;
font-weight: normal;
line-height: 24px;
color: #fff;
text-decoration: none;
display: block;
width: 120px;
color: #666;
margin: 20px 20px 0 0;
}

.input-file input[type="file"] {
cursor: pointer;
position: absolute;
height: 38px;
display: block;
top: 0;
right: 0;
font-size: 14px;
background-color: #f00;
/*transform: translate(-300px, 0px) scale(4);*/
/* height: 100%;
width: 100%; */
opacity: 0;
filter: alpha(opacity=0);
}

.finish {
float: left;
margin-top: 20px;
margin-right: 20px;
width: 120px;
height: 40px;
font-size: 12px;
background-color: #2c7;
text-align: center;
color: white;
border-radius: 4px;
cursor: pointer;
border: 1px #2c7 solid;
}

.coverText {
font-size: 12px !important;
color: #999 !important;
font-weight: lighter;
height: 20px;
line-height: 20px;
}
</style>
<style>
.crop-info[data-v-7b077dd1]{
display: none;
}
</style>


<!-- Add "scoped" attribute to limit CSS to this component only -->

+ 166
- 0
src/core/comps/upload/upload.vue 파일 보기

@@ -0,0 +1,166 @@
<template>
<div class="upaload">
<span class="input-file">请选择
<input @change="change" type="file" :ref="fkey" class="imgFile"></span>
<span @click.stop.prevent="download" class="download-file">下载</span>
<img v-show="showLoading" src="https://p2.lefile.cn/product/adminweb/2018/05/28/6f7b5572-8693-4f6c-a041-cf6f32b367ac.gif" class="loading">
<span style="margin-left:10px;positon:absolute" >{{msg}}</span>
<!-- <input type="button" style="margin-left:10px;" class="btn btn-info" @click="upload" value="上传" /> -->
<div>
<span class="download-filename">{{fileName}}</span>
</div>
</div>
</template>

<script>
export default {
components: {},
props:["fname","id","url","completedCallback","vtype"],
name: "FileUpload",
data(){
return {
fkey:Math.ceil(Math.random()*1000000000),
showLoading:false,
msg:"",
fileurl:"",
fileName:""
}
},
computed:{
},
methods:{
change:function(){
console.log(111)
let val = this.$refs[this.fkey].value;
this.msg = val.substring(val.lastIndexOf('\\') + 1);
this.upload();

},
resetFileInput:function(){
this.$refs[this.fkey].value = "";
},
upload:function(){
let dom = this.$refs[this.fkey];
let val = dom.value;
if(val){
let formData = new FormData();
formData.append(this.fname,dom.files[0]);
if(this.vtype){
let fileName = dom.files[0].name;
this.fileName=fileName;
var suffix = fileName.substring(fileName.lastIndexOf('.')+1);
if(this.vtype.indexOf(',') == -1){
if(this.vtype != suffix){
this.msg = "后缀名必须为:"+ this.vtype;
return;
}
}else{
let res = this.vtype.split(',').filter(item=>{
return item.toLowerCase() == suffix.toLowerCase();
})
if(res.length == 0){
this.msg = "后缀名必须为:"+ this.vtype;
return;
}
}
}
this.showLoading = true;
this.uploadFetch(this.url,formData).then((result) => {
debugger
this.msg = "上传成功";
this.showLoading = false;
this.fileurl=result.data.url;
result.data.filename=this.fileName
this.completedCallback({success:true,data:result});
}).catch((err) => {
this.showLoading = false;
this.msg = "上传异常";
this.resetFileInput();
this.completedCallback({success:false,data:err});
});
}else{
this.msg = "请选择文件";
}
},
download:function(){
if(this.id){
location.href ="/O/wxRentContract/download?id="+this.id;
}else{
location.href = this.fileurl;
}
}
},
created(){
},
mounted () {
}
}
</script>

<style scoped>
.imgFile{
cursor:pointer;
}
.input-file {
position: relative;
overflow: hidden;
text-align: center;
display: inline-block;
width: 120px;
border: 1px #999 solid;
background-color: #fff;
border-radius: 4px;
padding: 7px 10px;
font-size: 12px;
font-weight: normal;
line-height: 24px;
text-decoration: none;
color: #666;
margin: 0 20px 0 30px;
}
.download-file {
position: relative;
overflow: hidden;
text-align: center;
display: inline-block;
width: 120px;
border: 1px #dcdfe6 solid;
background-color: #409EFF;
border-radius: 4px;
padding: 7px 10px;
font-size: 12px;
font-weight: normal;
line-height: 24px;
color: #fff;
text-decoration: none;
margin:0 20px 0 30px;
}
.download-filename{
width: 120px;
padding: 7px 10px;
display: inline-block;
line-height: 24px;
margin-left: 50px;
}
.input-file input[type="file"] {
cursor:pointer;
position: absolute;
display: block;
top: 0;
right: 0;
font-size: 14px;
background-color: #f00;
/*transform: translate(-300px, 0px) scale(4);*/
/* height: 100%;
width: 100%; */
opacity: 0;
filter: alpha(opacity=0);
}
.loading{width:24px;}
</style>

+ 264
- 0
src/core/tool/ajaxService.js 파일 보기

@@ -0,0 +1,264 @@
/**
* Created by wupeng5 on 2018/1/7.
*/
/**
* ajax 处理类,
* get: return promise
* post: return promise
* all: params:PromiseArray, return promise
* 接口返回格式{code:0,message:"xx",data:object}
* code:200, 成功, 其他为失败
* code:701,未登录
* code失败的情况下,打印message
* return promise
*
* 组件内部请求ajax必须继承此类extends:AjaxUtil
*
**/

let param = function(obj) {
var query = '';
var name, value, fullSubName, subName, subValue, innerObj, i;

for (name in obj) {
value = obj[name];

if (value instanceof Array) {
for (i = 0; i < value.length; ++i) {
subValue = value[i];
fullSubName = name + '[' + i + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
} else if (value instanceof Object) {
for (subName in value) {
subValue = value[subName];
fullSubName = name + '[' + subName + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
} else if (value !== undefined && value !== null) {
query += encodeURIComponent(name) + '='
+ encodeURIComponent(value) + '&';
}
}

return query.length ? query.substr(0, query.length - 1) : query;
};

import Q from "q";
// export default {
// name: "AjaxUtil",
// methods:{
// getFetch(url){
// let symbol = url.indexOf('?') == -1?"?":"&";
// url = url + symbol + "ran="+Math.ceil(Math.random()*10000000);
// let defer = Q.defer();
// let headers = {
// 'Content-Type': 'application/json; charset=UTF-8'
// };
// let options = {
// method:"get",
// credentials:'include',
// headers:headers
// };
// let that = this;
// fetch(url,options).then(d =>d.json()).then(function (data) {
// let code = data.code;
// if(code == "701"){
// that.$router.push({path:"login"});
// }else{
// if(code == "200"){
// defer.resolve({data:data.data,params:data.params});
// }else{
// defer.reject({data: data.message});
// }
// }
// }).catch(function(err) {
// defer.reject({data: "Server Error!"});
// throw new Error(url + " request server error!");
// });
// return defer.promise;
// },
// postFetch(url,data){
// let symbol = url.indexOf('?') == -1?"?":"&";
// url = url + symbol + "ran="+Math.ceil(Math.random()*10000000);
// let defer = Q.defer();
// let headers = {
// // 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
// 'Content-Type': 'application/json; charset=UTF-8'
// };
// let options = {
// method:"post",
// credentials:'include',
// headers:headers
// };
// if(data){
// // options.body = param(data);
// options.body = JSON.stringify(data);
// }
// let that = this;
// fetch(url,options).then(d =>d.json()).then(function (data) {
// let code = data.code;
// if(code == "701"){
// that.$router.push({path:"login"});
// }else{
// if(code == "200"){
// defer.resolve({data:data.data,params:data.params});
// }else{
// defer.reject({data: data.message});
// }
// }
// }).catch(function(err) {
// defer.reject({data: "Server Error!"});
// throw new Error(url + " request server error!");
// });
// return defer.promise;
// },
// uploadFetch(url,data){
// let symbol = url.indexOf('?') == -1?"?":"&";
// url = url + symbol + "ran="+Math.ceil(Math.random()*10000000);
// let defer = Q.defer();
// let options = {
// method:"post",
// credentials:'include'
// };
// if(data){
// options.body = data;
// }
// let that = this;
// fetch(url,options).then(d =>d.json()).then(function (data) {
// let code = data.code;
// if(code == "701"){
// that.$router.push({path:"login"});
// }else{
// if(code == "200"){
// defer.resolve({data:data.data,params:data.params});
// }else{
// defer.reject({data: data.message});
// }
// }
// }).catch(function(err) {
// defer.reject({data: "Server Error!"});
// throw new Error(url + " request server error!");
// });
// return defer.promise;
// },
// fetchAll(promises){
// return Q.all(promises);
// }
// },
// };

export default {
install:function(Vue){
Vue.prototype.getFetch=function(url){
let symbol = url.indexOf('?') == -1?"?":"&";
url = url + symbol + "ran="+Math.ceil(Math.random()*10000000);
let defer = Q.defer();
let headers = {
'Content-Type': 'application/json; charset=UTF-8'
};
let options = {
method:"get",
credentials:'include',
headers:headers
};
let that = this;
fetch(url,options).then(d =>d.json()).then( (data)=> {
let code = data.code;
if(code == "701"){
that.$router.push({path:"/login"});
}else{
if(code == "200"){
defer.resolve({data:data.data,params:data.params});
}else{
defer.reject({data: data.message});
}
}
}).catch((err)=> {
defer.reject({data: "Server Error!"});
// this.showAlertMsg("error","服务器异常");
throw new Error(url + " request server error!");
});
return defer.promise;
};
Vue.prototype.postFetch = function(url,data){
let symbol = url.indexOf('?') == -1?"?":"&";
url = url + symbol + "ran="+Math.ceil(Math.random()*10000000);
let defer = Q.defer();
let headers = {
// 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
'Content-Type': 'application/json; charset=UTF-8',
};
let options = {
method:"post",
credentials:'include',
headers:headers
};
if(data){
// options.body = param(data);
options.body = JSON.stringify(data);
}
let that = this;
fetch(url,options).then(d =>d.json()).then((data)=> {
let code = data.code;
if(code == "701"){
that.$router.push({path:"/login"});
}else{
if(code == "200"){
defer.resolve({data:data.data,params:data.params});
}else{
defer.reject({data: data.message});
}
}
}).catch(function(err) {
defer.reject({data: "Server Error!"});
throw new Error(url + " request server error!");
});
return defer.promise;
};
Vue.prototype.uploadFetch = function(url,data){
let symbol = url.indexOf('?') == -1?"?":"&";
url = url + symbol + "ran="+Math.ceil(Math.random()*10000000);
let defer = Q.defer();
let options = {
method:"post",
credentials:'include'
};
if(data){
options.body = data;
}
let that = this;
fetch(url,options).then(d =>d.json()).then( (data)=> {
let code = data.code;
if(code == "701"){
that.$router.push({path:"/login"});
}else{
if(code == "200"){
defer.resolve({data:data.data,params:data.params});
this.$Message.success(data.message);
}else{
defer.reject({data: data.message});
}
}
}).catch(function(err) {
defer.reject({data: "Server Error!"});
// this.showAlertMsg("error","服务器异常");
throw new Error(url + " request server error!");
});
return defer.promise;
},
Vue.prototype.fetchAll = (promises)=>{
return Q.all(promises);
}
}
}

+ 28
- 0
src/core/tool/alert.js 파일 보기

@@ -0,0 +1,28 @@
export default {
install:function(Vue){
Vue.prototype.showConfirm = function(title,cb){
this.$confirm(title, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if(cb){cb()};
}).catch(() => {
// this.showAlertMsg('info','操作异常!');
});
}
Vue.prototype.showAlertMsg =function(type,msg) {
this.$message({
type: type?type:'success',
message: msg?msg:'操作成功'
});
}
Vue.prototype.showNotify = function(type,msg,title){
this.$notify({
title: title?title:'警告',
type: type?type:'error',
message: msg?msg:"操作成功"
});
}
}
}

+ 460
- 0
src/core/tool/commonUtil.js 파일 보기

@@ -0,0 +1,460 @@
/**
* Created by wupeng5 on 2018/2/1.
*/
import moment from 'moment';
let CommonUtil = {
throwError:function(str){
console.log(str);
//throw new Error(str);
},
object:{
equalsObject(source,target){
let p;
for (p in source) {
if (typeof (target[p]) == 'undefined') {
return false;
}
}
for (p in source) {
if (source[p]) {
switch (typeof (source[p])) {
case 'object':
if (!this.equalsObject(source[p], target[p])) {
return false;
}
break;
case 'function':
if (typeof (target[p]) == 'undefined' ||
(p != 'equals' && source[p].toString() != target[p].toString()))
return false;
break;
default:
if (source[p] != target[p]) {
return false;
}
}
} else {
if (target[p])
return false;
}
}
for (p in target) {
if (typeof (source[p]) == 'undefined') {
return false;
}
}

return true;
},
cloneObj(source){
if(source){
return JSON.parse(JSON.stringify(source));
}
return null;
},
deepArrayClone(data){
return [...data];
},
getProperties(obj){
let res = [];
if(!obj){
return res;
}
for(let i in obj){
res.push(i);
}
return res;
},
/**
* js中的任务队列
* @params: data:Array
* @params: process:function
* @params: completedCallback : function 执行完毕的回调
* @params: context(可选): 执行环境,如果没有,则为window
* return undefined
* demo:
* let data = [{name:1},{name:2},{name:3},{name:4},{name:5},{name:6},{name:7}];
* function print(item){console.log(item.name);}
* taskQueue(data,print,cb);
* **/
taskQueue:function(array,process,completedCallback,context){
setTimeout(function(){
if(completedCallback && typeof completedCallback == "function"){
if(array.length == 0){
completedCallback({data:"all tasks completed!"});
return;
}
}
let item = array.shift();
process.call(context,item);
if(array.length >0){
setTimeout(arguments.callee,100);
}
},100)
},
/**
* 节流函数:
* 如果在段时间内一直操作DOM,可能会导致浏览器内存问题,甚至崩溃,所以在一段时间内,我们让该持续性的操作间隔的执行
* @params: method:function 需要执行的函数
* @params: context(可选):执行环境,如果没有,则为window
* return undefined
* demo:
* function resizeDiv(){
* let div = document.querySelector("#div1");
* div.style.height = div.offsetWidth + "px";
* }
* throttle(resizeDiv);
* **/
throttle:function(method,context) {
clearTimeout(method.tId);
method.tId = setTimeout(function () {
method.call(context);
}, 80)
},
addPrimaryAndCk(data,ck){
data.map(item=>{
if(ck!=undefined){
if(!ck){
item.ck = false;
}else{
item.ck = true;
}
}else{
item.ck = false;
}
item.cls = "";
item.__tmpId = Math.ceil(Math.random()*10000000000000000);
});
return data;
},
getCheckedItems(arr,field){
let res = {items:[],vals:[]};
arr.map(item=>{
if(item.ck){
res.items.push(item);
if(field){
res.vals.push(item[field]);
}
}
})
return res;
},
getInfoInArrayByField(field,vals,array){
let res = [];
vals.map(item=>{
array.map(k=>{
if(k[vals] == item){
res.push(k);
}
})
})
return res;
}
},
cookie:{
removeCookie(name){
this.setCookie(name,"",new Date(0));
},
getCookie(name){
let cookie = document.cookie;
let cookieName = encodeURIComponent(name) + "=",
cookieStart = cookie.indexOf(cookieName),
cookieValue = null;
if(cookieStart > -1){
let cookieEnd = cookie.indexOf(';',cookieStart);
if(cookieEnd == -1){
cookieEnd = cookie.length;
}
cookieValue = decodeURIComponent(cookie.substring(cookieStart + cookieName.length,cookieEnd));
}
return cookieValue;
},
setCookie(name,value,expires){
let cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value);
if(expires instanceof Date){
cookieText += "; expires=" + expires.toGMTString();
}
document.cookie = cookieText+";path=/;domain="+document.domain;
},
},
arrayServer:{
_private:{
getIndexByString: function (array, str) {
let _index = -1;
for (let i = 0; i < array.length; i++) {
if (array[i] == str) {
_index = i;
break;
}
}
return _index;
},
getIndexByObject: function (array, obj) {
let _index = -1;
for (let i = 0; i < array.length; i++) {
if (CommonUtil.object.equalsObject(array[i], obj)) {
_index = i;
break;
}
}
return _index;
},
removeSingleStr: function (array, str) {
let _index = this.getIndexByString(array, str);
if (_index == -1) {
return array;
}
array.splice(_index, 1);
return array;
},
removeSingleObject: function (array, item) {
let _index = this.getIndexByObject(array, item);
if (_index == -1) {
return array;
}
array.splice(_index, 1);
return array;
},
sortByDate:function(array, field, desc){
let _arr = CommonUtil.object.cloneObj(array);
_arr.map(function(item){
item._tmpDateField = new Date(item[field]).getTime();
})
_arr.sort(function (a, b) {
if(desc){
return a._tmpDateField - b._tmpDateField;
}else{
return b._tmpDateField - a._tmpDateField;
}
})
return _arr;
},
sortByNumAndChar:function(array, field, desc){
let _arr = CommonUtil.object.cloneObj(array);
_arr.sort(function (a, b) {
if(desc){
return a[field] - b[field];
}else{
return b[field] - a[field];
}
})
return _arr;
}
},
getIndex:function(array, item){
if(array instanceof Array == false){
CommonUtil.throwError("params[array] must be Array in getIndex method");
return;
}
if (typeof item == "object") {
return CommonUtil.arrayServer._private.getIndexByObject(array, item);
} else if (typeof item == "string") {
return CommonUtil.arrayServer._private.getIndexByString(array, item);
} else {
return -1;
}
},
removeItems:function(array, items){
if(array instanceof Array == false){
CommonUtil.throwError("params[array] must be Array in removeItems method");
return;
}
items.map(function (item) {
if (typeof item == "object") {
CommonUtil.arrayServer._private.removeSingleObject(array, item);
}
if (typeof item == "string") {
CommonUtil.arrayServer._private.removeSingleStr(array, item);
}
})
return array;
},
insertItem:function(array, items){
if(array instanceof Array == false){
CommonUtil.throwError("params[array] must be Array in removeItems method");
return;
}
items.map(function (item) {
if (typeof item == "object") {
CommonUtil.arrayServer._private.removeSingleObject(array, item);
}
if (typeof item == "string") {
CommonUtil.arrayServer._private.removeSingleStr(array, item);
}
})
return array;
},
uniq:function(array,field){
if(array instanceof Array == false){
CommonUtil.throwError("params[array] must be Array in uniq method");
return;
}
if(!field){
var result = [], hash = {};
for (var i = 0, elem; (elem = array[i]) != null; i++) {
if (!hash[elem]) {
result.push(elem);
hash[elem] = true;
}
}
return result;
}else{
var hash = {};
return array.reduce(function (item, next) {
  hash[next[field]] ? '' : hash[next[field]] = true && item.push(next);
   return item;
}, []);
}
},
getSimpleValuesByField:function(array,field){
if(array instanceof Array == false){
CommonUtil.throwError("params[array] must be Array in getSimpleValuesByField method");
return;
}
let res = [];
array.forEach(function(item){
res.push(item[field]);
})
return res;
},
getFieldsByCk:(array,field)=>{
if(array instanceof Array == false){
CommonUtil.throwError("params[array] must be Array in getSimpleValuesByField method");
return;
}
let res = [];
array.forEach(function(item){
if(item.ck){
if(field){
res.push(item[field]);
}else{
res.push(item);
}
}
})
return res;
},
sortByField:function(array,field,desc){
if(array instanceof Array == false){
CommonUtil.throwError("params[array] must be Array in sortByField method");
return;
}
if(array.length == 0){
return array;
}
let res = null;
let tmp = array[0][field];

//check Date
if (new Date(tmp) != "Invalid Date") {
res = _private.sortByDate(array, field, desc);
} else {
res = _private.sortByNumAndChar(array, field, desc);
}
return res;
},
getChannelsForCoupon:function(arr1,arr2){
let res = [];
arr1.forEach(d=>{
arr2.forEach(x=>{
if(x.id == d){
res.push(x.title);
}
})
})
return res;
}
},
timechuo:{
//计算下单的时间与现在的时间的
timechuo:function(endTime,startTime) {
var s2 = new Date(startTime.replace(/-/g, "/"));
var s1 = new Date(endTime.replace(/-/g, "/"));
var runTime = parseInt((s1.getTime() - s2.getTime()) / 1000);
var year = Math.floor(runTime / 86400 / 365);
var runTime = runTime % (86400 * 365);
var month = Math.floor(runTime / 86400 / 30);
var runTime = runTime % (86400 * 30);
var day = Math.floor(runTime / 86400);
var runTime = runTime % 86400;
var hour = Math.floor(runTime / 3600);
var runTime = runTime % 3600;
var minute = Math.floor(runTime / 60);
var runTime = runTime % 60;
var second = runTime;
console.log(month, day, hour, minute, second);
return (day)
}
},
date:{
date:function(val){
if(!val){return "";}
let d = new Date(val);
let m = d.getMonth()+1;
m = m>=10?m:"0"+m;
let day = d.getDate();
day = d.getDate()>=10?d.getDate():"0"+d.getDate();
return d.getFullYear() + "-" + m + "-" + day;
},
dateTime:function(val){
return this.date(val) + " " + this.time(val);
},
time:function(val){
if(!val){return "";}
let d = new Date(val);
let h = d.getHours() >=10?d.getHours():"0"+d.getHours();
let m = d.getMinutes() >=10?d.getMinutes():"0"+d.getMinutes();
let s = d.getSeconds() >=10?d.getSeconds():"0"+d.getSeconds();
return h + ":" + m + ":" +s;
},
//当前月的第一天
getCurrentMonthFirst(){
let date=new Date();
date.setDate(1);
return this.date(date);
},
//当前月的最后一天
getCurrentMonthLast(){
let date=new Date();
let currentMonth=date.getMonth();
let nextMonth=++currentMonth;
let nextMonthFirstDay=new Date(date.getFullYear(),nextMonth,1);
let oneDay=1000*60*60*24;
return this.date(new Date(nextMonthFirstDay-oneDay));
}
},
pvuv:{
pvuvKey:"pvuvKey",
setPVUV:function(){
let params = {
// actionDate:CommonUtil.date.date(new Date().toLocaleDateString()),
actionDate:moment(new Date()).format('YYYY-MM-DD'),
url:this.$route.name,
type:"1"
}
this.postFetch("/O/wxAdminLog/pvlog",params);
}
},
checkInChannels:function(array,channels){
if(!array){
array = [];
}
let count = 0;
for (let i = 0; i < array.length; i++) {
for (let index = 0; index < channels.length; index++) {
if(array[i] == channels[index].channelId){
count++;
}
}
}
if(count == channels.length){
return false;
}
return true;
}
}

export default CommonUtil

+ 16
- 0
src/core/tool/dataCache.js 파일 보기

@@ -0,0 +1,16 @@
/**
* Created by wupeng5 on 2018/1/14.
*/

let dataCache = function(){

this.dictionary = {};

this.get = function(){
}

this.set = function(){

}
};

+ 104
- 0
src/core/tool/report.js 파일 보기

@@ -0,0 +1,104 @@
export default {
initLine:function(x,data){
return {
toolbox: {
show: true,
feature: {
magicType: {
type: ['bar']
},
dataView: {show: true, readOnly: true},
restore: {},
},
top: "5%",
right: "10%",
},
xAxis: {
type: 'category',
data: x,//['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
tooltip : {
trigger: 'axis',
},
yAxis: {
type: 'value',
splitLine: {
show: true,
lineStyle: {
type: "dash"
}
}
},
series: data
// [
// {
// name: 'name1',
// data: [1000, 932, 901, 934, 1290, 1330, 1320],
// type: 'line'
// },
// {
// name: 'name2',
// data: [3000, 932, 901, 934, 1290, 1330, 1320],
// type: 'line'
// }
// ]
};
},
initPie:function(title,x,data){
return {
title : {
text: title?title:"",
x:'center'
},
tooltip : {
trigger: 'item',
formatter: "{b} : {c} ({d}%)"
},
legend: {
orient: 'vertical',
left: 'left',
data: x //['直接访问','邮件营销','联盟广告','视频广告','搜索引擎']
},
series : [
{
// name: '详情',
type: 'pie',
radius : '55%',
center: ['50%', '60%'],
data:data
// [{value:335, name:'直接访问'},
// {value:310, name:'邮件营销'},
// {value:234, name:'联盟广告'},
// {value:135, name:'视频广告'},
// {value:1548, name:'搜索引擎'}]
,
itemStyle: {
emphasis: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
},
label:{show:true,formatter:'{b}:{c} ({d}%)'}
}
]
}
},
initBar:function(x,y){
return {
xAxis: {
type: 'category',
data: x//['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
tooltip: {},
yAxis: {
type: 'value'
},
series: [{
data: y,//[120, 200, 150, 80, 70, 110, 130],
type: 'bar',
label:{show:true}
}]
};
}
}

+ 101
- 0
src/core/tool/validator.js 파일 보기

@@ -0,0 +1,101 @@
/**
* Created by wupeng5 on 2017/12/21.
*/

/*
* 验证表单类
* property:strategys {json object}, 验证规则,为function
* property:rules<Array> , 保存规则,
* [{strategy: 'isNotEmpty',errorMsg:'用户名不能为空'},{strategy: 'minLength:6',errorMsg:'用户名长度不能小于6位'}]
*
* add, 添加规则
* start:Array 返回结果,为数组
* */
var Validator = function(){
this.rules = [];
/*
* rules: [{strategy: 'isNotEmpty',errorMsg:'用户名不能为空'},
{strategy: 'minLength:6',errorMsg:'用户名长度不能小于6位'}]
*value :dom element.value
*
* 返回删除的第一个
* */
this.add = function(value,rules){
var that = this;
rules.map(function(rule){
(function(rule){
//获取strategy key数组,可能有附加条件用:隔开
var strategyAry = rule.strategy.split(":");
var errorMsg = rule.errorMsg;
var fun = function(){
//获取获取strategy key具体值
var strategy = strategyAry.shift();
strategyAry.unshift(value);
strategyAry.push(errorMsg);
return that.strategys[strategy].apply(value,strategyAry);
}
that.rules.push(fun);
})(rule);
})
return this;
}
this.start = function(){
var res = [];
this.rules.map(function(validatorFunc){
var msg = validatorFunc();
if(msg){
res.push(msg);
}
})
return res;
}
}

Validator.prototype.strategys = {
isNotEmpty:function(value,errorMsg){
if(value === "") {
return errorMsg;
}
},
minLength:function(value,length,errorMsg){
if(value.length < length) {
return errorMsg;
}
},
maxLength:function(value,length,errorMsg){
if(value.length > length) {
return errorMsg;
}
},
mobileFormat: function(value,errorMsg) {
if(!/(^1[3|5|8][0-9]{9}$)/.test(value)) {
return errorMsg;
}
},
emailFormat:function(value,errorMsg){
if(!/\w@\w*\.\w/.test(value)){
return errorMsg;
}
},
urlFormat:function(value,errorMsg){
var strRegex = "^((https|http|ftp|rtsp|mms)?://)"
+ "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" //ftp的user@
+ "(([0-9]{1,3}\.){3}[0-9]{1,3}" // IP形式的URL- 199.194.52.184
+ "|" // 允许IP和DOMAIN(域名)
+ "([0-9a-z_!~*'()-]+\.)*" // 域名- www.
+ "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\." // 二级域名
+ "[a-z]{2,6})" // first level domain- .com or .museum
+ "(:[0-9]{1,4})?" // 端口- :80
+ "((/?)|" // a slash isn't required if there is no file name
+ "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$";
var re = new RegExp(strRegex);
if (!re.test(value)){
return errorMsg;
}
},
numFormat:function(value,errorMsg){
if(isNaN(str)){
return errorMsg;
}
}
}

+ 30
- 0
src/index.html 파일 보기

@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta name="version" content=<%= htmlWebpackPlugin.options.version %> />
<meta name="renderer" content="webkit">
<title>富茂小程序管理后台</title>
<title></title>
<link rel="stylesheet" href="./static/css/app.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.1/cropper.css" rel="stylesheet">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.1/cropper.js"></script>
<script src="./static/js/event.js"></script>
<style>
.map{
position: fixed;
left: 500px;
top: 0;
width: 500px;
height: 300px;
}
</style>
</head>
<body>
<div id="app"></div>
<!-- <div style="position: absolute;top: 98%;left: 92%;">version:<%= htmlWebpackPlugin.options.version %></div> -->
</body>
</html>

+ 35
- 0
src/main.js 파일 보기

@@ -0,0 +1,35 @@
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue';
import Vuex from 'vuex';
import App from './App.vue';
import router from './router/index.js';

import ElementUI from 'element-ui'; //引入js
import 'element-ui/lib/theme-chalk/index.css';//引入css

import AlertMsg from "./core/tool/alert.js";
import AjaxService from "./core/tool/ajaxService.js";

import store from "./store/index.js";
import BaiduMap from 'vue-baidu-map'

import 'babel-polyfill'
Vue.use(BaiduMap, {
// ak 是在百度地图开发者平台申请的密钥 详见 http://lbsyun.baidu.com/apiconsole/key */
ak: '9iFIaYXhOfi4CpSBP0xKYOBCBOGEWH0A'
})

Vue.use(Vuex);
Vue.use(ElementUI);
Vue.use(AlertMsg);
Vue.use(AjaxService);

/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})

+ 83
- 0
src/router/index.js 파일 보기

@@ -0,0 +1,83 @@
import Vue from 'vue';
import Router from 'vue-router';
import Vuex from 'vuex';

import AuthHOC from "../components/authHOC/authHoc.js";
import Input from "../components/input.vue";
//布局&登录
import Layout from "../components/layout/layout.vue";
import Login from '../components/login/login.vue';

Vue.use(Router);
Vue.use(Vuex);

export default new Router({
// mode:"history",
routes: [
{
path: '/',
name: 'login',
component: Login
},
{
path: '/login',
name: 'login1',
component: Login
},
{
path: '/layout',
name: 'Layout',
component: AuthHOC(Layout),
children: [
{
path: '/input',
name: 'Input',
component: Input
},
//首页
{
path: '/',
name: 'HomePage',
component: r => require.ensure([], () => r(require('../components/layout/homePage.vue')), 'HomePage')
},
//服务器配置
{
path: '/basicSettings',
name: 'basicSettings',
component: r => require.ensure([], () => r(require('../components/basicSettings/list.vue')), 'basicSettings')
},
// 草稿
{
path: '/draft',
name: 'draft',
component: r => require.ensure([], () => r(require('../components/draft/list.vue')), 'draft')
},
//code提交列表
{
path: '/codesubmit',
name: 'codesubmit',
component: r => require.ensure([], () => r(require('../components/codesubmit/list.vue')), 'codesubmit')
},
//审核
{
path: '/audit',
name: 'audit',
component: r => require.ensure([], () => r(require('../components/audit/list.vue')), 'audit')
},
// 发布
{
path: '/release',
name: 'release',
component: r => require.ensure([], () => r(require('../components/release/list.vue')), 'release')
},
// 成员管理
{
path: '/member',
name: 'member',
component: r => require.ensure([], () => r(require('../components/member/list.vue')), 'member')
}
]
},

]
})

+ 55
- 0
src/service/couponData/data.js 파일 보기

@@ -0,0 +1,55 @@


export let CacheData = {
//小程序端
appType:[
{name:"B端小程序",value:1},
{name:"C端小程序",value:2},
{name:"公众号服务号",value:3},
{name:"公众号订阅号",value:4},
],
//授权状态
authorizationStatus:[
{name:"已授权",value:0},
{name:"未授权",value:1},
],
//审核状态
auditStatus:[
{name:"审核成功",value:0},
{name:"审核失败",value:1},
{name:"审核中",value:2},
{name:"已撤回",value:3},
],
//code提交状态
codeStatus:[
{name:"提交成功",value:0},
{name:"提交失败",value:1}
],
//发布状态
releaseStatus:[
{name:"发布成功",value:0},
{name:"未发布",value:1},
{name:"版本回退",value:2}
],
//是否设置基础设置
baseStatus:[
{name:"已设置",value:0},
{name:"暂无设置",value:1}
],
//是否设置服务器域名
domainStatus:[
{name:"已设置",value:0},
{name:"暂无设置",value:1}
],
//是否设置业务域名
webdomainStatus:[
{name:"已设置",value:0},
{name:"暂无设置",value:1}
],
//是否设置模板消息
templateStatus:[
{name:"已设置",value:0},
{name:"暂无设置",value:1}
]

}

+ 59
- 0
src/static/css/app.css 파일 보기

@@ -0,0 +1,59 @@

@font-face {font-family: "iconfont";
src: url('../font/iconfont.eot?t=1522291528940'); /* IE9*/
src: url('../font/iconfont.eot?t=1522291528940#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('../font/iconfont.woff?t=1473155405') format('woff'),
url('../font/iconfont.ttf?t=1522291528940') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
url('../font/iconfont.svg?t=1522291528940#iconfont') format('svg'); /* iOS 4.1- */
}
.icon {
font-family:"iconfont" !important;
font-size:14px;
font-style:normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-jian:before { content: "\e600"; }

.icon-arrow-right:before { content: "\e602"; }
.icon-jiahao:before { content: "\e726"; }
.icon-arrow-bot:before { content: "\e6aa"; }
.icon-arrow-top:before { content: "\e6b0"; }
.icon-duihaocheckmark17:before { content: "\e770"; }
.icon-yonghu:before { content: "\e639"; }
.icon-caidan:before { content: "\e608"; }
.icon-mima:before { content: "\e622"; }
.icon-arrow-left:before { content: "\e667"; }
.icon-tianjia:before { content: "\e64f"; }
.icon-cuowu:before { content: "\e616"; }
.icon-cuowu1:before { content: "\e674"; }
.icon-edit:before { content: "\e61f"; }
.icon-duihao:before { content: "\e69e"; }
.icon-search:before { content: "\e613"; }
.icon-tuichu:before { content: "\e652"; }
.icon-cuo:before { content: "\e68c"; }

.icon-arrow-up:before { content: "\e667"; transform: rotate(90deg);display: block;}

.icon-arrow-down:before { content: "\e667"; transform: rotate(-90deg);display: block;}


BIN
src/static/font/iconfont.eot 파일 보기


+ 87
- 0
src/static/font/iconfont.svg 파일 보기

@@ -0,0 +1,87 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<!--
2013-9-30: Created.
-->
<svg>
<metadata>
Created by iconfont
</metadata>
<defs>

<font id="iconfont" horiz-adv-x="1024" >
<font-face
font-family="iconfont"
font-weight="500"
font-stretch="normal"
units-per-em="1024"
ascent="896"
descent="-128"
/>
<missing-glyph />
<glyph glyph-name="x" unicode="x" horiz-adv-x="1001"
d="M281 543q-27 -1 -53 -1h-83q-18 0 -36.5 -6t-32.5 -18.5t-23 -32t-9 -45.5v-76h912v41q0 16 -0.5 30t-0.5 18q0 13 -5 29t-17 29.5t-31.5 22.5t-49.5 9h-133v-97h-438v97zM955 310v-52q0 -23 0.5 -52t0.5 -58t-10.5 -47.5t-26 -30t-33 -16t-31.5 -4.5q-14 -1 -29.5 -0.5
t-29.5 0.5h-32l-45 128h-439l-44 -128h-29h-34q-20 0 -45 1q-25 0 -41 9.5t-25.5 23t-13.5 29.5t-4 30v167h911zM163 247q-12 0 -21 -8.5t-9 -21.5t9 -21.5t21 -8.5q13 0 22 8.5t9 21.5t-9 21.5t-22 8.5zM316 123q-8 -26 -14 -48q-5 -19 -10.5 -37t-7.5 -25t-3 -15t1 -14.5
t9.5 -10.5t21.5 -4h37h67h81h80h64h36q23 0 34 12t2 38q-5 13 -9.5 30.5t-9.5 34.5q-5 19 -11 39h-368zM336 498v228q0 11 2.5 23t10 21.5t20.5 15.5t34 6h188q31 0 51.5 -14.5t20.5 -52.5v-227h-327z" />

<glyph glyph-name="jian" unicode="&#58880;" d="M512.16384 860.6051199999999c-262.57546667 0-476.20426667-213.6288-476.20426667-476.20426667 0-262.57653333 213.6288-476.20426667 476.20426667-476.20426666 262.57653333 0 476.20533333 213.62773333 476.20533333 476.20426666C988.36810667 646.97632 774.73930667 860.6051199999999 512.16384 860.6051199999999zM512.16384-32.27925332999996c-229.76042667 0-416.67893333 186.91957333-416.67893333 416.68117333 0 229.76042667 186.91850667 416.67893333 416.67893333 416.67893333 229.7616 0 416.67893333-186.91850667 416.67893333-416.67893333C928.84277333 154.63925332999997 741.92426667-32.27925332999996 512.16384-32.27925332999996zM690.74069333 414.16298667H333.5880704c-16.45173333 0-29.7632-13.31146667-29.7632-29.76213334 0-16.42218667 13.31146667-29.7632 29.7632-29.7632h357.15263147c16.45173333 0 29.7632 13.34090667 29.7632 29.7632C720.50389333 400.85152 707.19242667 414.16298667 690.74069333 414.16298667z" horiz-adv-x="1024" />

<glyph glyph-name="arrow-right" unicode="&#58882;" d="M336.733 776.333l-56.278-55.72 334.857-337.154-337.673-334.315 55.802-56.184 393.944 390.04z" horiz-adv-x="1024" />

<glyph glyph-name="jiahao" unicode="&#59174;" d="M512-62.01661100000001c-119.648434 0-232.1288 46.367961-316.736783 130.559656-84.640667 84.255342-131.263217 196.255772-131.263217 315.455235 0 119.168499 46.624271 231.199892 131.232254 315.424271 84.607983 84.191695 197.088348 130.559656 316.736783 130.559656s232.1288-46.367961 316.704099-130.559656c84.67163-84.224378 131.263217-196.255772 131.263217-315.391587 0.032684-119.199462-46.591587-231.232576-131.263217-315.455235C744.1288-15.615965999999958 631.648434-62.01661100000001 512-62.01661100000001zM512 766.016611c-102.623626 0-199.071738-39.743475-271.583282-111.936783-72.480581-72.12794-112.416718-168.063432-112.416718-270.079828s39.903454-197.951888 112.384034-270.047144c72.511544-72.191587 168.959656-111.936783 271.583282-111.936783 102.592662 0 199.071738 39.743475 271.583282 111.936783 72.480581 72.160624 112.416718 168.063432 112.384034 270.079828 0 102.016396-39.903454 197.919204-112.384034 270.016181C711.071738 726.240452 614.592662 766.016611 512 766.016611zM736.00086 415.99914L544.00086 415.99914 544.00086 607.99914c0 17.664722-14.336138 32.00086-32.00086 32.00086s-32.00086-14.336138-32.00086-32.00086l0-192L288.00086 415.99914c-17.664722 0-32.00086-14.336138-32.00086-32.00086s14.336138-32.00086 32.00086-32.00086l192 0 0-192c0-17.695686 14.336138-32.00086 32.00086-32.00086s32.00086 14.303454 32.00086 32.00086L544.00258 351.99914l192 0c17.695686 0 32.00086 14.336138 32.00086 32.00086S753.696546 415.99914 736.00086 415.99914z" horiz-adv-x="1024" />

<glyph glyph-name="arrow-bot" unicode="&#59050;" d="M171.15136 554.99776l684.02176 0-342.016-341.99552L171.15136 554.99776z" horiz-adv-x="1024" />

<glyph glyph-name="arrow-top" unicode="&#59056;" d="M855.16288 213.00224000000003L171.14112 213.00224000000003l342.016 341.99552L855.16288 213.00224000000003z" horiz-adv-x="1024" />

<glyph glyph-name="duihaocheckmark17" unicode="&#59248;" d="M704.20625 544.734375L441.6875 282.21562500000005l-121.865625 121.89375c-10.715625 10.715625-28.125 10.715625-38.840625 0-10.715625-10.715625-10.715625-28.125 0-38.840625l137.953125-137.953125c0.928125-1.321875 1.490625-2.840625 2.671875-4.021875 5.540625-5.540625 12.825-8.1 20.08125-7.903125 7.25625-0.16875 14.56875 2.3625 20.109375 7.903125 1.18125 1.18125 1.74375 2.7 2.671875 4.021875l278.578125 278.578125c10.715625 10.715625 10.715625 28.125 0 38.840625C732.303125 555.45 714.921875 555.45 704.20625 544.734375zM512 834C263.459375 834 62 632.540625 62 384c0-248.540625 201.459375-450 450-450 248.5125 0 450 201.459375 450 450C962 632.540625 760.540625 834 512 834zM512-9.75C294.5375-9.75 118.25 166.53750000000002 118.25 384 118.25 601.4625 294.5375 777.75 512 777.75c217.4625 0 393.75-176.2875 393.75-393.75C905.75 166.53750000000002 729.4625-9.75 512-9.75z" horiz-adv-x="1024" />

<glyph glyph-name="yonghu" unicode="&#58937;" d="M502.496 832.864c125.888 0 227.936-100.384 227.936-224.192 0-123.84-102.048-224.224-227.936-224.224-125.888 0-227.936 100.384-227.936 224.224C274.56 732.512 376.64 832.864 502.496 832.864L502.496 832.864zM502.496 832.864c125.888 0 227.936-100.384 227.936-224.192 0-123.84-102.048-224.224-227.936-224.224-125.888 0-227.936 100.384-227.936 224.224C274.56 732.512 376.64 832.864 502.496 832.864L502.496 832.864zM417.024 309.696l189.984 0c162.624 0 294.432-129.632 294.432-289.6l0-18.656c0-63.04-131.84-65.44-294.432-65.44l-189.984 0c-162.624 0-294.432 0.096-294.432 65.44l0 18.656C122.592 180.064 254.4 309.696 417.024 309.696L417.024 309.696zM417.024 309.696" horiz-adv-x="1024" />

<glyph glyph-name="caidan" unicode="&#58888;" d="M68.191078 334.687898l98.624205 0 0 98.624205L68.191078 433.312102 68.191078 334.687898zM68.191078 137.439488l98.624205 0 0 98.624205L68.191078 236.063693 68.191078 137.439488zM68.191078 531.936307l98.624205 0 0 98.624205L68.191078 630.560512 68.191078 531.936307zM265.439488 334.687898l690.369434 0 0 98.624205L265.439488 433.312102 265.439488 334.687898zM265.439488 137.439488l690.369434 0 0 98.624205L265.439488 236.063693 265.439488 137.439488zM265.439488 630.560512l0-98.624205 690.369434 0 0 98.624205L265.439488 630.560512z" horiz-adv-x="1024" />

<glyph glyph-name="mima" unicode="&#58914;" d="M768.9216 473.27232 372.06016 473.27232C378.88 530.78016 329.37984 764.57984 512.2048 770.27328c173.83424 6.59456 146.78016-213.34016 146.78016-213.34016l85.13536-0.57344c0 0 24.73984 294.4-231.91552 295.8336C232.09984 837.98016 297.82016 518.81984 289.28 473.27232c1.98656 0 4.56704 0 7.29088 0-55.88992 0-101.21216-45.34272-101.21216-101.21216l0-337.38752c0-55.88992 45.34272-101.21216 101.21216-101.21216l472.35072 0c55.88992 0 101.21216 45.34272 101.21216 101.21216L870.13376 372.06016C870.13376 427.9296 824.79104 473.27232 768.9216 473.27232zM566.4768 178.97472l0-76.84096c0-18.57536-15.1552-33.73056-33.73056-33.73056-18.57536 0-33.73056 15.1552-33.73056 33.73056l0 76.84096c-20.09088 11.69408-33.73056 33.21856-33.73056 58.12224 0 37.2736 30.208 67.4816 67.4816 67.4816 37.2736 0 67.4816-30.208 67.4816-67.4816C600.22784 212.19328 586.58816 190.6688 566.4768 178.97472z" horiz-adv-x="1024" />

<glyph glyph-name="arrow-left" unicode="&#58983;" d="M671.807-31.803999999999974l-415.632 415.804 415.632 415.803 63.445-63.616-352.017-352.209 352.017-352.102z" horiz-adv-x="1024" />

<glyph glyph-name="tianjia" unicode="&#58959;" d="M925.304287 481.160787 606.244429 481.160787 606.244429 800.322974c0 17.60048-14.223643 31.926451-31.926451 31.926451L446.7145 832.249425c-17.60048 0-31.926451-14.223643-31.926451-31.926451l0-319.059858L95.72819 481.263116c-17.60048 0-31.926451-14.223643-31.926451-31.926451l0-127.603478c0-17.60048 14.223643-31.926451 31.926451-31.926451l319.059858 0 0-319.059858c0-17.60048 14.223643-31.926451 31.926451-31.926451l127.603478 0c17.60048 0 31.926451 14.325972 31.926451 31.926451L606.244429 289.806735l319.059858 0c17.60048 0 31.926451 14.223643 31.926451 31.926451L957.230738 449.336664C957.230738 466.937144 943.007095 481.160787 925.304287 481.160787L925.304287 481.160787z" horiz-adv-x="1024" />

<glyph glyph-name="cuowu" unicode="&#58902;" d="M945.91565013 549.48833387c-23.25132907 54.90806827-56.43632533 104.13975573-98.68169813 146.38512853-42.2453728 42.2453728-91.58622187 75.5395296-146.38512853 98.68169813C643.97585493 818.5706176 583.71888853 830.7966688 521.49702187 830.7966688s-122.47883307-12.2260512-179.35180267-36.24150827c-54.90806827-23.25132907-104.13975573-56.43632533-146.38512853-98.68169813s-75.5395296-91.58622187-98.68169814-146.38512853C73.06293547 492.61536427 60.83688427 432.35839787 60.83688427 370.13653120000004s12.2260512-122.47883307 36.24150826-179.35180267c23.25132907-54.90806827 56.43632533-104.13975573 98.68169814-146.38512853 42.2453728-42.2453728 91.58622187-75.5395296 146.38512853-98.68169813 56.763808-24.01545707 117.12993493-36.24150827 179.35180267-36.24150827s122.47883307 12.2260512 179.35180266 36.24150827c54.90806827 23.25132907 104.13975573 56.43632533 146.38512854 98.68169813 42.2453728 42.2453728 75.5395296 91.58622187 98.68169813 146.38512853 24.01545707 56.763808 36.24150827 117.12993493 36.24150827 179.35180267S969.93110827 492.61536427 945.91565013 549.48833387zM521.49702187-42.49269119999997c-227.4918784 0-412.6292224 185.137344-412.6292224 412.6292224s185.137344 412.6292224 412.6292224 412.6292224 412.6292224-185.137344 412.6292224-412.6292224S748.98890027-42.49269119999997 521.49702187-42.49269119999997zM547.25905813 367.40750187000003l112.2176832 112.2176832c9.38786027 9.38786027 9.38786027 24.67042453 0 33.94912426l0 0c-9.38786027 9.38786027-24.67042453 9.38786027-33.94912426 0L513.30993387 401.35662613 400.54644587 514.0109536c-9.38786027 9.38786027-24.67042453 9.38786027-33.94912427 0l0 0c-9.38786027-9.38786027-9.38786027-24.67042453 0-33.94912427l112.65432747-112.65432746L366.05151573 254.20736853000005c-9.38786027-9.38786027-9.38786027-24.67042453 0-33.94912426 9.38786027-9.38786027 24.67042453-9.38786027 33.94912427 0l113.20013333 113.20013333 112.65432747-112.65432747c9.38786027-9.38786027 24.67042453-9.38786027 33.94912427 0 9.38786027 9.38786027 9.38786027 24.67042453 0 33.94912427L547.25905813 367.40750187000003z" horiz-adv-x="1024" />

<glyph glyph-name="cuowu1" unicode="&#58996;" d="M508.74077 830.629529c-247.026716 0-447.274148-200.247432-447.274148-447.274148 0-247.028515 200.247432-447.274148 447.274148-447.274148s447.274148 200.245434 447.274148 447.274148C956.014918 630.3820969999999 755.767486 830.629529 508.74077 830.629529zM509.450888 70.26345700000002c-34.495812 0-62.461451 26.162862-62.461451 58.442176 0 32.277716 27.965639 58.442376 62.461451 58.442376 34.506804 0 62.471444-26.16466 62.471444-58.442376C571.922333 96.42611899999997 543.957693 70.26345700000002 509.450888 70.26345700000002zM621.45475 557.394183l-49.630151-276.31326c0-0.306592 0.097734-0.5906 0.097734-0.895393 0-32.279514-27.965639-58.442176-62.471444-58.442176-34.495812 0-62.461451 26.162862-62.461451 58.442176 0 0.304993 0.087541 0.5896 0.097734 0.895393l-49.641943 276.31326 0.699326 0c-0.437304 3.800024-0.699326 7.621832-0.699326 11.509596 0 58.093613 50.144002 105.179688 112.004861 105.179688s112.003861-47.086076 112.003861-105.179688c0-3.888564-0.262022-7.709573-0.699126-11.509596L621.45475 557.394183z" horiz-adv-x="1024" />

<glyph glyph-name="edit" unicode="&#58911;" d="M924.766 708.515c-32.297 32.412-62.339 68.774-99.757 95.411-34.261 7.093-50.787-29.928-74.311-47.237 39.777-46.201 86.117-87.013 128.923-130.718 19.407 23.095 65.369 46.724 45.145 82.543zM903.499 533.974c-27.158-27.294-55.258-53.806-81.519-82.146-0.648-109.327 0.273-218.642-0.375-327.946-0.545-40.3-35.851-76.004-76.13-77.445-165.797-0.65-331.717-0.65-497.513-0.127-44.75 1.191-80.6 44.103-77.048 88.058-0.125 158.274-0.125 316.403 0 474.533-3.406 43.84 32.55 85.968 76.797 87.535 109.85 1.451 219.739-0.125 329.462 0.794 28.495 25.717 54.737 53.942 82.063 80.976-146.242 0-292.337 0.773-438.557-0.397-68.274-1.18-129.445-60.898-130.614-129.403-0.272-184.515-0.793-368.895 0.25-553.399 0.272-66.414 56.7-124.012 122.091-130.322l574.541 0c61.944 10.884 115.115 64.972 115.907 129.403 1.839 146.576 0.399 293.297 0.649 439.883zM859.669 605.757c-43.058 43.309-86.365 86.357-129.946 129.142-95.309-94.619-190.867-188.987-285.63-284.128 42.91-43.182 86.094-86.22 129.674-128.871 95.433 94.484 190.718 189.238 285.902 283.856zM373.604 252.22c58.392 15.877 89.499 25.874 147.911 41.616 15.607 4.973 25.989 7.98 33.992 11.167-41.345 39.369-88.852 87.891-130.072 127.523-17.32-60.106-34.534-120.201-51.832-180.305z" horiz-adv-x="1024" />

<glyph glyph-name="duihao" unicode="&#59038;" d="M62 384C62 632.5241376 263.4758624 834 512 834s450-201.4758624 450-450-201.4758624-450-450-450S62 135.47586239999998 62 384z m368.53448291-171.06206924a31.03448291 31.03448291 0 0 1 43.41724102-1.11724102l294.88965556 274.15862052a31.03448291 31.03448291 0 0 1-42.25344873 45.46551708l-271.69137862-254.4827581-127.5517248 131.52413759a31.03448291 31.03448291 0 1 1-44.55-43.21551709l147.75517266-152.33275898z" horiz-adv-x="1024" />

<glyph glyph-name="search" unicode="&#58899;" d="M960-18.7l-211.9 211.9c25.4 29.9 46.1 63.4 61.5 99.8 20.3 47.9 30.5 98.6 30.5 151s-10.2 103.1-30.5 151c-19.6 46.2-47.5 87.7-83.1 123.3-35.7 35.7-77.2 63.6-123.5 83.2-47.9 20.3-98.6 30.5-151 30.5-52.4 0-103.1-10.2-151-30.5-46.2-19.6-87.7-47.5-123.3-83.1-35.7-35.6-63.6-77.1-83.2-123.4-20.3-47.9-30.5-98.6-30.5-151s10.2-103.1 30.5-151c19.6-46.2 47.5-87.7 83.1-123.3 35.6-35.6 77.1-63.6 123.3-83.1 47.9-20.3 98.6-30.5 151-30.5 52.4 0 103.1 10.2 151 30.5 36.4 15.4 69.8 36 99.8 61.5l212-212.1 45.3 45.3zM578.1 145.4c-39.9-16.8-82.3-25.4-126.1-25.4s-86.2 8.6-126.1 25.4c-38.6 16.3-73.3 39.7-103 69.5-29.7 29.7-53.1 64.4-69.5 103-16.8 39.9-25.4 82.3-25.4 126.1s8.6 86.2 25.4 126.1c16.3 38.6 39.7 73.3 69.5 103 29.7 29.7 64.4 53.1 103 69.5 39.9 16.8 82.3 25.4 126.1 25.4 43.8 0 86.2-8.6 126.1-25.4 38.6-16.3 73.3-39.7 103-69.5 29.7-29.7 53.1-64.4 69.5-103 16.8-39.9 25.4-82.3 25.4-126.1s-8.6-86.2-25.4-126.1c-16.3-38.6-39.7-73.3-69.5-103-29.7-29.8-64.4-53.1-103-69.5z" horiz-adv-x="1024" />

<glyph glyph-name="tuichu" unicode="&#58962;" d="M950.093 408.228l-179.775 173.078c-14.382 13.851-35.955 13.851-50.336 0-14.382-13.842-14.382-34.614 0-48.465l118.647-114.228h-345.168c-21.573 0-35.955-13.842-35.955-34.614s14.382-34.614 35.955-34.614h345.168l-118.639-114.228c-14.382-13.851-14.382-34.623 0-48.465 7.192-6.93 14.382-10.386 25.164-10.386 10.792 0 17.982 3.465 25.173 10.386l179.775 176.535s0 3.465 3.6 3.465c10.782 10.386 10.782 31.149-3.6 41.535zM853.01 141.69299999999998c-21.573 0-35.955-13.851-35.955-34.614v-69.237c0-20.763-14.382-34.614-35.955-34.614h-611.235c-21.573 0-35.955 13.851-35.955 34.614v692.317c0 20.763 14.382 34.614 35.955 34.614h611.235c21.573 0 35.955-13.851 35.955-34.614v-69.237c0-20.764 14.382-34.614 35.955-34.614s35.955 13.851 35.955 34.614v69.237c0 58.842-46.736 103.842-107.865 103.842h-611.235c-61.119 0-107.865-45-107.865-103.842v-692.317c0-58.842 46.747-103.842 107.865-103.842h611.235c61.128 0 107.865 45 107.865 103.842v69.237c0 20.764-14.382 34.614-35.955 34.614z" horiz-adv-x="1024" />

<glyph glyph-name="cuo" unicode="&#59020;" d="M939.78396445 564.20010667c-23.33696 55.09461333-56.61468445 104.52992-99.14481778 147.05891555s-91.96430222 75.80785778-147.05891556 99.14481778c-57.02883555 24.16412445-117.64849778 36.31559111-180.06129778 36.31559111s-123.03246222-12.28913778-180.06129778-36.31559111c-55.09461333-23.33696-104.52992-56.61468445-147.05891555-99.14481778-42.52899555-42.52899555-75.80785778-91.96430222-99.14481778-147.05891555-24.16412445-57.02883555-36.31559111-117.64849778-36.31559111-180.06129778s12.28913778-123.03246222 36.31559111-180.06129778c23.33696-55.09461333 56.61468445-104.52992 99.14481778-147.05891556 42.52899555-42.52899555 91.96430222-75.80785778 147.05891555-99.14481777 57.02883555-24.16412445 117.64849778-36.31559111 180.06129778-36.31559111s123.03246222 12.28913778 180.06129778 36.31559111c55.09461333 23.33696 104.52992 56.61468445 147.05891556 99.14481777 42.52899555 42.52899555 75.80785778 91.96430222 99.14481778 147.05891556 24.16412445 57.02883555 36.31559111 117.64849778 36.3155911 180.06129778s-12.15260445 123.03246222-36.3155911 180.06129778zM706.97415111 232.10780445c12.84096-12.84096 12.84096-33.96835555 0-46.81045334s-33.96835555-12.84096-46.81045333 0l-150.78741333 150.64860444-150.64860445-150.78741333c-12.84096-12.84096-33.96835555-12.84096-46.81045333 0s-12.84096 33.96835555 0 46.81045333l150.64860444 150.64860445-150.78741333 150.78741333c-12.84096 12.84096-12.84096 33.96835555 0 46.81045334 12.84096 12.84096 33.96835555 12.84096 46.81045333 0l150.64860444-150.64860445 150.64860445 150.64860445c12.84096 12.84096 33.96835555 12.84096 46.81045333 0s12.84096-33.96835555 0-46.81045334l-150.37326222-150.64860444 150.64860444-150.64860444z" horiz-adv-x="1024" />



</font>
</defs></svg>

BIN
src/static/font/iconfont.ttf 파일 보기


BIN
src/static/font/iconfont.woff 파일 보기


BIN
src/static/images/login-bg.png 파일 보기

Before After
Width: 1920  |  Height: 1281  |  Size: 601 KiB

BIN
src/static/images/logout.png 파일 보기

Before After
Width: 200  |  Height: 200  |  Size: 3.6 KiB

+ 24
- 0
src/static/js/event.js 파일 보기

@@ -0,0 +1,24 @@

/**
* 单页面通信,订阅 + 发布
* on为注册
* broadcast为执行,一旦broadcast执行,会主动推送消息到on注册的地方
* **/
var EventPublisher = function(){

this.eventCallbackDictionary = {};

this.on = function(eventName,callback){
this.eventCallbackDictionary[eventName] = callback;
}

this.broadcast = function(eventName,data){
for(var i in this.eventCallbackDictionary){
if(i == eventName && this.eventCallbackDictionary[eventName]){
this.eventCallbackDictionary[eventName](data);
//this.eventCallbackDictionary[eventName] = null;
}
}
}
}
var eventCtl = new EventPublisher();

+ 11
- 0
src/store/coupon/game.js 파일 보기

@@ -0,0 +1,11 @@
export default{
state: {
couponTableData: []
},
mutations: {
increment (state,data) {
// 变更状态
state.couponTableData=data
}
}
}

+ 17
- 0
src/store/coupon/store.js 파일 보기

@@ -0,0 +1,17 @@


export default{
state:{
channels:[]
},
mutations:{
setChannels(state,data){
state.channels = data;
}
},
actions:{
setChannels(context,data){
context.commit("setChannels",data);
}
}
}

+ 10
- 0
src/store/index.js 파일 보기

@@ -0,0 +1,10 @@


import Vuex from 'vuex';
import topNav_store from "./topNav/store.js";

export default new Vuex.Store({
modules:{
topNav:topNav_store,
}
})

+ 17
- 0
src/store/member/store.js 파일 보기

@@ -0,0 +1,17 @@


export default{
state:{
memberId:""
},
mutations:{
setMemberId(state,data){
state.memberId = data;
}
},
actions:{
setMemberId(context,data){
context.commit("setMemberId",data);
}
}
}

+ 40
- 0
src/store/topNav/store.js 파일 보기

@@ -0,0 +1,40 @@


export default{
state:{
data:[],
uname:"",
index:'',
},
getters:{
tmp_data(state){
if(state.data.length == 0){
return ['未配置']
}
return state.data;
}
},
mutations:{
setNavData(state,data){
state.data = data;
},
setName(state,name){
state.uname = name;
},
setIndex(state,index){
state.index = index;
}
},
actions:{
setNavData(context,data){
console.log("触发分发setNavData");
context.commit("setNavData",data);
},
setUName(context,data){
context.commit("setName",data);
},
setIndex(context,data){
context.commit("setIndex",data);
}
}
}

+ 116
- 0
src/utils/config.js 파일 보기

@@ -0,0 +1,116 @@

export let configUrl = {
//登录
doLogin:"/T/doLogin",
//获得后端版本号
getversion:"/T/version",
//验证码
captcha:"/T/captcha.jpg",
//微信第三方开放平台授权相关接口
getMobilePreAuthUrl:"/T/wt_auth/getMobilePreAuthUrl",
//获取授权跳转页
gotoAuthUrlShow:"/T/wt_auth/goto_auth_url_show",
//授权跳转页面
gotoAuthUrl:"/T/wt_auth/goto_auth_url",
//获得小程序的模板
getTempList:"/T/weappDraftTemplate/tempList",
//获得小程序草稿
tempDraftList:"/T/weappDraftTemplate/tempDraftList",
//小程序草稿转为模板
addToTemplate:"/T/weappDraftTemplate/addToTemplate",
//删除小程序模板
deleteTemplate:"/T/weappDraftTemplate/deleteTemplate",
//获得小程序列表
weappList:"/T/weapp/list",
//首页 小程序扩展配置列表
weappExtSetList:"/T/weappExtSet/list",
//小程序提交审核
batchCodeCommitAndAudit:'/T/weapp/batchCodeCommitAndAudit',
//批量上传code并提交审核
batchCodeCommitAndAudit:"/T/weapp/batchCodeCommitAndAudit",
//获得小程序体验二维码
getQrcode:"/T/weappCode/getQrcode",
//批量发布
batchRelease:"/T/weapp/batchRelease",
//获取授权小程序帐号已设置的类目
getCategory:"/T/weappCode/getCategory",
//将第三方提交的代码包提交审核
submitAudit:"/T/weappCode/submitAudit",
//小程序审核撤回
undoCodeAudit:"/T/weappCode/undoCodeAudit",
//查询最新一次提交的审核状态
getLatestAuditstatus:"/T/weappCode/getLatestAuditstatus",
//发布已通过审核的小程序
releaesAudited:"/T/weappCode/releaesAudited",
//小程序不带分页列表
webappallist:"/T/weapp/allist",
//设置小程序服务器域名
modifyDomain:"/T/weappSet/modifyDomain",
//设置小程序业务域名
setWebViewDomain:"/T/weappSet/setWebViewDomain",
//绑定微信用户为小程序体验者
bindTester:"/T/weappSet/bindTester",
//解除绑定小程序的体验者
unbindTester:"/T/weappSet/unbindTester",
//获得体验者的列表
getTesterList:"/T/weappSet/getTesterList",
//小程序发布状态分页列表接口
releaseStatusList:"/T/weapp/releaseStatusList",
//小程序版本回退
revertCodeRelease:"/T/weappCode/revertCodeRelease",
//批量审核查询
batchAuditQuery:"/T/weapp/batchAuditQuery",
//小程序基础设置接口 分页列表接口
weappBasicSetList:"/T/weappBasicSet/list",
//批量基础配置
batchBasicSet:"/T/weapp/batchBasicSet",
//批量撤回
batchAuditCancel:"/T/weapp/batchAuditCancel",
//获取小程序服务器域名
getDomain:"/T/weappSet/getDomain",
//获取小程序业务域名
getWebDomain:"/T/weappSet/getWebDomain",
//小程序审核撤回
undoCodeAudit:"/T/weappCode/undoCodeAudit",
//小程序批量提交代码
batchCodeCommit:"/T/weapp/batchCodeCommit",
//小程序批量提交审核
batchCodeAudit:"/T/weapp/batchCodeAudit",
//获取小程序已设置的账号类目
getCategory:"/T/weappCode/getCategory",
//小程序code提交状态分页列表接口
codeStatusList:"/T/weapp/codeStatusList",
//小程序code提交版本列表
codeVersionList:"/T/weapp/codeVersionList",
// 小程序审核状态分页列表接口
auditStatusList:"/T/weapp/auditStatusList",
//小程序审核版本列表
auditVersionList:"/T/weapp/auditVersionList",
//小程序发布版本列表
releaseVersionList:"/T/weapp/releaseVersionList",
//发布已通过审核的小程序
releaseAudited:"/T/weappCode/releaseAudited",
//查询最新一次提交的审核状态
getLatestAuditstatus:"/T/weappCode/getLatestAuditstatus",
//创建微信开放平台
createOpenPlatform:"/T/wxOpen/createOpenPlatform",
//绑定微信开放平台
bindOpenPlatform:"/T/wxOpen/bindOpenPlatform",
//解绑微信开放平台
unbindOpenPlatform:"/T/wxOpen/unbindOpenPlatform",
//获取微信开放平台
getOpenPlatform:"/T/wxOpen/getOpenPlatform",
//重置公众号Quota
clearQuota:"/T/wxOpen/clearQuota",
//小程序扩展配置接口
weappExtSetupdate:"/T/weappExtSet/update",
//拉取当前所有已授权的帐号基本信息
getAuthorizerList:"/T/wxOpen/getAuthorizerList",
//批量扩展配置
batchExtendSet:"/T/weappExtSet/batchUpdate",
//获取帐号下已存在的模板列表
getTemplateList:"/T/weappMsgTemplate/getTemplateList",
//删除帐号下的某个模板
delTemplate:"/T/weappMsgTemplate/delTemplate"

}

+ 11
- 0
src/utils/validate.js 파일 보기

@@ -0,0 +1,11 @@
//深拷贝
export function deepcopy(source) {
if (!source) {
return source;
}
let sourceCopy = source instanceof Array ? [] : {};
for (let item in source) {
sourceCopy[item] = typeof source[item] === 'object' ? deepcopy(source[item]) : source[item];
}
return sourceCopy;
};

+ 5
- 0
typings.json 파일 보기

@@ -0,0 +1,5 @@
{
"globalDependencies": {
"popper.js": "registry:dt/popper.js#0.4.0+20161005184000"
}
}

+ 155
- 0
webpack.config.js 파일 보기

@@ -0,0 +1,155 @@
var path = require('path');
var webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const packageInfo = require('./package.json');
const CompressionWebpackPlugin = require("compression-webpack-plugin");
module.exports = (env = {}) =>{
console.log(`------------------- ${env.Generative?'生产':'开发'}环境 -------------------`);
var plugins = (module.exports.plugins || []).concat([
new CleanWebpackPlugin(['dist']),
new webpack.optimize.UglifyJsPlugin({
// sourceMap: true,
// compress: {
// warnings: false
// }
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
if(!env.Generative){
plugins = [];
}
plugins.push(
new CompressionWebpackPlugin({
filename: '[path].gz[query]', //压缩后的文件名
algorithm: 'gzip',// 压缩格式 有:gzip、brotliCompress、
test: /\.(js|css|svg)$/,
threshold: 10240,// 只处理比这个值大的资源,按字节算
minRatio: 0.8, //只有压缩率比这个值小的文件才会被处理,压缩率=压缩大小/原始大小,如果压缩后和原始文件大小没有太大区别,就不用压缩
deleteOriginalAssets: false //是否删除原文件,最好不删除,服务器会自动优先返回同名的.gzip资源,如果找不到还可以拿原始文件
}));
plugins.push(new CopyWebpackPlugin([{
// from: './src/static',
// to: 'static'
from : path.join(__dirname,'./src/static'),
to : 'static'
}]));
plugins.push(new HtmlWebpackPlugin({
// title: "自动生成网页标题",
filename: "./index.html",
hash:true,
showErrors: true,
version: packageInfo.version,
template: './src/index.html'
}));

return {
entry: {
app:['babel-polyfill','./src/main.js'],
vendor: ['vue', 'vue-router', 'vuex', 'element-ui']
},
output: {
path: path.resolve(__dirname, './dist'),//输出结果
publicPath: env.production ? './' : '/', //文件路径
filename: '[name].js',
chunkFilename: 'js/[name].js'
},
module: {
rules: [
// 使用vue-loader 加载 .vue 结尾的文件
{
test: /\.vue$/,
loader: 'vue-loader',
options: {
loaders: {
},
// other vue-loader options go here
presets: ['es2015'],
plugins: ['transform-runtime', 'transform-object-rest-spread']
},
// query: {
// }
},
// 使用babel 加载 .js 结尾的文件
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/
},
// 加载图标
{
test: /\.(png|jpg|gif|svg)$/,
loader: 'file-loader',
options: {
name: '[name].[ext]?[hash]',
limit: 8192,
outputPath: 'static/images/'
}
},
//加载css
{
test: /\.css$/,
loader: "style-loader!css-loader",
// loader: 'style-loader!css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]',
// exclude: /node_modules/
},
// {
// test: /\.scss$/,
// loader: "style-loader!css-loader!sass-loader!"
// },
// {
// test: /\.(woff|woff2|svg|ttf|eot)$/,
// use:[
// {loader:'file-loader',options:{name:'fonts/[name].[hash:8].[ext]'}}//项目设置打包到dist下的fonts文件夹下
// // {loader:'url-loader',options:{name:'fonts/[name].[hash:8].[ext]'}}//项目设置打包到dist下的fonts文件夹下
// ]
// },
{
test: /\.(woff|woff2|svg|eot|ttf)\??.*$/,
// loader: 'url-loader'
loader:'url-loader',options:{name:'fonts/[name].[hash:8].[ext]'}//项目设置打包到dist下的fonts文件夹下
},
// {
// test: /\.html$/,
// loader: 'html-loader',
// options: {
// minimize: false
// }
// }
]
},
resolve: {
alias: {
'vue$': 'vue/dist/vue.esm.js'
}
},
externals: {
"BMap": "BMap"
},
devServer: {
inline: true, //检测文件变化,实时构建并刷新浏览器
port: "8880",
proxy: {
'/T': {
target: 'https://opentest.malls.iformall.com/T',
// target: 'http://10.100.30.171:6060',
pathRewrite: {
"^/T": ""
},
secure: false,
changeOrigin: true
},
},
historyApiFallback: true,
},
performance: {
hints: false
},
plugins:plugins,
// devtool: '#eval-source-map'//开发模式下更方便定位错误
devtool:env.Generative?false:'#eval-source-map'
}
}

불러오는 중...
취소
저장