Browse Source

功能配置

preview
jiangyy 5 years ago
parent
commit
73e5bc9690
  1. 4
      epmet-oper-web/.env.development
  2. 1
      epmet-oper-web/.env.production
  3. 8
      epmet-oper-web/public/index.html
  4. 7
      epmet-oper-web/src/js/columns/columns.js
  5. 84
      epmet-oper-web/src/js/columns/miniPro/customizedFunction.js
  6. 47
      epmet-oper-web/src/views/components/CTable.vue
  7. 23
      epmet-oper-web/src/views/modules/code/VersionItem.vue
  8. 50
      epmet-oper-web/src/views/modules/code/VersionManage.vue
  9. 266
      epmet-oper-web/src/views/modules/customer-manage/MiniProManage/MiniProManage.vue
  10. 0
      epmet-oper-web/src/views/modules/customer/RegisterList.vue
  11. 0
      epmet-oper-web/src/views/modules/customer/customer-info.vue
  12. 0
      epmet-oper-web/src/views/modules/customer/customer-manage.vue
  13. 180
      epmet-oper-web/src/views/modules/customer/miniCustomize/ConfigEdit.vue
  14. 370
      epmet-oper-web/src/views/modules/customer/miniCustomize/ConfigItem.vue
  15. 163
      epmet-oper-web/src/views/modules/customer/miniCustomize/CustomerList.vue
  16. 889
      epmet-oper-web/src/views/modules/customer/miniCustomize/MiniHome.vue
  17. 167
      epmet-oper-web/src/views/modules/customize/CustomizedFunction copy.vue
  18. 247
      epmet-oper-web/src/views/modules/miniPro/customFun/CustomFun.vue
  19. 263
      epmet-oper-web/src/views/modules/miniPro/customFun/Edit.vue

4
epmet-oper-web/.env.development

@ -1,5 +1,5 @@
NODE_ENV=development
VUE_APP_API_SERVER = http://192.168.1.130:8080/api
# VUE_APP_API_SERVER = http://192.168.1.130:8080/api
# VUE_APP_API_SERVER = http://10.10.10.207:8080/api
# VUE_APP_API_SERVER = https://epmet-dev.elinkservice.cn/api
VUE_APP_API_SERVER = https://epmet-dev.elinkservice.cn/api
VUE_APP_NODE_ENV=dev

1
epmet-oper-web/.env.production

@ -1,2 +1,3 @@
NODE_ENV=production
VUE_APP_API_SERVER = https://epmet-cloud.elinkservice.cn/api
VUE_APP_NODE_ENV=prod

8
epmet-oper-web/public/index.html

@ -34,11 +34,13 @@
<!-- 开发环境 -->
<% if (process.env.VUE_APP_NODE_ENV === 'dev') { %>
<!-- <script>window.SITE_CONFIG['apiURL'] = 'http://10.10.10.98:8080/api';</script> -->
<script>
<!-- <script>
window.SITE_CONFIG['apiURL'] = 'http://192.168.1.130:8080/api'
</script>
</script> -->
<!-- <script>window.SITE_CONFIG['apiURL'] = 'http://localhost:8080/api';</script> -->
<!-- <script>window.SITE_CONFIG['apiURL'] = 'https://epmet-dev.elinkservice.cn/api';</script> -->
<script>
window.SITE_CONFIG['apiURL'] = 'https://epmet-dev.elinkservice.cn/api'
</script>
<% } %>
<!-- 集成测试环境 dev -->
<% if (process.env.VUE_APP_NODE_ENV === 'prod:sit') { %>

7
epmet-oper-web/src/js/columns/columns.js

@ -6,6 +6,8 @@ import RegisterInfo from './customer/customer'
import MiniProManage from './customer/miniProManage'
import Version from './customer/version'
import CustomizedFunction from './miniPro/customizedFunction'
export default {
Temp: Temp, // 代码上传——模板list
CommitCodeList: CommitCode['list'], // 代码上传——已上传的代码列表
@ -15,5 +17,8 @@ export default {
RegisterInfo: RegisterInfo, // 客户管理——客户注册信息
MiniProManage: MiniProManage, // 客户管理——客户小程序管理
Version: Version // 客户管理——基础库
Version: Version, // 客户管理——基础库
// 小程序管理
CustomizedFunction: CustomizedFunction // 定制功能
}

84
epmet-oper-web/src/js/columns/miniPro/customizedFunction.js

@ -0,0 +1,84 @@
export default [
{
key: 'customizedName',
title: '功能名称',
display: ['formA', 'formU', 'table', 'model'],
fixed: false,
block: true,
width: 100
},
{
key: 'shoppingStatus',
title: '上架状态',
display: ['formA', 'formU', 'table', 'model'],
fixed: false,
block: true,
format: (cellValue, index) => {
if (cellValue === 0) {
return '下架'
} else if (cellValue === 1) {
return '上架'
} else {
return '未知'
}
},
width: 80
},
{
key: 'functionExplain',
title: '功能说明',
display: ['formA', 'formU', 'table', 'model'],
fixed: false,
block: true,
width: 120
},
{
key: 'iconLargeImg',
title: '大图标',
display: ['formA', 'formU', 'table', 'model'],
fixed: false,
block: true,
width: 100,
tableType: 'image'
},
{
key: 'iconSmallImg',
title: '小图标',
display: ['formA', 'formU', 'table', 'model'],
fixed: false,
block: true,
width: 100,
tableType: 'image'
},
{
key: 'targetLink',
title: '外链地址',
display: ['formA', 'formU', 'table', 'model'],
block: true,
width: 60
},
// {
// key: 'domainName',
// title: '业务域名',
// display: ['formA', 'formU', 'table', 'model'],
// block: true,
// width: 60
// },
{
key: 'fromApp',
title: '来源',
display: ['formA', 'formU', 'table', 'model'],
block: true,
format: (cellValue, index) => {
if (cellValue === 'gov') {
return '工作端'
} else if (cellValue === 'resi') {
return '居民端'
} else {
return '未知'
}
},
width: 80
}
]

47
epmet-oper-web/src/views/components/CTable.vue

@ -37,7 +37,7 @@
</div>
<template v-for="col in tableColumn">
<!--渲染列-->
<el-table-column v-if="col.render"
<el-table-column v-if="col.tableType==='span'"
:key="col.key"
:label="col.title"
:min-width="col.width"
@ -49,8 +49,26 @@
<span v-html="col.render(scope.row[col.key])"></span>
</template>
</el-table-column>
<!--图片列-->
<el-table-column v-if="col.tableType==='image'"
:key="col.key"
:label="col.title"
:min-width="col.width"
:fixed="col.isFrozen"
show-overflow-tooltip
:align="'center'"
:header-align="headerAlign"
:formatter="col.formatter">
<template slot-scope="scope">
<img :src="scope.row[col.key]"
:style="{width: col.imgWidth?col.imgWidth:'50px',height:col.imgHeight?col.imgHeight:'50px'}"
class="function-icon"
:fit=" col.fill?col.fill:'fill'">
</template></el-table-column>
<!--普通列-->
<el-table-column v-else
<el-table-column v-if="!col.tableType||col.tableType===''"
:key="col.key"
:label="col.title"
:min-width="col.width"
@ -178,20 +196,25 @@ export default {
pageVisible: { // page lyx 20190411
type: Boolean,
default: true
},
operationWidth: {
type: Number,
default: 120
}
},
computed: {
//
operationWidth: () => {
return 120
// if (this.operations.includes('add')) {
// return (this.operations.length - 1) * 80 // add
// } else if (this.operations.includes('analyze')) {
// return (this.operations.length + 0.5) * 80 // analyze
// } else {
// return this.operations.length * 140
// }
},
// operationWidth: () => {
// return 120
// // if (this.operations.includes('add')) {
// // return (this.operations.length - 1) * 80 // add
// // } else if (this.operations.includes('analyze')) {
// // return (this.operations.length + 0.5) * 80 // analyze
// // } else {
// // return this.operations.length * 140
// // }
// },
tableSize () {
if (this.resolution === 'small') {
return 10

23
epmet-oper-web/src/views/modules/code/VersionItem.vue

@ -2,12 +2,16 @@
<div>
<div v-show="showSubmit==='0'">
<div>
<el-button type="default"
<el-button size="mini"
type="default"
@click="versionCancel">返回</el-button>
<el-button type="primary"
<el-button size="mini"
type="primary"
@click="loadData">刷新</el-button>
<el-button type="primary"
<el-button size="mini"
type="primary"
@click="operHistoryShow">操作历史</el-button>
<span style="margin-left:20px">{{customerName}}{{clientTypeShow}}</span>
</div>
<el-row class="row"
:gutter="20">
@ -88,7 +92,7 @@
type="primary"
@click="speedupaudit">加急申请</el-button>
<el-button v-if="audit.status==='audit_success'"
<el-button v-if="audit.status==='audit_success'||audit.status==='release_failed'"
class="btn_card"
size="mini"
type="primary"
@ -264,8 +268,9 @@ export default {
customerId: '',
clientType: ''
},
customerName: '',
clientTypeShow: '',
optionData: {},
// release: {
// codeId: '',
// version: '1.0.3',
@ -327,8 +332,10 @@ export default {
...mapGetters(['clientHeight'])
},
methods: {
initData (customerId, clientType, optionData) {
initData (customerId, clientType, customerName, optionData) {
this.params = { customerId, clientType }
this.customerName = customerName
this.clientTypeShow = clientType === 'resi' ? '居民端' : '工作端'
this.optionData = optionData
this.loadData()
@ -371,6 +378,8 @@ export default {
this.audit.statusShow = '审核被拒绝'
} else if (this.audit.status === 'withdrawn') {
this.audit.statusShow = '已撤回'
} else if (this.audit.status === 'release_failed') {
this.audit.statusShow = '发布失败'
} else {
this.audit.statusShow = '审核延后'
}
@ -565,7 +574,7 @@ export default {
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const url = 'https://epmet-cloud.elinkservice.cn/api/third/code/release'
const url = 'https://epmet-cloud.elinkservice.cn/api/third/code/revertcoderelease'
// const url = '/third/code/revertcoderelease'
const param = {
codeId: this.release.codeId

50
epmet-oper-web/src/views/modules/code/VersionManage.vue

@ -108,18 +108,18 @@ export default {
return true
}
},
{
lable: '基本信息', //
size: 'mini',
style: 'margin: 0 6px;',
type: 'text',
slot: '',
plain: false,
methodName: 'getaccountbasicinfo', //
isShow: (row) => {
return true
}
},
// {
// lable: '', //
// size: 'mini',
// style: 'margin: 0 6px;',
// type: 'text',
// slot: '',
// plain: false,
// methodName: 'getaccountbasicinfo', //
// isShow: (row) => {
// return true
// }
// },
{
lable: '设置基础库版本', //
size: 'mini',
@ -131,19 +131,19 @@ export default {
isShow: (row) => {
return true
}
},
{
lable: '类目', //
size: 'mini',
style: 'margin: 0 6px;',
type: 'text',
slot: '',
plain: false,
methodName: 'getcategory', //
isShow: (row) => {
return true
}
}
// {
// lable: '', //
// size: 'mini',
// style: 'margin: 0 6px;',
// type: 'text',
// slot: '',
// plain: false,
// methodName: 'getcategory', //
// isShow: (row) => {
// return true
// }
// }
],
//
showVersion: false,
@ -208,7 +208,7 @@ export default {
//
versionManage (row) {
this.showVersion = true
this.$refs['ref_version_item'].initData(row.customerId, row.clientType, this.form.data)
this.$refs['ref_version_item'].initData(row.customerId, row.clientType, row.customerName, this.form.data)
},
//

266
epmet-oper-web/src/views/modules/customer-manage/MiniProManage/MiniProManage.vue

@ -1,266 +0,0 @@
<!-- 客户小程序管理 -->
<template>
<div>
<el-card shadow="never"
class="aui-card--fill">
<div class="mod-demo__demo}">
<el-form :inline="true"
:model="tableParams">
<el-form-item>
<el-select v-model="tableParams.customerId"
placeholder="客户"
clearable>
<el-option v-for="item in form.data['customerId']"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="tableParams.clientType"
placeholder="类型"
clearable>
<el-option v-for="item in form.data['clientType']"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="loadTableData()">查询</el-button>
</el-form-item>
<!-- <el-form-item>
<el-button type="primary"
@click="commitCodeDiaShow('')">上传代码</el-button>
</el-form-item> -->
</el-form>
<c-table column-type="index"
ref="table"
:url="tableUrl"
:params="tableParams"
keyword="MiniProManage"
:operations="operations"
:tableHeight="tableHeight"
@setweappsupportversion="setweappsupportversion"
@getaccountbasicinfo="getaccountbasicinfo"
@getcategory="getcategory">
</c-table>
</div>
</el-card>
<!-- <low-version ref="ref_version_form"></low-version>
<basic-info ref="ref_basic_info"></basic-info>
<category ref="ref_catefoty"></category> -->
</div>
</template>
<script>
import CDialog from '@c/CDialog'
import CTable from '@c/CTable'
// import LowVersion from './LowVersion'
// import BasicInfo from './BasicInfo'
// import Category from './Category'
import { mapGetters } from 'vuex'
import { Loading } from 'element-ui' // Loading
let loading//
export default {
data () {
return {
//
tableParams: {
customerId: '', //
clientType: '', //
state: '', //
commitDate: '', //
submitDate: '', //
source: this.env
},
//
tableUrl: 'https://epmet-cloud.elinkservice.cn/api/third/code/uploadlist',
//
operations: [
{
lable: '基本信息', //
size: 'mini',
style: 'margin: 0 6px;',
type: 'text',
slot: '',
plain: false,
methodName: 'getaccountbasicinfo', //
isShow: (row) => {
return true
}
},
{
lable: '设置基础库版本', //
size: 'mini',
style: 'margin: 0 6px;',
type: 'text',
slot: '',
plain: false,
methodName: 'setweappsupportversion', //
isShow: (row) => {
return true
}
},
{
lable: '类目', //
size: 'mini',
style: 'margin: 0 6px;',
type: 'text',
slot: '',
plain: false,
methodName: 'getcategory', //
isShow: (row) => {
return true
}
}
],
//
operDia: {
visible: false
},
//
qrCodeDia: {
visible: false
},
src: '',
//
form: {
dataUrl: [], // //url
data: { //
clientType: [
{
value: 'resi',
label: '居民端'
},
{
value: 'work',
label: '工作端'
}
]
}
}
}
},
components: {
CDialog, CTable
},
activated () {
let params = this.$route.params
//
if (params.showCommit) {
this.form.data.customerId = params.customerList
this.commitCodeDiaShow(params.customerId)
}
this.$nextTick(() => {
this.$refs.table.doLayout() //
})
},
mounted () {
this.renderSelData()
this.loadTableData()
},
computed: {
tableHeight () {
return this.clientHeight - 60 - 80 - 80 - 90
},
...mapGetters(['clientHeight', 'env'])
},
methods: {
//
refresh () {
this.loadTableData()
},
//
loadTableData () {
this.tableParams.source = this.env
this.$nextTick(() => {
this.$refs.table.loadData() //
})
},
//
setweappsupportversion (row) {
this.$refs['ref_version_form'].initData(row.customerId, row.clientType)
},
//
getaccountbasicinfo (row) {
this.$refs['ref_basic_info'].initData(row.customerId, row.clientType)
},
//
getcategory (row) {
this.$refs['ref_catefoty'].initData(row.customerId, row.clientType)
},
async renderSelData () { // //
const customerUrl = ' https://epmet-cloud.elinkservice.cn/api/third/pacustomer/registerbyauth'
const param = {
// workAuth: 1,
// resiAuth: 1,
source: this.env,
initState: 1
}
this.startLoading()
await window.app.ajax.post(customerUrl, param,
(data, rspMsg) => {
this.endLoading()
if (data) {
let customerList = []
data.forEach(element => {
let oneObj = {
value: element.customerId,
label: element.customerName
}
customerList.push(oneObj)
})
this.form.data.customerId = customerList
this.$forceUpdate()
}
},
(rspMsg, data) => {
this.endLoading()
this.$message.error(rspMsg)
})
},
//
startLoading () {
loading = Loading.service({
lock: true, //
text: '正在加载……', //
background: 'rgba(0,0,0,.7)' //
})
},
//
endLoading () {
// clearTimeout(timer);
if (loading) {
loading.close()
}
}
}
}
</script>
<style>
.el-upload__tip {
color: rgb(155, 155, 155);
}
</style>

0
epmet-oper-web/src/views/modules/customer-manage/RegisterList.vue → epmet-oper-web/src/views/modules/customer/RegisterList.vue

0
epmet-oper-web/src/views/modules/customer-manage/customer-info.vue → epmet-oper-web/src/views/modules/customer/customer-info.vue

0
epmet-oper-web/src/views/modules/customer-manage/customer-manage.vue → epmet-oper-web/src/views/modules/customer/customer-manage.vue

180
epmet-oper-web/src/views/modules/customer/miniCustomize/ConfigEdit.vue

@ -0,0 +1,180 @@
<template>
<el-dialog :visible.sync="visible"
:title="'修改定制功能'"
:close-on-click-modal="false"
:before-close="handleClose"
:close-on-press-escape="false">
<el-form :inline="true"
:model="dataForm"
:rules="dataRule"
ref="dataForm"
:label-width="'120px'">
<el-form-item label="功能名称"
prop="functionName">
<el-input class="item_width_1"
v-model="dataForm.functionName"
placeholder="功能名称"></el-input>
</el-form-item>
<el-form-item prop="iconLargeImg"
label="大图标">
<el-upload class="item_width_1 avatar-uploader"
:action="uploadUlr"
:show-file-list="false"
:on-success="function (res, file) { return handleImgSuccess(res, file, 'large')}"
:before-upload="beforeImgUpload">
<img v-if="dataForm.iconLargeImg"
:src="dataForm.iconLargeImg"
style="width:70px;height:70px"
class="function-icon">
<i v-else
class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item prop="iconSmallImg"
label="小图标">
<el-upload class="item_width_1 avatar-uploader"
:action="uploadUlr"
:show-file-list="false"
:on-success="function (res, file) { return handleImgSuccess(res, file, 'small')}"
:before-upload="beforeImgUpload">
<img v-if="dataForm.iconSmallImg"
:src="dataForm.iconSmallImg"
style="width:70px;height:70px"
class="function-icon">
<i v-else
class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
</el-form>
<template slot="footer">
<el-button @click="visible = false">{{ $t('cancel') }}</el-button>
<el-button type="primary"
@click="saveForm()">{{ $t('confirm') }}</el-button>
</template>
</el-dialog>
</template>
<script>
export default {
data () {
return {
visible: false,
dataForm: {
customerId: '',
functionId: '',
functionName: '',
iconLargeImg: '',
iconSmallImg: ''
},
uploadUlr: window.SITE_CONFIG['apiURL'] + '/oss/file/function/upload'
}
},
created () {
// this.queryFunctionList()
},
computed: {
dataRule () {
return {
functionName: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
iconLargeImg: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
iconSmallImg: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
]
}
}
},
methods: {
init (dataForm) {
console.log(dataForm)
this.visible = true
// this.dataForm=dataForm
this.$nextTick(() => {
Object.assign(this.dataForm, dataForm)
})
},
//
handleImgSuccess (res, file, type) {
if (res.code === 0 && res.msg === 'success') {
if (type === 'large') {
this.dataForm.iconLargeImg = res.data.url
} else if (type === 'small') {
this.dataForm.iconSmallImg = res.data.url
}
} else {
this.$message.error(res.msg)
}
},
beforeImgUpload (file) {
// const isPNG = file.type === 'image/png'
const isLt1M = file.size / 1024 / 1024 < 1
// if (!isPNG) {
// this.$message.error(' PNG !')
// }
if (!isLt1M) {
this.$message.error('上传图片大小不能超过 1MB!')
}
// return isPNG && isLt1M
return isLt1M
},
saveForm () {
this.$refs['dataForm'].validate((valid) => {
if (!valid) {
this.$message.error('表单验证失败!')
} else {
console.log(this.dataForm)
const url = 'https://nei.netease.com/api/apimock-v2/e3b1d0eb88e905f6c7ee559b2d6bb7ad/oper/customize/customerfunctiondetail/updatecustomerfunction'
// const url = '/oper/customize/customerfunctiondetail/updatecustomerfunction'
window.app.ajax.post(url, this.dataForm,
(data, rspMsg) => {
this.$message({
type: 'success',
message: '保存成功'
})
this.visible = false
this.$emit('editDiaOK')
},
(rspMsg, data) => {
this.endLoading()
this.$message.error(rspMsg)
})
}
})
},
handleClose () {
this.visible = false
}
}
}
</script>
<style scoped>
.function-icon {
width: 28px;
}
.item_width_1 {
width: 300px;
}
.item_width_2 {
width: 700px;
}
.block {
display: block;
}
</style>

370
epmet-oper-web/src/views/modules/customer/miniCustomize/ConfigItem.vue

@ -0,0 +1,370 @@
<!-- 配置详情 -->
<template>
<div style=" position: relative;">
<div class="div_btn">
<el-button type="default"
@click="diaCancel">取消返回</el-button>
</div>
<el-table :data="customizedList"
border
style="width: 100%;"
:height="tableHeight"
ref="ref_customer_table">
<!-- <el-table-column type="selection"
header-align="center"
align="center"
checked="true"
width="40"></el-table-column> -->
<el-table-column label="排序"
type="index"
align="center"
width="50"></el-table-column>
<el-table-column label="默认名称"
header-align="center"
align="center"
width="100"
prop="customizedName">
</el-table-column>
<el-table-column label="自定义名称"
header-align="center"
align="center"
width="150"
prop="customizedName">
</el-table-column>
<el-table-column label="功能说明"
header-align="center"
align="center"
prop="customizedName">
</el-table-column>
<el-table-column label="大图标"
header-align="center"
align="center"
width="150"
prop="customizedName">
<template slot-scope="scope">
<img v-if="scope.row.iconLargeImg"
:src="scope.row.iconLargeImg"
style="width: 50px; height: 50px"
class="function-icon"
:fit="'fill'">
</template>
</el-table-column>
<el-table-column label="小图标"
header-align="center"
align="center"
width="110"
prop="customizedName">
<template slot-scope="scope">
<img v-if="scope.row.iconSmallImg"
:src="scope.row.iconSmallImg"
style="width: 50px; height: 50px"
class="function-icon"
:fit="'fill'">
</template>
</el-table-column>
<el-table-column label="上架状态"
header-align="center"
align="center"
width="100"
prop="shoppingStatusShow">
</el-table-column>
<!--操作列-->
<el-table-column label="操作"
header-align="center"
align="center"
class="operate"
width="250">
<template slot-scope="scope">
<el-button v-if="scope.row.shoppingStatus==='0'"
size="mini"
class="btn_putaway"
type="primary"
@click.stop="upOrDown(scope.row.functionId, '1')">上架</el-button>
<el-button v-if="scope.row.shoppingStatus==='1'"
size="mini"
class="btn_putaway"
type="primary"
@click.stop="upOrDown(scope.row.functionId, '0')">下架</el-button>
<el-button size="mini"
type="primary"
@click.stop="editShow( scope.row)">修改</el-button>
<el-button size="mini"
type="primary"
@click.stop="moveUp">上移</el-button>
</template>
</el-table-column>
</el-table>
<c-dialog :title="upOrDownDia.title"
:width="40"
:dialogHeight="0.5"
:visible="upOrDownDia.visible"
@cancel="upOrDownDiaCancel"
@ok="upOrDownDiaOk">
<div style="text-align:center;margin-top:40px">
<el-input type="textarea"
:autosize="{ minRows: 2, maxRows: 4}"
:rows="3"
resize="none"
style="width:500px"
placeholder='请输入理由'
v-model="upOrDownDia.reason">
</el-input>
<div class="el-upload__tip"
style="margin-top:20px">灰度的百分比 1 ~ 100 的整数控制发布的节奏避免一上线就影响到所有的用户</div>
</div>
</c-dialog>
<config-edit ref="ref_config_edit"
@ok="editDiaOK"
@cancel="editDiaCancel">
</config-edit>
</div>
</template>
<script>
import CDialog from '@c/CDialog'
import ConfigEdit from './ConfigEdit'
import { mapGetters } from 'vuex'
import { Loading } from 'element-ui' // Loading
let loading //
export default {
data () {
return {
loading: false,
customerId: '', // id
//
customizedList: [],
customizeForm: [],
uploadUlr: window.SITE_CONFIG['apiURL'] + '/oss/file/function/upload',
//
upOrDownDia: {
visible: false,
title: '理由',
reason: ''
},
upOrDownForm: {
customerId: '',
functionId: '',
shoppingStatus: '',
reason: ''
}
}
},
components: {
CDialog
},
mounted () {
},
computed: {
tableHeight () {
return this.clientHeight - 220
},
...mapGetters(['clientHeight']),
dataRule () {
return {
customizedName: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
functionIcon: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
functionGroup: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
shoppingStatus: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
functionExplain: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
]
}
}
},
methods: {
initData (customerId) {
this.customerId = customerId
this.loadTableData()
},
//
loadTableData () {
let params = {
customerId: this.customerId
}
// const url = '/oper/customize/customerfunctiondetail/customerfunctionlist'
const url = 'https://nei.netease.com/api/apimock-v2/e3b1d0eb88e905f6c7ee559b2d6bb7ad/oper/customize/customerfunctiondetail/customerfunctionlist'
window.app.ajax.post(url, params,
(data, rspMsg) => {
this.$nextTick(() => {
this.customizedList = data
this.customizedList.forEach(element => {
element.shoppingStatusShow = element.shoppingStatus === '0' ? element.shoppingStatusShow = '下架' : '上架'
})
})
},
(rspMsg, data) => {
this.endLoading()
this.$message.error(rspMsg)
})
},
//
upOrDown (functionId, shoppingStatus) {
this.upOrDownDia.title = shoppingStatus === '0' ? '下架原因' : '上架原因'
this.upOrDownForm = {
customerId: this.customerId,
functionId: functionId,
shoppingStatus: shoppingStatus,
reason: ''
}
this.upOrDownDia.visible = true
},
upOrDownDiaCancel () {
this.upOrDownDia.visible = false
},
upOrDownDiaOk () {
this.startLoading()
this.upOrDownForm.reason = this.upOrDownForm.reason
const url = 'https://nei.netease.com/api/apimock-v2/e3b1d0eb88e905f6c7ee559b2d6bb7ad/oper/customize/customerfunctiondetail/updateshoppingstatus'
// const url = '/oper/customize/customerfunctiondetail/updateshoppingstatus'
window.app.ajax.post(url, this.upOrDownForm,
(data, rspMsg) => {
this.$message.success('操作成功')
this.upOrDownDia.visible = false
},
(rspMsg, data) => {
this.$message.error(rspMsg)
})
this.endLoading()
},
//
editShow (row) {
this.$refs['ref_config_edit'].init(row)
},
editDiaOK () {
this.loadTableData()
},
editDiaCancel () {
},
//
handleLargeSuccess (res, file, index) {
if (res.code === 0 && res.msg === 'success') {
this.customizedList[index].iconLargeImg = res.data.url
} else {
this.$message.error(res.msg)
}
},
//
handleSmallSuccess (res, file, index) {
if (res.code === 0 && res.msg === 'success') {
this.customizedList[index].iconSmallImg = res.data.url
} else {
this.$message.error(res.msg)
}
},
beforeAvatarUpload (file) {
// const isPNG = file.type === 'image/png'
// const isLt1M = file.size / 1024 / 1024 < 1
// if (!isPNG) {
// this.$message.error(' PNG !')
// }
// if (!isLt1M) {
// this.$message.error(' 1MB!')
// }
// return isPNG && isLt1M
},
//
moveUp () {
console.log(this.customizedList)
this.customizedList.forEach((element, index) => {
element.displayOrder = index
})
const url = 'https://nei.netease.com/api/apimock-v2/e3b1d0eb88e905f6c7ee559b2d6bb7ad/oper/customize/customerfunctiondetail/updatedisplayorder'
// const url = '/oper/customize/customerfunctiondetail/updatedisplayorder'
window.app.ajax.post(url, this.customizedList,
(data, rspMsg) => {
// this.$message.success('')
},
(rspMsg, data) => {
this.$message.error(rspMsg)
})
},
//
diaCancel () {
this.$emit('cancleSubmit')
},
//
startLoading () {
loading = Loading.service({
lock: true, //
text: '正在加载……', //
background: 'rgba(0,0,0,.7)' //
})
},
//
endLoading () {
// clearTimeout(timer);
if (loading) {
loading.close()
}
}
},
props: {
ConfigEdit
}
}
</script>
<style scoped >
.el-tabs {
margin: 0 10px;
}
.form_item {
width: 200px;
}
.div_btn {
z-index: 10;
/* position: absolute; */
margin: 0 0 20px 0;
}
.btn_soldout {
background-color: rgb(255, 79, 79);
border-color: rgb(255, 79, 79);
}
.btn_putaway {
background-color: rgb(89, 161, 255);
border-color: rgb(89, 161, 255);
}
</style>

163
epmet-oper-web/src/views/modules/customer/miniCustomize/CustomerList.vue

@ -0,0 +1,163 @@
<template>
<el-card shadow="never"
class="aui-card--fill">
<div v-show="showType==='list'"
class="mod-/oper/customize__homecomponent}">
<el-form :inline="true">
<el-form-item>
<el-input v-model="ruleForm.name"
placeholder="请输入客户名称"
:clearable="true"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary"
@click="submitForm(ruleForm)">查询</el-button>
</el-form-item>
</el-form>
<el-table :data="customerList"
border
style="width: 100%;">
<el-table-column label="客户名称"
header-align="center"
align="center"
prop="customerName"></el-table-column>
<el-table-column label="logo"
header-align="center"
align="center"
prop="logo">
<template slot-scope="scope">
<el-image style="width: 50px; height: 50px"
:src="scope.row.logo"
@click="addSrcList(scope.row.logo)"
:preview-src-list="srcList"></el-image>
</template>
</el-table-column>
<el-table-column :label="$t('handle')"
fixed="right"
header-align="center"
align="center"
width="350">
<template slot-scope="scope">
<el-button type="text"
size="small"
@click="showMiniHome(scope.row.customerId,scope.row.customerName,0)">居民端首页</el-button>
<el-button type="text"
size="small"
@click="showMiniHome(scope.row.customerId,scope.row.customerName,1)">工作端首页</el-button>
<el-button type="text"
size="small"
@click="showConfigItem(scope.row.customerId)">功能配置</el-button>
<el-button type="text"
size="small"
@click="showConfigItem(scope.row.customerId)">角色权限</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination :current-page="pageNo"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="pageSizeChangeHandle"
@current-change="pageCurrentChangeHandle">
</el-pagination>
</div>
<div v-show="showType==='miniHome'">
<mini-home ref="ref_mini_home"
@cancleBack='cancleBack'></mini-home>
</div>
<div v-show="showType==='config'">
<config-item ref="ref_config_item"
@cancleBack='cancleBack'></config-item>
</div>
</el-card>
</template>
<script>
import ConfigItem from './ConfigItem'
import MiniHome from './MiniHome'
export default {
data () {
return {
diaName: '功能配置',
noImg: '暂无图片',
customerList: [],
input: '',
customerId: '',
pageNo: 1,
pageSize: 10,
ruleForm: { name: '' },
total: 0,
srcList: [],
showType: 'list'//
}
},
components: {
ConfigItem, MiniHome
},
created () {
this.queryCustomerList()
},
methods: {
queryCustomerList () {
let params = {
customerName: '',
pageNo: this.pageNo,
pageSize: this.pageSize
}
this.$http.post('/oper/crm/customer/pagequery', params).then(({ data: res }) => {
if (res.code === 0) {
this.customerList = res.data.list
this.total = res.data.total
}
})
},
submitForm (formName) {
let params = {
customerName: formName.name,
pageNo: this.pageNo,
pageSize: this.pageSize
}
this.$http.post('/oper/crm/customer/pagequery', params).then(({ data: res }) => {
if (res.code === 0) {
this.customerList = res.data.list
}
})
},
showMiniHome (customerId, customerName, type) {
this.showType = 'miniHome'
this.$refs['ref_mini_home'].startSetWxIndex(customerId, customerName, type)
},
//
showConfigItem (customerId) {
this.showType = 'config'
this.$refs['ref_config_item'].initData(customerId)
},
pageCurrentChangeHandle (val) {
this.pageNo = val
this.queryCustomerList()
},
pageSizeChangeHandle (val) {
this.pageSize = val
this.queryCustomerList()
},
addSrcList (url) {
this.srcList = []
this.srcList.push(url)
},
//
cancleBack () {
this.showType = 'list'
}
}
}
</script>

889
epmet-oper-web/src/views/modules/customer/miniCustomize/MiniHome.vue

@ -0,0 +1,889 @@
<template>
<div>
<div class="m-wx_index"
v-show="step==2">
<el-button type="default"
@click="cancleBack">取消返回</el-button>
<el-button type="info"
@click="isInPreview = true">预览</el-button>
<el-button type="success"
@click="save">保存</el-button>
<el-button type="danger"
@click="publish">发布</el-button>
<span style="margin-left:20px; color:#aaa; font-size:13px">({{ wxIndex.customerName }} - {{ wxIndex.clientType===1 ? '政府端' : '居民端' }})</span>
<el-row class="wrap"
:gutter="20">
<el-col :span="5">
<h4>选择组件</h4>
<div class="mw-cpt_type">
<div class="d-function"
v-show="item.componentList.length > 0"
:key="item.functionId"
v-for="item in cptTypeList">
<div class="d-info"
@click="shiftCptTypeItemUnfold(item)">
<img v-if="item.functionName=='议事厅'"
class="d-ico"
src="@/assets/img/modules/wx-mini/index-set/function-cpt1.png">
<img v-else-if="item.functionName=='社群'"
class="d-ico"
src="@/assets/img/modules/wx-mini/index-set/function-cpt2.png">
<img v-else-if="item.functionName=='党建声音'"
class="d-ico"
src="@/assets/img/modules/wx-mini/index-set/function-cpt3.png">
<img v-else-if="item.functionName=='消息通知'"
class="d-ico"
src="@/assets/img/modules/wx-mini/index-set/function-cpt4.png">
<img v-else
class="d-ico"
src="@/assets/img/modules/wx-mini/index-set/common-cpt.png">
<span class="d-name">{{ item.functionName }}</span>
<img class="d-arrow"
:class="{'z-unfold': item.isUnfold}"
src="@/assets/img/modules/wx-mini/index-set/arrow-down.png">
</div>
<div class="d-list"
v-show="item.isUnfold">
<div class="d-item"
:key="cptItem.componentId"
v-for="cptItem in item.componentList">
<span class="d-item-region">({{ getCptRegionName(checkCptRegion(cptItem)) }})</span>
<span class="d-item-name">{{ cptItem.componentName }}</span>
<span class="d-item-btn z-disabled"
v-if="!checkCptReuse(cptItem) && checkExistCpt(cptItem)">已添加</span>
<span class="d-item-btn"
v-else
@click="beforeAddCpt(cptItem)">
<img src="@/assets/img/modules/wx-mini/index-set/add.png">
<span>添加</span>
</span>
</div>
</div>
</div>
</div>
</el-col>
<el-col :span="13">
<div class="mw-show"
:class="{'z-preview': isInPreview}">
<div v-show="isInPreview"
class="mw-show-close">
<el-button type="default"
@click="isInPreview = false"
icon="el-icon-close"
circle></el-button>
</div>
<div class="mw-phone">
<img class="mw-phone-topbar"
v-show="isInPreview"
src="@/assets/img/modules/wx-mini/index-set/page/wx-top.png">
<div class="mw-phone-top"
v-show="!isInPreview || topCptList.length>0"
:class="{'z-none': !isInPreview}">
<div class="mw-phone-hint"
v-show="!isInPreview"
:class="{'z-out-left': topCptList.length>0}">{{ getCptRegionName('top') }}</div>
<cpt-item :item="item"
:key="item.tempOnlyId"
:is-focused="focusedCpt.tempOnlyId===item.tempOnlyId"
@del="delCpt"
@sort="changeCptDisplayOrder"
@focus="focusCpt"
v-for="item in topCptList"></cpt-item>
</div>
<div class="mw-phone-ban"
v-show="!isInPreview || banCptList.length>0"
:class="{'z-none': !isInPreview}">
<div class="mw-phone-hint"
v-show="!isInPreview"
:class="{'z-out-left': banCptList.length>0}">{{ getCptRegionName('ban') }}</div>
<cpt-item :item="item"
:key="item.tempOnlyId"
:is-focused="focusedCpt.tempOnlyId===item.tempOnlyId"
@del="delCpt"
@sort="changeCptDisplayOrder"
@focus="focusCpt"
v-for="item in banCptList"></cpt-item>
</div>
<div class="mw-phone-fixed"
v-show="!isInPreview || fixedCptList.length>0"
:class="{'z-none': !isInPreview}">
<div class="mw-phone-hint"
v-show="!isInPreview"
:class="{'z-out-down': fixedCptList.length>0}">{{ getCptRegionName('fixed') }}</div>
<cpt-item :item="item"
:key="item.tempOnlyId"
:is-focused="focusedCpt.tempOnlyId===item.tempOnlyId"
@del="delCpt"
@sort="changeCptDisplayOrder"
@focus="focusCpt"
v-for="item in fixedCptList"></cpt-item>
</div>
<div class="mw-phone-cnt"
v-show="!isInPreview || cntCptList.length>0"
:class="{'z-none': !isInPreview}">
<div class="mw-phone-hint"
v-show="!isInPreview"
:class="{'z-out-left': cntCptList.length>0}">{{ getCptRegionName('cnt') }}</div>
<cpt-item :item="item"
:key="item.tempOnlyId"
:is-focused="focusedCpt.tempOnlyId===item.tempOnlyId"
@del="delCpt"
@sort="changeCptDisplayOrder"
@focus="focusCpt"
v-for="item in cntCptList"></cpt-item>
</div>
</div>
</div>
</el-col>
<el-col :span="6">
<transition v-show="focusedCpt.tempOnlyId"
name="el-zoom-in-top">
<div class="mw-set el-zoom-in-top"
v-if="focusedCpt.tempOnlyId">
<div class="d-set-head"
@click="focusedCpt.demoIsUnfold = !focusedCpt.demoIsUnfold">
<span class="d-title">演示数据</span>
<img class="d-arrow"
:class="{'z-unfold': focusedCpt.demoIsUnfold}"
src="@/assets/img/modules/wx-mini/index-set/arrow-down.png">
</div>
<el-form v-show="focusedCpt.demoIsUnfold"
ref="form">
<el-form-item>
<el-input type="textarea"
v-model="focusedCpt.demoData"></el-input>
</el-form-item>
</el-form>
<div class="d-set-head"
@click="focusedCpt.confIsUnfold = !focusedCpt.confIsUnfold">
<span class="d-title">高级选项</span>
<img class="d-arrow"
:class="{'z-unfold': focusedCpt.confIsUnfold}"
src="@/assets/img/modules/wx-mini/index-set/arrow-down.png">
</div>
<el-form v-show="focusedCpt.confIsUnfold"
ref="form">
<el-form-item>
<el-input type="textarea"
v-model="focusedCpt.configuration"></el-input>
</el-form-item>
<div class="d-config-hint"
v-show="focusedCpt.configurationDescription">
<img src="@/assets/img/modules/wx-mini/index-set/info.png">
<span>{{ focusedCpt.configurationDescription }}</span>
</div>
</el-form>
<div class="d-operate">
<el-button type="default"
size="small"
round
@click="resetFocusedCptData">重置</el-button>
<el-button type="success"
size="small"
round
@click="saveFocusedCptData">保存</el-button>
</div>
</div>
</transition>
</el-col>
</el-row>
</div>
</div>
</template>
<style lang="scss" src="@/assets/scss/modules/wx-mini/index-set.scss"></style>
<script>
import mixinViewModule from '@/mixins/view-module'
import componentWxcpt from '@/components/wx-index/cpt-item'
import { Loading } from 'element-ui'
import nextTick from 'dai-js/tools/nextTick'
import getRandomString from 'dai-js/tools/getRandomString'
import cloneDeep from 'lodash/cloneDeep'
let loading //
// mock
const getMockFilterUrl = (url) => {
const usedMockTest = false
const mockBaseUrl = 'https://nei.netease.com/api/apimock/30f0251f1b7dc90a8c38e3c634ef2a8b/api'
if (usedMockTest) {
return mockBaseUrl + url
} else {
return url
}
}
//
const envIsDev = process.env.VUE_APP_NODE_ENV === 'dev'
export default {
mixins: [mixinViewModule],
data () {
const cptTypeListTestdata = [
//
{
functionId: '0',
functionName: '通用组件',
functionType: 1, // 1 2
isUnfold: true,
componentList: [
{
componentId: '7',
componentName: '最新议题',
componentFrontId: 'resi-functionList-hall-latestIssueList',
region: 'functionList',
configuration: {
num: 3
},
demoData: {
list: [
{
avatar: '',
title: '最新议题的标题。最新议题的标题。最新议题的标题。最新议题的标题。',
content: '最新议题的内容,最新议题的内容,最新议题的内容。',
author: '山东路45号-刘女士',
date: '2020-01-02'
},
{
avatar: '',
title: '最新议题的标题。',
content: '最新议题的内容,最新议题的内容,最新议题的内容。',
author: '山东路45号-刘女士',
date: '2020-01-02'
},
{
avatar: '',
title: '最新议题的标题。',
content: '最新议题的内容,最新议题的内容,最新议题的内容。',
author: '山东路45号-刘女士',
date: '2020-01-02'
}
]
},
configurationDescription: ''
},
{
componentId: '8',
componentName: '最新发布',
componentFrontId: 'resi-functionList-voice-newsList',
region: 'functionList',
configuration: {
num: 3
},
demoData: {
list: [
{
pic: '',
title: '新型冠状病毒检测重大突破!新型冠状病毒检测重大突破!!!',
author: '大港路党支部',
date: '2020-01-02'
},
{
pic: '',
title: '新型冠状病毒检测重大突破!',
author: '大港路党支部',
date: '2020-01-02'
},
{
pic: '',
title: '新型冠状病毒检测重大突破!',
author: '大港路党支部',
date: '2020-01-02'
}
]
},
configurationDescription: ''
},
{
componentId: '9',
componentName: '结案项目',
componentFrontId: 'resi-functionList-hall-closedProjectList',
region: 'functionList',
configuration: {
num: 3
},
demoData: {
list: [
{
title: '结案项目的标题。',
content: '结案项目的内容,结案项目的内容,结案项目的内容。',
author: '党支部-卫生部门',
date: '2020-01-02'
},
{
title: '结案项目的标题。',
content: '结案项目的内容,结案项目的内容,结案项目的内容。',
author: '党支部-卫生部门',
date: '2020-01-02'
},
{
title: '结案项目的标题。',
content: '结案项目的内容,结案项目的内容,结案项目的内容。',
author: '党支部-卫生部门',
date: '2020-01-02'
}
]
},
configurationDescription: ''
}
]
},
//
{
functionId: '1',
functionName: '议事厅',
functionType: 2, // 1 2
isUnfold: false,
componentList: [
{
componentId: '1',
componentName: '顶部标题',
componentFrontId: 'resi-titleList-home-gridNameTitle',
configuration: {
// content: ''
},
demoData: {
ico: '',
avatar: '',
title: '青岛市市北区大港路第二网格'
},
region: 'titleList',
configurationDescription: '请配置具体内容'
},
{
componentId: '2',
componentName: '轮播图',
componentFrontId: 'resi-topList-voice-hotNewsSwiper',
configuration: {
// content: ''
},
demoData: {
pic: '',
title: '轮播图新闻标题'
},
region: 'topList',
configurationDescription: '请配置具体内容'
},
{
componentId: '3',
componentName: '消息通知',
componentFrontId: 'resi-floatingList-mine-newMessageButton',
configuration: {
// content: ''
},
demoData: {
ico: '',
text: '有新消息!'
},
region: 'floatingList',
configurationDescription: ''
},
{
componentId: '5',
componentName: '功能菜单',
componentFrontId: 'resi-functionList-extend-moreFunctionIcons',
region: 'functionList',
configuration: {
// bgc: '#eee'
},
demoData: {
list: [
{
ico: '',
text: '议事厅'
},
{
ico: '',
text: '社群'
},
{
ico: '',
text: '党建声音'
},
{
ico: '',
text: '更多功能'
}
]
},
configurationDescription: ''
},
{
componentId: '6',
componentName: '热门群',
componentFrontId: 'resi-functionList-group-recommendGroupSlider',
region: 'functionList',
configuration: {
// bgc: '#fff'
},
demoData: {
list: [
{
ico: '',
no: '1',
avatar: '',
title: '群名称',
info1: '山东路45号-张三',
info2: '共240人',
info3: '党员11人'
},
{
ico: '',
no: '2',
avatar: '',
title: '群名称',
info1: '山东路45号-张三',
info2: '共240人',
info3: '党员11人'
},
{
ico: '',
no: '3',
avatar: '',
title: '群名称',
info1: '山东路45号-张三',
info2: '共240人',
info3: '党员11人'
}
]
},
configurationDescription: ''
}
]
}
]
return {
mixinViewModuleOptions: {
getDataListURL: getMockFilterUrl('/oper/crm/customer/getvalidcustomerlist'),
getDataListIsPage: false
},
dataList: !envIsDev ? [] : [
{
customerName: '测试1',
customerId: '1'
},
{
customerName: '测试2',
customerId: '2'
}
],
// : 1 2
step: 1,
wxIndex: {
customerId: '',
customerName: '',
clientType: ''
},
//
isInPreview: false,
//
cptTypeList: !envIsDev ? [] : cptTypeListTestdata,
//
cptList: [
// {
// componentId: '1',
// componentName: '',
// componentFrontId: 'top_title',
// configuration: {
// content: ''
// },
// demoData: {
// content: ''
// },
// configurationDescription: '',
// displayOrder: 1,
// region: 1 // 1top 2ban 3fixed 4cnt
// }
],
lastSavedCptList: [],
focusedCpt: {
tempOnlyId: ''
}
}
},
components: {
'cpt-item': componentWxcpt
},
computed: {
cptTypeListTiled () {
const { cptTypeList } = this
let list = []
cptTypeList.forEach(item => {
list = [...list, ...item.componentList]
})
return list
},
topCptList () {
return this.cptList.filter(item => this.checkCptRegion(item) === 'top')
},
banCptList () {
return this.cptList.filter(item => this.checkCptRegion(item) === 'ban')
},
cntCptList () {
console.log('cntCpt发生了变化')
let arr = this.cptList.filter(item => this.checkCptRegion(item) === 'cnt')
arr.sort((f, s) => f.displayOrder - s.displayOrder)
return arr
},
fixedCptList () {
return this.cptList.filter(item => this.checkCptRegion(item) === 'fixed')
}
},
methods: {
cancleBack () {
this.$emit('cancleBack')
},
//
toStep (s) {
this.step = s
},
//
async startSetWxIndex (id, name, type) {
this.wxIndex.customerId = id
this.wxIndex.customerName = name
this.wxIndex.clientType = type
console.log(this.wxIndex)
this.startLoading()
// let loadingInstance = Loading.service()
await this.getCptTypeList()
await this.getCptList()
this.toStep(2)
this.cleanFocusCpt()
this.endLoading()
// loadingInstance.close()
},
processBackendCptData (item) {
let demoData = {}
let configuration = {}
const tempOnlyId = getRandomString(20)
try {
demoData = JSON.parse(item.demoData)
configuration = JSON.parse(item.configuration)
} catch (err) {
console.log(err)
}
return { tempOnlyId, ...item, demoData, configuration }
},
//
getCptTypeList () {
const url = getMockFilterUrl('/oper/customize/home/getcomponentlistbycustomer')
const { wxIndex: { clientType, customerId } } = this
return this.$http.post(
url,
{ clientType, customerId }
).then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
} else {
let list = [{
functionId: '0',
functionName: '通用组件',
functionType: 1, // 1 2
isUnfold: true,
componentList: res.data.commonList.map(this.processBackendCptData)
}, ...res.data.functionList.map(item => {
return {
functionId: item.functionId,
functionName: item.functionName,
functionType: 2, // 1 2
isUnfold: false,
componentList: item.componentList.map(this.processBackendCptData)
}
})]
this.cptTypeList = list
console.log('可用组件列表', list)
}
}).catch((err) => {
console.log(err)
return this.$message.error('网络错误')
})
},
//
getCptList () {
const url = getMockFilterUrl('/oper/customize/home/gethomedesignbycustomer')
const { wxIndex: { clientType, customerId } } = this
return this.$http.post(
url,
{ clientType, customerId }
).then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
} else {
let list = [
...res.data.titleList,
...res.data.topList,
...res.data.functionList,
...res.data.floatingList
]
this.cptList = list.map(this.processBackendCptData)
this.lastSavedCptList = cloneDeep(this.cptList)
console.log('用户储存组件列表', list)
}
}).catch((err) => {
console.log(err)
return this.$message.error('网络错误')
})
},
//
save () {
console.log('保存配置')
const url = getMockFilterUrl('/oper/customize/home/savehomedesign')
const { wxIndex: { clientType, customerId }, cptList } = this
const componentList = cptList.map(item => {
return {
componentId: item.componentId,
region: item.region,
displayOrder: item.displayOrder,
demoData: JSON.stringify(item.demoData),
configuration: JSON.stringify(item.configuration)
}
})
return this.$http.post(
url,
{ clientType, customerId, componentList }
).then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
} else {
console.log(res)
this.lastSavedCptList = cloneDeep(this.cptList)
return this.$message.success('保存成功')
}
}).catch((err) => {
console.log(err)
return this.$message.error('网络错误')
})
},
//
publish () {
console.log('发布配置')
const url = getMockFilterUrl('/oper/customize/home/distributehomedesign')
const { wxIndex: { clientType, customerId }, cptList } = this
const componentList = cptList.map(item => {
return {
componentId: item.componentId,
region: item.region,
displayOrder: item.displayOrder,
demoData: JSON.stringify(item.demoData),
configuration: JSON.stringify(item.configuration)
}
})
if (componentList.length === 0) {
return this.$message.error('您尚未选择任何组件,不能发布')
}
return this.$confirm('目前的设置会呈现在所有用户的小程序上,是否继续发布?', '确认发布', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
return this.$http.post(
url,
{ clientType, customerId, componentList }
).then(({ data: res }) => {
if (res.code !== 0) {
return this.$message.error(res.msg)
} else {
console.log(res)
this.lastSavedCptList = cloneDeep(this.cptList)
return this.$message.success('发布成功')
}
}).catch((err) => {
console.log(err)
return this.$message.error('网络错误')
})
}).catch((err) => {
console.log(err)
})
},
//
checkCptRegion (item) {
const { region } = item
if (region === 'titleList') {
return 'top'
} else if (region === 'topList') {
return 'ban'
} else if (region === 'functionList') {
return 'cnt'
} else if (region === 'floatingList') {
return 'fixed'
} else {
return 'none'
}
},
//
checkCptReuse (item) {
const { componentFrontId } = item
const reuseList = this.cptTypeList[0].componentList.map(v => v.componentFrontId)
const fun = name => name === componentFrontId
return reuseList.findIndex(fun) !== -1
},
//
getCptRegionName (id) {
return {
'top': '标题区',
'ban': '置顶区',
'fixed': '浮窗区',
'cnt': '功能区',
'none': ''
}[id]
},
// -
beforeAddCpt (item) {
console.log('添加组件到实例-前验证')
const regionType = this.checkCptRegion(item)
const tempOnlyId = getRandomString(20)
if (regionType === 'top') {
if (this.topCptList.length > 0) {
this.$message('标题区已有组件,请删除后再添加')
} else {
this.addCpt(item, tempOnlyId)
}
} else if (regionType === 'ban') {
if (this.banCptList.length > 0) {
this.$message('置顶区已有组件,请删除后再添加')
} else {
this.addCpt(item, tempOnlyId)
}
} else if (regionType === 'fixed') {
if (this.fixedCptList.length > 0) {
this.$message('浮窗区已有组件,请删除后再添加')
} else {
this.addCpt(item, tempOnlyId)
}
} else if (regionType === 'cnt') {
this.cntCptListResort()
this.addCpt(item, tempOnlyId, (this.cntCptList.length + 1) * 10)
} else {
return false
}
},
// displayOrder
cntCptListResort () {
console.log('实例内容组件重置displayOrder属性')
this.cntCptList.forEach((item, index) => {
item.displayOrder = (index + 1) * 10
})
},
//
addCpt (item, tempOnlyId, displayOrder = 0) {
console.log('添加组件到实例')
let trueItem = cloneDeep(item)
trueItem.tempOnlyId = tempOnlyId
trueItem.displayOrder = displayOrder
this.cptList.push(trueItem)
},
//
async changeCptDisplayOrder (item, type) {
console.log('改变实例组件显示顺序')
if (type === 'up') {
item.displayOrder -= 11
} else if (type === 'down') {
item.displayOrder += 11
}
await nextTick()
this.cntCptListResort()
},
//
delCpt (item) {
this.cptList = this.cptList.filter(cptItem => item.tempOnlyId !== cptItem.tempOnlyId)
if (this.focusedCpt.tempOnlyId === item.tempOnlyId) {
this.focusedCpt = { tempOnlyId: '' }
}
this.cntCptListResort()
},
//
checkExistCpt (item) {
return this.cptList.some(cptItem => item.componentFrontId === cptItem.componentFrontId)
},
//
cleanFocusCpt () {
this.focusedCpt = { tempOnlyId: '' }
},
//
focusCpt (item) {
console.log('聚焦实例组件')
if (this.isInPreview) return
if (this.focusedCpt.tempOnlyId === item.tempOnlyId) {
this.cleanFocusCpt()
} else {
this.focusedCpt = { ...cloneDeep(item), demoData: JSON.stringify(item.demoData), configuration: JSON.stringify(item.configuration), demoIsUnfold: true, confIsUnfold: false }
}
},
//
saveFocusedCptData () {
const { focusedCpt } = this
this.cptList.forEach(item => {
if (item.tempOnlyId === focusedCpt.tempOnlyId) {
try {
item.demoData = JSON.parse(focusedCpt.demoData)
item.configuration = JSON.parse(focusedCpt.configuration)
} catch (err) {
this.$alert('json数据格式有误', '无法保存', {
confirmButtonText: '确定'
})
console.log(err)
}
}
})
},
//
resetFocusedCptData () {
const { focusedCpt } = this
const fun = item => {
if (item.tempOnlyId === focusedCpt.tempOnlyId) {
focusedCpt.demoData = JSON.stringify(item.demoData)
focusedCpt.configuration = JSON.stringify(item.configuration)
return true
} else {
return false
}
}
if (!this.lastSavedCptList.some(fun)) {
this.cptTypeListTiled.forEach(item => {
if (item.componentFrontId === focusedCpt.componentFrontId) {
focusedCpt.demoData = JSON.stringify(item.demoData)
focusedCpt.configuration = JSON.stringify(item.configuration)
}
})
}
},
//
shiftCptTypeItemUnfold (item) {
item.isUnfold = !item.isUnfold
},
//
startLoading () {
loading = Loading.service({
lock: true, //
text: '正在加载……', //
background: 'rgba(0,0,0,.7)' //
})
},
//
endLoading () {
// clearTimeout(timer);
if (loading) {
loading.close()
}
}
}
}
</script>

167
epmet-oper-web/src/views/modules/customize/CustomizedFunction copy.vue

@ -0,0 +1,167 @@
<template>
<el-card shadow="never"
class="aui-card--fill">
<div class="mod-sys__params">
<el-form :inline="true"
:model="dataForm"
@keyup.enter.native="getDataList()">
<el-form-item label="功能名称">
<el-input v-model="dataForm.functionName"
:placeholder="$t('params.paramCode')"
clearable></el-input>
</el-form-item>
<el-form-item label="上架状态">
<el-select v-model="dataForm.shoppingStatus"
placeholder="全部"
clearable>
<el-option v-for="item in shoppingStatusList"
:key="item.dictValue"
:label="item.dictName"
:value="item.dictValue">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="getDataList()">{{ $t('query') }}</el-button>
</el-form-item>
<el-form-item>
<el-button v-if="$hasPermission('sys:params:save')"
type="primary"
@click="addOrUpdateHandle()">{{ $t('add') }}</el-button>
</el-form-item>
<el-form-item>
<el-button v-if="$hasPermission('sys:params:delete')"
type="danger"
@click="deleteHandle()">{{ $t('deleteBatch') }}</el-button>
</el-form-item>
</el-form>
<el-table v-loading="dataListLoading"
:data="dataList"
border
@selection-change="dataListSelectionChangeHandle"
style="width: 100%;">
<el-table-column prop="customizedName"
label="功能名称"
header-align="center"
align="center"></el-table-column>
<el-table-column prop="shoppingStatusShow"
label="上架状态"
:formatter="stateFormat"
header-align="center"
align="center"></el-table-column>
<el-table-column prop="functionExplain"
label="功能说明"
header-align="center"
align="center"></el-table-column>
<el-table-column prop="targetLink"
label="外链地址"
header-align="center"
align="center"></el-table-column>
<el-table-column prop="domainName"
label="业务域名"
header-align="center"
align="center"></el-table-column>
<el-table-column prop="iconLargeImg"
label="大图标"
header-align="center"
align="center">
<img :src="scope.row.iconLargeImg"
style="width: 50px; height: 50px"
class="function-icon"
:fit="'fill'"></el-table-column>
<el-table-column prop="iconSmallImg"
label="小图标"
header-align="center"
align="center">
<img :src="scope.row.iconSmallImg"
style="width: 50px; height: 50px"
class="function-icon"
:fit="'fill'"></el-table-column>
<el-table-column :label="$t('handle')"
fixed="right"
header-align="center"
align="center"
width="150">
<template slot-scope="scope">
<el-button v-if="$hasPermission('sys:params:update')"
type="text"
size="small"
@click="addOrUpdateHandle(scope.row.id)">{{$t('update')}}
</el-button>
<el-button v-if="$hasPermission('sys:params:delete')"
type="text"
size="small"
@click="deleteHandle(scope.row.id)">{{$t('delete')}}
</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination :current-page="page"
:page-sizes="[10, 20, 50, 100]"
:page-size="limit"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="pageSizeChangeHandle"
@current-change="pageCurrentChangeHandle">
</el-pagination>
<!-- 弹窗, 新增 / 修改 -->
<add-or-update v-if="addOrUpdateVisible"
ref="addOrUpdate"
@refreshDataList="getDataList"></add-or-update>
</div>
</el-card>
</template>
<script>
import mixinViewModule from '@/mixins/view-module'
import AddOrUpdate from './function-add-or-update'
export default {
name: 'function',
mixins: [mixinViewModule],
data () {
return {
mixinViewModuleOptions: {
// getDataListURL: '/oper/customize/functioncustomized/functioncustomizedlist',
getDataListURL: 'https://nei.netease.com/api/apimock-v2/e3b1d0eb88e905f6c7ee559b2d6bb7ad/oper/customize/functioncustomized/functioncustomizedlist',
getDataListIsPage: true,
deleteURL: '/oper/customize/function',
deleteIsBatch: true
},
dataForm: {
functionName: '',
functionGroup: '',
shoppingStatus: ''
},
shoppingStatusList: [
{
'dictName': '下架',
'dictValue': '0'
}, {
'dictName': '上架',
'dictValue': '1'
}
]
}
},
components: {
AddOrUpdate
},
methods: {
stateFormat (row, column) {
if (row.shoppingStatus === 0) {
return '下架'
} else {
return '上架'
}
}
}
}
</script>
<style scoped>
</style>

247
epmet-oper-web/src/views/modules/miniPro/customFun/CustomFun.vue

@ -0,0 +1,247 @@
<template>
<div>
<el-card shadow="never"
class="aui-card--fill">
<div class="mod-demo__demo}">
<el-form :inline="true"
:model="tableParams">
<el-form-item>
<el-input v-model="tableParams.customizedName"
placeholder="功能名称"
clearable>
</el-input>
</el-form-item>
<el-form-item>
<el-select v-model="tableParams.fromApp"
placeholder="来源"
clearable>
<el-option v-for="item in form.data['fromApp']"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="loadTableData()">查询</el-button>
</el-form-item>
<el-form-item>
<el-button type="primary"
@click="addShow()">新增</el-button>
</el-form-item>
</el-form>
<c-table column-type=""
ref="table"
:url="tableUrl"
:params="tableParams"
:operationWidth="80"
keyword="CustomizedFunction"
:operations="operations"
:tableHeight="tableHeight"
@editShow="editShow"
@del="del">
</c-table>
</div>
</el-card>
<edit ref="ref_edit"
@ok="editDiaOK"
@cancel="editDiaCancel">
</edit>
</div>
</template>
<script>
import CDialog from '@c/CDialog'
import CTable from '@c/CTable'
import Edit from './Edit'
import { mapGetters } from 'vuex'
import { Loading } from 'element-ui' // Loading
let loading//
export default {
data () {
return {
selCodeId: '',
//
tableParams: {
customizedName: '', //
fromApp: '' //
},
//
tableUrl: 'https://nei.netease.com/api/apimock-v2/e3b1d0eb88e905f6c7ee559b2d6bb7ad/oper/customize/functioncustomized/functioncustomizedlist',
// tableUrl: '/oper/customize/f unctioncustomized/functioncustomizedlist',
operations: [
{
lable: '修改', //
size: 'mini',
style: 'margin: 0 6px;',
type: 'text',
slot: '',
plain: false,
methodName: 'editShow', //
isShow: (row) => {
return true
}
},
{
lable: '删除', //
size: 'mini',
style: 'margin: 0 6px;',
type: 'text',
slot: '',
plain: false,
methodName: 'del', //
isShow: (row) => {
return true
}
}
],
// //
// editDia: {
// visible: false
// },
src: '',
//
form: {
dataUrl: [], // //url
data: { //
fromApp: [
{
value: 'resi',
label: '居民端'
},
{
value: 'gov',
label: '工作端'
}
]
}
}
}
},
components: {
CDialog, CTable, Edit
},
activated () {
this.$nextTick(() => {
this.$refs.table.doLayout() //
})
},
mounted () {
this.renderSelData()
this.loadTableData()
},
computed: {
tableHeight () {
return this.clientHeight - 60 - 80 - 80 - 90
},
...mapGetters(['clientHeight', 'env'])
},
methods: {
//
refresh () {
this.loadTableData()
},
//
loadTableData () {
this.tableParams.source = this.env
this.$nextTick(() => {
this.$refs.table.loadData() //
})
},
//
addShow () {
let row = {
functionId: '',
customizedName: '',
iconLargeImg: '',
iconSmallImg: '',
shoppingStatus: '1',
functionExplain: '',
targetLink: '',
domainName: '',
fromApp: 'resi'
}
this.$refs['ref_edit'].init(row)
},
//
editShow (row) {
this.$refs['ref_edit'].init(row)
},
//
del (row) {
this.$confirm('确认删除当前定制功能', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const url = 'https://nei.netease.com/api/apimock-v2/e3b1d0eb88e905f6c7ee559b2d6bb7ad/oper/customize/functioncustomized/deletefunctioncustomized'
// const url = '/oper/customize/functioncustomized/deletefunctioncustomized'
const param = {
functionId: row.functionId
}
window.app.ajax.post(url, param,
(data, rspMsg) => {
this.$message.success('删除成功' + rspMsg)
this.refresh()
},
(rspMsg, data) => {
this.$message.error(rspMsg)
})
}).catch(() => {
})
},
editDiaOK () {
this.refresh()
},
editDiaCancel () {
},
async renderSelData () { // //
},
//
startLoading () {
loading = Loading.service({
lock: true, //
text: '正在加载……', //
background: 'rgba(0,0,0,.7)' //
})
},
//
endLoading () {
// clearTimeout(timer);
if (loading) {
loading.close()
}
}
}
}
</script>
<style>
.el-upload__tip {
color: rgb(155, 155, 155);
}
</style>

263
epmet-oper-web/src/views/modules/miniPro/customFun/Edit.vue

@ -0,0 +1,263 @@
<template>
<el-dialog :visible.sync="visible"
:title="'修改定制功能'"
:close-on-click-modal="false"
:before-close="handleClose"
:close-on-press-escape="false">
<el-form :inline="true"
:model="dataForm"
:rules="dataRule"
ref="dataForm"
:label-width="'120px'">
<el-form-item label="功能名称"
prop="customizedName">
<el-input class="item_width_1"
v-model="dataForm.customizedName"
placeholder="功能名称"></el-input>
</el-form-item>
<el-form-item label="来源"
prop="fromApp">
<el-select class="item_width_1"
v-model="dataForm.fromApp"
placeholder="请选择"
clearable>
<el-option v-for="item in fromAppList"
:key="item.dictValue"
:label="item.dictName"
:value="item.dictValue">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="上架状态"
prop="shoppingStatus">
<el-select class="item_width_1"
v-model="dataForm.shoppingStatus"
placeholder="请选择"
clearable>
<el-option v-for="item in shoppingStatusList"
:key="item.dictValue"
:label="item.dictName"
:value="item.dictValue">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="外链地址"
prop="targetLink">
<el-input class="item_width_1"
v-model="dataForm.targetLink"
placeholder="外链地址"></el-input>
</el-form-item>
<el-form-item prop="iconLargeImg"
label="大图标">
<el-upload class="item_width_1 avatar-uploader"
:action="uploadUlr"
:show-file-list="false"
:on-success="function (res, file) { return handleImgSuccess(res, file, 'large')}"
:before-upload="beforeImgUpload">
<img v-if="dataForm.iconLargeImg"
:src="dataForm.iconLargeImg"
style="width:70px;height:70px"
class="function-icon">
<i v-else
class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item prop="iconSmallImg"
label="小图标">
<el-upload class="item_width_1 avatar-uploader"
:action="uploadUlr"
:show-file-list="false"
:on-success="function (res, file) { return handleImgSuccess(res, file, 'small')}"
:before-upload="beforeImgUpload">
<img v-if="dataForm.iconSmallImg"
:src="dataForm.iconSmallImg"
style="width:70px;height:70px"
class="function-icon">
<i v-else
class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</el-form-item>
<el-form-item class="block"
label="业务域名"
prop="domainName">
<el-input class="item_width_2"
v-model="dataForm.domainName"
placeholder="业务域名"
type="textarea"></el-input>
</el-form-item>
<div slot="tip"
class="el-upload__tip">可写多个;分隔</div>
<el-form-item class="block"
label="功能说明"
prop="functionExplain">
<el-input class="item_width_2"
v-model="dataForm.functionExplain"
placeholder="功能说明"
type="textarea"></el-input>
</el-form-item>
</el-form>
<template slot="footer">
<el-button @click="visible = false">{{ $t('cancel') }}</el-button>
<el-button type="primary"
@click="saveForm()">{{ $t('confirm') }}</el-button>
</template>
</el-dialog>
</template>
<script>
export default {
data () {
return {
visible: false,
dataForm: {
functionId: '',
customizedName: '',
iconLargeImg: '',
iconSmallImg: '',
shoppingStatus: 1,
functionExplain: '',
targetLink: '',
domainName: '',
fromApp: 'resi'
},
uploadUlr: window.SITE_CONFIG['apiURL'] + '/oss/file/function/upload',
fromAppList: [
{
'dictName': '工作端',
'dictValue': 'gov'
}, {
'dictName': '居民端',
'dictValue': 'resi'
}
],
shoppingStatusList: [
{
'dictName': '下架',
'dictValue': '0'
}, {
'dictName': '上架',
'dictValue': '1'
}
]
}
},
created () {
// this.queryFunctionList()
},
computed: {
dataRule () {
return {
customizedName: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
iconLargeImg: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
iconSmallImg: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
fromApp: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
shoppingStatus: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
functionExplain: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
],
targetLink: [
{ required: true, message: this.$t('validate.required'), trigger: 'blur' }
]
}
}
},
methods: {
init (dataForm) {
console.log(dataForm)
this.visible = true
// this.dataForm=dataForm
this.$nextTick(() => {
Object.assign(this.dataForm, dataForm)
})
},
//
handleImgSuccess (res, file, type) {
if (res.code === 0 && res.msg === 'success') {
if (type === 'large') {
this.dataForm.iconLargeImg = res.data.url
} else if (type === 'small') {
this.dataForm.iconSmallImg = res.data.url
}
} else {
this.$message.error(res.msg)
}
},
beforeImgUpload (file) {
// const isPNG = file.type === 'image/png'
const isLt1M = file.size / 1024 / 1024 < 1
// if (!isPNG) {
// this.$message.error(' PNG !')
// }
if (!isLt1M) {
this.$message.error('上传图片大小不能超过 1MB!')
}
// return isPNG && isLt1M
return isLt1M
},
saveForm () {
this.$refs['dataForm'].validate((valid) => {
if (!valid) {
this.$message.error('表单验证失败!')
} else {
console.log(this.dataForm)
const url = 'https://nei.netease.com/api/apimock-v2/e3b1d0eb88e905f6c7ee559b2d6bb7ad/oper/customize/functioncustomized/updatecustomized'
// const url = '/oper/customize/functioncustomized/updatecustomized'
window.app.ajax.post(url, this.dataForm,
(data, rspMsg) => {
this.$message({
type: 'success',
message: '保存成功'
})
this.visible = false
this.$emit('editDiaOK')
},
(rspMsg, data) => {
this.endLoading()
this.$message.error(rspMsg)
})
}
})
},
handleClose () {
this.visible = false
}
}
}
</script>
<style scoped>
.function-icon {
width: 28px;
}
.item_width_1 {
width: 300px;
}
.item_width_2 {
width: 700px;
}
.block {
display: block;
}
</style>
Loading…
Cancel
Save