数字平昌
This commit is contained in:
64
project/shuzipingchang/app/AppDynamic/AppDynamic.vue
Normal file
64
project/shuzipingchang/app/AppDynamic/AppDynamic.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<div class="AppActivitiesManagement">
|
||||
<keep-alive :include="['List']">
|
||||
<component ref="component" :is="component" :permissions="permissions " @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import List from './components/List'
|
||||
import Detail from './components/Detail'
|
||||
|
||||
export default {
|
||||
name: 'AppDynamic',
|
||||
label: '精选动态',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
component: 'List',
|
||||
params: {},
|
||||
include: []
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
List,
|
||||
Detail
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange (data) {
|
||||
if (data.type === 'Detail') {
|
||||
this.component = 'Detail'
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'List') {
|
||||
this.component = 'List'
|
||||
this.params = data.params
|
||||
|
||||
this.$nextTick(() => {
|
||||
if (data.isRefresh) {
|
||||
this.$refs.component.getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.AppActivitiesManagement {
|
||||
height: 100%;
|
||||
background: #F3F6F9;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
110
project/shuzipingchang/app/AppDynamic/components/Detail.vue
Normal file
110
project/shuzipingchang/app/AppDynamic/components/Detail.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<ai-detail class="AppDynamicDetail">
|
||||
<template slot="title">
|
||||
<ai-title title="详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-card title="基本信息">
|
||||
<template #content>
|
||||
<ai-wrapper
|
||||
label-width="120px">
|
||||
<ai-info-item label="类型" isLine :value="info.title"></ai-info-item>
|
||||
<ai-info-item label="所属网格" isLine :value="info.girdName"></ai-info-item>
|
||||
<ai-info-item label="文章类型" isLine :value="info.contentType === '0' ? '文章' : '视频'"></ai-info-item>
|
||||
<ai-info-item label="分类" v-if="info.categoryName" isLine :value="info.categoryName"></ai-info-item>
|
||||
<ai-info-item label="正文" v-if="info.contentType === '0'" isLine>
|
||||
<AiArticle :value="info.content"></AiArticle>
|
||||
</ai-info-item>
|
||||
<ai-info-item label="附件" isLine>
|
||||
<div class="files">
|
||||
<div class="file-item" v-for="(item, index) in info.files" :key="index">
|
||||
<video controls :src="item.url" v-if="['.mp4', '.mov'].includes(item.postfix)"></video>
|
||||
<img :src="item.url" v-else v-viewer="{movable: true}">
|
||||
</div>
|
||||
</div>
|
||||
</ai-info-item>
|
||||
</ai-wrapper>
|
||||
</template>
|
||||
</ai-card>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Detail',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object,
|
||||
moduleId: String
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
info: {},
|
||||
id: ''
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
if (this.params && this.params.id) {
|
||||
this.id = this.params.id
|
||||
this.getInfo(this.params.id)
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getInfo (id) {
|
||||
this.instance.post(`/app/appcontentinfo/queryDetailById?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.info = res.data
|
||||
this
|
||||
this.info = {
|
||||
...res.data,
|
||||
pictureUrl: res.data.pictureUrl ? [{
|
||||
url: res.data.pictureUrl
|
||||
}] : [],
|
||||
files: res.data.files.map(v => {
|
||||
return {
|
||||
...v,
|
||||
postfix: v.postfix.toLowerCase()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancel (isRefresh) {
|
||||
this.$emit('change', {
|
||||
type: 'List',
|
||||
isRefresh: !!isRefresh
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.AppDynamicDetail {
|
||||
.files {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
.file-item {
|
||||
width: 240px;
|
||||
height: 240px;
|
||||
margin: 0 20px 20px 0;
|
||||
|
||||
img, video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
144
project/shuzipingchang/app/AppDynamic/components/List.vue
Normal file
144
project/shuzipingchang/app/AppDynamic/components/List.vue
Normal file
@@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<ai-list class="notice">
|
||||
<ai-title slot="title" title="精选动态" v-model="search.areaId" isShowBottomBorder isShowArea :hideLevel="hideLevel - 1" @change="search.current = 1, getList()"></ai-title>
|
||||
<template slot="content">
|
||||
<ai-search-bar class="search-bar">
|
||||
<template #left>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-input
|
||||
v-model="search.title"
|
||||
class="search-input"
|
||||
size="small"
|
||||
v-throttle="() => {search.current = 1, getList()}"
|
||||
placeholder="姓名、推送人"
|
||||
clearable
|
||||
@clear="search.current = 1, search.title = '', getList()"
|
||||
suffix-icon="iconfont iconSearch">
|
||||
</el-input>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="total"
|
||||
style="margin-top: 6px;"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@getList="getList">
|
||||
<el-table-column slot="options" width="120px" fixed="right" label="操作" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click="remove(row.id)">下架</el-button>
|
||||
<el-button type="text" @click="toDetail(row.id)">详情</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
name: 'List',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
search: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
title: '',
|
||||
areaId: ''
|
||||
},
|
||||
total: 0,
|
||||
colConfigs: [
|
||||
{ prop: 'title', label: '类型', align: 'left', width: '200px' },
|
||||
{ prop: 'createUserName', label: '姓名', align: 'center' },
|
||||
{ prop: 'girdName', label: '所属网格', align: 'center' },
|
||||
{ prop: 'examineUserName', label: '推送人', align: 'center' },
|
||||
{ prop: 'createTime', label: '推送时间', align: 'center' }
|
||||
],
|
||||
tableData: [],
|
||||
moduleId: ''
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
|
||||
hideLevel () {
|
||||
return this.user.info.areaList.length || 0
|
||||
},
|
||||
|
||||
params () {
|
||||
return {
|
||||
...this.search
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.search.areaId = this.user.info.areaId
|
||||
this.getInfo()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getInfo () {
|
||||
this.instance.post(`/app/appintegraluserapply/queryModuleByName`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.moduleId = res.data
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getList()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getList () {
|
||||
this.instance.post(`/app/appcontentinfo/list-web`, null, {
|
||||
params: {
|
||||
moduleId: this.moduleId,
|
||||
...this.search,
|
||||
areaId: this.search.areaId
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
remove(id) {
|
||||
this.$confirm('确定删除该数据?').then(() => {
|
||||
this.instance.post(`/app/appcontentinfo/deleteIntegralApply?ids=${id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('下架成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
toDetail(id) {
|
||||
this.$emit('change', {
|
||||
type: 'Detail',
|
||||
params: {
|
||||
id: id || ''
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
76
project/shuzipingchang/app/AppHelp/AppHelp.vue
Normal file
76
project/shuzipingchang/app/AppHelp/AppHelp.vue
Normal file
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<div class="AppHelp">
|
||||
<keep-alive :include="['List']">
|
||||
<component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Detail from './components/Detail'
|
||||
import List from './components/List'
|
||||
import Add from './components/Add'
|
||||
import GagList from './components/GagList'
|
||||
|
||||
export default {
|
||||
name: 'AppHelp',
|
||||
label: '邻里互助',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
component: 'List',
|
||||
params: {},
|
||||
include: []
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
Add,
|
||||
List,
|
||||
Detail,
|
||||
GagList
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange (data) {
|
||||
if (data.type === 'GagList') {
|
||||
this.component = 'GagList'
|
||||
}
|
||||
|
||||
if (data.type === 'Add') {
|
||||
this.component = 'Add'
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'Detail') {
|
||||
this.component = 'Detail'
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'List') {
|
||||
this.component = 'List'
|
||||
this.params = data.params
|
||||
|
||||
this.$nextTick(() => {
|
||||
if (data.isRefresh) {
|
||||
this.$refs.component.getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.AppHelp {
|
||||
height: 100%;
|
||||
background: #F3F6F9;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
177
project/shuzipingchang/app/AppHelp/components/Add.vue
Normal file
177
project/shuzipingchang/app/AppHelp/components/Add.vue
Normal file
@@ -0,0 +1,177 @@
|
||||
<template>
|
||||
<ai-detail class="content-add">
|
||||
<template slot="title">
|
||||
<ai-title :title="params.id ? '编辑帖子' : '我要发帖'" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-card title="发帖信息">
|
||||
<template #content>
|
||||
<el-form class="ai-form" :model="form" label-width="120px" ref="form">
|
||||
<el-form-item label="发布单位" prop="publishDepartName" style="width: 100%;" :rules="[{ required: true, message: '请选择单位', trigger: 'change' }]">
|
||||
<ai-picker :instance="instance" multiple @pick="e => onUserChange(e)" dialogTitle="选择部门" action="/app/wxcp/wxdepartment/departList">
|
||||
<div class="time-select">
|
||||
<span class="dept-name" style="color:#999;" v-if="!form.publishDepartName">选择部门</span>
|
||||
<span class="dept-name" v-else>{{form.publishDepartName}}</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</ai-picker>
|
||||
</el-form-item>
|
||||
<el-form-item prop="visibleAreaId" style="width: 100%;" label="发布地区" :rules="[{required: true, message: '请选择地区', trigger: 'change'}]">
|
||||
<ai-area-select clearable @fullname="v => form.visibleAreaName = v" always-show :instance="instance" v-model="form.visibleAreaId" :disabled-level="disabledLevel"></ai-area-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="发布内容" prop="content" style="width: 100%;" :rules="[{required: true, message: '请输入发布内容', trigger: 'change'}]">
|
||||
<!-- <ai-editor v-model="form.content" :instance="instance"/> -->
|
||||
<el-input type="textarea" placeholder="请输入内容" v-model="form.content" rows="8" maxlength="500" :show-word-limit="true"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="图片" prop="files" style="width: 100%;">
|
||||
<ai-uploader
|
||||
:instance="instance"
|
||||
v-model="form.files"
|
||||
isShowTip
|
||||
:limit="9">
|
||||
</ai-uploader>
|
||||
</el-form-item>
|
||||
<el-form-item prop="themeId" style="width: 100%;" label="关联话题">
|
||||
<ai-select v-model="form.themeId" :selectList="talkList" placeholder="请选择关联话题" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</ai-card>
|
||||
</template>
|
||||
<template #footer>
|
||||
<el-button @click="cancel">取消</el-button>
|
||||
<el-button type="primary" @click="confirm">提交</el-button>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
name: 'Add',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
info: {},
|
||||
form: {
|
||||
themeId: '',
|
||||
content: '',
|
||||
areaId: '',
|
||||
visibleAreaName: '',
|
||||
files: [],
|
||||
areaName: '',
|
||||
publishDepartName: '',
|
||||
publishDepartIdList: [],
|
||||
},
|
||||
id: '',
|
||||
department: [],
|
||||
talkList: [],
|
||||
isFlag: false
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user'])
|
||||
},
|
||||
|
||||
created () {
|
||||
if (this.params && this.params.id) {
|
||||
this.id = this.params.id
|
||||
this.getInfo(this.params.id)
|
||||
}
|
||||
this.form.visibleAreaId =this.user.info.areaId
|
||||
this.form.visibleAreaName =this.user.info.areaName
|
||||
this.disabledLevel = this.user.info.areaList.length
|
||||
this.getTalkList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getInfo (id) {
|
||||
this.instance.post(`/app/appneighborhoodassistance/queryDetailById?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.form = res.data
|
||||
this.form.publishDepartIdList = this.form.publishDepartId.split(',')
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
confirm () {
|
||||
if(this.isFlag) return
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.isFlag = true
|
||||
this.instance.post(`/app/appneighborhoodassistance/addOrUpdate`, {
|
||||
...this.form,
|
||||
publishDepartId: this.form.publishDepartIdList.join(',')
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('提交成功')
|
||||
setTimeout(() => {
|
||||
this.cancel(true)
|
||||
}, 600)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancel (isRefresh) {
|
||||
this.$emit('change', {
|
||||
type: 'List',
|
||||
isRefresh: !!isRefresh
|
||||
})
|
||||
},
|
||||
|
||||
onChange (e) {
|
||||
if (e.length) {
|
||||
this.form.publishDepartIdList = e.map(v => v.id)
|
||||
this.form.publishDepartName = e.map(v => v.name).join(',')
|
||||
} else {
|
||||
this.form.publishDepartIdList = ''
|
||||
this.form.publishDepartName = ''
|
||||
}
|
||||
},
|
||||
|
||||
onUserChange (e) {
|
||||
this.deptList = e
|
||||
this.onChange(e)
|
||||
},
|
||||
|
||||
getTalkList() {
|
||||
this.instance.post(`/app/appneighborhoodassistancetheme/list?size=100`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.talkList = []
|
||||
res.data.records.map((item) => {
|
||||
this.talkList.push({
|
||||
dictName: item.title,
|
||||
dictValue: item.id
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.time-select {
|
||||
padding: 0 16px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
border: 1px solid #d0d4dc;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
.el-icon-arrow-down {
|
||||
line-height: 36px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
294
project/shuzipingchang/app/AppHelp/components/Detail.vue
Normal file
294
project/shuzipingchang/app/AppHelp/components/Detail.vue
Normal file
@@ -0,0 +1,294 @@
|
||||
<template>
|
||||
<ai-detail class="detail">
|
||||
<template slot="title">
|
||||
<ai-title title="帖子详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-card title="帖子信息">
|
||||
<template #content>
|
||||
<div class="talk-info">
|
||||
<div class="user">
|
||||
<img :src="info.createUserAvatar" alt="">
|
||||
<div class="info">
|
||||
<h2>{{info.createUserName}}</h2>
|
||||
<div class="time-flex">
|
||||
<span class="area-name">{{info.publishDepartName}}</span>
|
||||
<span>{{info.createTime}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<span v-if="info.themeId">#【{{info.themeInfo.title}}】</span>{{info.content}}
|
||||
</div>
|
||||
<ai-uploader :instance="instance" disabled v-model="info.files">
|
||||
</ai-uploader>
|
||||
</div>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-card title="评论信息">
|
||||
<template #content>
|
||||
<div class="comment-list" v-if="commontList.length">
|
||||
<div class="title">评论</div>
|
||||
<div class="item" v-for="(item, index) in commontList" :key="index">
|
||||
<div class="user">
|
||||
<img :src="item.createUserAvatar" alt="">
|
||||
<div class="info-flex">
|
||||
<h2>{{item.createUserName}}</h2>
|
||||
<span>{{item.createTime}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-flex">
|
||||
<p>{{item.content}}</p>
|
||||
<div @click="delCommontOrReply('评论', item.id)">删除</div>
|
||||
</div>
|
||||
<div class="reply-list" v-if="item.replyList && item.replyList.length && item.isShowReply">
|
||||
<div class="reply-item" v-for="(reply, indexs) in item.replyList" :key="indexs">
|
||||
<div class="reply-user">
|
||||
<img :src="item.createUserAvatar" alt="">
|
||||
<div class="reply-name">
|
||||
<span>{{reply.createUserName}}</span>回复<span>{{item.createUserName}}</span>
|
||||
</div>
|
||||
<span class="reply-time">{{reply.createTime}}</span>
|
||||
</div>
|
||||
<div class="content-flex">
|
||||
<p>{{reply.content}}</p>
|
||||
<div @click="delCommontOrReply('回复', reply.id)">删除</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="reply-more" @click="item.isShowReply = !item.isShowReply" :class="[item.isShowReply ? 'active' : '']">
|
||||
<span class="line"></span>{{item.isShowReply ? '收起' : `展开${item.replyList.length}条回复`}}
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ai-empty v-else>暂无评论</ai-empty>
|
||||
</template>
|
||||
</ai-card>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Detail',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
commontList: [],
|
||||
info: {},
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
getAvatar(row){
|
||||
return row.avatar||row.photo||'https://cdn.cunwuyun.cn/dvcp/h5/defaultAvatar.png'
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.getInfo()
|
||||
this.getList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList() {
|
||||
this.instance.post(`/app/appneighborhoodassistance/commontList?id=${this.params.id}&size=100`).then(res => {
|
||||
if (res.code == 0) {
|
||||
res.data.records.map((item) => {
|
||||
item.isShowReply = false
|
||||
})
|
||||
this.commontList = res.data.records
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getInfo () {
|
||||
this.instance.post(`/app/appneighborhoodassistance/queryDetailById?id=${this.params.id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
if (res.data) {
|
||||
this.info = res.data
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancel () {
|
||||
this.$emit('change', {
|
||||
type: 'List',
|
||||
isRefresh: true
|
||||
})
|
||||
},
|
||||
|
||||
delCommontOrReply(text, id) {
|
||||
this.$confirm(`确定删除该${text}?`).then(() => {
|
||||
this.instance.post(`/app/appneighborhoodassistance/delComment?id=${id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('删除成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.detail {
|
||||
.talk-info {
|
||||
.user {
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
img {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
margin-right: 16px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.info {
|
||||
width: calc(100% - 76px);
|
||||
h2 {
|
||||
font-size: 20px;
|
||||
line-height: 30px;
|
||||
font-weight: 400;
|
||||
}
|
||||
.time-flex {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
line-height: 30px;
|
||||
.area-name {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.content {
|
||||
font-size: 16px;
|
||||
line-height: 32px;
|
||||
word-break: break-all;
|
||||
span {
|
||||
color: #26f;
|
||||
}
|
||||
}
|
||||
}
|
||||
.comment-list {
|
||||
.title {
|
||||
color: #333;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
line-height: 40px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.item {
|
||||
border-bottom: 1px solid #ddd;
|
||||
padding-bottom: 16px;
|
||||
.user {
|
||||
display: flex;
|
||||
margin-bottom: 8px;
|
||||
img {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
margin-right: 16px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.info-flex {
|
||||
width: calc(100% - 76px);
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
line-height: 60px;
|
||||
h2 {
|
||||
font-size: 20px;
|
||||
font-weight: 400;
|
||||
}
|
||||
span {
|
||||
color: #999;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.content-flex {
|
||||
display: flex;
|
||||
font-size: 16px;
|
||||
line-height: 30px;
|
||||
margin-bottom: 8px;
|
||||
padding-left: 76px;
|
||||
p {
|
||||
width: calc(100% - 50px);
|
||||
word-break: break-all;
|
||||
}
|
||||
div {
|
||||
color: #26f;
|
||||
width: 50px;
|
||||
text-align: right;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.reply-list {
|
||||
padding-left: 100px;
|
||||
.reply-item {
|
||||
margin-bottom: 8px;
|
||||
.reply-user {
|
||||
font-size: 14px;
|
||||
img {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.reply-name {
|
||||
display: inline-block;
|
||||
color: #333;
|
||||
width: 300px;
|
||||
span {
|
||||
display: inline-block;
|
||||
color: #666;
|
||||
margin: 0 8px;
|
||||
}
|
||||
}
|
||||
.reply-time {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
.content-flex {
|
||||
font-size: 14px;
|
||||
line-height: 24px;
|
||||
padding-left: 58px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.reply-more {
|
||||
font-size: 14px;
|
||||
line-height: 28px;
|
||||
color: #333;
|
||||
.line {
|
||||
display: inline-block;
|
||||
width: 120px;
|
||||
border-top: 1px solid #eee;
|
||||
vertical-align: middle;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.el-icon-arrow-down {
|
||||
transition: all ease 0.5s;
|
||||
transform: rotate(0);
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
&.active .el-icon-arrow-down {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
109
project/shuzipingchang/app/AppHelp/components/GagList.vue
Normal file
109
project/shuzipingchang/app/AppHelp/components/GagList.vue
Normal file
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<ai-list class="notice">
|
||||
<template slot="title">
|
||||
<ai-title title="禁言列表" isShowBack isShowBottomBorder @onBackClick="cancel"></ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-search-bar>
|
||||
<template #left>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-input
|
||||
v-model="search.userName"
|
||||
class="search-input"
|
||||
size="small"
|
||||
v-throttle="() => {search.current = 1, getList()}"
|
||||
placeholder="请输入用户昵称"
|
||||
clearable
|
||||
@clear="search.current = 1, search.userName = '', getList()"
|
||||
suffix-icon="iconfont iconSearch">
|
||||
</el-input>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="total"
|
||||
style="margin-top: 6px;"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@getList="getList">
|
||||
<el-table-column slot="options" width="100px" fixed="right" label="操作" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click="remove(row.userId)">解除禁言</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'GagList',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
search: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
userName: ''
|
||||
},
|
||||
total: 0,
|
||||
colConfigs: [
|
||||
{ prop: 'userName', label: '用户昵称', align: 'left' },
|
||||
{ prop: 'areaName', label: '所属地区', align: 'center' },
|
||||
{ prop: 'createTime', label: '被禁言时间', align: 'center' }
|
||||
],
|
||||
tableData: []
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList() {
|
||||
this.instance.post(`/app/appneighborhoodassistance/blacklist`, null, {
|
||||
params: {
|
||||
...this.search
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
remove (id) {
|
||||
this.$confirm('确定对该用户解除禁言?').then(() => {
|
||||
this.instance.post(`/app/appneighborhoodassistance/addBlacklist?userId=${id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('解除成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
cancel () {
|
||||
this.$emit('change', {
|
||||
type: 'List',
|
||||
isRefresh: true
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
181
project/shuzipingchang/app/AppHelp/components/List.vue
Normal file
181
project/shuzipingchang/app/AppHelp/components/List.vue
Normal file
@@ -0,0 +1,181 @@
|
||||
<template>
|
||||
<ai-list class="notice">
|
||||
<template slot="title">
|
||||
<ai-title title="邻里互助" isShowBottomBorder isShowArea :hideLevel="hideLevel-1" v-model="search.areaId" @change="changeArea">
|
||||
<template #rightBtn>
|
||||
<el-button size="small" type="primary" @click="toGagList">禁言名单</el-button>
|
||||
</template>
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-search-bar class="search-bar">
|
||||
<template #left>
|
||||
<el-button size="small" type="primary" icon="iconfont iconAdd" @click="toAdd('')">我要发帖</el-button>
|
||||
<el-date-picker
|
||||
v-model="dateList"
|
||||
@change="search.current = 1,getList()"
|
||||
type="daterange"
|
||||
size="small"
|
||||
value-format="yyyy-MM-dd"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期">
|
||||
</el-date-picker>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-input
|
||||
v-model="search.createUserName"
|
||||
class="search-input"
|
||||
size="small"
|
||||
v-throttle="() => {search.current = 1, getList()}"
|
||||
placeholder="请输入发帖人"
|
||||
clearable
|
||||
@clear="search.current = 1, search.createUserName = '', getList()"
|
||||
suffix-icon="iconfont iconSearch">
|
||||
</el-input>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="total"
|
||||
style="margin-top: 6px;"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@getList="getList">
|
||||
<el-table-column slot="options" width="180px" fixed="right" label="操作" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click="toDetail(row.id)">详情</el-button>
|
||||
<el-button type="text" @click="remove(row.id)">删除</el-button>
|
||||
<el-button type="text" @click="gag(row.createUserId, row.blacklist)">{{ row.blacklist ? '解除禁言' : '禁言' }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
name: 'List',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
search: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
createUserName: '',
|
||||
areaId: ''
|
||||
},
|
||||
total: 0,
|
||||
colConfigs: [
|
||||
{ prop: 'content', label: '内容', align: 'left' },
|
||||
{ prop: 'createUserName', label: '发帖人', align: 'center', width: '120' },
|
||||
{ prop: 'createUserAreaName', label: '所属地区', align: 'center' },
|
||||
{ prop: 'createTime', label: '创建时间', align: 'center' },
|
||||
{ prop: 'commentCount', label: '评论数', align: 'center', width: '120' },
|
||||
{ prop: 'appreciateCount', label: '点赞数', align: 'center', width: '120' },
|
||||
{ prop: 'sharedCount', label: '分享数', align: 'center', width: '120' },
|
||||
{ prop: 'blacklist', label: '状态', align: 'center', format: v => v ? '禁言' : '正常' },
|
||||
{ slot: 'options'},
|
||||
],
|
||||
tableData: [],
|
||||
dateList: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
hideLevel() {
|
||||
return this.user.info.areaList?.length || 0
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.search.areaId = this.user.info.areaId
|
||||
this.getList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList() {
|
||||
this.instance.post(`/app/appneighborhoodassistance/list`, null, {
|
||||
params: {
|
||||
...this.search,
|
||||
createUserAreaId: this.search.areaId,
|
||||
beginDate: this.dateList[0] || '',
|
||||
endDate: this.dateList[1] || '',
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
changeArea () {
|
||||
this.search.current = 1
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
toGagList () {
|
||||
this.$emit('change', {
|
||||
type: 'GagList'
|
||||
})
|
||||
},
|
||||
|
||||
gag (id, status) {
|
||||
this.$confirm(`确定${status ? '解除禁言' : '禁言'}该用户?`).then(() => {
|
||||
this.instance.post(`/app/appneighborhoodassistance/addBlacklist?userId=${id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success(`${status ? '解除禁言' : '禁言'}成功!`)
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
remove (id) {
|
||||
this.$confirm('确定删除该帖子?').then(() => {
|
||||
this.instance.post(`/app/appneighborhoodassistance/delete?id=${id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('删除成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
toDetail (id) {
|
||||
this.$emit('change', {
|
||||
type: 'Detail',
|
||||
params: {
|
||||
id: id || ''
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toAdd(id) {
|
||||
this.$emit('change', {
|
||||
type: 'Add',
|
||||
params: {
|
||||
id: id || ''
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,647 @@
|
||||
<template>
|
||||
<section class="AppIntegralStatistics">
|
||||
<el-row class="overallStatistics">
|
||||
<div class="title">
|
||||
<p>总体统计</p>
|
||||
<div class="title_right">
|
||||
<div>
|
||||
<span v-for="(item,index) in timeCheck" :key="index" :class="type == index? 'active':''"
|
||||
@click="timeChange(index)">{{ item }}</span>
|
||||
</div>
|
||||
<el-cascader ref="cascader1" v-model="girdArr" :options="girdOptions" placeholder="所属网格" size="small"
|
||||
:props="defaultProps" :show-all-levels="false" @change="gridChange" clearable></el-cascader>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card_list">
|
||||
<div class="card">
|
||||
<h2>积分余额汇总
|
||||
<el-tooltip
|
||||
placement="right"
|
||||
style="width: 16px;"
|
||||
content="截止目前所有居民剩余可用积分余额的总和">
|
||||
<i class="el-icon-warning-outline"></i>
|
||||
</el-tooltip>
|
||||
</h2>
|
||||
<p class="color1">{{ data.nowIntegral || 0 }}</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>发放积分</h2>
|
||||
<p class="color1">{{ data.addIntegral || 0 }}</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>消耗积分</h2>
|
||||
<p class="color1">{{ Math.abs(data.reduceIntegral) || 0 }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="echertsBox">
|
||||
<div class="left_Box">
|
||||
<p>个人积分排行</p>
|
||||
<div>
|
||||
<div id="chart1" style="height: 300px; width: 100%;" v-show="userSortListX.length && userSortListY.length"></div>
|
||||
<ai-empty v-show="!userSortListX.length && !userSortListY.length" style="height: 200px; width: 100%;" id="empty"></ai-empty>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right_Box">
|
||||
<p>网格积分排行</p>
|
||||
<div>
|
||||
<div id="chart2" style="height: 300px; width: 100%;" v-show="girdSortListX.length && girdSortListY.length"></div>
|
||||
<ai-empty v-show="!girdSortListX.length && !girdSortListY.length" style="height: 200px; width: 100%;" id="empty"></ai-empty>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-row>
|
||||
|
||||
<ai-card>
|
||||
<ai-title slot="title" title="积分明细"/>
|
||||
<template #content>
|
||||
<ai-search-bar>
|
||||
<template #left>
|
||||
<el-cascader ref="cascader2" v-model="girdIdArr" :options="girdOptions" placeholder="所属网格" size="small"
|
||||
:props="defaultProps" :show-all-levels="false" clearable @change="gridChangeOpt"></el-cascader>
|
||||
<ai-select v-model="search.integralType" placeholder="请选择类型" @change="current=1, getTableData()"
|
||||
:selectList="dict.getDict('integralType')"/>
|
||||
<el-date-picker v-model="time" size="small" type="daterange" value-format="yyyy-MM-dd"
|
||||
range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" @change="onChange">
|
||||
</el-date-picker>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-input size="small" placeholder="请输入姓名" v-model="search.userName" clearable
|
||||
@clear="current = 1, search.userName = '', getTableData()" suffix-icon="iconfont iconSearch"
|
||||
v-throttle="() => {(current = 1), getTableData();}" />
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table :tableData="tableData" :total="total" :current.sync="current" :size.sync="size"
|
||||
@getList="getTableData" :col-configs="colConfigs" :dict="dict">
|
||||
<el-table-column slot="eventDesc" label='事件' align="center" width="400px" show-overflow-tooltip>
|
||||
<template slot-scope="{ row }">
|
||||
<span>{{ row.integralRuleName || row.eventDesc}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column slot="changeIntegral" label="变动积分" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<span>{{ row.integralCalcType == 0 ? '-' : '+' }}{{ row.changeIntegral }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column slot="options" label="操作" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<el-button type="text" @click="open(row.id)">详情</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-card>
|
||||
|
||||
<el-dialog title="详情" :visible.sync="dialog" customFooter width="700">
|
||||
<ai-detail>
|
||||
<template #content>
|
||||
<ai-wrapper>
|
||||
<ai-info-item label="姓名" :value="details.integralUserName" />
|
||||
<ai-info-item label="所属网格" :value="details.girdName"/>
|
||||
<ai-info-item label="事件" isLine :value="details.eventDesc">
|
||||
<span v-if="details.integralRuleId">{{ details.integralRuleName }}</span>
|
||||
<span v-else>{{ details.eventDesc }}</span>
|
||||
</ai-info-item>
|
||||
<ai-info-item label="时间" isLine :value="details.createTime"/>
|
||||
<ai-info-item label="积分变动">
|
||||
{{ details.integralCalcType == 0 ? '-' : '+' }}{{ details.changeIntegral }}
|
||||
</ai-info-item>
|
||||
<ai-info-item label="积分余额" :value="details.nowIntegral"/>
|
||||
<ai-info-item label="凭证" isLine v-if="fileDownLoad.length">
|
||||
<ai-file-list :fileList="fileDownLoad" style="width: 200px;" :fileOps="{name: 'name'}"></ai-file-list>
|
||||
</ai-info-item>
|
||||
</ai-wrapper>
|
||||
</template>
|
||||
</ai-detail>
|
||||
<span slot="footer" class="dialog-footer" center>
|
||||
<el-button @click="dialog = false" style="width: 92px">关闭</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
|
||||
<ai-dialog :visible.sync="dialogDate" title="选择时间" width="500px" customFooter>
|
||||
<el-date-picker v-model="timeList" size="small" type="daterange" value-format="yyyy-MM-dd"
|
||||
range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期">
|
||||
</el-date-picker>
|
||||
<el-button slot="footer" @click="selectDete" type="primary">确认</el-button>
|
||||
</ai-dialog>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from "vuex"
|
||||
import * as echarts from 'echarts';
|
||||
import dayjs from 'dayjs'
|
||||
export default {
|
||||
name: "AppIntegralStatistics",
|
||||
label: "积分统计",
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
myChart1: null,
|
||||
myChart2: null,
|
||||
tableData: [],
|
||||
search: {
|
||||
current: 1,
|
||||
userName: '',
|
||||
girdId: '',
|
||||
integralType: '',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
},
|
||||
girdIdArr:[],
|
||||
total: 0,
|
||||
size: 10,
|
||||
current: 1,
|
||||
girdList: [],
|
||||
time: [],
|
||||
timeCheck: ['昨日','近7天','近30天','自定义'],
|
||||
dialog: false,
|
||||
dialogDate: false,
|
||||
timeList: [],
|
||||
type: '1',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
data: {},
|
||||
girdId: '',
|
||||
girdArr: [],
|
||||
girdOptions: [],
|
||||
defaultProps: {
|
||||
label: 'girdName',
|
||||
value: 'id',
|
||||
children: 'children',
|
||||
checkStrictly: true,
|
||||
},
|
||||
details: {},
|
||||
fileDownLoad: [],
|
||||
userSortListX: [],
|
||||
userSortListY: [],
|
||||
girdSortListX: [],
|
||||
girdSortListY: [],
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
colConfigs() {
|
||||
return [
|
||||
{ prop: "integralUserName", label: '姓名', align: "left", width: "200px" },
|
||||
{ prop: "girdName", label: '所属网格', align: "center", width: "180px" },
|
||||
{ slot: "eventDesc"},
|
||||
{ prop: "integralType", label: '类型', align: "center", dict: "integralType"},
|
||||
{ slot: "changeIntegral", label: '积分变动', align: "center", },
|
||||
{ prop: "nowIntegral", label: '剩余积分', align: "center", },
|
||||
{ prop: "createTime", label: '时间', align: "center", },
|
||||
{ slot: "options" }
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.time = [dayjs().subtract(1,'week').format('YYYY-MM-DD'),dayjs().format('YYYY-MM-DD')]
|
||||
this.$dict.load('epidemicDangerousAreaLevel','integralType','integralRuleEvent','integralRuleEventType').then(() => {
|
||||
this.getStatistics()
|
||||
this.getGridList()
|
||||
this.getRanking()
|
||||
this.search.startTime = this.time?.[0]
|
||||
this.search.endTime = this.time?.[1]
|
||||
this.getTableData()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
// 统计接口
|
||||
getStatistics() {
|
||||
this.instance.post('/app/appintegraluser/allAppletUserIntegral',null, {
|
||||
params: {
|
||||
type: this.type,
|
||||
girdId: this.girdId,
|
||||
startTime: this.startTime,
|
||||
endTime: this.endTime,
|
||||
}
|
||||
}).then(res => {
|
||||
if(res?.data) {
|
||||
this.data = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 人员、网格排行
|
||||
getRanking() {
|
||||
this.instance.post('/app/appintegraluser/userAndGirdIntegralSortByApplet',null,{
|
||||
params: {
|
||||
type: this.type,
|
||||
girdId: this.girdId,
|
||||
startTime: this.startTime,
|
||||
endTime: this.endTime
|
||||
}
|
||||
}).then((res) => {
|
||||
if(res?.data) {
|
||||
this.userSortListX = res.data.userSortList.map(e=> e.userName).reverse()
|
||||
this.userSortListY = res.data.userSortList.map(e=> e.changeIntegral).reverse()
|
||||
this.girdSortListX = res.data.girdSortList.map(e=> e.girdName).reverse()
|
||||
this.girdSortListY = res.data.girdSortList.map(e=> e.changeIntegral).reverse()
|
||||
this.getColEcherts1(this.userSortListX,this.userSortListY)
|
||||
this.getColEcherts2(this.girdSortListX,this.girdSortListY)
|
||||
}
|
||||
})
|
||||
},
|
||||
// 积分明细
|
||||
getTableData() {
|
||||
this.instance.post('/app/appintegraluser/girdIntegralDetailByApplet',null,{
|
||||
params: {
|
||||
...this.search,
|
||||
current: this.current,
|
||||
size: this.size,
|
||||
total: this.total,
|
||||
}
|
||||
}).then(res => {
|
||||
if(res?.data) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
gridChangeOpt(val) {
|
||||
this.girdIdArr = val
|
||||
this.search.girdId = val?.[val.length - 1]
|
||||
this.$refs.cascader2.dropDownVisible = false;
|
||||
this.getTableData()
|
||||
},
|
||||
|
||||
getColEcherts1(xData,yData) {
|
||||
let chartDom1 = document.getElementById('chart1');
|
||||
chartDom1.style.width = (window.innerWidth - 435) / 2 + "px";
|
||||
this.myChart1 = echarts.init(chartDom1);
|
||||
this.myChart1.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '16px',
|
||||
right: '28px',
|
||||
bottom: '14px',
|
||||
top: '16px',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
boundaryGap: [0, 0.01],
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
data: xData,
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
},
|
||||
|
||||
series: [
|
||||
{
|
||||
data: yData,
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: "#5087ec",
|
||||
label: {
|
||||
show: true, //开启显示
|
||||
position: 'right', //在上方显示
|
||||
textStyle: {
|
||||
fontSize: 13,
|
||||
color: '#666'
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
barWidth: 10,
|
||||
barGap: '20%',
|
||||
}
|
||||
]
|
||||
}, true);
|
||||
window.addEventListener("resize", this.onResize)
|
||||
},
|
||||
getColEcherts2(xData,yData) {
|
||||
let chartDom2 = document.getElementById('chart2');
|
||||
chartDom2.style.width = (window.innerWidth - 435) / 2 + "px";
|
||||
this.myChart2 = echarts.init(chartDom2);
|
||||
this.myChart2.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '16px',
|
||||
right: '28px',
|
||||
bottom: '14px',
|
||||
top: '16px',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
boundaryGap: [0, 0.01],
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
data: xData,
|
||||
axisTick: {
|
||||
show: false,
|
||||
},
|
||||
axisLine: {
|
||||
show: false,
|
||||
},
|
||||
triggerEvent: true,
|
||||
//设置文本过长超出隐藏...表示
|
||||
axisLabel:{
|
||||
margin: 8,
|
||||
formatter: function(params){
|
||||
var val=""
|
||||
if(params.length > 8) {
|
||||
val = params.substr(0,8)+'...'
|
||||
return val
|
||||
} else {
|
||||
return params;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
data: yData,
|
||||
type: 'bar',
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: "#5087ec",
|
||||
label: {
|
||||
show: true, //开启显示
|
||||
position: 'right', //在右方显示
|
||||
textStyle: {
|
||||
fontSize: 13,
|
||||
color: '#666'
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
barWidth: 10,
|
||||
barGap: '20%',
|
||||
}
|
||||
]
|
||||
}, true);
|
||||
window.addEventListener("resize", this.onResize2)
|
||||
// this.extension(this.myChart2)
|
||||
},
|
||||
onResize1() {
|
||||
this.myChart1.resize()
|
||||
},
|
||||
onResize2() {
|
||||
this.myChart2.resize()
|
||||
},
|
||||
gridChange(val) {
|
||||
this.girdArr = val
|
||||
this.girdId = val?.[val.length - 1]
|
||||
this.$refs.cascader1.dropDownVisible = false;
|
||||
this.getStatistics()
|
||||
this.getRanking()
|
||||
},
|
||||
// 所有网格
|
||||
getGridList() {
|
||||
this.instance.post(`/app/appgirdinfo/listAll3`).then((res) => {
|
||||
if (res?.code == 0) {
|
||||
this.girdOptions = this.toTree(res.data)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 转树形结构
|
||||
toTree(data) {
|
||||
let result = [];
|
||||
if (!Array.isArray(data)) {
|
||||
return result
|
||||
}
|
||||
let map = {};
|
||||
data.forEach(item => {
|
||||
map[item.id] = item;
|
||||
});
|
||||
data.forEach(item => {
|
||||
let parent = map[item.parentGirdId];
|
||||
if (parent) {
|
||||
(parent.children || (parent.children = [])).push(item);
|
||||
} else {
|
||||
result.push(item);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
},
|
||||
|
||||
timeChange(index) {
|
||||
if(index == 3) {
|
||||
this.dialogDate = true
|
||||
}
|
||||
this.type = index
|
||||
this.getStatistics()
|
||||
this.getRanking()
|
||||
},
|
||||
|
||||
open(id) {
|
||||
this.dialog = true
|
||||
this.getDetail(id)
|
||||
},
|
||||
|
||||
onChange(val) {
|
||||
this.search.startTime = val?.[0]
|
||||
this.search.endTime = val?.[1]
|
||||
this.getTableData()
|
||||
},
|
||||
|
||||
getDetail(id) {
|
||||
this.instance.post(`/app/appintegraldetail/queryDetailById?id=${id}`).then(res=> {
|
||||
if(res?.data) {
|
||||
this.details = res.data
|
||||
if(res.data.enclosure) {
|
||||
let str = res.data.enclosure.split('/')
|
||||
this.fileDownLoad = [{
|
||||
url:res.data.enclosure,
|
||||
name: str?.[str.length - 1]
|
||||
}]
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
selectDete() {
|
||||
if(!this.timeList || !this.timeList.length) {
|
||||
return this.$message.error('请选择自定义时间');
|
||||
}
|
||||
this.startTime = this.timeList?.[0]
|
||||
this.endTime = this.timeList?.[1]
|
||||
this.dialogDate = false
|
||||
this.getStatistics()
|
||||
this.getRanking()
|
||||
},
|
||||
|
||||
},
|
||||
|
||||
filters: {
|
||||
formatTime(num) {
|
||||
if(num > 0) {
|
||||
return '+' + num
|
||||
} else {
|
||||
return num
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.getColEcherts1()
|
||||
this.getColEcherts2()
|
||||
},
|
||||
|
||||
destroyed () {
|
||||
window.removeEventListener('resize', this.onResize1)
|
||||
window.removeEventListener('resize', this.onResize2)
|
||||
},
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AppIntegralStatistics {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding-top: 20px;
|
||||
overflow-y: scroll;
|
||||
.overallStatistics {
|
||||
width: 100%;
|
||||
margin-bottom: 16px;
|
||||
padding: 20px;
|
||||
box-sizing: border-box;
|
||||
background: #FFF;
|
||||
|
||||
.title {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 16px;
|
||||
p {
|
||||
font-size: 16px;
|
||||
font-family: MicrosoftYaHeiSemibold;
|
||||
color: #222222;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.title_right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
span {
|
||||
display: inline-block;
|
||||
width: 70px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #D0D4DC;
|
||||
margin-right: 8px;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.active {
|
||||
color: #2266FF;
|
||||
border: 1px solid #2266FF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card_list {
|
||||
display: flex;
|
||||
.card {
|
||||
flex: 1;
|
||||
height: 96px;
|
||||
background: #F9F9F9;
|
||||
border-radius: 2px;
|
||||
margin-right: 20px;
|
||||
padding: 16px 24px;
|
||||
box-sizing: border-box;
|
||||
h2 {
|
||||
color: #888888;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
p {
|
||||
margin-top: 8px;
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.color1 {
|
||||
color: #2891FF;
|
||||
}
|
||||
.color2 {
|
||||
color: #22AA99;
|
||||
}
|
||||
.color3 {
|
||||
color: #F8B425;
|
||||
}
|
||||
}
|
||||
.card:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
.echertsBox {
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
background: #FFF;
|
||||
display: flex;
|
||||
.left_Box {
|
||||
margin-right: 16px;
|
||||
flex: 1;
|
||||
}
|
||||
.right_Box {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.left_Box,
|
||||
.right_Box {
|
||||
background: #F9F9F9;
|
||||
box-shadow: 0px 4px 6px -2px rgba(15,15,21,0.1500);
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
#chart1,
|
||||
#chart2 {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
p {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// .chartCss {
|
||||
// position: absolute;
|
||||
// color: black;
|
||||
// background:white;
|
||||
// font-family: Aril;
|
||||
// font-size: 12px;
|
||||
// padding: 5px;
|
||||
// display: inline;
|
||||
// }
|
||||
|
||||
:deep( .el-dialog__footer ){
|
||||
text-align: center;
|
||||
}
|
||||
:deep( .el-dialog__header ){
|
||||
border-bottom: 1px solid #DDD;
|
||||
}
|
||||
:deep( .ai-detail ){
|
||||
background: #FFF;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<div class="AppHelp">
|
||||
<keep-alive :include="['List']">
|
||||
<component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Detail from './components/Detail'
|
||||
import List from './components/List'
|
||||
|
||||
export default {
|
||||
name: 'AppIntegratingAudit',
|
||||
label: '积分审核',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
component: 'List',
|
||||
params: {},
|
||||
include: []
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
List,
|
||||
Detail
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange (data) {
|
||||
if (data.type === 'Add') {
|
||||
this.component = 'Add'
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'Detail') {
|
||||
this.component = 'Detail'
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'List') {
|
||||
this.component = 'List'
|
||||
this.params = data.params
|
||||
|
||||
this.$nextTick(() => {
|
||||
if (data.isRefresh) {
|
||||
this.$refs.component.getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.AppHelp {
|
||||
height: 100%;
|
||||
background: #F3F6F9;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,270 @@
|
||||
<template>
|
||||
<ai-detail class="detail">
|
||||
<template slot="title">
|
||||
<ai-title title="积分审核" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||
<template #rightBtn>
|
||||
<el-button size="small" type="primary" @click="isShow = true" v-if="info.status === '0'">审核</el-button>
|
||||
</template>
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-card title="基本信息">
|
||||
<template #content>
|
||||
<ai-wrapper>
|
||||
<ai-info-item label="事件类型" isLine :value="info.applyItemName"></ai-info-item>
|
||||
<ai-info-item label="申请人" :value="info.integralUserName"></ai-info-item>
|
||||
<ai-info-item label="手机号" :value="info.phone"></ai-info-item>
|
||||
<ai-info-item label="所属地区" :value="info.areaName"></ai-info-item>
|
||||
<ai-info-item label="所属网格" :value="info.girdName"></ai-info-item>
|
||||
<ai-info-item label="审核时间" v-if="info.status === '1'" :value="info.auditTime"></ai-info-item>
|
||||
<ai-info-item label="申请时间" v-if="info.status === '0'" :value="info.createTime"></ai-info-item>
|
||||
<ai-info-item label="状态">
|
||||
<span>{{ dict.getLabel('appIntegralApplyEventStatus', info.status) }}</span>
|
||||
<span v-if="info.status === '1'" style="margin-left: 10px; color: green">积分+{{ info.applyIntegral }}</span>
|
||||
</ai-info-item>
|
||||
<ai-info-item label="审批意见" v-if="info.status === '2'" isLine>
|
||||
<span style="color: red;">{{ info.auditDesc }}</span>
|
||||
</ai-info-item>
|
||||
</ai-wrapper>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-card title="事件信息">
|
||||
<template #right>
|
||||
<el-button size="small" type="primary" @click="showEvent" v-if="info.status === '0'">编辑</el-button>
|
||||
</template>
|
||||
<template #content>
|
||||
<ai-wrapper>
|
||||
<ai-info-item label="积分值" isLine :value="info.applyIntegral"></ai-info-item>
|
||||
<ai-info-item label="事件描述" isLine :value="info.content"></ai-info-item>
|
||||
<ai-info-item label="图片" isLine v-if="info.images && info.images.length">
|
||||
<div class="files">
|
||||
<!-- <div class="file-item" v-for="(item, index) in info.images" :key="index" v-viewer="{movable: true}">
|
||||
<img :src="item.url">
|
||||
</div> -->
|
||||
<ai-uploader
|
||||
:instance="instance"
|
||||
fileType="img"
|
||||
acceptType=".jpg,.png,.jpeg"
|
||||
v-model="info.images"
|
||||
:limit="9" :disabled="true">
|
||||
</ai-uploader>
|
||||
</div>
|
||||
</ai-info-item>
|
||||
<ai-info-item label="视频" isLine v-if="info.videos && info.videos.length">
|
||||
<div class="files">
|
||||
<div class="file-item" v-for="(item, index) in info.videos" :key="index">
|
||||
<video controls :src="item.url"></video>
|
||||
</div>
|
||||
</div>
|
||||
</ai-info-item>
|
||||
</ai-wrapper>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-dialog
|
||||
:visible.sync="isShow"
|
||||
@onConfirm="onConfirm"
|
||||
@close="onClose"
|
||||
width="890px"
|
||||
title="审核">
|
||||
<el-form class="ai-form" :model="form" label-width="120px" ref="form">
|
||||
<el-form-item label="是否通过" prop="auditStatus" style="width: 100%;" :rules="[{required: true, message: '请选择是否通过', trigger: 'change'}]">
|
||||
<el-radio-group v-model="form.auditStatus">
|
||||
<el-radio label="0">否</el-radio>
|
||||
<el-radio label="1">是</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item prop="auditDesc" v-if="form.auditStatus === '0'" label="审批意见" style="width: 100%" :rules="[{required: true, message: '请输入审批意见', trigger: 'blur'}]">
|
||||
<el-input size="small" type="textarea" :rows="5" v-model="form.auditDesc" clearable placeholder="请输入审批意见"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ai-dialog>
|
||||
|
||||
<ai-dialog
|
||||
:visible.sync="isShowEvent"
|
||||
@onConfirm="onEventConfirm"
|
||||
@close="onClose"
|
||||
width="890px"
|
||||
title="编辑">
|
||||
<el-form class="ai-form" :model="eventForm" label-width="120px" ref="eventForm">
|
||||
<el-form-item label="积分值" prop="applyIntegral" :rules="[{required: true, message: '请输入积分值', trigger: 'change'}]">
|
||||
<el-input-number style="width: 200px;" size="small" :precision="2" type="input" v-model="eventForm.applyIntegral" clearable placeholder="请输入积分值" :min="0"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item prop="content" label="事件描述" style="width: 100%" :rules="[{required: true, message: '请输入事件描述', trigger: 'blur'}]">
|
||||
<el-input size="small" type="textarea" :rows="5" :maxlength="300" show-word-limit v-model="eventForm.content" clearable placeholder="请输入事件描述"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item style="width: 100%" label="图片">
|
||||
<ai-uploader
|
||||
:instance="instance"
|
||||
fileType="img"
|
||||
acceptType=".jpg,.png,.jpeg"
|
||||
v-model="eventForm.images"
|
||||
:limit="9">
|
||||
</ai-uploader>
|
||||
</el-form-item>
|
||||
<el-form-item style="width: 100%" label="视频">
|
||||
<ai-uploader
|
||||
:instance="instance"
|
||||
fileType="file"
|
||||
acceptType=".mp4,.MOV"
|
||||
v-model="eventForm.videos"
|
||||
:limit="9">
|
||||
</ai-uploader>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ai-dialog>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Detail',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
info: {},
|
||||
form: {
|
||||
auditDesc: '',
|
||||
auditStatus: ''
|
||||
},
|
||||
eventForm: {
|
||||
files: null,
|
||||
images: [],
|
||||
videos: [],
|
||||
content: '',
|
||||
applyIntegral: ''
|
||||
},
|
||||
isShowEvent: false,
|
||||
isShow: false
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.getInfo()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getInfo () {
|
||||
this.instance.post(`/app/appintegraluserapply/queryDetailById?id=${this.params.id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
if (res.data) {
|
||||
this.info = {
|
||||
...res.data,
|
||||
files: res.data.files.map(v => {
|
||||
return {
|
||||
...v,
|
||||
postfix: v.postfix.toLowerCase()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (res.data.status === '0') {
|
||||
this.eventForm.files = res.data.files
|
||||
this.eventForm.content = res.data.content
|
||||
this.eventForm.applyIntegral = res.data.applyIntegral
|
||||
}
|
||||
this.info.images = res.data.files.filter(e => (['jpeg', 'jpg', 'png'].includes(e.postfix.split('.')[1])))
|
||||
this.info.videos = res.data.files.filter(e => (['mp4', 'MOV'].includes(e.postfix.split('.')[1])))
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
showEvent () {
|
||||
this.eventForm.files = null
|
||||
this.eventForm.content = this.info.content
|
||||
this.eventForm.applyIntegral = this.info.applyIntegral
|
||||
this.eventForm.images = this.info.images
|
||||
this.eventForm.videos = this.info.videos
|
||||
this.isShowEvent = true
|
||||
},
|
||||
|
||||
onClose () {
|
||||
this.form.auditDesc = ''
|
||||
this.form.auditStatus = ''
|
||||
},
|
||||
|
||||
onEventConfirm () {
|
||||
if ((this.eventForm.images.length + this.eventForm.videos.length) > 9) {
|
||||
return this.$message.error('图片和视频不得超过9个')
|
||||
} else {
|
||||
this.eventForm.files = [...this.eventForm.images,...this.eventForm.videos]
|
||||
}
|
||||
this.$refs.eventForm.validate((valid) => {
|
||||
if (valid) {
|
||||
this.instance.post(`/app/appintegraluserapply/updateByGirdMember`, {
|
||||
...this.eventForm,
|
||||
id: this.params.id,
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('编辑成功!')
|
||||
this.isShowEvent = false
|
||||
this.getInfo()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onConfirm () {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.instance.post(`/app/appintegraluserapply/auditById`, {
|
||||
...this.form,
|
||||
id: this.params.id
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('审核成功!')
|
||||
this.isShow = false
|
||||
this.getInfo()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancel () {
|
||||
this.$emit('change', {
|
||||
type: 'List',
|
||||
isRefresh: true
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.detail {
|
||||
.files {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
.file-item {
|
||||
width: 118px;
|
||||
height: 118px;
|
||||
margin: 0 20px 20px 0;
|
||||
|
||||
img, video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
img {
|
||||
cursor: pointer;
|
||||
transition: all ease 0.3s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,293 @@
|
||||
<template>
|
||||
<ai-list class="AppIntegratingAudit">
|
||||
<template slot="title">
|
||||
<ai-title title="积分审核" isShowBottomBorder v-model="search.areaId" isShowArea :hideLevel="hideLevel - 1" @change="changeArea">
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-search-bar class="search-bar">
|
||||
<template #left>
|
||||
<ai-select
|
||||
v-model="search.applyItemId"
|
||||
@change="(search.current = 1), getList()"
|
||||
placeholder="请选择事件/类型"
|
||||
:selectList="dictList">
|
||||
</ai-select>
|
||||
<el-date-picker
|
||||
v-model="search.createTimeStart"
|
||||
type="date"
|
||||
size="small"
|
||||
value-format="yyyy-MM-dd"
|
||||
placeholder="选择开始日期"
|
||||
@change="search.current = 1, getList()">
|
||||
</el-date-picker>
|
||||
<el-date-picker
|
||||
v-model="search.createTimeEnd"
|
||||
type="date"
|
||||
size="small"
|
||||
value-format="yyyy-MM-dd"
|
||||
placeholder="选择结束日期"
|
||||
@change="search.current = 1, getList()">
|
||||
</el-date-picker>
|
||||
<ai-picker
|
||||
:instance="instance"
|
||||
:multiple="false"
|
||||
dialogTitle="选择网格"
|
||||
:ops="{ label: 'girdName' }"
|
||||
pageTitle="网格"
|
||||
action="/app/appgirdinfo/girdList"
|
||||
v-model="userList"
|
||||
@pick="onGridChange">
|
||||
<div class="userSelcet">
|
||||
<span style="color: #606266;" v-if="search.girdId">{{ search.girdName }}</span>
|
||||
<span v-else>请选择网格</span>
|
||||
<i class="el-icon-arrow-up" v-if="!search.girdId"></i>
|
||||
<i class="el-icon-circle-close" v-if="search.girdId" @click.stop="userList = [], search.girdId = '', search.girdName = '', search.current = 1, getList()"></i>
|
||||
</div>
|
||||
</ai-picker>
|
||||
<ai-select
|
||||
v-model="search.status"
|
||||
@change="(search.current = 1), getList()"
|
||||
placeholder="请选择状态"
|
||||
:selectList="$dict.getDict('appIntegralApplyEventStatus')">
|
||||
</ai-select>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-input
|
||||
v-model="search.createUserName"
|
||||
class="search-input"
|
||||
size="small"
|
||||
v-throttle="() => {search.current = 1, getList()}"
|
||||
placeholder="请输入申请人、审批人"
|
||||
clearable
|
||||
@clear="search.current = 1, search.createUserName = '', getList()"
|
||||
suffix-icon="iconfont iconSearch">
|
||||
</el-input>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="total"
|
||||
style="margin-top: 6px;"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@getList="getList">
|
||||
<el-table-column slot="options" width="180px" fixed="right" label="操作" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click="toDetail(row.id)">详情</el-button>
|
||||
<!-- <el-button type="text" @click="remove(row.id)">删除</el-button> -->
|
||||
<el-button type="text" @click="push(row.id)" v-if="row.status === '1' && row.pushStatus === '0'">推送精选</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { MessageBox } from 'element-ui'
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
name: 'List',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
search: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
areaId: '',
|
||||
applyItemId: '',
|
||||
girdId: '',
|
||||
createTimeStart: '',
|
||||
createTimeEnd: '',
|
||||
girdName: ''
|
||||
},
|
||||
userList: [],
|
||||
dictList: [],
|
||||
total: 10,
|
||||
colConfigs: [
|
||||
{ prop: 'applyItemName', label: '事件类型', align: 'left' },
|
||||
{ prop: 'integralUserName', label: '申请人', align: 'center' },
|
||||
{ prop: 'areaName', label: '所属地区', align: 'center' },
|
||||
{ prop: 'girdName', label: '所属网格', align: 'center' },
|
||||
{ prop: 'createTime', label: '申请时间', align: 'center' },
|
||||
{ prop: 'status', label: '状态', align: 'center', format: v => this.dict.getLabel('appIntegralApplyEventStatus', v) },
|
||||
{ prop: 'auditUserName', label: '审批人', align: 'center' },
|
||||
{ prop: 'pushStatus', label: '推送精选', align: 'center', format: v => this.dict.getLabel('appIntegralApplyEventPushStatus', v) }
|
||||
],
|
||||
tableData: [],
|
||||
dateList: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
|
||||
hideLevel () {
|
||||
return this.user.info.areaList?.length || 0
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.search.areaId = this.user.info.areaId
|
||||
this.$dict.load('appIntegralApplyEventStatus', 'appIntegralApplyEventPushStatus').then(() => {
|
||||
this.getList()
|
||||
this.getRulesList()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
getRulesList () {
|
||||
this.instance.post(`/app/appintegralrule/listByAppletFD?current=1&size=3000`).then((res) => {
|
||||
if (res.code === 0) {
|
||||
this.dictList = res.data.records.map(v => {
|
||||
return {
|
||||
dictName: v.ruleName,
|
||||
dictValue: v.id
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onGridChange (e) {
|
||||
if (e.length) {
|
||||
this.search.girdId = e[0].id
|
||||
this.search.girdName = e[0].girdName
|
||||
this.search.current = 1
|
||||
this.getList()
|
||||
}
|
||||
},
|
||||
|
||||
getList () {
|
||||
this.instance.post(`/app/appintegraluserapply/list`, null, {
|
||||
params: {
|
||||
...this.search
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
changeArea () {
|
||||
this.search.current = 1
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
push (id) {
|
||||
MessageBox.confirm('是否将精选内容对全体居民公开,选则否将只对本村/社区居民公开。', '推送精选', {
|
||||
distinguishCancelAndClose: true,
|
||||
confirmButtonText: '是',
|
||||
type: 'warning',
|
||||
closeOnClickModal: false,
|
||||
center: true,
|
||||
customClass: 'AiConfirm',
|
||||
cancelButtonText: '否'
|
||||
}).then(() => {
|
||||
this.instance.post(`/app/appintegraluserapply/pushById?id=${id}&status=1`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.getList()
|
||||
this.$message.success('推送成功')
|
||||
}
|
||||
})
|
||||
}).catch((e) => {
|
||||
e === 'cancel' && this.instance.post(`/app/appintegraluserapply/pushById?id=${id}&status=0`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.getList()
|
||||
this.$message.success('推送成功')
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
remove (id) {
|
||||
this.$confirm('确定删除该帖子?').then((e) => {
|
||||
this.instance.post(`/app/appintegraluserapply/delete?id=${id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('删除成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
toDetail (id) {
|
||||
this.$emit('change', {
|
||||
type: 'Detail',
|
||||
params: {
|
||||
id: id || ''
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toAdd(id) {
|
||||
this.$emit('change', {
|
||||
type: 'Add',
|
||||
params: {
|
||||
id: id || ''
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.AppIntegratingAudit {
|
||||
.userSelcet {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 215px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #d0d4dc;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
|
||||
&:hover {
|
||||
border-color: $placeholderColor;
|
||||
}
|
||||
|
||||
i {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
height: 100%;
|
||||
line-height: 32px;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
color: #d0d4dc;
|
||||
transform: rotateZ(180deg);
|
||||
}
|
||||
|
||||
.el-icon-circle-close:hover {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
span {
|
||||
flex: 1;
|
||||
padding: 0 15px;
|
||||
font-size: 12px;
|
||||
color: $placeholderColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div class="AppActivitiesManagement">
|
||||
<keep-alive :include="['List']">
|
||||
<component ref="component" :is="component" :permissions="permissions " @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import List from './components/List'
|
||||
|
||||
export default {
|
||||
name: 'AppIntegratingDjust',
|
||||
label: '积分调整',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
component: 'List',
|
||||
params: {},
|
||||
include: []
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
List
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange (data) {
|
||||
if (data.type === 'Detail') {
|
||||
this.component = 'Detail'
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'List') {
|
||||
this.component = 'List'
|
||||
this.params = data.params
|
||||
|
||||
this.$nextTick(() => {
|
||||
if (data.isRefresh) {
|
||||
this.$refs.component.getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.AppActivitiesManagement {
|
||||
height: 100%;
|
||||
background: #F3F6F9;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,357 @@
|
||||
<template>
|
||||
<ai-list class="gridScoreManage">
|
||||
<ai-title slot="title" title="积分调整" isShowBottomBorder></ai-title>
|
||||
<template #content>
|
||||
<ai-search-bar>
|
||||
<template #left>
|
||||
<el-button type="primary" size="small" icon="iconfont iconAdd" @click="changeIntegral('',0)"> 批量调整积分</el-button>
|
||||
<el-cascader ref="cascader1" clearable v-model="girdIdList" :options="girdOptions" placeholder="所属网格" size="small"
|
||||
:props="defaultProps" :show-all-levels="false" @change="gridChange"></el-cascader>
|
||||
</template>
|
||||
<template #right>
|
||||
<ai-import :instance="instance" :dict="dict" type="appintegraluser" name="积分管理"
|
||||
@success="getTableData()">
|
||||
<el-button icon="iconfont iconImport">导入</el-button>
|
||||
</ai-import>
|
||||
<ai-download :instance="instance" url="/app/appintegraluser/girdIntegralExport" :params="search" fileName="积分调整"
|
||||
:disabled="tableData.length == 0">
|
||||
</ai-download>
|
||||
<el-input size="small" placeholder="姓名" v-model="search.userName" clearable
|
||||
@clear="current = 1, search.userName = '', getTableData()" suffix-icon="iconfont iconSearch"
|
||||
v-throttle="() => {(current = 1), getTableData();}"/>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
:tableData="tableData"
|
||||
:total="total"
|
||||
:current.sync="current"
|
||||
:size.sync="size"
|
||||
@getList="getTableData()"
|
||||
:col-configs="colConfigs"
|
||||
:dict="dict"
|
||||
@sort-change="changeTableSort">
|
||||
<el-table-column slot="options" label="操作" width="120" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click="changeIntegral(row,1)">调整积分</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
<ai-dialog
|
||||
title="调整积分"
|
||||
:visible.sync="dialog"
|
||||
:destroyOnClose="true"
|
||||
width="720px"
|
||||
@onConfirm="onConfirm"
|
||||
@closed="form={},chooseUserList=[]">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="选择人员" prop="ids">
|
||||
<ai-person-select :instance="instance" :customClicker="true" :chooseUserList="chooseUserList"
|
||||
url="/app/appgirdmemberinfo/list" headerTitle="网格员列表"
|
||||
:isMultiple="true" dialogTitle="选择" @selectPerson="selectPerson" class="aipersonselect">
|
||||
<template name="option" v-slot:option="{ item }">
|
||||
<span class="iconfont iconProlife">{{ item.name }}</span>
|
||||
<ai-id mode="show" :show-eyes="false" :value="item.idNumber"/>
|
||||
</template>
|
||||
</ai-person-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="调整说明" prop="eventDesc">
|
||||
<el-input v-model.trim="form.eventDesc" placeholder="请输入..." type="textarea" :rows="4" show-word-limit
|
||||
maxlength="100"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="上传凭证">
|
||||
<ai-uploader :instance="instance" fileType="file" v-model="form.file" :limit="1"></ai-uploader>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="integralCalcType">
|
||||
<ai-select v-model="form.integralCalcType" :selectList="dict.getDict('integralCalcType')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="积分" prop="integral">
|
||||
<el-input v-model.trim="form.integral" placeholder="请输入正数" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ai-dialog>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from "vuex";
|
||||
export default {
|
||||
name: "List",
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
search: {
|
||||
userName: '',
|
||||
girdId: '',
|
||||
current: 1,
|
||||
size: 10,
|
||||
sortFiled: '',
|
||||
sortRule: '',
|
||||
},
|
||||
girdIdList: [],
|
||||
tableData: [],
|
||||
size: 10,
|
||||
total: 0,
|
||||
current: 1,
|
||||
girdList: [],
|
||||
form: {
|
||||
ids: [],
|
||||
eventDesc: "",
|
||||
enclosure: "", // 附件
|
||||
integralCalcType: "",
|
||||
integral: '',
|
||||
file: [],
|
||||
},
|
||||
personList: [],
|
||||
dialog: false,
|
||||
girdOptions: [],
|
||||
defaultProps: {
|
||||
label: 'girdName',
|
||||
value: 'id',
|
||||
checkStrictly: true,
|
||||
},
|
||||
chooseUserList: [],
|
||||
flag: false,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$dict.load('integralCalcType')
|
||||
this.getTableData()
|
||||
this.getGridList()
|
||||
},
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
colConfigs() {
|
||||
return [
|
||||
{ prop: "integralUserName", label: '姓名', align: "left", },
|
||||
{ prop: "areaName", label: '所属地区', align: "center" },
|
||||
{ prop: "auditDesc", label: '调整说明', align: "center" },
|
||||
{ prop: "applyItemName", label: '类型', align: "center" },
|
||||
{ prop: "applyIntegral", label: '积分', align: "center" },
|
||||
{ prop: "auditTime", label: '操作时间', align: "center", sortable: "custom" },
|
||||
{ prop: "auditUserName", label: '操作人', align: "center", sortable: "custom" },
|
||||
{ slot: "options" },
|
||||
]
|
||||
},
|
||||
rules() {
|
||||
return {
|
||||
ids: [{required: true, message: '请选择人员', trigger: 'blur'}],
|
||||
eventDesc: [{required: true, message: '请输入调整说明', trigger: 'blur'}],
|
||||
integralCalcType: [{required: true, message: '请选择类型', trigger: 'change'}],
|
||||
integral: [{required: true, message: '请输入积分', trigger: 'blur' },
|
||||
{pattern: /^([1-9]\d*|0)(\.\d{1,2})?$/, message: '请输入正数且最多只能保留两位小数'}],
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
getTableData() {
|
||||
this.instance.post(`/app/appintegraluserapply/list`,null,{
|
||||
params: {
|
||||
...this.search,
|
||||
current: this.current,
|
||||
size: this.size,
|
||||
total: this.total
|
||||
}
|
||||
}).then(res => {
|
||||
if(res?.data) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
selectPerson(val) {
|
||||
if (val) {
|
||||
this.personList = val
|
||||
this.form.ids = [...this.personList.map(e => e.id)]
|
||||
} else {
|
||||
this.form.ids = this.chooseUserList.map(e => e.id)
|
||||
}
|
||||
},
|
||||
changeIntegral(row,type) {
|
||||
if(type==0) {
|
||||
this.dialog = true
|
||||
} else if(type ==1) {
|
||||
this.chooseUserList = [{
|
||||
id: row.userId,
|
||||
name: row.userName
|
||||
}]
|
||||
this.form.ids = this.chooseUserList.map(e => e.id)
|
||||
this.dialog = true
|
||||
}
|
||||
},
|
||||
getGridList() {
|
||||
this.instance.post(`/app/appgirdinfo/listAll3`).then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.girdOptions = this.toTree(res.data)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
// 转树形结构
|
||||
toTree(data) {
|
||||
let result = [];
|
||||
if (!Array.isArray(data)) {
|
||||
return result
|
||||
}
|
||||
let map = {};
|
||||
data.forEach(item => {
|
||||
map[item.id] = item;
|
||||
});
|
||||
data.forEach(item => {
|
||||
let parent = map[item.parentGirdId];
|
||||
if (parent) {
|
||||
(parent.children || (parent.children = [])).push(item);
|
||||
} else {
|
||||
result.push(item);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
},
|
||||
|
||||
gridChange(val) {
|
||||
this.girdIdList = val
|
||||
this.search.girdId = val?.[val.length - 1]
|
||||
this.$refs.cascader1.dropDownVisible = false;
|
||||
this.getTableData()
|
||||
},
|
||||
|
||||
changeTableSort(col) {
|
||||
if(col.prop === 'integral') { // 剩余积分
|
||||
this.search.sortFiled = 0
|
||||
if(col.order === 'ascending') {
|
||||
this.search.sortRule = true
|
||||
} else if(col.order === 'descending') {
|
||||
this.search.sortRule = false
|
||||
} else if(col.order === null) {
|
||||
this.search.sortRule = ''
|
||||
}
|
||||
} else if(col.prop === 'totalIntegral') { // 累计积分
|
||||
this.search.sortFiled = 1
|
||||
if(col.order === 'ascending') {
|
||||
this.search.sortRule = true
|
||||
} else if(col.order === 'descending') {
|
||||
this.search.sortRule = false
|
||||
} else if(col.order === null) {
|
||||
this.search.sortRule = ''
|
||||
}
|
||||
} else if(col.prop === 'usedIntegral') { // 已用积分
|
||||
this.search.sortFiled = 2
|
||||
if(col.order === 'ascending') {
|
||||
this.search.sortRule = true
|
||||
} else if(col.order === 'descending') {
|
||||
this.search.sortRule = false
|
||||
} else if(col.order === null) {
|
||||
this.search.sortRule = ''
|
||||
}
|
||||
}
|
||||
this.getTableData()
|
||||
},
|
||||
|
||||
onConfirm() {
|
||||
if(this.flag) return
|
||||
|
||||
if(this.form.file?.length) {
|
||||
this.form.enclosure = this.form.file[0].url
|
||||
}
|
||||
this.$refs.form.validate((valid)=> {
|
||||
if(valid) {
|
||||
this.flag = true
|
||||
this.instance.post(`/app/appintegraluser/changeIntegral`,{
|
||||
ids: this.form.ids,
|
||||
eventDesc: this.form.eventDesc,
|
||||
enclosure: this.form.enclosure, // 附件
|
||||
integralCalcType: this.form.integralCalcType,
|
||||
integral: this.form.integral,
|
||||
}).then(res => {
|
||||
if(res?.code == 0) {
|
||||
this.$message.success('调整积分成功')
|
||||
setTimeout(() =>{
|
||||
this.dialog = false
|
||||
this.getTableData()
|
||||
this.flag = false
|
||||
}, 600)
|
||||
} else {
|
||||
this.flag = false
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
toDetail(id) {
|
||||
this.$emit('change', {
|
||||
type: 'gridScoreDetail',
|
||||
params: {
|
||||
id: id
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.gridScoreManage {
|
||||
|
||||
.userlist {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.userlist, .user {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.user {
|
||||
position: relative;
|
||||
width: 70px;
|
||||
text-align: center;
|
||||
|
||||
.remove-icon {
|
||||
position: absolute;
|
||||
right: 7px;
|
||||
top: -4px;
|
||||
line-height: 1;
|
||||
padding: 6px 0;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
color: crimson;
|
||||
}
|
||||
}
|
||||
|
||||
img, h2 {
|
||||
display: block;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
margin: 0 auto 4px;
|
||||
font-size: 14px;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
h2 {
|
||||
background-color: $primaryColor;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<ai-list v-if="!isShowDetail">
|
||||
<template slot="title">
|
||||
<ai-title title="订单管理" :isShowBottomBorder="false" v-model="areaId" :isShowArea="currIndex != '1'" :hideLevel="hideLevel - 1" @change="onAreaChange">
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="tabs">
|
||||
<el-tabs v-model="currIndex">
|
||||
<el-tab-pane v-for="(tab,i) in tabs" :key="i" :label="tab.label">
|
||||
<component :areaId="areaId" :ref="String(i)" v-if="currIndex == i" :is="tab.comp" @change="onChange" lazy :instance="instance" :dict="dict" :permissions="permissions"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
</ai-list>
|
||||
<ResidentDetail v-else-if="componentName === 'ResidentDetail'" :areaId="areaId" :params="params" :instance="instance" :dict="dict" @change="onChange"></ResidentDetail>
|
||||
<GirdDetail v-else-if="componentName === 'GirdDetail'" :areaId="areaId" :params="params" :instance="instance" :dict="dict" @change="onChange"></GirdDetail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ResidentDetail from './components/ResidentDetail'
|
||||
import GirdDetail from './components/GirdDetail'
|
||||
import GirdList from './components/GirdList'
|
||||
import ResidentList from './components/ResidentList'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'AppIntegratingOrder',
|
||||
label: '订单管理',
|
||||
|
||||
components: {
|
||||
ResidentList,
|
||||
GirdList,
|
||||
ResidentDetail,
|
||||
GirdDetail
|
||||
},
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
|
||||
hideLevel () {
|
||||
return this.user.info.areaList?.length || 0
|
||||
},
|
||||
|
||||
tabs () {
|
||||
const tabList = [
|
||||
{label: '居民积分订单', name: 'ResidentList', comp: ResidentList, permission: ''},
|
||||
{label: '网格积分订单', name: 'GirdList', comp: GirdList, permission: ''}
|
||||
].filter(item => {
|
||||
return true
|
||||
})
|
||||
|
||||
return tabList
|
||||
}
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
activeName: 'GoodsList',
|
||||
currIndex: '0',
|
||||
componentName: '',
|
||||
params: {},
|
||||
areaName: '',
|
||||
areaId: '',
|
||||
isShowDetail: false
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.areaId = this.user.info.areaId
|
||||
},
|
||||
|
||||
methods: {
|
||||
onAreaChange () {
|
||||
if (this.currIndex != '1') {
|
||||
this.$nextTick(() => {
|
||||
this.$refs[this.currIndex][0].getList()
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onChange (data) {
|
||||
if (data.type === 'GirdList') {
|
||||
this.componentName = 'GirdList'
|
||||
this.isShowDetail = false
|
||||
this.params = data.params
|
||||
}
|
||||
if (data.type === 'ResidentList') {
|
||||
this.componentName = 'ResidentList'
|
||||
this.isShowDetail = false
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'GirdDetail') {
|
||||
this.componentName = 'GirdDetail'
|
||||
this.isShowDetail = true
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'ResidentDetail') {
|
||||
this.componentName = 'ResidentDetail'
|
||||
this.isShowDetail = true
|
||||
this.params = data.params
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,172 @@
|
||||
<template>
|
||||
<ai-detail class="AppDynamicDetail">
|
||||
<template slot="title">
|
||||
<ai-title title="详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-card title="基本信息">
|
||||
<template #right>
|
||||
<el-button type="primary" v-if="info.status === '0'" @click="isShow = true">订单核销</el-button>
|
||||
<el-button type="danger" v-if="info.status === '0' || info.status === '1'" @click="cancelOrder">取消订单</el-button>
|
||||
</template>
|
||||
<template #content>
|
||||
<ai-wrapper
|
||||
label-width="120px">
|
||||
<ai-info-item label="订单编号" :value="info.serialNumber"></ai-info-item>
|
||||
<ai-info-item label="订单状态" :value="dict.getLabel('integralSGOStatus', info.status)"></ai-info-item>
|
||||
<ai-info-item label="兑换人" :value="info.integralUserName"></ai-info-item>
|
||||
<ai-info-item label="创建时间" :value="info.createTime"></ai-info-item>
|
||||
<ai-info-item label="备注" :value="info.remarks" isLine></ai-info-item>
|
||||
</ai-wrapper>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-card title="操作信息" v-if="info.status === '1'">
|
||||
<template #content>
|
||||
<ai-wrapper
|
||||
label-width="120px">
|
||||
<ai-info-item label="核销人" :value="info.examineUserName"></ai-info-item>
|
||||
<ai-info-item label="时间" :value="info.examineTime"></ai-info-item>
|
||||
</ai-wrapper>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-card title="商品信息">
|
||||
<template #content>
|
||||
<ai-table
|
||||
:isShowPagination="false"
|
||||
:tableData="[info]"
|
||||
:col-configs="colConfigs"
|
||||
@getList="() => {}">
|
||||
<el-table-column
|
||||
label="商品"
|
||||
slot="goods"
|
||||
align="left"
|
||||
width="250">
|
||||
<template v-slot="{ row }">
|
||||
<div class="goods">
|
||||
<ai-uploader
|
||||
:disabled="true"
|
||||
:instance="instance"
|
||||
:value="[{url: row.goodsPicUrl}]"
|
||||
:limit="1">
|
||||
</ai-uploader>
|
||||
<p>{{ row.goodsTitle }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-dialog
|
||||
title="订单核销"
|
||||
:visible.sync="isShow"
|
||||
:destroyOnClose="true"
|
||||
width="650px"
|
||||
@onConfirm="onConfirm"
|
||||
@close="form.verificationCode = '', id = ''">
|
||||
<el-form style="height: 200px" class="ai-form" ref="form" :model="form" label-width="120px">
|
||||
<el-form-item label="核销码" style="width: 100%" prop="verificationCode" :rules="[{required: true, message: '请输入核销码', trigger: 'blur'}]">
|
||||
<el-input v-model="form.verificationCode" placeholder="请输入核销码" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ai-dialog>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'GirdDetail',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
info: {},
|
||||
isShow: false,
|
||||
id: '',
|
||||
form: {
|
||||
verificationCode: ''
|
||||
},
|
||||
colConfigs: [
|
||||
{ prop: 'goodsSerialNumber', label: '商品ID', align: 'left' },
|
||||
{ slot: 'goods' },
|
||||
{ prop: 'goodsType', label: '商品类型', align: 'center', format: v => this.dict.getLabel('integralSGType', v) },
|
||||
{ prop: 'goodsIntegralPrice', label: '兑换所需积分', align: 'center' },
|
||||
{ prop: 'payMoney', label: '兑换后补差价金额', align: 'center' },
|
||||
{ prop: 'quantity', label: '数量', align: 'center' },
|
||||
{ prop: 'usedIntegral', label: '消耗积分', align: 'center' }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
if (this.params && this.params.id) {
|
||||
this.id = this.params.id
|
||||
this.getInfo(this.params.id)
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getInfo (id) {
|
||||
this.instance.post(`/app/appintegralsupermarketorder/queryDetailById?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.info = {
|
||||
...res.data
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancelOrder () {
|
||||
this.$confirm('确定取消该订单吗?').then(() => {
|
||||
this.instance.post(`/app/appintegralsupermarketorder/cancel?id=${this.params.id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('取消成功!')
|
||||
this.getInfo(this.params.id)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
onConfirm () {
|
||||
this.$refs.form.validate((valid)=> {
|
||||
if(valid) {
|
||||
this.instance.post(`/app/appintegralsupermarketorder/examine`, null, {
|
||||
params: {
|
||||
...this.form,
|
||||
id: this.params.id
|
||||
}
|
||||
}).then(res => {
|
||||
if(res.code == 0) {
|
||||
this.isShow = false
|
||||
this.getInfo(this.params.id)
|
||||
this.$message.success('核销成功')
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancel (isRefresh) {
|
||||
this.$emit('change', {
|
||||
type: 'GirdList',
|
||||
isRefresh: !!isRefresh
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.AppDynamicDetail {
|
||||
.goods {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<ai-list isTabs class="GoodsList">
|
||||
<template slot="content">
|
||||
<ai-search-bar>
|
||||
<template slot="left">
|
||||
<ai-select
|
||||
v-model="search.goodsType"
|
||||
@change="(search.current = 1), getList()"
|
||||
placeholder="请选择商品类型"
|
||||
:selectList="dict.getDict('integralSGType')">
|
||||
</ai-select>
|
||||
<ai-select
|
||||
v-model="search.status"
|
||||
@change="(search.current = 1), getList()"
|
||||
placeholder="请选择订单状态"
|
||||
:selectList="dict.getDict('integralSGOStatus')">
|
||||
</ai-select>
|
||||
<el-date-picker
|
||||
v-model="search.startTime"
|
||||
type="date"
|
||||
size="small"
|
||||
value-format="yyyy-MM-dd"
|
||||
placeholder="选择订单开始日期"
|
||||
@change="search.current = 1, getList()">
|
||||
</el-date-picker>
|
||||
<el-date-picker
|
||||
v-model="search.endTime"
|
||||
type="date"
|
||||
size="small"
|
||||
value-format="yyyy-MM-dd"
|
||||
placeholder="选择订单结束日期"
|
||||
@change="search.current = 1, getList()">
|
||||
</el-date-picker>
|
||||
<ai-download
|
||||
v-if="permissions('app_appintegralsupermarketorder_export')"
|
||||
:instance="instance"
|
||||
url="/app/appintegralsupermarketorder/export"
|
||||
:params="search"
|
||||
fileName="订单列表"
|
||||
:disabled="tableData.length == 0">
|
||||
</ai-download>
|
||||
</template>
|
||||
<template slot="right">
|
||||
<el-input
|
||||
v-model="search.goodsTitle"
|
||||
class="search-input"
|
||||
size="small"
|
||||
v-throttle="() => {search.current = 1, getList()}"
|
||||
placeholder="请输入商品名称、兑换人"
|
||||
clearable
|
||||
@clear="search.current = 1, search.goodsTitle = '', getList()"
|
||||
suffix-icon="iconfont iconSearch">
|
||||
</el-input>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
style="margin-top: 8px;"
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="total"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@getList="getList">
|
||||
<el-table-column
|
||||
label="商品"
|
||||
slot="goods"
|
||||
align="left"
|
||||
width="350">
|
||||
<template v-slot="{ row }">
|
||||
<div class="goods">
|
||||
<ai-uploader
|
||||
:disabled="true"
|
||||
:instance="instance"
|
||||
:value="[{url: row.goodsPicUrl}]"
|
||||
:limit="1">
|
||||
</ai-uploader>
|
||||
<p>{{ row.goodsTitle }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" slot="options" align="center" width="210" fixed="right">
|
||||
<template v-slot="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" title="取消订单" v-if="row.status === '0' || row.status === '1'" @click="cancel(row.id)">取消订单</el-button>
|
||||
<el-button type="text" title="订单核销" v-if="row.status === '0'" @click="id = row.id, isShow = true">订单核销</el-button>
|
||||
<el-button type="text" title="详情" @click="toDetail(row.id)">详情</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
<ai-dialog
|
||||
title="订单核销"
|
||||
:visible.sync="isShow"
|
||||
:destroyOnClose="true"
|
||||
width="650px"
|
||||
@onConfirm="onConfirm"
|
||||
@close="form.verificationCode = '', id = ''">
|
||||
<el-form style="height: 200px" class="ai-form" ref="form" :model="form" label-width="120px">
|
||||
<el-form-item label="核销码" style="width: 100%" prop="verificationCode" :rules="[{required: true, message: '请输入核销码', trigger: 'blur'}]">
|
||||
<el-input v-model="form.verificationCode" placeholder="请输入核销码" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ai-dialog>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'GirdList',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
search: {
|
||||
goodsType: '',
|
||||
goodsTitle: '',
|
||||
current: 1,
|
||||
status: '',
|
||||
size: 10,
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
},
|
||||
isShow: false,
|
||||
form: {
|
||||
verificationCode: ''
|
||||
},
|
||||
id: '',
|
||||
total: 0,
|
||||
tableData: [],
|
||||
colConfigs: [
|
||||
{ prop: 'goodsSerialNumber', label: '商品ID', align: 'left' },
|
||||
{ slot: 'goods', align: 'center' },
|
||||
{ prop: 'goodsType', label: '商品类型', align: 'center', format: v => this.dict.getLabel('integralSGType', v) },
|
||||
{ prop: 'quantity', label: '数量', align: 'center', format: v => `${v}` },
|
||||
{ prop: 'usedIntegral', label: '消耗积分', align: 'center' },
|
||||
{ prop: 'payMoney', label: '兑换后再付', align: 'center' },
|
||||
{ prop: 'integralUserName', label: '兑换人', align: 'center' },
|
||||
{ prop: 'createTime', width: 150, label: '创建时间', align: 'center' },
|
||||
{ prop: 'status', label: '状态', align: 'center', format: v => this.dict.getLabel('integralSGOStatus', v) }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
},
|
||||
|
||||
created () {
|
||||
this.dict.load('integralSGType', 'integralSGOStatus').then(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList () {
|
||||
this.instance.post(`/app/appintegralsupermarketorder/list`, null, {
|
||||
params: {
|
||||
...this.search,
|
||||
type: 0
|
||||
}
|
||||
}).then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onConfirm () {
|
||||
this.$refs.form.validate((valid)=> {
|
||||
if(valid) {
|
||||
this.instance.post(`/app/appintegralsupermarketorder/examine`, null, {
|
||||
params: {
|
||||
...this.form,
|
||||
id: this.id
|
||||
}
|
||||
}).then(res => {
|
||||
if(res.code == 0) {
|
||||
this.isShow = false
|
||||
this.getList()
|
||||
this.$message.success('核销成功')
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toDetail (id) {
|
||||
this.$emit('change', {
|
||||
type: 'GirdDetail',
|
||||
params: {
|
||||
id
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancel (id) {
|
||||
this.$confirm('确定取消该订单吗?').then(() => {
|
||||
this.instance.post(`/app/appintegralsupermarketorder/cancel?id=${id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('取消成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.GoodsList {
|
||||
.goods {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,172 @@
|
||||
<template>
|
||||
<ai-detail class="AppDynamicDetail">
|
||||
<template slot="title">
|
||||
<ai-title title="详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-card title="基本信息">
|
||||
<template #right>
|
||||
<el-button type="primary" v-if="info.status === '0'" @click="isShow = true">订单核销</el-button>
|
||||
<el-button type="danger" v-if="info.status === '0' || info.status === '1'" @click="cancelOrder">取消订单</el-button>
|
||||
</template>
|
||||
<template #content>
|
||||
<ai-wrapper
|
||||
label-width="120px">
|
||||
<ai-info-item label="订单编号" :value="info.serialNumber"></ai-info-item>
|
||||
<ai-info-item label="订单状态" :value="dict.getLabel('integralSGOStatus', info.status)"></ai-info-item>
|
||||
<ai-info-item label="兑换人" :value="info.integralUserName"></ai-info-item>
|
||||
<ai-info-item label="创建时间" :value="info.createTime"></ai-info-item>
|
||||
<ai-info-item label="备注" :value="info.remarks" isLine></ai-info-item>
|
||||
</ai-wrapper>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-card title="操作信息" v-if="info.status === '1'">
|
||||
<template #content>
|
||||
<ai-wrapper
|
||||
label-width="120px">
|
||||
<ai-info-item label="核销人" :value="info.examineUserName"></ai-info-item>
|
||||
<ai-info-item label="时间" :value="info.examineTime"></ai-info-item>
|
||||
</ai-wrapper>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-card title="商品信息">
|
||||
<template #content>
|
||||
<ai-table
|
||||
:isShowPagination="false"
|
||||
:tableData="[info]"
|
||||
:col-configs="colConfigs"
|
||||
@getList="() => {}">
|
||||
<el-table-column
|
||||
label="商品"
|
||||
slot="goods"
|
||||
align="left"
|
||||
width="250">
|
||||
<template v-slot="{ row }">
|
||||
<div class="goods">
|
||||
<ai-uploader
|
||||
:disabled="true"
|
||||
:instance="instance"
|
||||
:value="[{url: row.goodsPicUrl}]"
|
||||
:limit="1">
|
||||
</ai-uploader>
|
||||
<p>{{ row.goodsTitle }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-dialog
|
||||
title="订单核销"
|
||||
:visible.sync="isShow"
|
||||
:destroyOnClose="true"
|
||||
width="650px"
|
||||
@onConfirm="onConfirm"
|
||||
@close="form.verificationCode = '', id = ''">
|
||||
<el-form style="height: 200px" class="ai-form" ref="form" :model="form" label-width="120px">
|
||||
<el-form-item label="核销码" style="width: 100%" prop="verificationCode" :rules="[{required: true, message: '请输入核销码', trigger: 'blur'}]">
|
||||
<el-input v-model="form.verificationCode" placeholder="请输入核销码" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ai-dialog>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ResidentDetail',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
info: {},
|
||||
isShow: false,
|
||||
id: '',
|
||||
form: {
|
||||
verificationCode: ''
|
||||
},
|
||||
colConfigs: [
|
||||
{ prop: 'goodsSerialNumber', label: '商品ID', align: 'left' },
|
||||
{ slot: 'goods' },
|
||||
{ prop: 'goodsType', label: '商品类型', align: 'center', format: v => this.dict.getLabel('integralSGType', v) },
|
||||
{ prop: 'goodsIntegralPrice', label: '兑换所需积分', align: 'center' },
|
||||
{ prop: 'payMoney', label: '兑换后补差价金额', align: 'center' },
|
||||
{ prop: 'quantity', label: '数量', align: 'center' },
|
||||
{ prop: 'usedIntegral', label: '消耗积分', align: 'center' }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
if (this.params && this.params.id) {
|
||||
this.id = this.params.id
|
||||
this.getInfo(this.params.id)
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getInfo (id) {
|
||||
this.instance.post(`/app/appintegralsupermarketorder/queryDetailById?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.info = {
|
||||
...res.data
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancelOrder () {
|
||||
this.$confirm('确定取消该订单吗?').then(() => {
|
||||
this.instance.post(`/app/appintegralsupermarketorder/cancel?id=${this.params.id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('取消成功!')
|
||||
this.getInfo(this.params.id)
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
onConfirm () {
|
||||
this.$refs.form.validate((valid)=> {
|
||||
if(valid) {
|
||||
this.instance.post(`/app/appintegralsupermarketorder/examine`, null, {
|
||||
params: {
|
||||
...this.form,
|
||||
id: this.params.id
|
||||
}
|
||||
}).then(res => {
|
||||
if(res.code == 0) {
|
||||
this.isShow = false
|
||||
this.getInfo(this.params.id)
|
||||
this.$message.success('核销成功')
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancel (isRefresh) {
|
||||
this.$emit('change', {
|
||||
type: 'ResidentList',
|
||||
isRefresh: !!isRefresh
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.AppDynamicDetail {
|
||||
.goods {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,256 @@
|
||||
<template>
|
||||
<ai-list isTabs class="GoodsList">
|
||||
<template slot="content">
|
||||
<ai-search-bar>
|
||||
<template slot="left">
|
||||
<ai-select
|
||||
v-model="search.goodsType"
|
||||
@change="(search.current = 1), getList()"
|
||||
placeholder="请选择商品类型"
|
||||
:selectList="dict.getDict('integralSGType')">
|
||||
</ai-select>
|
||||
<ai-select
|
||||
v-model="search.status"
|
||||
@change="(search.current = 1), getList()"
|
||||
placeholder="请选择订单状态"
|
||||
:selectList="dict.getDict('integralSGOStatus')">
|
||||
</ai-select>
|
||||
<el-date-picker
|
||||
v-model="search.startTime"
|
||||
type="date"
|
||||
size="small"
|
||||
value-format="yyyy-MM-dd"
|
||||
placeholder="选择订单开始日期"
|
||||
@change="search.current = 1, getList()">
|
||||
</el-date-picker>
|
||||
<el-date-picker
|
||||
v-model="search.endTime"
|
||||
type="date"
|
||||
size="small"
|
||||
value-format="yyyy-MM-dd"
|
||||
placeholder="选择订单结束日期"
|
||||
@change="search.current = 1, getList()">
|
||||
</el-date-picker>
|
||||
<ai-download
|
||||
v-if="permissions('app_appintegralsupermarketorder_export')"
|
||||
:instance="instance"
|
||||
url="/app/appintegralsupermarketorder/export"
|
||||
:params="search"
|
||||
fileName="订单列表"
|
||||
:disabled="tableData.length == 0">
|
||||
</ai-download>
|
||||
</template>
|
||||
<template slot="right">
|
||||
<el-input
|
||||
v-model="search.goodsTitle"
|
||||
class="search-input"
|
||||
size="small"
|
||||
v-throttle="() => {search.current = 1, getList()}"
|
||||
placeholder="请输入商品名称、兑换人"
|
||||
clearable
|
||||
@clear="search.current = 1, search.goodsTitle = '', getList()"
|
||||
suffix-icon="iconfont iconSearch">
|
||||
</el-input>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
style="margin-top: 8px;"
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="total"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@getList="getList">
|
||||
<el-table-column
|
||||
label="商品"
|
||||
slot="goods"
|
||||
align="left"
|
||||
width="350">
|
||||
<template v-slot="{ row }">
|
||||
<div class="goods">
|
||||
<!-- <ai-uploader
|
||||
:disabled="true"
|
||||
:instance="instance"
|
||||
:value="[{url: row.goodsPicUrl}]"
|
||||
:limit="1">
|
||||
</ai-uploader> -->
|
||||
<div class="img-content">
|
||||
<img :src="row.goodsPicUrl" alt="" v-viewer>
|
||||
<span class="type" :class="`type`+row.goodsType">{{$dict.getLabel('integralSGType', row.goodsType)}}</span>
|
||||
</div>
|
||||
<p>{{ row.goodsTitle }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" slot="options" align="center" width="210" fixed="right">
|
||||
<template v-slot="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" title="取消订单" v-if="row.status === '0' || row.status === '1'" @click="cancel(row.id)">取消订单</el-button>
|
||||
<el-button type="text" title="订单核销" v-if="row.status === '0'" @click="id = row.id, isShow = true">订单核销</el-button>
|
||||
<el-button type="text" title="详情" @click="toDetail(row.id)">详情</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
<ai-dialog
|
||||
title="订单核销"
|
||||
:visible.sync="isShow"
|
||||
:destroyOnClose="true"
|
||||
width="650px"
|
||||
@onConfirm="onConfirm"
|
||||
@close="form.verificationCode = '', id = ''">
|
||||
<el-form style="height: 200px" class="ai-form" ref="form" :model="form" label-width="120px">
|
||||
<el-form-item label="核销码" style="width: 100%" prop="verificationCode" :rules="[{required: true, message: '请输入核销码', trigger: 'blur'}]">
|
||||
<el-input v-model="form.verificationCode" placeholder="请输入核销码" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ai-dialog>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Viewer from 'v-viewer'
|
||||
import Vue from 'vue'
|
||||
Vue.use(Viewer)
|
||||
export default {
|
||||
name: 'ResidentList',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function,
|
||||
areaId: String,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
search: {
|
||||
goodsType: '',
|
||||
goodsTitle: '',
|
||||
current: 1,
|
||||
status: '',
|
||||
size: 10,
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
},
|
||||
isShow: false,
|
||||
form: {
|
||||
verificationCode: ''
|
||||
},
|
||||
id: '',
|
||||
total: 0,
|
||||
tableData: [],
|
||||
colConfigs: [
|
||||
{ prop: 'goodsSerialNumber', label: '商品ID', align: 'left' },
|
||||
{ slot: 'goods', align: 'center' },
|
||||
{ prop: 'goodsType', label: '商品类型', align: 'center', format: v => this.dict.getLabel('integralSGType', v) },
|
||||
{ prop: 'quantity', label: '数量', align: 'center', format: v => `${v}` },
|
||||
{ prop: 'usedIntegral', label: '消耗积分', align: 'center' },
|
||||
{ prop: 'payMoney', label: '兑换后再付', align: 'center' },
|
||||
{ prop: 'integralUserName', label: '兑换人', align: 'center' },
|
||||
{ prop: 'createTime', width: 150, label: '创建时间', align: 'center' },
|
||||
{ prop: 'status', label: '状态', align: 'center', format: v => this.dict.getLabel('integralSGOStatus', v) }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
},
|
||||
|
||||
created () {
|
||||
this.dict.load('integralSGType', 'integralSGOStatus').then(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList () {
|
||||
this.instance.post(`/app/appintegralsupermarketorder/list`, null, {
|
||||
params: {
|
||||
...this.search,
|
||||
type: 1,
|
||||
girdCode: this.areaId
|
||||
}
|
||||
}).then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onConfirm () {
|
||||
this.$refs.form.validate((valid)=> {
|
||||
if(valid) {
|
||||
this.instance.post(`/app/appintegralsupermarketorder/examine`, null, {
|
||||
params: {
|
||||
...this.form,
|
||||
id: this.id
|
||||
}
|
||||
}).then(res => {
|
||||
if(res.code == 0) {
|
||||
this.isShow = false
|
||||
this.getList()
|
||||
this.$message.success('核销成功')
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toDetail (id) {
|
||||
this.$emit('change', {
|
||||
type: 'ResidentDetail',
|
||||
params: {
|
||||
id
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancel (id) {
|
||||
this.$confirm('确定取消该订单吗?').then(() => {
|
||||
this.instance.post(`/app/appintegralsupermarketorder/cancel?id=${id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('取消成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.GoodsList {
|
||||
.goods {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.img-content {
|
||||
position: relative;
|
||||
margin-right: 8px;
|
||||
img {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.type {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 120px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
z-index: 999;
|
||||
}
|
||||
.type1 {
|
||||
background-color: #E64E39;
|
||||
}
|
||||
.type0 {
|
||||
background-color: #FF6900;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div class="AppHelp">
|
||||
<keep-alive :include="['List']">
|
||||
<component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import List from './components/List'
|
||||
import Add from './components/Add'
|
||||
|
||||
export default {
|
||||
name: 'AppIntegratingPublic',
|
||||
label: '积分公示',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
component: 'List',
|
||||
params: {},
|
||||
include: []
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
Add,
|
||||
List
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange (data) {
|
||||
if (data.type === 'Add') {
|
||||
this.component = 'Add'
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'List') {
|
||||
this.component = 'List'
|
||||
this.params = data.params
|
||||
|
||||
this.$nextTick(() => {
|
||||
if (data.isRefresh) {
|
||||
this.$refs.component.getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.AppHelp {
|
||||
height: 100%;
|
||||
background: #F3F6F9;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,138 @@
|
||||
<template>
|
||||
<ai-detail class="content-add">
|
||||
<template slot="title">
|
||||
<ai-title :title="params.id ? '编辑公示' : '添加公示'" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-card title="基本信息">
|
||||
<template #content>
|
||||
<el-form class="ai-form" :model="form" label-width="120px" ref="form">
|
||||
<el-form-item label="所属网格" prop="girdId" style="width: 100%;" :rules="[{ required: true, message: '请选择所属网格', trigger: 'change' }]">
|
||||
<ai-picker :ops="{label: 'girdName'}" :instance="instance" v-model="form.girdId" @pick="e => onUserChange(e)" dialogTitle="选择所属网格" action="/app/appgirdinfo/girdList">
|
||||
<div class="time-select">
|
||||
<span class="dept-name" style="color:#999;" v-if="!form.girdName">选择所属网格</span>
|
||||
<span class="dept-name" v-else>{{ form.girdName }}</span>
|
||||
<i class="el-icon-arrow-down"></i>
|
||||
</div>
|
||||
</ai-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="一类" prop="classOne" style="width: 100%;" :rules="[{required: true, message: '请输入一类', trigger: 'change'}]">
|
||||
<el-input placeholder="请输入一类" size="small" v-model="form.classOne"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="二类" prop="classTwo" style="width: 100%;" :rules="[{required: true, message: '请输入二类', trigger: 'change'}]">
|
||||
<el-input placeholder="请输入二类" size="small" v-model="form.classTwo"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="三类" prop="classThree" style="width: 100%;" :rules="[{required: true, message: '请输入三类', trigger: 'change'}]">
|
||||
<el-input placeholder="请输入三类" size="small" v-model="form.classThree"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="分值" prop="integral" style="width: 100%;" :rules="[{required: true, message: '请输入分值', trigger: 'change'}]">
|
||||
<el-input-number v-model="form.integral" :min="0"></el-input-number>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</ai-card>
|
||||
</template>
|
||||
<template #footer>
|
||||
<el-button @click="cancel">取消</el-button>
|
||||
<el-button type="primary" @click="confirm">提交</el-button>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
name: 'Add',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
form: {
|
||||
classOne: '',
|
||||
classThree: '',
|
||||
classTwo: '',
|
||||
girdId: '',
|
||||
girdName: '',
|
||||
integral: ''
|
||||
},
|
||||
id: ''
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
if (this.params && this.params.id) {
|
||||
this.id = this.params.id
|
||||
this.getInfo(this.params.id)
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getInfo (id) {
|
||||
this.instance.post(`/app/appintegralpublicityinfo/queryDetailById?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.form = {
|
||||
...res.data,
|
||||
girdId: [res.data.girdId]
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
confirm () {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.isFlag = true
|
||||
this.instance.post(`/app/appintegralpublicityinfo/addOrUpdate`, {
|
||||
...this.form,
|
||||
girdId: this.form.girdId[0]
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('提交成功')
|
||||
setTimeout(() => {
|
||||
this.cancel(true)
|
||||
}, 600)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancel (isRefresh) {
|
||||
this.$emit('change', {
|
||||
type: 'List',
|
||||
isRefresh: !!isRefresh
|
||||
})
|
||||
},
|
||||
|
||||
onUserChange (e) {
|
||||
if (e.length) {
|
||||
this.form.girdName = e[0].girdName
|
||||
} else {
|
||||
this.form.girdId = []
|
||||
this.form.girdName = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.time-select {
|
||||
padding: 0 16px;
|
||||
height: 36px;
|
||||
line-height: 36px;
|
||||
border: 1px solid #d0d4dc;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
cursor: pointer;
|
||||
.el-icon-arrow-down {
|
||||
line-height: 36px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,192 @@
|
||||
<template>
|
||||
<ai-list class="notice">
|
||||
<template slot="title">
|
||||
<ai-title title="积分公示" isShowBottomBorder>
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-search-bar class="search-bar">
|
||||
<template #left>
|
||||
<ai-picker
|
||||
:ops="{label: 'girdName'}"
|
||||
dialogTitle="选择所属网格"
|
||||
action="/app/appgirdinfo/girdList"
|
||||
:instance="instance"
|
||||
@change="search.current = 1, getList()"
|
||||
@pick="onGirdChange"
|
||||
v-model="search.girdId">
|
||||
<div class="userSelcet">
|
||||
<span style="color: #606266;" v-if="search.girdId.length">{{ search.girdName }}</span>
|
||||
<span v-else>请选择网格</span>
|
||||
<i class="el-icon-arrow-up" v-if="!search.girdId.length"></i>
|
||||
<i class="el-icon-circle-close" v-if="search.girdId.length" @click.stop="search.girdId = [], search.girdName, search.current = 1, getList()"></i>
|
||||
</div>
|
||||
</ai-picker>
|
||||
<el-button size="small" type="primary" icon="iconfont iconAdd" @click="toAdd('')">添加</el-button>
|
||||
<ai-import
|
||||
:instance="instance"
|
||||
:dict="dict"
|
||||
type="appintegralpublicityinfo" name="积分公示"
|
||||
@success="search.current = 1, getList()">
|
||||
</ai-import>
|
||||
</template>
|
||||
<template #right>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="total"
|
||||
style="margin-top: 6px;"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@getList="getList">
|
||||
<el-table-column slot="options" width="120px" fixed="right" label="操作" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click="toAdd(row.id)">详情</el-button>
|
||||
<el-button type="text" @click="remove(row.id)">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
name: 'List',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
search: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
girdId: [],
|
||||
girdName: ''
|
||||
},
|
||||
total: 0,
|
||||
colConfigs: [
|
||||
{ prop: 'girdName', label: '所属网格', align: 'left' },
|
||||
{ prop: 'classOne', label: '一类', align: 'center' },
|
||||
{ prop: 'classTwo', label: '二类', align: 'center' },
|
||||
{ prop: 'classThree', label: '三类', align: 'center' },
|
||||
{ prop: 'integral', label: '分值', align: 'center' },
|
||||
{ slot: 'options'},
|
||||
],
|
||||
tableData: []
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.getList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
onGirdChange (e) {
|
||||
if (e.length) {
|
||||
this.search.girdName = e[0].girdName
|
||||
}
|
||||
|
||||
this.search.current = 1
|
||||
this.getList()
|
||||
},
|
||||
|
||||
getList() {
|
||||
this.instance.post(`/app/appintegralpublicityinfo/list`, null, {
|
||||
params: {
|
||||
...this.search,
|
||||
girdName: '',
|
||||
girdId: this.search.girdId.length ? this.search.girdId[0] : ''
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
remove (id) {
|
||||
this.$confirm('确定删除该数据?').then(() => {
|
||||
this.instance.post(`/app/appintegralpublicityinfo/delete?ids=${id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('删除成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
toDetail (id) {
|
||||
this.$emit('change', {
|
||||
type: 'Detail',
|
||||
params: {
|
||||
id: id || ''
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toAdd(id) {
|
||||
this.$emit('change', {
|
||||
type: 'Add',
|
||||
params: {
|
||||
id: id || ''
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notice .userSelcet {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 215px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #d0d4dc;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
|
||||
&:hover {
|
||||
border-color: $placeholderColor;
|
||||
}
|
||||
|
||||
i {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
height: 100%;
|
||||
line-height: 32px;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
color: #d0d4dc;
|
||||
transform: rotateZ(180deg);
|
||||
}
|
||||
|
||||
.el-icon-circle-close:hover {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
span {
|
||||
flex: 1;
|
||||
padding: 0 15px;
|
||||
font-size: 12px;
|
||||
color: $placeholderColor;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<div class="AppHelp">
|
||||
<keep-alive :include="['List']">
|
||||
<component ref="component" :is="component" :params="params" :instance="instance" :dict="dict"></component>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import List from './components/List'
|
||||
export default {
|
||||
name: 'AppIntegratingRules',
|
||||
label: '积分规则',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
component: 'List',
|
||||
params: {},
|
||||
include: []
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
List
|
||||
},
|
||||
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.AppHelp {
|
||||
height: 100%;
|
||||
background: #F3F6F9;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,611 @@
|
||||
<template>
|
||||
<ai-list class="gridScoreRules">
|
||||
<ai-title
|
||||
slot="title"
|
||||
title="积分规则"
|
||||
isShowBottomBorder>
|
||||
</ai-title>
|
||||
<template slot="content">
|
||||
<ai-search-bar>
|
||||
<template #left>
|
||||
<el-button type="primary" icon="iconfont iconAdd" @click="dialog = true"> 添加</el-button>
|
||||
<el-cascader size="small" v-model="systemRuleIdList" :options="rulesOps" placeholder="请选择事件/类型" clearable :props="rulesProps"
|
||||
@change="handleTypeSearch" ref="eventTypeSearch"/>
|
||||
<ai-select v-model="search.status" @change="(page.current = 1), getList()" placeholder="请选择状态" :selectList="$dict.getDict('integralRuleStatus')">
|
||||
</ai-select>
|
||||
<ai-picker
|
||||
:instance="instance"
|
||||
dialogTitle="选择网格"
|
||||
:ops="{label: 'girdName', id: 'girdCode'}"
|
||||
pageTitle="网格"
|
||||
:action="'/app/appgirdinfo/girdList?idType=1'"
|
||||
v-model="searchGirdList"
|
||||
@pick="onGirdChange">
|
||||
<div class="userSelcet">
|
||||
<span style="color: #606266;" v-if="search.girdCode">{{ girdName }}</span>
|
||||
<span v-else>有效地区</span>
|
||||
<i class="el-icon-arrow-up" v-if="!search.girdCode"></i>
|
||||
<i class="el-icon-circle-close" v-if="search.girdCode" @click.stop="searchGirdList = [], search.girdCode = '', name = '', search.current = 1, getList()"></i>
|
||||
</div>
|
||||
</ai-picker>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="page.total"
|
||||
:dict="dict"
|
||||
:current.sync="page.current"
|
||||
:size.sync="page.size"
|
||||
@getList="getList()">
|
||||
<el-table-column slot="integral" label="分值" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<span>{{ row.integral > 0 ? "+" : "" }}{{ row.integral }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column slot="options" label="操作" align="center" fixed="right" width="160">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click="changeStatus(row.id, 0)" v-if="row.status == 1">停用</el-button>
|
||||
<el-button type="text" @click="changeStatus(row.id, 1)" v-else>启用</el-button>
|
||||
<el-button type="text" @click="toEdit(row)">编辑</el-button>
|
||||
<el-button type="text" @click="remove(row.id)">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
<ai-dialog :title="dialogTitle" :visible.sync="dialog" @onConfirm="onConfirm" @close="closed" width="900px">
|
||||
<div class="form_div" v-if="dialog">
|
||||
<el-form ref="DialogForm" :model="form" :rules="formRules" size="small" label-suffix=":" label-width="150px">
|
||||
<el-form-item label="事件类型" prop="systemRuleId">
|
||||
<el-cascader v-model="form.systemRuleId" ref="cascaderArr" :props="etOps" clearable placeholder="请选择" @change="handleTypeForm" :options="rulesOps"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="自定义事件" prop="ruleName" v-if="form.systemRuleId !== '17'">
|
||||
<ai-select v-model="form.ruleName" @change="change" placeholder="请选择自定义事件" :selectList="dict.getDict('appIntegralApplyEventType')">
|
||||
</ai-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="规则">
|
||||
<div>常规</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="周期范围" prop="scoringCycle">
|
||||
<ai-select v-model="form.scoringCycle" :selectList="dict.getDict('integralRuleScoringCycle')" />
|
||||
</el-form-item>
|
||||
<el-form-item label="奖励次数">
|
||||
<el-input type="number" placeholder="请输入,周期范围内,不填写表示不限制" v-model.number="form.numberLimit" clearable />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="积分分值" prop="integral">
|
||||
<el-input placeholder="请输入" v-model="form.integral" clearable/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="有效地区" prop="girdName" required>
|
||||
<ai-picker
|
||||
:instance="instance"
|
||||
dialogTitle="选择网格"
|
||||
:ops="{label: 'girdName', id: 'girdCode'}"
|
||||
pageTitle="网格"
|
||||
:action="'/app/appgirdinfo/girdList?idType=1'"
|
||||
v-model="form.girdCode"
|
||||
@pick="onPick">
|
||||
<div class="AppAnnounceDetail-select">
|
||||
<el-input size="small" class="AppAnnounceDetail-select__input" placeholder="请选择..." disabled v-model="form.girdName"></el-input>
|
||||
<div class="select-left" v-if="girdList.length">
|
||||
<span v-for="(item, index) in girdList" :key="index">{{ item.girdName }}</span>
|
||||
</div>
|
||||
<i v-if="!girdList.length">请选择</i>
|
||||
<div class="select-right">{{ girdList.length ? '重新选择' : '选择' }}</div>
|
||||
</div>
|
||||
</ai-picker>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</ai-dialog>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "gridScoreRules",
|
||||
label: "积分规则",
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function,
|
||||
},
|
||||
data() {
|
||||
var validcode = (rule, value, callback) => {
|
||||
if (value) {
|
||||
if (value != 0) {
|
||||
if (!/^(([1-9]{1}\d*)|(0{1}))(\.\d{1,2})?$/.test(value)) {
|
||||
callback(new Error('请输入积分分值,只可输入正数、最多保留两位小数'))
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
} else {
|
||||
callback(new Error('请输入有效的积分分值'));
|
||||
}
|
||||
} else {
|
||||
callback(new Error('请输入积分分值'));
|
||||
}
|
||||
}
|
||||
return {
|
||||
girdList: [],
|
||||
girdName: '',
|
||||
search: {
|
||||
status: "",
|
||||
systemRuleId: "",
|
||||
ruleName: "",
|
||||
girdCode: ''
|
||||
},
|
||||
searchGirdList: [],
|
||||
systemRuleIdList: [],
|
||||
page: {current: 1, size: 10, total: 0},
|
||||
colConfigs: [
|
||||
{
|
||||
prop: "parentRuleName",
|
||||
label: "类型",
|
||||
dict: "integralRuleEventType",
|
||||
},
|
||||
{prop: "ruleName", label: "事件", dict: "integralRuleEvent", align: "center"},
|
||||
{prop: "ruleType", label: "规则", dict: "integralRuleRuleType", align: "center"},
|
||||
{
|
||||
prop: "scoringCycle",
|
||||
label: "周期范围",
|
||||
align: "center",
|
||||
dict: "integralRuleScoringCycle",
|
||||
render: (h, {row}) => {
|
||||
return h(
|
||||
"span",
|
||||
{},
|
||||
row.numberLimit.length
|
||||
? $dict.getLabel("integralRuleScoringCycle", row.scoringCycle)
|
||||
: $dict.getLabel("integralRuleScoringCycle", row.scoringCycle) +
|
||||
row.numberLimit +
|
||||
"次"
|
||||
);
|
||||
},
|
||||
},
|
||||
{slot: "integral", label: "积分分值", align: "center"},
|
||||
{
|
||||
prop: "validRangeData",
|
||||
label: "有效地区",
|
||||
align: "center",
|
||||
format: v => JSON.parse(v).girdName
|
||||
},
|
||||
{
|
||||
prop: "status",
|
||||
label: "状态",
|
||||
align: "center",
|
||||
dict: "integralRuleStatus",
|
||||
},
|
||||
{slot: "options", label: "操作", align: "center"},
|
||||
],
|
||||
tableData: [],
|
||||
dialog: false,
|
||||
form: {
|
||||
ruleType: "0",
|
||||
systemRuleId: "",
|
||||
ruleName: "",
|
||||
scoringCycle: "",
|
||||
numberLimit: "",
|
||||
integral: "",
|
||||
validRangeType: "1",
|
||||
validRangeData: "",
|
||||
girdName: '',
|
||||
girdCode: []
|
||||
},
|
||||
formRules: {
|
||||
systemRuleId: [
|
||||
{required: true, message: "请选择事件/类型", trigger: "change"},
|
||||
],
|
||||
ruleName: [
|
||||
{required: true, message: "请选择自定义事件", trigger: "change"},
|
||||
],
|
||||
scoringCycle: [
|
||||
{required: true, message: "请选择周期范围", trigger: "change"},
|
||||
],
|
||||
integral: [{required: true, validator: validcode, trigger: "blur"},],
|
||||
girdName: [
|
||||
{required: true, message: "请选择网格", trigger: "change"},
|
||||
],
|
||||
},
|
||||
rulesOps: [],
|
||||
rulesProps: {
|
||||
label: "ruleName",
|
||||
value: "id",
|
||||
checkStrictly: true,
|
||||
},
|
||||
radio: 0,
|
||||
treeObj: {
|
||||
treeList: [],
|
||||
defaultProps: {
|
||||
label: "girdName",
|
||||
value: "id",
|
||||
children: 'children',
|
||||
isLeaf: 'leaf'
|
||||
},
|
||||
},
|
||||
treeSelected: {},
|
||||
girdInfoList: [],
|
||||
rulueType: "0",
|
||||
girdNameList: [],
|
||||
list: [],
|
||||
isOneAndTen: false,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.form.areaId = this.$store.state.user.info.areaId
|
||||
this.$dict.load("integralRuleStatus", "integralRuleRuleType", "integralRuleScoringCycle",
|
||||
"integralRuleEvent", "integralRuleEventType", 'appIntegralApplyEventType').then(() => {
|
||||
this.getList();
|
||||
this.getRulesList();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
onGirdChange (e) {
|
||||
if (e.length) {
|
||||
this.girdName = e[0].girdName
|
||||
this.search.girdCode = e[0].girdCode
|
||||
} else {
|
||||
this.girdName = ''
|
||||
}
|
||||
|
||||
this.searchGirdList = e
|
||||
|
||||
this.page.current = 1
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
onPick (e) {
|
||||
if (e.length) {
|
||||
this.form.girdName = e[0].girdName
|
||||
} else {
|
||||
this.form.girdName = ''
|
||||
this.form.girdCode = []
|
||||
}
|
||||
|
||||
this.girdList = e
|
||||
},
|
||||
|
||||
getList() {
|
||||
this.instance
|
||||
.post(`/app/appintegralrule/listByAppletFD`, null, {
|
||||
params: {
|
||||
...this.search,
|
||||
...this.page,
|
||||
},
|
||||
})
|
||||
.then((res) => {
|
||||
if (res?.data) {
|
||||
this.tableData = res.data.records;
|
||||
this.page.total = res.data.total;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
change (e) {
|
||||
},
|
||||
closed () {
|
||||
this.form.ruleType = '0'
|
||||
this.form.systemRuleId = ''
|
||||
this.form.ruleName = ''
|
||||
this.form.scoringCycle = ''
|
||||
this.form.numberLimit = ''
|
||||
this.form.integral = ''
|
||||
this.form.validRangeType = '1'
|
||||
this.form.validRangeData = ''
|
||||
this.form.girdName = ''
|
||||
this.form.girdCode = []
|
||||
this.girdList = []
|
||||
},
|
||||
toEdit(row) {
|
||||
this.form = {...row}
|
||||
if (this.form?.validRangeData) {
|
||||
this.form.girdName = JSON.parse(this.form.validRangeData).girdName
|
||||
this.form.girdCode = [JSON.parse(this.form.validRangeData).girdCode]
|
||||
this.girdList = [JSON.parse(this.form.validRangeData)]
|
||||
}
|
||||
this.$nextTick(() => {
|
||||
this.dialog = true;
|
||||
});
|
||||
},
|
||||
remove(id) {
|
||||
this.$confirm("删除后不可恢复,是否要删除该规则?", {
|
||||
type: "error",
|
||||
}).then(() => {
|
||||
this.instance
|
||||
.post(`/app/appintegralrule/delete?ids=${id}`)
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success("删除成功!");
|
||||
this.getList();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
changeStatus(id, status) {
|
||||
let text = status == 1 ? "启用" : "停用";
|
||||
this.$confirm(`确定${text}该条规则?`).then(() => {
|
||||
this.instance
|
||||
.post(`/app/appintegralrule/enableStatus?id=${id}`)
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success(`${text}成功!`);
|
||||
this.getList();
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
onConfirm() {
|
||||
this.$refs.DialogForm.validate((valid) => {
|
||||
if (valid) {
|
||||
let formData = this.$copy(this.form);
|
||||
// formData.ladderRule = JSON.stringify(formData.ladderRule)
|
||||
formData.integral = formData.integral || 0;
|
||||
this.instance
|
||||
.post(`/app/appintegralrule/addOrUpdate`, {
|
||||
...formData,
|
||||
appCodeType: '2',
|
||||
girdCode: '',
|
||||
validRangeData: JSON.stringify({
|
||||
id: this.girdList[0].id,
|
||||
girdName: this.girdList[0].girdName,
|
||||
girdCode: this.girdList[0].girdCode
|
||||
})
|
||||
})
|
||||
.then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success(
|
||||
`${this.isEdit ? "编辑成功" : "添加成功"}`
|
||||
);
|
||||
this.dialog = false;
|
||||
this.getList();
|
||||
this.closed();
|
||||
this.girdInfoList = []
|
||||
this.girdNameList = []
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
handleTypeSearch(v) {
|
||||
this.systemRuleIdList = v
|
||||
this.search.systemRuleId = v?.[v.length - 1];
|
||||
this.search.ruleName = this.$refs.eventTypeSearch.getCheckedNodes()[0]?.label
|
||||
this.page.current = 1;
|
||||
this.$refs.eventTypeSearch.dropDownVisible = false;
|
||||
this.getList();
|
||||
},
|
||||
handleTypeForm(v) {
|
||||
if (this.dialog) {
|
||||
if(v[1] == '17') {
|
||||
this.form.scoringCycle = '0'
|
||||
this.form.numberLimit = '1'
|
||||
this.isOneAndTen = true
|
||||
} else {
|
||||
this.form.scoringCycle = ''
|
||||
this.form.numberLimit = ''
|
||||
this.isOneAndTen = false
|
||||
}
|
||||
this.form.systemRuleId = v?.[v.length - 1];
|
||||
}
|
||||
},
|
||||
handleDelete(i) {
|
||||
this.$confirm("是否要删除该规则?")
|
||||
.then(() => {
|
||||
this.form.ladderRule.splice(i, 1);
|
||||
})
|
||||
.catch(() => 0);
|
||||
},
|
||||
checkIntegral(v) {
|
||||
return /\.\d{2,}$/.test(v) ? Math.abs(v).toFixed(1) : Math.abs(v);
|
||||
},
|
||||
getRulesList() {
|
||||
this.instance
|
||||
.post(`/app/appintegralsystemrule/listByAppletFD?current=1&size=3000`)
|
||||
.then((res) => {
|
||||
if (res?.data) {
|
||||
this.rulesOps = this.toTree(res.data.records)
|
||||
this.rulesOps.push({
|
||||
ruleName: "积分申请",
|
||||
id: "积分申请",
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
// 转树形结构
|
||||
toTree(data) {
|
||||
let result = [];
|
||||
if (!Array.isArray(data)) {
|
||||
return result;
|
||||
}
|
||||
let map = {};
|
||||
data.forEach((item) => {
|
||||
map[item.id] = item;
|
||||
});
|
||||
data.forEach((item) => {
|
||||
let parent = map[item.parentRuleId];
|
||||
if (parent) {
|
||||
(parent.children || (parent.children = [])).push(item);
|
||||
} else {
|
||||
result.push(item);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
isEdit() {
|
||||
return !!this.form.id;
|
||||
},
|
||||
dialogTitle() {
|
||||
return this.isEdit ? "编辑积分规则" : "添加积分规则";
|
||||
},
|
||||
etOps() {
|
||||
return {
|
||||
value: "id",
|
||||
label: "ruleName",
|
||||
};
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.gridScoreRules {
|
||||
height: 100%;
|
||||
background: #f3f6f9;
|
||||
|
||||
.userSelcet {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 215px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #d0d4dc;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
|
||||
&:hover {
|
||||
border-color: $placeholderColor;
|
||||
}
|
||||
|
||||
i {
|
||||
display: flex;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
height: 100%;
|
||||
line-height: 32px;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
color: #d0d4dc;
|
||||
transform: rotateZ(180deg);
|
||||
}
|
||||
|
||||
.el-icon-circle-close:hover {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
span {
|
||||
flex: 1;
|
||||
padding: 0 15px;
|
||||
font-size: 12px;
|
||||
color: $placeholderColor;
|
||||
}
|
||||
}
|
||||
|
||||
:deep( .ai-list__content--right ){
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// :deep( .searchRightZone ){
|
||||
// display: flex;
|
||||
// }
|
||||
|
||||
.AppAnnounceDetail-select {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 32px;
|
||||
line-height: 1;
|
||||
background: #F5F5F5;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #D0D4DC;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
|
||||
&:hover {
|
||||
border-color: #26f;
|
||||
}
|
||||
|
||||
& > i {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
line-height: 32px;
|
||||
padding: 0 12px;
|
||||
color: #888888;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
border-right: 1px solid #D0D4DC;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.AppAnnounceDetail-select__input {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.select-right {
|
||||
height: 100%;
|
||||
padding: 0 12px;
|
||||
color: #222222;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
transition: all ease 0.3s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.select-left {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
padding: 5px 0 0px 12px;
|
||||
border-right: 1px solid #D0D4DC;
|
||||
border-radius: 4px 0 0 4px;
|
||||
background: #fff;
|
||||
|
||||
em {
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
margin: 0 4px 5px 0;
|
||||
color: #222222;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
span {
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
margin: 0 4px 5px 0;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
color: #222222;
|
||||
background: #F3F4F7;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #D0D4DC;
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep( .ai-dialog ){
|
||||
.el-cascader {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tableInput {
|
||||
& > input {
|
||||
text-align: center;
|
||||
border: none;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<ai-list v-if="!isShowDetail">
|
||||
<template slot="title">
|
||||
<ai-title title="积分超市" :isShowBottomBorder="false">
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="tabs">
|
||||
<el-tabs v-model="currIndex">
|
||||
<el-tab-pane v-for="(tab,i) in tabs" :key="i" :label="tab.label">
|
||||
<component :ref="String(i)" v-if="currIndex == i" :is="tab.comp" @change="onChange" lazy :instance="instance" :dict="dict" :permissions="permissions"/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</template>
|
||||
</ai-list>
|
||||
<AddGoods v-else-if="componentName === 'AddGoods'" :params="params" :instance="instance" :dict="dict" @change="onChange"></AddGoods>
|
||||
<AddStore v-else-if="componentName === 'AddStore'" :params="params" :instance="instance" :dict="dict" @change="onChange"></AddStore>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AddGoods from './components/addGoods'
|
||||
import AddStore from './components/AddStore'
|
||||
import StoreList from './components/StoreList'
|
||||
import GoodsList from './components/GoodsList'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'AppIntegratingSupermarket',
|
||||
label: '积分超市',
|
||||
|
||||
components: {
|
||||
GoodsList,
|
||||
StoreList,
|
||||
AddGoods,
|
||||
AddStore
|
||||
},
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
|
||||
tabs () {
|
||||
const tabList = [
|
||||
{label: '商品信息', name: 'GoodsList', comp: GoodsList, permission: ''},
|
||||
{label: '店铺管理', name: 'StoreList', comp: StoreList, permission: ''}
|
||||
].filter(item => {
|
||||
return true
|
||||
})
|
||||
|
||||
return tabList
|
||||
}
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
activeName: 'GoodsList',
|
||||
currIndex: '0',
|
||||
componentName: '',
|
||||
params: {},
|
||||
isShowDetail: false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
onAreaChange () {
|
||||
if (this.currIndex === '0') {
|
||||
this.$nextTick(() => {
|
||||
this.$refs[this.currIndex][0].getList()
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
onChange (data) {
|
||||
if (data.type === 'GoodsList') {
|
||||
this.componentName = 'GoodsList'
|
||||
this.isShowDetail = false
|
||||
this.params = data.params
|
||||
}
|
||||
if (data.type === 'StoreList') {
|
||||
this.componentName = 'StoreList'
|
||||
this.isShowDetail = false
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'AddGoods') {
|
||||
this.componentName = 'AddGoods'
|
||||
this.isShowDetail = true
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'AddStore') {
|
||||
this.componentName = 'AddStore'
|
||||
this.isShowDetail = true
|
||||
this.params = data.params
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
@@ -0,0 +1,507 @@
|
||||
<template>
|
||||
<ai-detail class="appgoods">
|
||||
<template slot="title">
|
||||
<ai-title :title="id ? '编辑店铺' : '添加店铺'" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-card title="基本信息">
|
||||
<template #content>
|
||||
<el-form class="ai-form" :model="form" label-width="120px" ref="form">
|
||||
<el-form-item style="width: 100%" label="店铺名称" prop="title" :rules="[{required: true, message: '请输入店铺名称', trigger: 'blur'}]">
|
||||
<el-input type="input" size="small" v-model="form.title" clearable placeholder="请输入店铺名称" :maxlength="50" show-word-limit></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item style="width: 100%" label="店铺类型" prop="type" :rules="[{required: true, message: '请选择店铺类型', trigger: 'change'}]">
|
||||
<ai-select
|
||||
v-model="form.type"
|
||||
placeholder="请选择店铺类型"
|
||||
:selectList="dict.getDict('integralSSType')">
|
||||
</ai-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="可见范围" label-width="120px" prop="serviceType" :rules="[{required: true, message: '请选择可见范围', trigger: 'change'}]">
|
||||
<el-radio-group v-model="form.serviceType" @change="form.girdList = [], girdList = [], form.visibleNames = ''">
|
||||
<el-radio label="0">不限</el-radio>
|
||||
<el-radio label="1">仅指定网格可见</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择网格" v-if="form.serviceType === '1'" style="width: 100%;" label-width="120px" prop="visibleNames" :rules="[{ required: true, message: '请选择网格', trigger: 'change' }]">
|
||||
<ai-picker
|
||||
:instance="instance"
|
||||
multiple
|
||||
dialogTitle="选择网格"
|
||||
:ops="{label: 'girdName', id: 'girdCode'}"
|
||||
pageTitle="网格"
|
||||
:action="'/app/appgirdinfo/girdList?idType=1'"
|
||||
v-model="form.girdList"
|
||||
@pick="onPick"
|
||||
@change="onSelcetChange">
|
||||
<div class="AppAnnounceDetail-select">
|
||||
<el-input size="small" class="AppAnnounceDetail-select__input" placeholder="请选择..." disabled v-model="form.visibleNames"></el-input>
|
||||
<div class="select-left" v-if="form.girdList.length">
|
||||
<span v-for="(item, index) in girdList" :key="index" v-if="index < 9">{{ item.girdName }}</span>
|
||||
<em v-if="girdList.length > 9">等{{ girdList.length }}个</em>
|
||||
</div>
|
||||
<i v-if="!form.girdList.length">请选择</i>
|
||||
<div class="select-right">{{ form.girdList.length ? '重新选择' : '选择' }}</div>
|
||||
</div>
|
||||
</ai-picker>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-card title="商品列表">
|
||||
<template #right>
|
||||
<el-button type="primary" icon="iconfont iconAdd" @click="showList">选择商品</el-button>
|
||||
</template>
|
||||
<template #content>
|
||||
<ai-table
|
||||
:tableData="form.goodsList"
|
||||
:isShowPagination="false"
|
||||
:col-configs="chooseColConfigs"
|
||||
@getList="() => {}">
|
||||
<el-table-column
|
||||
label="商品"
|
||||
slot="goods"
|
||||
align="left"
|
||||
width="300">
|
||||
<template v-slot="{ row }">
|
||||
<div class="goods">
|
||||
<ai-uploader
|
||||
:disabled="true"
|
||||
:instance="instance"
|
||||
:value="[{url: row.goods.picUrl}]"
|
||||
:limit="1">
|
||||
</ai-uploader>
|
||||
<p>{{ row.goods.title }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="兑换所需积分"
|
||||
slot="integralPrice"
|
||||
align="center"
|
||||
width="140">
|
||||
<template v-slot="{ row }">
|
||||
<el-input-number style="width: 120px;" :precision="2" size="small" type="input" v-model="row.integralPrice" :min="0" placeholder="请输入"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="兑换后补差价金额"
|
||||
slot="payMoney"
|
||||
align="center"
|
||||
width="150">
|
||||
<template v-slot="{ row }">
|
||||
<el-input-number style="width: 120px;" :precision="2" size="small" type="input" v-if="row.goods.type !== '0'" :min="0" v-model="row.payMoney" clearable placeholder="请输入"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="库存"
|
||||
slot="stock"
|
||||
align="center"
|
||||
width="140">
|
||||
<template v-slot="{ row }">
|
||||
<el-input-number style="width: 120px;" :precision="0" size="small" type="input" v-model="row.stock" :min="0" clearable placeholder="请输入"></el-input-number>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" slot="options" align="center" width="180" fixed="right">
|
||||
<template v-slot="{ row, $index }">
|
||||
<div class="table-options">
|
||||
<el-button v-if="row.id" type="text" :title="row.status === '0' ? '上架' : '下架'" @click="changeStatus(row.status, $index)">{{ row.status === '0' ? '上架' : '下架' }}</el-button>
|
||||
<el-button type="text" title="删除" @click="remove($index)">删除</el-button>
|
||||
<el-button type="text" title="复制链接" v-if="row.goods.type === '1'" @click="copy(row.goods.jdUrl)">复制链接</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-dialog
|
||||
title="选择商品"
|
||||
:visible.sync="isShow"
|
||||
:destroyOnClose="true"
|
||||
@confirm="onConfirm"
|
||||
width="1080px">
|
||||
<ai-search-bar>
|
||||
<template slot="left">
|
||||
<ai-select
|
||||
v-model="search.type"
|
||||
@change="(search.current = 1), getList()"
|
||||
placeholder="请选择商品类型"
|
||||
:selectList="dict.getDict('integralSGType')">
|
||||
</ai-select>
|
||||
<ai-select
|
||||
v-model="search.status"
|
||||
@change="(search.current = 1), getList()"
|
||||
placeholder="请选择状态"
|
||||
:selectList="dict.getDict('integralSGStatus')">
|
||||
</ai-select>
|
||||
</template>
|
||||
<template slot="right">
|
||||
<el-input
|
||||
v-model="search.title"
|
||||
class="search-input"
|
||||
size="small"
|
||||
v-throttle="() => {search.current = 1, getList()}"
|
||||
placeholder="请输入商品名称"
|
||||
clearable
|
||||
@clear="search.current = 1, search.title = '', getList()"
|
||||
suffix-icon="iconfont iconSearch">
|
||||
</el-input>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
ref="aiTable"
|
||||
style="margin-top: 8px;"
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="total"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@selection-change="handleSelectionChange"
|
||||
@getList="getList">
|
||||
<el-table-column
|
||||
label="商品"
|
||||
slot="goods"
|
||||
align="left"
|
||||
width="300">
|
||||
<template v-slot="{ row }">
|
||||
<div class="goods">
|
||||
<ai-uploader
|
||||
:disabled="true"
|
||||
:instance="instance"
|
||||
:value="[{url: row.picUrl}]"
|
||||
:limit="1">
|
||||
</ai-uploader>
|
||||
<p>{{ row.title }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</ai-dialog>
|
||||
</template>
|
||||
<template #footer>
|
||||
<el-button @click="cancel">取消</el-button>
|
||||
<el-button type="primary" @click="confirm">提交</el-button>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AddStore',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
isShow: false,
|
||||
form: {
|
||||
title: '',
|
||||
type: '',
|
||||
serviceType: '0',
|
||||
visibleNames: '',
|
||||
girdList: [],
|
||||
goodsList: []
|
||||
},
|
||||
girdList: [],
|
||||
id: '',
|
||||
search: {
|
||||
type: '',
|
||||
title: '',
|
||||
current: 1,
|
||||
status: '',
|
||||
size: 10
|
||||
},
|
||||
total: 0,
|
||||
tableData: [],
|
||||
chooseColConfigs: [
|
||||
{ slot: 'goods' },
|
||||
{ prop: 'goods', label: '商品类型', align: 'center', format: v => this.dict.getLabel('integralSGType', v.type) },
|
||||
{ slot: 'integralPrice' },
|
||||
{ slot: 'payMoney' },
|
||||
{ prop: 'goods', label: '商品链接', align: 'center', format: v => v.jdUrl },
|
||||
{ slot: 'stock' },
|
||||
{ prop: 'status', width: 90, label: '状态', align: 'center', format: v => this.dict.getLabel('integralSGStatus', v) || '已上架' }
|
||||
],
|
||||
colConfigs: [
|
||||
{ type: 'selection', label: '', align: 'left' },
|
||||
{ prop: 'serialNumber', label: '商品ID', align: 'center' },
|
||||
{ slot: 'goods', align: 'center' },
|
||||
{ prop: 'type', label: '商品类型', align: 'center', format: v => this.dict.getLabel('integralSGType', v) },
|
||||
{ prop: 'onlineTime', label: '上架时间', align: 'center' },
|
||||
{ prop: 'status', width: 90, label: '状态', align: 'center', format: v => this.dict.getLabel('integralSGStatus', v) }
|
||||
],
|
||||
chooseList: []
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.dict.load('integralSGType', 'integralSGStatus').then(() => {
|
||||
this.getList()
|
||||
})
|
||||
|
||||
if (this.params && this.params.id) {
|
||||
this.id = this.params.id
|
||||
this.getInfo(this.params.id)
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList () {
|
||||
this.instance.post(`/app/appintegralsupermarketgoods/list`, null, {
|
||||
params: {
|
||||
...this.search
|
||||
}
|
||||
}).then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
copy (url) {
|
||||
let oInput = document.createElement('input')
|
||||
oInput.value = url
|
||||
document.body.appendChild(oInput)
|
||||
oInput.select()
|
||||
document.execCommand('Copy')
|
||||
this.$message({
|
||||
message: '已复制',
|
||||
type: 'success'
|
||||
})
|
||||
oInput.remove()
|
||||
},
|
||||
|
||||
changeStatus (status, index) {
|
||||
this.$confirm(`确定${status === '0' ? '上架' : '下架'}该商品?`).then(() => {
|
||||
this.$set(this.form.goodsList[index], 'status', status === '0' ? '1' : '0')
|
||||
this.$message.success(`${status === '0' ? '上架' : '下架'}成功`)
|
||||
})
|
||||
},
|
||||
|
||||
handleSelectionChange (e) {
|
||||
this.chooseList = e
|
||||
},
|
||||
|
||||
remove (index) {
|
||||
this.$confirm('确定删除该商品吗?').then(() => {
|
||||
this.form.goodsList.splice(index, 1)
|
||||
this.$message.success('删除成功!')
|
||||
})
|
||||
},
|
||||
|
||||
showList () {
|
||||
this.isShow = true
|
||||
|
||||
// this.$nextTick(() => {
|
||||
// if (this.form.goodsList.length) {
|
||||
// this.form.goodsList.map(v => v.goods).forEach(v => {
|
||||
// if (this.tableData.filter(e => e.id === v.id).length) {
|
||||
// this.$refs.aiTable.toggleRowSelection(this.tableData.filter(e => e.id === v.id)[0], true)
|
||||
// }
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
},
|
||||
|
||||
onConfirm () {
|
||||
this.isShow = false
|
||||
let list = this.chooseList.filter(v => {
|
||||
return this.form.goodsList.map(e => e.goodsId).indexOf(v.id) === -1
|
||||
}).map(v => {
|
||||
return {
|
||||
goods: {
|
||||
...v
|
||||
},
|
||||
goodsId: v.id,
|
||||
integralPrice: undefined,
|
||||
payMoney: undefined,
|
||||
stock: undefined,
|
||||
status: v.status
|
||||
}
|
||||
})
|
||||
|
||||
this.form.goodsList = [
|
||||
...this.form.goodsList ,
|
||||
...list
|
||||
]
|
||||
},
|
||||
|
||||
getInfo (id) {
|
||||
this.instance.post(`/app/appintegralsupermarketshop/queryDetailById?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.form = {
|
||||
...res.data,
|
||||
visibleNames: '1',
|
||||
girdList: res.data.serviceType === '1' ? res.data.visibleConfig.map(v => v.visibleId) : []
|
||||
}
|
||||
|
||||
this.girdList = res.data.visibleConfig.map(v => {
|
||||
return {
|
||||
girdCode: v.visibleId,
|
||||
girdName: v.visibleName
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
onPick (e) {
|
||||
this.girdList = e
|
||||
},
|
||||
|
||||
onSelcetChange (e) {
|
||||
if (e.length) {
|
||||
this.form.visibleNames = '1'
|
||||
} else {
|
||||
this.form.visibleNames = ''
|
||||
this.form.girdList = []
|
||||
}
|
||||
},
|
||||
|
||||
confirm () {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
if (!this.form.goodsList.length) {
|
||||
return this.$message.error('请选择商品')
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.form.goodsList.length; i++) {
|
||||
if (!this.form.goodsList[i].integralPrice) {
|
||||
return this.$message.error('请输入兑换所需积分')
|
||||
}
|
||||
if (!this.form.goodsList[i].payMoney && this.form.goodsList[i].goods.type === '1') {
|
||||
return this.$message.error('请输入兑换后补差价金额')
|
||||
}
|
||||
if (!this.form.goodsList[i].stock) {
|
||||
return this.$message.error('请输入库存')
|
||||
}
|
||||
}
|
||||
|
||||
this.instance.post(`/app/appintegralsupermarketshop/addOrUpdate`, {
|
||||
...this.form,
|
||||
id: this.params.id || '',
|
||||
visibleConfig: this.form.serviceType === '1' ? this.girdList.map(v => {
|
||||
return {
|
||||
visibleId: v.girdCode,
|
||||
visibleName: v.girdName
|
||||
}
|
||||
}) : []
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('提交成功')
|
||||
setTimeout(() => {
|
||||
this.cancel(true)
|
||||
}, 600)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancel (isRefresh) {
|
||||
this.$emit('change', {
|
||||
type: 'GoodsList',
|
||||
isRefresh: !!isRefresh
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.appgoods {
|
||||
.goods {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 250px;
|
||||
height: 120px;
|
||||
}
|
||||
.AppAnnounceDetail-select {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 32px;
|
||||
line-height: 1;
|
||||
background: #F5F5F5;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #D0D4DC;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
|
||||
&:hover {
|
||||
border-color: #26f;
|
||||
}
|
||||
|
||||
& > i {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
line-height: 32px;
|
||||
padding: 0 12px;
|
||||
color: #888888;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
border-right: 1px solid #D0D4DC;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.AppAnnounceDetail-select__input {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.select-right {
|
||||
height: 100%;
|
||||
padding: 0 12px;
|
||||
color: #222222;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
transition: all ease 0.3s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.select-left {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
padding: 5px 0 0px 12px;
|
||||
border-right: 1px solid #D0D4DC;
|
||||
border-radius: 4px 0 0 4px;
|
||||
background: #fff;
|
||||
|
||||
em {
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
margin: 0 4px 5px 0;
|
||||
color: #222222;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
span {
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
margin: 0 4px 5px 0;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
color: #222222;
|
||||
background: #F3F4F7;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #D0D4DC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,214 @@
|
||||
<template>
|
||||
<ai-list isTabs class="GoodsList">
|
||||
<template slot="content">
|
||||
<ai-search-bar>
|
||||
<template slot="left">
|
||||
<el-button type="primary" icon="iconfont iconAdd" @click="toAdd('')">添加</el-button>
|
||||
<ai-select
|
||||
v-model="search.type"
|
||||
@change="(search.current = 1), getList()"
|
||||
placeholder="请选择商品类型"
|
||||
:selectList="dict.getDict('integralSGType')">
|
||||
</ai-select>
|
||||
<ai-select
|
||||
v-model="search.status"
|
||||
@change="(search.current = 1), getList()"
|
||||
placeholder="请选择类型"
|
||||
:selectList="dict.getDict('integralSGStatus')">
|
||||
</ai-select>
|
||||
</template>
|
||||
<template slot="right">
|
||||
<el-input
|
||||
v-model="search.title"
|
||||
class="search-input"
|
||||
size="small"
|
||||
v-throttle="() => {search.current = 1, getList()}"
|
||||
placeholder="请输入商品名称"
|
||||
clearable
|
||||
@clear="search.current = 1, search.title = '', getList()"
|
||||
suffix-icon="iconfont iconSearch">
|
||||
</el-input>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
style="margin-top: 8px;"
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="total"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@getList="getList">
|
||||
<el-table-column
|
||||
label="商品"
|
||||
slot="goods"
|
||||
align="left"
|
||||
width="450">
|
||||
<template v-slot="{ row }">
|
||||
<div class="goods">
|
||||
<!-- <ai-uploader class="upload"
|
||||
:disabled="true"
|
||||
:instance="instance"
|
||||
:value="[{url: row.picUrl}]"
|
||||
:limit="1">
|
||||
<span class="type" :class="`type`+row.type">{{$dict.getLabel('integralSGType', row.type)}}</span>
|
||||
</ai-uploader> -->
|
||||
<div class="img-content">
|
||||
<img :src="row.picUrl" alt="" v-viewer>
|
||||
<span class="type" :class="`type`+row.type">{{$dict.getLabel('integralSGType', row.type)}}</span>
|
||||
</div>
|
||||
|
||||
<p>{{ row.title }}</p>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" slot="options" align="center" width="210" fixed="right">
|
||||
<template v-slot="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" title="编辑" @click="toAdd(row.id)">编辑</el-button>
|
||||
<el-button type="text" :title="row.status === '0' ? '上架' : '下架'" @click="changeStatus(row)">{{ row.status === '0' ? '上架' : '下架' }}</el-button>
|
||||
<el-button type="text" title="删除" @click="remove(row.id)">删除</el-button>
|
||||
<el-button type="text" title="复制链接" v-if="row.type === '1'" @click="copy(row.jdUrl)">复制链接</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Viewer from 'v-viewer'
|
||||
import Vue from 'vue'
|
||||
Vue.use(Viewer)
|
||||
export default {
|
||||
name: 'GoodsList',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
search: {
|
||||
type: '',
|
||||
title: '',
|
||||
current: 1,
|
||||
status: '',
|
||||
size: 10
|
||||
},
|
||||
total: 0,
|
||||
tableData: [],
|
||||
colConfigs: [
|
||||
{ prop: 'serialNumber', label: '商品ID', align: 'left' },
|
||||
{ slot: 'goods', align: 'center' },
|
||||
{ prop: 'type', label: '商品类型', align: 'center', format: v => this.dict.getLabel('integralSGType', v) },
|
||||
{ prop: 'onlineTime', label: '上架时间', align: 'center' },
|
||||
{ prop: 'status', label: '状态', align: 'center', format: v => this.dict.getLabel('integralSGStatus', v) }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
},
|
||||
|
||||
created () {
|
||||
this.dict.load('integralSGType', 'integralSGStatus').then(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList () {
|
||||
this.instance.post(`/app/appintegralsupermarketgoods/list`, null, {
|
||||
params: {
|
||||
...this.search
|
||||
}
|
||||
}).then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toAdd (id) {
|
||||
this.$emit('change', {
|
||||
type: 'AddGoods',
|
||||
params: {
|
||||
id: id || ''
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
copy (url) {
|
||||
let oInput = document.createElement('input')
|
||||
oInput.value = url
|
||||
document.body.appendChild(oInput)
|
||||
oInput.select()
|
||||
document.execCommand('Copy')
|
||||
this.$message({
|
||||
message: '已复制',
|
||||
type: 'success'
|
||||
})
|
||||
oInput.remove()
|
||||
},
|
||||
|
||||
remove (id) {
|
||||
this.$confirm('确定删除该商品吗?').then(() => {
|
||||
this.instance.post(`/app/appintegralsupermarketgoods/delete?id=${id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('删除成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
changeStatus (row) {
|
||||
this.$confirm(`确定${row.status === '0' ? '上架' : '下架'}该商品?`).then(() => {
|
||||
this.instance.post(`/app/appintegralsupermarketgoods/online?id=${row.id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success(`${row.status === '0' ? '上架' : '下架'}成功`)
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.GoodsList {
|
||||
.goods {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.img-content {
|
||||
position: relative;
|
||||
margin-right: 8px;
|
||||
img {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.type {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 120px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
z-index: 999;
|
||||
}
|
||||
.type1 {
|
||||
background-color: #E64E39;
|
||||
}
|
||||
.type0 {
|
||||
background-color: #FF6900;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<ai-list isTabs class="order_management">
|
||||
<template slot="content">
|
||||
<ai-search-bar>
|
||||
<template slot="left">
|
||||
<el-button type="primary" icon="iconfont iconAdd" @click="toAdd('')">添加</el-button>
|
||||
<ai-select
|
||||
v-model="search.type"
|
||||
@change="(search.current = 1), getList()"
|
||||
placeholder="请选择店铺类型"
|
||||
:selectList="dict.getDict('integralSSType')">
|
||||
</ai-select>
|
||||
<ai-select
|
||||
v-model="search.status"
|
||||
@change="(search.current = 1), getList()"
|
||||
placeholder="请选择状态"
|
||||
:selectList="dict.getDict('integralSSStatus')">
|
||||
</ai-select>
|
||||
</template>
|
||||
<template slot="right">
|
||||
<el-input
|
||||
v-model="search.title"
|
||||
class="search-input"
|
||||
size="small"
|
||||
v-throttle="() => {search.current = 1, getList()}"
|
||||
placeholder="请输入店铺名称"
|
||||
clearable
|
||||
@clear="search.current = 1, search.title = '', getList()"
|
||||
suffix-icon="iconfont iconSearch">
|
||||
</el-input>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
style="margin-top: 8px;"
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="total"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@getList="getList">
|
||||
<el-table-column label="网格店铺服务网格" slot="grid" align="center">
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ row.type === '0' ? (row.visibleNames ? row.visibleNames : row.serviceType === '0' ? '不限' : '-') : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="居民店铺服务地区" slot="area" align="center">
|
||||
<template v-slot="{ row }">
|
||||
<span>{{ row.type === '1' ? (row.visibleNames ? row.visibleNames : row.serviceType === '0' ? '不限' : '-') : '-' }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" slot="options" align="center" width="160" fixed="right">
|
||||
<template v-slot="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" title="编辑" @click="toAdd(row.id)">编辑</el-button>
|
||||
<el-button type="text" :title="row.status === '0' ? '启用' : '停用'" @click="changeStatus(row)">{{ row.status === '0' ? '启用' : '停用' }}</el-button>
|
||||
<el-button type="text" title="删除" @click="remove(row.id)">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'GoodsList',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
search: {
|
||||
type: '',
|
||||
title: '',
|
||||
current: 1,
|
||||
status: '',
|
||||
size: 10
|
||||
},
|
||||
total: 0,
|
||||
tableData: [],
|
||||
shopList: [],
|
||||
colConfigs: [
|
||||
{ prop: 'serialNumber', label: '店铺ID', align: 'left' },
|
||||
{ prop: 'title', label: '店铺名称', align: 'center' },
|
||||
{ prop: 'type', label: '店铺类型', align: 'center', format: v => this.dict.getLabel('integralSSType', v) },
|
||||
{ slot: 'grid', label: '网格店铺服务网格', align: 'center' },
|
||||
{ slot: 'area', label: '居民店铺服务地区', align: 'center' },
|
||||
{ prop: 'goodsCount', label: '店铺商品数', align: 'center' },
|
||||
{ prop: 'status', label: '状态', align: 'center', format: v => this.dict.getLabel('integralSSStatus', v) }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
},
|
||||
|
||||
created () {
|
||||
this.dict.load('integralSSType', 'integralSSStatus', 'integralSSSType').then(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList () {
|
||||
this.instance.post(`/app/appintegralsupermarketshop/list`, null, {
|
||||
params: {
|
||||
...this.search
|
||||
}
|
||||
}).then((res) => {
|
||||
if (res.code == 0) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toAdd (id) {
|
||||
this.$emit('change', {
|
||||
type: 'AddStore',
|
||||
params: {
|
||||
id: id || ''
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
remove (id) {
|
||||
this.$confirm('确定删除该商品吗?').then(() => {
|
||||
this.instance.post(`/app/appintegralsupermarketshop/delete?id=${id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('删除成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
changeStatus (row) {
|
||||
this.$confirm(`确定${row.status === '0' ? '启用' : '停用'}该商铺?`).then(() => {
|
||||
this.instance.post(`/app/appintegralsupermarketshop/enable?id=${row.id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success(`${row.status === '0' ? '启用' : '停用'}成功`)
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.order_management {
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,220 @@
|
||||
<template>
|
||||
<ai-detail class="appgoods">
|
||||
<template slot="title">
|
||||
<ai-title :title="id ? '编辑商品' : '添加商品'" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-card title="基本信息">
|
||||
<template #content>
|
||||
<el-form class="ai-form" :model="form" label-width="120px" ref="form">
|
||||
<el-form-item style="width: 100%" label="商品名称" prop="title" :rules="[{required: true, message: '请输入商品名称', trigger: 'blur'}]">
|
||||
<el-input type="input" size="small" v-model="form.title" clearable placeholder="请输入商品名称" :maxlength="50" show-word-limit></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item style="width: 100%" label="商品类型" prop="type" :rules="[{required: true, message: '请选择商品类型', trigger: 'change'}]">
|
||||
<ai-select
|
||||
v-model="form.type"
|
||||
placeholder="请选择商品类型"
|
||||
:selectList="dict.getDict('integralSGType')">
|
||||
</ai-select>
|
||||
</el-form-item>
|
||||
<el-form-item style="width: 100%" label="商品类型说明" prop="typeExplain">
|
||||
<el-input type="input" size="small" v-model="form.typeExplain" clearable placeholder="请输入商品类型说明" maxlength="50" show-word-limit></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item style="width: 100%" label="商品图片" prop="picUrl" :rules="[{required: true, message: '请选择商品图片', trigger: 'change'}]">
|
||||
<ai-uploader
|
||||
:instance="instance"
|
||||
isShowTip
|
||||
isCrop
|
||||
:cropOps="{
|
||||
fixedNumber: [1, 1]
|
||||
}"
|
||||
v-model="form.picUrl"
|
||||
:limit="1">
|
||||
<template slot="tips">
|
||||
<p>建议尺寸:400*400,支持上传jpg/png格式图片,最多上传一张,单个图片大小不超过10M</p>
|
||||
</template>
|
||||
</ai-uploader>
|
||||
</el-form-item>
|
||||
<el-form-item label="零售价格" prop="retailPrice" :rules="[{required: true, message: '请输入零售价格', trigger: 'change'}]">
|
||||
<el-input-number style="width: 200px;" size="small" :precision="2" type="input" v-model="form.retailPrice" clearable placeholder="请输入零售价格" :min="0"></el-input-number>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.type === '1'" label="商品链接" prop="jdUrl" :rules="[{required: true, message: '请输入商品链接', trigger: 'blur'}]">
|
||||
<el-input type="input" size="small" v-model="form.jdUrl" clearable placeholder="请输入商品链接"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item style="width: 100%" label="商品描述" prop="description">
|
||||
<el-input type="textarea" :rows="4" size="small" v-model="form.description" clearable placeholder="请输入商品描述"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</ai-card>
|
||||
</template>
|
||||
<template #footer>
|
||||
<el-button @click="cancel">取消</el-button>
|
||||
<el-button type="primary" @click="confirm">提交</el-button>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Add',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
form: {
|
||||
typeExplain: '',
|
||||
title: '',
|
||||
description: '',
|
||||
jdUrl: '',
|
||||
retailPrice: undefined,
|
||||
picUrl: []
|
||||
},
|
||||
girdList: [],
|
||||
cropOps: {
|
||||
width: '800px',
|
||||
height: '800px'
|
||||
},
|
||||
id: ''
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
if (this.params && this.params.id) {
|
||||
this.id = this.params.id
|
||||
this.getInfo(this.params.id)
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getInfo (id) {
|
||||
this.instance.post(`/app/appintegralsupermarketgoods/queryDetailById?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.form = res.data
|
||||
this.form.picUrl = [{
|
||||
url: res.data.picUrl
|
||||
}]
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
confirm () {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.instance.post(`/app/appintegralsupermarketgoods/addOrUpdate`, {
|
||||
...this.form,
|
||||
picUrl: this.form.picUrl[0].url,
|
||||
id: this.params.id || ''
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('提交成功')
|
||||
setTimeout(() => {
|
||||
this.cancel(true)
|
||||
}, 600)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancel (isRefresh) {
|
||||
this.$emit('change', {
|
||||
type: 'GoodsList',
|
||||
isRefresh: !!isRefresh
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.appgoods {
|
||||
.AppAnnounceDetail-select {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 32px;
|
||||
line-height: 1;
|
||||
background: #F5F5F5;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #D0D4DC;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
|
||||
&:hover {
|
||||
border-color: #26f;
|
||||
}
|
||||
|
||||
& > i {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
line-height: 32px;
|
||||
padding: 0 12px;
|
||||
color: #888888;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
border-right: 1px solid #D0D4DC;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.AppAnnounceDetail-select__input {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.select-right {
|
||||
height: 100%;
|
||||
padding: 0 12px;
|
||||
color: #222222;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
transition: all ease 0.3s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.select-left {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
padding: 5px 0 0px 12px;
|
||||
border-right: 1px solid #D0D4DC;
|
||||
border-radius: 4px 0 0 4px;
|
||||
background: #fff;
|
||||
|
||||
em {
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
margin: 0 4px 5px 0;
|
||||
color: #222222;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
span {
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
margin: 0 4px 5px 0;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
color: #222222;
|
||||
background: #F3F4F7;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #D0D4DC;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div class="AppHelp">
|
||||
<keep-alive :include="['List']">
|
||||
<component ref="component" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Add from './components/Add'
|
||||
import List from './components/List'
|
||||
import Detail from './components/Detail'
|
||||
|
||||
export default {
|
||||
name: 'AppIntegratingTask',
|
||||
label: '积分任务',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
component: 'List',
|
||||
params: {},
|
||||
include: []
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
Add,
|
||||
List,
|
||||
Detail
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange (data) {
|
||||
if (data.type === 'Add') {
|
||||
this.component = 'Add'
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'Detail') {
|
||||
this.component = 'Detail'
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'List') {
|
||||
this.component = 'List'
|
||||
this.params = data.params
|
||||
|
||||
this.$nextTick(() => {
|
||||
if (data.isRefresh) {
|
||||
this.$refs.component.getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.AppHelp {
|
||||
height: 100%;
|
||||
background: #F3F6F9;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
433
project/shuzipingchang/app/AppIntegratingTask/components/Add.vue
Normal file
433
project/shuzipingchang/app/AppIntegratingTask/components/Add.vue
Normal file
@@ -0,0 +1,433 @@
|
||||
<template>
|
||||
<ai-detail class="activitiesAdd">
|
||||
<ai-title slot="title" :title="id? '编辑活动':'创建活动'" isShowBottomBorder isShowBack @onBackClick="cancel(true)"/>
|
||||
<template slot="content">
|
||||
<ai-card title="基本信息">
|
||||
<template #content>
|
||||
<el-form class="ai-form" ref="form" :model="form" :rules="formRules" size="small" label-width="120px">
|
||||
|
||||
<el-form-item label="活动名称" prop="title" style="width: 100%">
|
||||
<el-input v-model="form.title" placeholder="请输入" show-word-limit maxlength="64"></el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="活动说明" style="width: 100%">
|
||||
<el-input type="textarea" :rows="5" v-model="form.detail" placeholder="请输入" show-word-limit maxlength="500"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动图片" prop="files">
|
||||
<ai-uploader
|
||||
:instance="instance"
|
||||
v-model="form.files"
|
||||
:limit="9">
|
||||
</ai-uploader>
|
||||
</el-form-item>
|
||||
<el-form-item prop="areaId" style="width: 100%;" label="活动地区" :rules="[{required: true, message: '请选择地区', trigger: 'change'}]">
|
||||
<ai-area-select
|
||||
clearable
|
||||
@fullname="v => form.areaName = v"
|
||||
:disabled-level="$store.state.user.info.areaList.length"
|
||||
always-show
|
||||
:instance="instance"
|
||||
v-model="form.areaId">
|
||||
</ai-area-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动地点" style="width: 100%;" prop="address" :rules="[{required: true, message: '请选择活动地点', trigger: 'change'}]">
|
||||
<el-input v-model="form.address" disabled>
|
||||
<template slot="append">
|
||||
<el-button @click="showMap = true">选择位置</el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="积分类型" prop="type" style="width: 100%" :rules="[{required: true, message: '请选择积分类型', trigger: 'change'}]">
|
||||
<el-radio-group v-model="form.type" @change="$refs.form.clearValidate()">
|
||||
<el-radio label="0">打卡得积分</el-radio>
|
||||
<el-radio label="1">报名得积分</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="打卡范围" prop="clockRange" style="width: 100%" v-if="form.type === '0'">
|
||||
<el-input type="number" v-model="form.clockRange" placeholder="请输入" >
|
||||
<template slot="append">米</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="form.type === '0' ? '进场打卡时间' : '报名时间'" prop="intoTime">
|
||||
<el-date-picker style="width: 100%" v-model="form.intoTime" type="datetimerange" start-placeholder="开始日期" :picker-options="timeOption"
|
||||
end-placeholder="结束日期" value-format="yyyy-MM-dd HH:mm:ss" ></el-date-picker>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="form.type === '0'" label="进场得积分" prop="intoIntegral">
|
||||
<el-input v-model="form.intoIntegral" type="number" placeholder="请输入" style="width: 100%">
|
||||
<template slot="append">积分</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="form.type === '0'" :label="form.type === '0' ? '离场打卡时间' : '离场时间'" prop="exitTime">
|
||||
<el-date-picker style="width: 100%" v-model="form.exitTime" type="datetimerange" start-placeholder="开始日期" :picker-options="timeOption"
|
||||
end-placeholder="结束日期" value-format="yyyy-MM-dd HH:mm:ss">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="form.type === '0'" label="离场得积分" prop="exitIntegral">
|
||||
<el-input v-model="form.exitIntegral" type="number" placeholder="请输入" style="width: 100%">
|
||||
<template slot="append">积分</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.type === '1'" label="报名得积分" prop="enrollIntegral" :rules="[{required: true, message: '请选择报名得积分', trigger: 'blur'}]">
|
||||
<el-input v-model="form.enrollIntegral" type="number" placeholder="请输入" style="width: 100%">
|
||||
<template slot="append">积分</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<ai-dialog title="地图" :visible.sync="showMap" @opened="initMap" width="800px" class="mapDialog" @onConfirm="selectMap">
|
||||
<div id="map"></div>
|
||||
<el-form label-width="80px" style="padding: 10px 20px 0 20px;">
|
||||
<el-row type="flex" justify="space-between">
|
||||
<el-form-item label="经度">
|
||||
<el-input disabled size="small" v-model="placeDetail.lng"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="纬度">
|
||||
<el-input disabled size="small" v-model="placeDetail.lat"></el-input>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<el-input id="searchPlaceInput" size="medium" class="searchPlaceInput" clearable v-model="searchPlace" autocomplete="on" @change="placeSearch.search(searchPlace)" placeholder="请输入关键字">
|
||||
<el-button type="primary" slot="append" @click="placeSearch.search(searchPlace)">搜索</el-button>
|
||||
</el-input>
|
||||
<div id="searchPlaceOutput" />
|
||||
</ai-dialog>
|
||||
</template>
|
||||
</ai-card>
|
||||
</template>
|
||||
<template #footer>
|
||||
<el-button class="delete-btn footer-btn" @click="cancel(false)">取消</el-button>
|
||||
<el-button class="footer-btn" type="primary" @click="confirm()">保存</el-button>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AMapLoader from '@amap/amap-jsapi-loader'
|
||||
export default {
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object,
|
||||
},
|
||||
|
||||
data() {
|
||||
var validLocation = (rule, value, callback) => {
|
||||
if(!this.form.lat || !this.form.lng) {
|
||||
return callback(new Error('请标绘地理位置'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
return {
|
||||
form: {
|
||||
title: '',
|
||||
detail: '',
|
||||
lng: '',
|
||||
lat: '',
|
||||
type: '0',
|
||||
areaId: '',
|
||||
enrollIntegral: '',
|
||||
files: [],
|
||||
address: '',
|
||||
clockRange: '',
|
||||
intoTime: [],
|
||||
intoBegintime: '',
|
||||
intoEndtime: '',
|
||||
intoIntegral: '',
|
||||
exitTime: [],
|
||||
exitBegintime: '',
|
||||
exitEndtime: '',
|
||||
exitIntegral: '',
|
||||
},
|
||||
formRules: {
|
||||
title: [{required: true, message: "请输入活动名称", trigger: "blur"}],
|
||||
location: [{required: true, validator: validLocation, trigger: "blur"}],
|
||||
clockRange: [{required: true, message: "请输入打卡范围", trigger: "blur"}],
|
||||
intoTime: [{required: true, message: "请选择进场打卡时间", trigger: "blur"}],
|
||||
intoIntegral: [{required: true, message: "请输入进场得积分", trigger: "blur"}],
|
||||
exitTime: [{required: true, message: "请选择离场打卡时间", trigger: "blur"}]
|
||||
},
|
||||
id: '',
|
||||
isEdit: false,
|
||||
info: {},
|
||||
mapDetail: null,
|
||||
map: null,
|
||||
placeSearch: null,
|
||||
placeDetail: {
|
||||
lng: '',
|
||||
lat: '',
|
||||
address: ''
|
||||
},
|
||||
lng: '',
|
||||
lat: '',
|
||||
showMap: false,
|
||||
searchPlace: '',
|
||||
timeOption: {
|
||||
disabledDate(date) {
|
||||
return date.getTime() < Date.now() - 24 * 60 * 60 * 1000
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.form.areaId = this.$store.state.user.info.areaId
|
||||
this.$dict.load('tfx_activityStatus')
|
||||
if(this.params && this.params.id) {
|
||||
this.id = this.params.id
|
||||
this.getDetail()
|
||||
setTimeout(() => {
|
||||
},500)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'form.intoTime': {
|
||||
handler(val) {
|
||||
if(val) {
|
||||
this.form.intoBegintime = val[0]
|
||||
this.form.intoEndtime = val[1]
|
||||
}
|
||||
}
|
||||
},
|
||||
'form.exitTime': {
|
||||
handler(val) {
|
||||
if(val) {
|
||||
this.form.exitBegintime = val[0]
|
||||
this.form.exitEndtime = val[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.$nextTick(() => {
|
||||
this.instance.post("/app/appdvcpconfig/getCorpLocation").then(res => {
|
||||
if (res.code == 0) {
|
||||
this.lng = res.data.lng
|
||||
this.lat = res.data.lat
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
selectMap() {
|
||||
this.form.lng = this.placeDetail.lng
|
||||
this.form.lat = this.placeDetail.lat
|
||||
this.form.address = this.placeDetail.address
|
||||
this.showMap = false
|
||||
},
|
||||
initMap() {
|
||||
if (this.map) return
|
||||
AMapLoader.load({
|
||||
key: '54a02a43d9828a8f9cd4f26fe281e74e',
|
||||
version: '2.0',
|
||||
plugins: ['AMap.PlaceSearch', 'AMap.AutoComplete', 'AMap.Geocoder'],
|
||||
}).then((AMap) => {
|
||||
this.map = new AMap.Map('map', {
|
||||
resizeEnable: true,
|
||||
zooms: [6, 20],
|
||||
center: this.form.lng ? [this.form.lng, this.form.lat] : [this.lng, this.lat],
|
||||
zoom: 11,
|
||||
})
|
||||
this.placeSearch = new AMap.PlaceSearch({ map: this.map })
|
||||
new AMap.AutoComplete({
|
||||
input: 'searchPlaceInput',
|
||||
output: 'searchPlaceOutput',
|
||||
}).on('select', (e) => {
|
||||
if (e?.poi) {
|
||||
this.placeSearch.setCity(e.poi.adcode)
|
||||
this.movePosition(e.poi.location)
|
||||
}
|
||||
})
|
||||
this.map.on('click', (e) => {
|
||||
new AMap.Geocoder().getAddress(e.lnglat, (sta, res) => {
|
||||
if (res?.regeocode) {
|
||||
this.placeDetail = {
|
||||
lng: e.lnglat?.lng,
|
||||
lat: e.lnglat?.lat,
|
||||
address: res.regeocode.formattedAddress,
|
||||
}
|
||||
}
|
||||
})
|
||||
this.movePosition(e.lnglat)
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
movePosition(center) {
|
||||
if (this.map) {
|
||||
this.map.clearMap()
|
||||
this.map.panTo(center)
|
||||
this.map.add([
|
||||
new AMap.Marker({
|
||||
position: center,
|
||||
clickable: true,
|
||||
}),
|
||||
])
|
||||
this.map.setFitView()
|
||||
}
|
||||
},
|
||||
cancel (isRefresh) {
|
||||
this.$emit('change', {
|
||||
type: 'List',
|
||||
isRefresh: !!isRefresh
|
||||
})
|
||||
},
|
||||
|
||||
getMap(lng,lat,address) {
|
||||
AMapLoader.load({
|
||||
key: '54a02a43d9828a8f9cd4f26fe281e74e',
|
||||
version: '2.0',
|
||||
plugins: ['AMap.PlaceSearch', 'AMap.AutoComplete', 'AMap.Geocoder'],
|
||||
}).then((AMap) => {
|
||||
this.mapDetail = new AMap.Map(document.getElementById("mapDetail"), {
|
||||
resizeEnable: true,
|
||||
zooms: [6, 20],
|
||||
zoom: 11,
|
||||
center:[lng,lat],
|
||||
})
|
||||
let marker = new AMap.Marker({
|
||||
position: new AMap.LngLat(lng,lat),
|
||||
title: address
|
||||
})
|
||||
this.mapDetail.add(marker);
|
||||
})
|
||||
},
|
||||
|
||||
update() {
|
||||
this.isEdit = true
|
||||
this.getDetail()
|
||||
},
|
||||
|
||||
getDetail() {
|
||||
this.instance.post(`/app/appintegraltask/queryDetailById`,null, {
|
||||
params: {id:this.id}
|
||||
}).then((res) => {
|
||||
if(res?.data) {
|
||||
this.form = res.data
|
||||
this.form.intoTime = [res.data.intoBegintime,res.data.intoEndtime]
|
||||
this.form.exitTime = [res.data.exitBegintime,res.data.exitEndtime]
|
||||
this.info = res.data
|
||||
this.placeDetail.lng = res.data.lng
|
||||
this.placeDetail.lat = res.data.lat
|
||||
this.getMap(this.info.lng,this.info.lat,this.info.address)
|
||||
}
|
||||
})
|
||||
},
|
||||
selectCandidate(v) {
|
||||
this.form.candidateUsers = v
|
||||
},
|
||||
selectVote(e) {
|
||||
this.form.voteUsers = e
|
||||
},
|
||||
|
||||
handleAreaSelect(v) {
|
||||
this.form.areaName = v?.[0]?.label
|
||||
},
|
||||
|
||||
confirm() {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
if(new Date(this.form.intoBegintime).getTime() <= Date.now()){
|
||||
return this.$message.error('进场打卡开始时间不能小于当前时间')
|
||||
}
|
||||
let intoEnd = new Date(this.form.intoEndtime).getTime()
|
||||
let exitBegin = new Date(this.form.exitBegintime).getTime()
|
||||
if(exitBegin <= intoEnd) {
|
||||
return this.$message.error('离场的开始时间不能小于且等于进场的结束时间')
|
||||
}
|
||||
this.instance.post(`/app/appintegraltask/addOrUpdate`,{
|
||||
...this.form
|
||||
}).then(res => {
|
||||
if(res.code == 0) {
|
||||
this.$message.success(this.id ? '编辑成功' : '新增成功')
|
||||
this.cancel(true)
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log(err);
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scope>
|
||||
.activitiesAdd {
|
||||
height: 100%;
|
||||
|
||||
:deep( .amap-logo ){
|
||||
display: none!important;
|
||||
}
|
||||
:deep( .amap-copyright ){
|
||||
display: none!important;
|
||||
}
|
||||
|
||||
:deep( .el-date-editor .el-input ){
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tips {
|
||||
width: 100%;
|
||||
border: 1px solid #f82;
|
||||
background-color: #fff3e9;
|
||||
color: #f82;
|
||||
padding: 8px 16px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
margin-bottom: 32px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.amap-container {
|
||||
height: 380px;
|
||||
}
|
||||
}
|
||||
|
||||
.mapDialog {
|
||||
.el-dialog__body {
|
||||
padding: 0;
|
||||
.ai-dialog__content {
|
||||
padding: 0;
|
||||
}
|
||||
.ai-dialog__content--wrapper {
|
||||
padding: 0 !important;
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 420px;
|
||||
}
|
||||
|
||||
.searchPlaceInput {
|
||||
position: absolute;
|
||||
width: 250px;
|
||||
top: 30px;
|
||||
left: 25px;
|
||||
}
|
||||
|
||||
#searchPlaceOutput {
|
||||
position: absolute;
|
||||
width: 250px;
|
||||
left: 25px;
|
||||
height: initial;
|
||||
top: 80px;
|
||||
background: white;
|
||||
z-index: 250;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
|
||||
.auto-item {
|
||||
text-align: left;
|
||||
font-size: 14px;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,192 @@
|
||||
<template>
|
||||
<ai-detail class="activitiesAdd">
|
||||
<template slot="title">
|
||||
<ai-title title="活动详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-card title="基本信息">
|
||||
<template #content>
|
||||
<ai-wrapper>
|
||||
<ai-info-item label="活动名称" :value="info.title"></ai-info-item>
|
||||
<ai-info-item label="创建人" :value="info.createUserName"></ai-info-item>
|
||||
<ai-info-item label="活动说明" isLine :value="info.detail"></ai-info-item>
|
||||
<ai-info-item label="活动图片" isLine>
|
||||
<ai-uploader
|
||||
disabled
|
||||
:instance="instance"
|
||||
:value="info.files">
|
||||
</ai-uploader>
|
||||
</ai-info-item>
|
||||
<ai-info-item label="活动地区" isLine :value="info.areaName"></ai-info-item>
|
||||
<ai-info-item label="活动地点" :value="info.address"></ai-info-item>
|
||||
<ai-info-item label="地图位置" isLine><div id="mapDetail"></div></ai-info-item>
|
||||
<ai-info-item label="积分类型" isLine :value="info.type === '0' ? '打卡得积分' : '报名得积分'"></ai-info-item>
|
||||
<ai-info-item label="活动状态">
|
||||
{{ dict.getLabel('fdIntegralTaskStatus',info.status) }}
|
||||
</ai-info-item>
|
||||
<ai-info-item v-if="info.type === '0'" label="打卡范围">{{ info.clockRange }}米</ai-info-item>
|
||||
<ai-info-item :label="info.type === '0' ? '进场打卡时间' : '报名时间'">{{ info.intoBegintime }}至{{ info.intoEndtime}}</ai-info-item>
|
||||
<ai-info-item v-if="info.type === '0'" label="进场得积分">{{ info.intoIntegral || 0 }}分</ai-info-item>
|
||||
<ai-info-item v-if="info.type === '0'" :label="info.type === '0' ? '离场打卡时间' : '离场时间'">{{ info.exitBegintime }}至{{ info.exitEndtime}}</ai-info-item>
|
||||
<ai-info-item v-if="info.type === '0'" label="离场得积分">{{ info.exitIntegral || 0 }}分</ai-info-item>
|
||||
<ai-info-item v-if="info.type === '1'" label="报名得积分">{{ info.enrollIntegral || 0 }}分</ai-info-item>
|
||||
</ai-wrapper>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-card title="打卡记录" v-if="info.type === '0'">
|
||||
<template #content>
|
||||
<ai-wrapper>
|
||||
<ai-info-item label="参与人数" :value="search1.total"></ai-info-item>
|
||||
</ai-wrapper>
|
||||
<ai-table
|
||||
:tableData="tableData1"
|
||||
:col-configs="colConfigs1"
|
||||
:total="search1.total"
|
||||
:current.sync="search1.current"
|
||||
:size.sync="search1.size"
|
||||
@getList="getList1">
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-card title="报名记录" v-if="info.type === '1'">
|
||||
<template #content>
|
||||
<ai-wrapper>
|
||||
<ai-info-item label="参与人数" :value="search1.total"></ai-info-item>
|
||||
</ai-wrapper>
|
||||
<ai-table
|
||||
:tableData="tableData1"
|
||||
:col-configs="colConfigs2"
|
||||
:total="search1.total"
|
||||
:current.sync="search1.current"
|
||||
:size.sync="search1.size"
|
||||
@getList="getList1">
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-card>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AMapLoader from '@amap/amap-jsapi-loader'
|
||||
export default {
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object,
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
id: '',
|
||||
info: {},
|
||||
mapDetail: null,
|
||||
map: null,
|
||||
search1: {
|
||||
total: 0,
|
||||
current: 1,
|
||||
size: 10
|
||||
},
|
||||
tableData1: [],
|
||||
colConfigs1: [
|
||||
{prop: 'realName', label: '姓名', align: 'center' },
|
||||
{prop: 'phone', label: '联系方式', align: 'center' },
|
||||
{prop: 'areaName', label: '所属地区', align: 'center' },
|
||||
{prop: 'intoClockTime', label: '进场打卡时间', align: 'center' },
|
||||
{prop: 'exitClockTime', label: '离场打卡时间', align: 'center' }
|
||||
],
|
||||
colConfigs2: [
|
||||
{prop: 'realName', label: '姓名', align: 'center' },
|
||||
{prop: 'phone', label: '联系方式', align: 'center' },
|
||||
{prop: 'areaName', label: '所属地区', align: 'center' },
|
||||
{prop: 'enrollClockTime', label: '报名时间', align: 'center' }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.id = this.params.id
|
||||
this.$dict.load('tfx_activityStatus').then(() => {
|
||||
this.getDetail()
|
||||
})
|
||||
|
||||
this.getList1()
|
||||
},
|
||||
|
||||
methods: {
|
||||
cancel (isRefresh) {
|
||||
this.$emit('change', {
|
||||
type: 'List',
|
||||
isRefresh: !!isRefresh
|
||||
})
|
||||
},
|
||||
|
||||
getList1 () {
|
||||
this.instance.post(`/app/appintegraltask/clockList?taskId=${this.params.id}`,null, {
|
||||
params: {
|
||||
...this.search1,
|
||||
}
|
||||
}).then(res=> {
|
||||
if(res?.data) {
|
||||
this.tableData1 = res.data.records
|
||||
this.search1.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
getMap(lng,lat,address) {
|
||||
AMapLoader.load({
|
||||
key: '54a02a43d9828a8f9cd4f26fe281e74e',
|
||||
version: '2.0',
|
||||
plugins: ['AMap.PlaceSearch', 'AMap.AutoComplete', 'AMap.Geocoder'],
|
||||
}).then((AMap) => {
|
||||
this.mapDetail = new AMap.Map(document.getElementById("mapDetail"), {
|
||||
resizeEnable: true,
|
||||
zooms: [6, 20],
|
||||
zoom: 11,
|
||||
center:[lng,lat],
|
||||
})
|
||||
let marker = new AMap.Marker({
|
||||
position: new AMap.LngLat(lng,lat),
|
||||
title: address
|
||||
})
|
||||
this.mapDetail.add(marker);
|
||||
})
|
||||
},
|
||||
|
||||
update() {
|
||||
this.isEdit = true
|
||||
this.getDetail()
|
||||
},
|
||||
|
||||
getDetail() {
|
||||
this.instance.post(`/app/appintegraltask/queryDetailById?id=${this.params.id}`).then((res) => {
|
||||
if(res.data) {
|
||||
this.info = res.data
|
||||
this.getMap(this.info.lng, this.info.lat, this.info.address)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scope>
|
||||
.activitiesAdd {
|
||||
height: 100%;
|
||||
|
||||
:deep( .amap-logo ){
|
||||
display: none!important;
|
||||
}
|
||||
:deep( .amap-copyright ){
|
||||
display: none!important;
|
||||
}
|
||||
|
||||
:deep( .el-date-editor .el-input ){
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.amap-container {
|
||||
height: 380px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,223 @@
|
||||
<template>
|
||||
<ai-list class="activitiesList">
|
||||
<ai-title
|
||||
slot="title"
|
||||
title="活动管理"
|
||||
isShowBottomBorder
|
||||
isShowArea
|
||||
:hideLevel="$store.state.user.info.areaList.length - 1"
|
||||
v-model="search.areaId"
|
||||
:instance="instance"
|
||||
@change="search.current = 1, getList()">
|
||||
</ai-title>
|
||||
<template #content>
|
||||
<ai-search-bar bottomBorder>
|
||||
<template #left>
|
||||
<el-button size="small" type="primary" icon="iconfont iconAdd" @click="toAdd('')" >创建活动</el-button>
|
||||
<el-date-picker
|
||||
v-model="search.beginDate"
|
||||
type="date"
|
||||
size="small"
|
||||
value-format="yyyy-MM-dd"
|
||||
placeholder="选择开始日期"
|
||||
@change="search.current = 1, getList()">
|
||||
</el-date-picker>
|
||||
<el-date-picker
|
||||
v-model="search.endDate"
|
||||
type="date"
|
||||
size="small"
|
||||
value-format="yyyy-MM-dd"
|
||||
placeholder="选择结束日期"
|
||||
@change="search.current = 1, getList()">
|
||||
</el-date-picker>
|
||||
<ai-select
|
||||
v-model="search.status"
|
||||
clearable
|
||||
placeholder="活动状态"
|
||||
:selectList="dict.getDict('fdIntegralTaskStatus')"
|
||||
@change="search.current = 1, getList()">
|
||||
</ai-select>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-input
|
||||
v-model="search.title"
|
||||
size="small"
|
||||
placeholder="活动名称/创建人"
|
||||
clearable
|
||||
v-throttle="() => {getList()}"
|
||||
@clear="search.title = '', getList()"
|
||||
suffix-icon="iconfont iconSearch">
|
||||
</el-input>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
:tableData="tableData"
|
||||
:total="search.total"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@getList="getList"
|
||||
:col-configs="colConfigs"
|
||||
:dict="dict">
|
||||
<el-table-column slot="qrcode" width="200px" label="二维码" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="qrcode">
|
||||
<el-button type="text" @click="qrcode(row.qrCode, row.id)">{{ row.qrCode ? '预览' : '生成' }}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column slot="options" label="操作" fixed="right" align="center" width="120px">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click.native="toDetail(row.id)">详情</el-button>
|
||||
<el-button type="text" :disabled="row.status ==2" @click.native="stopBtn(row.id)">结束</el-button>
|
||||
<!-- <el-button type="text" @click.native="handleDelete(row.id)">删除</el-button> -->
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
<div class="qrCode" v-viewer="{movable: true}" v-show="false">
|
||||
<img :src="img">
|
||||
</div>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
search: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 0,
|
||||
title: '',
|
||||
areaId: '',
|
||||
status: '',
|
||||
beginDate: '',
|
||||
endDate: ''
|
||||
},
|
||||
tableData: [],
|
||||
img: '',
|
||||
isLoading: false,
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.search.areaId = this.$store.state.user.info.areaId
|
||||
this.$dict.load('fdIntegralTaskStatus').then(()=> {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
computed: {
|
||||
colConfigs() {
|
||||
return [
|
||||
{ prop: "title", label: "活动名称", align: "left" },
|
||||
{ prop: "areaName", label: "活动地区", align: "center" },
|
||||
{ prop: "createUserName", label: "创建人", align: "center" },
|
||||
{
|
||||
prop: "intoBegintime",
|
||||
label: "开始结束时间",
|
||||
align: "center",
|
||||
width: "400px",
|
||||
render: (h, {row}) => h('p',
|
||||
{
|
||||
textAlign: 'center'
|
||||
},
|
||||
row.exitEndtime ? `${row.intoBegintime}至${row.exitEndtime}` : row.intoBegintime)
|
||||
},
|
||||
{ prop: "status", label: "活动状态", align: "center", dict:"fdIntegralTaskStatus" },
|
||||
{ slot: "qrcode" },
|
||||
{ slot: "options", },
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList() {
|
||||
this.instance.post(`/app/appintegraltask/list`,null, {
|
||||
params: {
|
||||
...this.search,
|
||||
}
|
||||
}).then(res=> {
|
||||
if(res?.data) {
|
||||
this.tableData = res.data.records
|
||||
this.search.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toDetail (id) {
|
||||
this.$emit('change', {
|
||||
type: 'Detail',
|
||||
params: {
|
||||
id: id || '',
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toAdd(id) {
|
||||
this.$emit('change', {
|
||||
type: 'Add',
|
||||
params: {
|
||||
id: id || '',
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
qrcode (qrcode, id) {
|
||||
if (!qrcode) {
|
||||
this.isLoading = true
|
||||
this.instance.post(`/app/appintegraltask/generateQrCode?id=${id}&width=400&height=400`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('二维码生成成功!')
|
||||
this.getList()
|
||||
}
|
||||
this.isLoading = false
|
||||
})
|
||||
} else {
|
||||
this.img = qrcode
|
||||
this.$nextTick(() => {
|
||||
setTimeout(() => {
|
||||
const viewer = this.$el.querySelector('.qrCode').$viewer
|
||||
viewer.view()
|
||||
}, 600)
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
handleDelete (id) {
|
||||
this.$confirm('确定删除该活动?').then(() => {
|
||||
this.instance.post(`/app/appintegraltask/delete?ids=${id}`).then(res=>{
|
||||
if(res.code == 0) {
|
||||
this.$message.success('删除成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
stopBtn (id) {
|
||||
this.$confirm('确定要结束该活动吗?').then(() => {
|
||||
this.instance.post(`/app/appintegraltask/stop?id=${id}`).then(res=>{
|
||||
if(res.code == 0) {
|
||||
this.$message.success('结束成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.activitiesList {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
202
project/shuzipingchang/app/AppPageSet/AppPageSet.vue
Normal file
202
project/shuzipingchang/app/AppPageSet/AppPageSet.vue
Normal file
@@ -0,0 +1,202 @@
|
||||
<template>
|
||||
<div class="AppPageSet">
|
||||
<ai-list class="list">
|
||||
<ai-title slot="title" title="引导页设置" isShowBottomBorder :instance="instance"></ai-title>
|
||||
<template slot="content">
|
||||
<ai-search-bar bottomBorder>
|
||||
<template #left>
|
||||
<el-button type="primary" @click="isShow = true" icon="iconfont iconAdd">添加</el-button>
|
||||
</template>
|
||||
<template #right>
|
||||
<span class="text">是否开启引导页</span> <el-switch v-model="isStart" @change="changeStatus" active-value="1" inactive-value="0"></el-switch>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<div class="content">
|
||||
<ai-table
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="total"
|
||||
style="margin-top: 16px;"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@getList="getList">
|
||||
<el-table-column
|
||||
slot="index"
|
||||
type="index"
|
||||
width="100px"
|
||||
label="序号"
|
||||
align="center">
|
||||
</el-table-column>
|
||||
<el-table-column slot="urlList" label="缩略图" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<ai-uploader
|
||||
:instance="instance"
|
||||
disabled
|
||||
v-model="row.urlList"
|
||||
:limit="1">
|
||||
</ai-uploader>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column slot="options" width="140px" fixed="right" label="操作" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click="edit(row)">编辑</el-button>
|
||||
<el-button type="text" @click="remove(row.id)">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</div>
|
||||
<ai-dialog
|
||||
:visible.sync="isShow"
|
||||
width="890px"
|
||||
:title="form.id ? '编辑引导页' : '添加引导页'"
|
||||
@close="onClose"
|
||||
@onConfirm="onConfirm">
|
||||
<el-form ref="form" class="ai-form" :model="form" label-width="110px" label-position="right">
|
||||
<el-form-item label="缩略图" style="width: 100%;" prop="urlList" :rules="[{required: true, message: '请上传缩略图', trigger: 'blur'}]">
|
||||
<ai-uploader v-if="isShow"
|
||||
:instance="instance"
|
||||
isShowTip
|
||||
v-model="form.urlList"
|
||||
:limit="1">
|
||||
</ai-uploader>
|
||||
</el-form-item>
|
||||
<el-form-item label="引导页名称" style="width: 100%" prop="title" :rules="[{required: true, message: '请输入引导页名称', trigger: 'blur'}]">
|
||||
<el-input v-model="form.title" size="small" placeholder="请输入引导页名称" maxlength="20"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ai-dialog>
|
||||
</template>
|
||||
</ai-list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'AppPageSet',
|
||||
label: '引导页设置',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
search: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
},
|
||||
colConfigs: [
|
||||
{ slot: 'index', label: '序号', align: 'center'},
|
||||
{ slot: 'urlList' },
|
||||
{ prop: 'title', label: '引导页名称', align: 'center' },
|
||||
{ prop: 'createTime', label: '创建时间', width: '200', align: 'center' },
|
||||
{ prop: 'createUserName', label: '创建人', width: '200', align: 'center' },
|
||||
{ slot: 'option'}
|
||||
],
|
||||
tableData: [],
|
||||
total: 0,
|
||||
isStart: '',
|
||||
isFlag: false,
|
||||
isShow: false,
|
||||
form: {
|
||||
urlList: [],
|
||||
picUrl: '',
|
||||
title: ''
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.getList()
|
||||
this.getStatus()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList () {
|
||||
this.instance.post(`/app/appwechatguidepage/list`, null, {
|
||||
params: {
|
||||
...this.search
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
res.data.records.map((item) => {
|
||||
item.urlList = [{url: item.picUrl}]
|
||||
})
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
remove (id) {
|
||||
this.$confirm('确定删除该数据?').then(() => {
|
||||
this.instance.post(`/app/appwechatguidepage/delete?ids=${id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('删除成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
edit (e) {
|
||||
this.form = {...e}
|
||||
this.form.urlList = [{
|
||||
url: e.picUrl
|
||||
}]
|
||||
this.isShow = true
|
||||
},
|
||||
onClose () {
|
||||
this.form.id = ''
|
||||
this.form.urlList = null
|
||||
this.form.title = ''
|
||||
this.isShow = false
|
||||
},
|
||||
onConfirm () {
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.instance.post(`/app/appwechatguidepage/addOrUpdate`, {
|
||||
...this.form,
|
||||
picUrl: this.form.urlList[0].url
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('提交成功!')
|
||||
this.onClose()
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
getStatus() {
|
||||
this.instance.post(`/app/appwechatguidepage/enableStatus`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.isStart = res.data
|
||||
this.isFlag = false
|
||||
}
|
||||
})
|
||||
},
|
||||
changeStatus() {
|
||||
if(this.isFlag == true) return
|
||||
this.isFlag = true
|
||||
this.instance.post(`/app/appwechatguidepage/enable`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success(this.isStart == 1 ? '引导页已开启' : '引导页已关闭')
|
||||
this.getStatus()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.AppPageSet {
|
||||
.text {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div class="AppHelp">
|
||||
<keep-alive :include="['List']">
|
||||
<component ref="component" :permissions="permissions" :is="component" @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Add from './components/Add'
|
||||
import List from './components/List'
|
||||
import Detail from './components/Detail'
|
||||
|
||||
export default {
|
||||
name: 'AppResidentInfo',
|
||||
label: '居民信息',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
component: 'List',
|
||||
params: {},
|
||||
include: []
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
Add,
|
||||
List,
|
||||
Detail
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange (data) {
|
||||
if (data.type === 'Add') {
|
||||
this.component = 'Add'
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'Detail') {
|
||||
this.component = 'Detail'
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'List') {
|
||||
this.component = 'List'
|
||||
this.params = data.params
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$refs.component.getList()
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.AppHelp {
|
||||
height: 100%;
|
||||
background: #F3F6F9;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
717
project/shuzipingchang/app/AppResidentInfo/components/Add.vue
Normal file
717
project/shuzipingchang/app/AppResidentInfo/components/Add.vue
Normal file
@@ -0,0 +1,717 @@
|
||||
<template>
|
||||
<ai-detail class="residentDetail">
|
||||
<ai-title slot="title" :title="pageTitle" isShowBack @onBackClick="back" isShowBottomBorder>
|
||||
<template v-if="params.type === 'Detail'" #rightBtn>
|
||||
<el-button icon="iconfont iconDelete" @click="handleDelete()">
|
||||
删除人员
|
||||
</el-button>
|
||||
</template>
|
||||
</ai-title>
|
||||
<template #content>
|
||||
<el-form class="content-right" :model="baseInfo" ref="ruleForm" :rules="rules" label-width="130px"
|
||||
label-position="right" size="small">
|
||||
<template v-if="params.type === 'Detail'">
|
||||
<ai-edit-card slot="" :title="baseInfo.name||'基本信息'" :show-btn="permissions('app_appresident_edit')"
|
||||
@save="saveFrom" @cancel="getDetail(baseInfo.id)">
|
||||
<template #edit>
|
||||
<el-row type="flex">
|
||||
<div class="fill">
|
||||
<el-form-item label="姓名:" prop="name">
|
||||
<el-input
|
||||
v-model="baseInfo.name"
|
||||
autocomplete="off"
|
||||
placeholder="请输入姓名"
|
||||
maxlength="20"
|
||||
:disabled="isEdit"
|
||||
show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证号:" prop="idNumber">
|
||||
<el-input v-model="baseInfo.idNumber" placeholder="请输入身份证号" :maxlength="18" show-word-limit
|
||||
@change="idChange" :disabled="isEdit"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="性别:" prop="sex">
|
||||
<ai-select v-model="baseInfo.sex" :selectList="dict.getDict('sex')" :disabled="isEdit"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item label="个人照片:" prop="photo" class="fill">
|
||||
<ai-avatar :instance="instance" v-model="baseInfo.photo"/>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<el-row type="flex">
|
||||
<div class="fill">
|
||||
<el-form-item label="出生日期:">
|
||||
<el-date-picker
|
||||
disabled
|
||||
:editable="false"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
format="yyyy-MM-dd"
|
||||
v-model="baseInfo.birthday"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="文化程度:" prop="education">
|
||||
<ai-select v-model="baseInfo.education" :selectList="dict.getDict('education')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="政治面貌:" prop="politicsStatus">
|
||||
<ai-select v-model="baseInfo.politicsStatus" :selectList="dict.getDict('politicsStatus')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="职业:" prop="job">
|
||||
<ai-select v-model="baseInfo.job" :selectList="dict.getDict('job')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="宗教信仰:" prop="faithType">
|
||||
<ai-select v-model="baseInfo.faithType" :selectList="dict.getDict('faithType')"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="fill">
|
||||
<el-form-item label="年龄:" prop="age">
|
||||
<el-input
|
||||
disabled
|
||||
v-model="baseInfo.age"
|
||||
autocomplete="off"
|
||||
size="small"
|
||||
placeholder="请输入年龄"
|
||||
type="number"
|
||||
@mousewheel.native.prevent
|
||||
/>
|
||||
<!-- <p v-else>{{baseInfo.age}}</p> -->
|
||||
</el-form-item>
|
||||
<el-form-item label="民族:" prop="nation">
|
||||
<ai-select v-model="baseInfo.nation" :selectList="dict.getDict('nation')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="婚姻状况:" prop="maritalStatus">
|
||||
<ai-select v-model="baseInfo.maritalStatus" :selectList="dict.getDict('maritalStatus')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="兵役状况:" prop="militaryStatus">
|
||||
<ai-select v-model="baseInfo.militaryStatus" :selectList="dict.getDict('militaryStatus')"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-form-item label="籍贯:" prop=" birthplaceAreaId">
|
||||
<ai-area-select
|
||||
clearable
|
||||
always-show
|
||||
:instance="instance"
|
||||
v-model="baseInfo.birthplaceAreaId"
|
||||
:areaLevel="3"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template>
|
||||
<ai-card title="基本信息">
|
||||
<ai-wrapper class="fill" slot="content">
|
||||
<ai-info-item label="性别" :value="dict.getLabel('sex', baseInfo.sex)"/>
|
||||
<ai-info-item label="身份证号">
|
||||
<ai-id mode="show" v-model="baseInfo.idNumber" right-btn class="line-center"/>
|
||||
</ai-info-item>
|
||||
<ai-info-item label="出生日期" :value="baseInfo.birthday"/>
|
||||
<ai-info-item label="年龄" :value="baseInfo.age"/>
|
||||
<ai-info-item label="籍贯" :value="baseInfo.birthplaceAreaName"/>
|
||||
<ai-info-item label="民族" :value="dict.getLabel('nation', baseInfo.nation)"/>
|
||||
<ai-info-item label="文化程度" :value="dict.getLabel('education', baseInfo.education)"/>
|
||||
<ai-info-item label="婚姻状况" :value="dict.getLabel('maritalStatus', baseInfo.maritalStatus)"/>
|
||||
<ai-info-item label="政治面貌" :value="dict.getLabel('politicsStatus', baseInfo.politicsStatus)"/>
|
||||
<ai-info-item label="兵役状况" :value="dict.getLabel('militaryStatus', baseInfo.militaryStatus)"/>
|
||||
<ai-info-item label="宗教信仰" :value="dict.getLabel('faithType', baseInfo.faithType)"/>
|
||||
<ai-info-item label="职业" :value="dict.getLabel('job', baseInfo.job)"/>
|
||||
</ai-wrapper>
|
||||
<ai-avatar v-model="baseInfo.photo" :editable="false"/>
|
||||
</ai-card>
|
||||
</template>
|
||||
</ai-edit-card>
|
||||
<ai-edit-card title="联络信息"
|
||||
@save="saveFrom" @cancel="getDetail(baseInfo.id)">
|
||||
<template #edit>
|
||||
<el-form-item label="联系方式:" prop="phone">
|
||||
<el-input v-model="baseInfo.phone" size="small" placeholder="请输入联系方式" :maxlength="11"
|
||||
show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item label="现住址:" prop="currentAreaId">
|
||||
<ai-area-select clearable always-show :instance="instance" :disabled-level="disabledLevel"
|
||||
v-model="baseInfo.currentAreaId" :valueLevel="4"/>
|
||||
<el-form-item>
|
||||
<el-input v-model="baseInfo.currentAddress" placeholder="详细地址" maxlength="30" show-word-limit
|
||||
clearable/>
|
||||
</el-form-item>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template>
|
||||
<ai-card title="联络信息" type="flex">
|
||||
<ai-wrapper slot="content">
|
||||
<ai-info-item label="联系方式" :value="baseInfo.phone"/>
|
||||
<ai-info-item label="现住址" isLine
|
||||
:value="[baseInfo.currentAreaName, baseInfo.currentAddress].join('')"/>
|
||||
</ai-wrapper>
|
||||
</ai-card>
|
||||
</template>
|
||||
</ai-edit-card>
|
||||
<ai-edit-card title="户籍信息"
|
||||
@save="saveFrom" @cancel="getDetail(baseInfo.id)">
|
||||
<template #edit>
|
||||
<el-row type="flex">
|
||||
<div class="fill">
|
||||
<el-form-item label="是否户主:" prop="householdName">
|
||||
<ai-select v-model="baseInfo.householdName" :selectList="dict.getDict('householdName')"
|
||||
@change="householdRelationChange"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="与户主关系:" prop="householdRelation" v-if="baseInfo.householdName==0">
|
||||
<ai-select v-model="baseInfo.householdRelation"
|
||||
:selectList="dict.getDict('householdRelation')"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="fill">
|
||||
<el-form-item label="户主身份证号:" prop="householdIdNumber" v-if="baseInfo.householdName==0">
|
||||
<el-input v-model="baseInfo.householdIdNumber" placeholder="请输入户主身份证号" :maxlength="18"
|
||||
clearable/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-form-item label="户籍地:" prop="householdAreaId">
|
||||
<ai-area-select clearable always-show :instance="instance" v-model="baseInfo.householdAreaId"/>
|
||||
<el-form-item v-if="baseInfo.householdAreaId">
|
||||
<el-input v-model="baseInfo.householdAddress" placeholder="详细地址" maxlength="30" show-word-limit
|
||||
clearable/>
|
||||
</el-form-item>
|
||||
</el-form-item>
|
||||
</template>
|
||||
<template>
|
||||
<ai-card title="户籍信息">
|
||||
<ai-wrapper slot="content">
|
||||
<ai-info-item label="是否户主" :value="dict.getLabel('householdName', baseInfo.householdName)"/>
|
||||
<template v-if="baseInfo.householdName==0">
|
||||
<ai-info-item label="与户主关系"
|
||||
:value="dict.getLabel('householdRelation', baseInfo.householdRelation)"/>
|
||||
<ai-info-item label="户主身份证号" :value="baseInfo.householdIdNumber"/>
|
||||
</template>
|
||||
<ai-info-item label="户籍地" isLine
|
||||
:value="[baseInfo.householdAreaName, baseInfo.householdAddress].join('')"/>
|
||||
</ai-wrapper>
|
||||
</ai-card>
|
||||
</template>
|
||||
</ai-edit-card>
|
||||
</template>
|
||||
<template v-else>
|
||||
<ai-card title="基本信息">
|
||||
<template #content>
|
||||
<el-row type="flex">
|
||||
<div class="fill">
|
||||
<el-form-item label="姓名:" prop="name">
|
||||
<el-input
|
||||
v-model="baseInfo.name"
|
||||
autocomplete="off"
|
||||
size="small"
|
||||
placeholder="请输入姓名"
|
||||
maxlength="20"
|
||||
show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item label="身份证号:" prop="idNumber">
|
||||
<el-input v-model="baseInfo.idNumber" placeholder="请输入身份证号" :maxlength="18" show-word-limit />
|
||||
</el-form-item>
|
||||
<el-form-item label="性别:" prop="sex">
|
||||
<ai-select v-model="baseInfo.sex" :selectList="dict.getDict('sex')"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<el-form-item label="个人照片:" prop="photo" class="fill">
|
||||
<ai-avatar :instance="instance" v-model="baseInfo.photo"/>
|
||||
</el-form-item>
|
||||
</el-row>
|
||||
<el-row type="flex">
|
||||
<div class="fill">
|
||||
<el-form-item label="出生日期:">
|
||||
<el-date-picker
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
format="yyyy-MM-dd"
|
||||
v-model="baseInfo.birthday"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="文化程度:" prop="education">
|
||||
<ai-select v-model="baseInfo.education" :selectList="dict.getDict('education')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="政治面貌:" prop="politicsStatus">
|
||||
<ai-select v-model="baseInfo.politicsStatus" :selectList="dict.getDict('politicsStatus')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="职业:" prop="job">
|
||||
<ai-select v-model="baseInfo.job" :selectList="dict.getDict('job')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="宗教信仰:" prop="faithType">
|
||||
<ai-select v-model="baseInfo.faithType" :selectList="dict.getDict('faithType')"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="fill">
|
||||
<el-form-item label="年龄:" prop="age">
|
||||
<el-input
|
||||
v-model="baseInfo.age"
|
||||
size="small"
|
||||
placeholder="请输入年龄"
|
||||
type="number"
|
||||
/>
|
||||
<!-- <p v-else>{{baseInfo.age}}</p> -->
|
||||
</el-form-item>
|
||||
<el-form-item label="民族:" prop="nation">
|
||||
<ai-select v-model="baseInfo.nation" :selectList="dict.getDict('nation')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="婚姻状况:" prop="maritalStatus">
|
||||
<ai-select v-model="baseInfo.maritalStatus" :selectList="dict.getDict('maritalStatus')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="兵役状况:" prop="militaryStatus">
|
||||
<ai-select v-model="baseInfo.militaryStatus" :selectList="dict.getDict('militaryStatus')"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-form-item label="籍贯:" prop=" birthplaceAreaId">
|
||||
<ai-area-select
|
||||
clearable
|
||||
always-show
|
||||
:instance="instance"
|
||||
v-model="baseInfo.birthplaceAreaId"
|
||||
:areaLevel="3"
|
||||
/>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-card title="联络信息">
|
||||
<template #content>
|
||||
<el-form-item label="联系方式:" prop="phone">
|
||||
<el-input v-model="baseInfo.phone" size="small" placeholder="请输入联系方式" :maxlength="11"
|
||||
show-word-limit/>
|
||||
</el-form-item>
|
||||
<el-form-item label="现住址:" prop="currentAreaId">
|
||||
<ai-area-select clearable always-show :instance="instance" :disabled-level="disabledLevel"
|
||||
v-model="baseInfo.currentAreaId" :valueLevel="4"/>
|
||||
<el-form-item>
|
||||
<el-input v-model="baseInfo.currentAddress" placeholder="详细地址" maxlength="30" show-word-limit
|
||||
clearable/>
|
||||
</el-form-item>
|
||||
</el-form-item>
|
||||
<el-form-item label="所属网格" prop="girdName" required>
|
||||
<ai-picker
|
||||
:instance="instance"
|
||||
dialogTitle="选择所属网格"
|
||||
:ops="{label: 'girdName', id: 'id'}"
|
||||
pageTitle="所属网格"
|
||||
:action="'/app/appgirdinfo/girdList'"
|
||||
v-model="baseInfo.girdId"
|
||||
@pick="onPick">
|
||||
<div class="AppAnnounceDetail-select">
|
||||
<el-input size="small" class="AppAnnounceDetail-select__input" placeholder="请选择..." disabled v-model="baseInfo.girdName"></el-input>
|
||||
<div class="select-left" v-if="girdList.length">
|
||||
<span v-for="(item, index) in girdList" :key="index">{{ item.girdName }}</span>
|
||||
</div>
|
||||
<i v-if="!girdList.length">请选择网格</i>
|
||||
<div class="select-right">{{ girdList.length ? '重新选择' : '选择网格' }}</div>
|
||||
</div>
|
||||
</ai-picker>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</ai-card>
|
||||
<ai-card title="户籍信息">
|
||||
<template #content>
|
||||
<el-row type="flex">
|
||||
<div class="fill">
|
||||
<el-form-item label="是否户主:" prop="isHousehold">
|
||||
<ai-select v-model="baseInfo.isHousehold" :selectList="dict.getDict('householdName')"
|
||||
@change="householdRelationChange"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="与户主关系:" prop="householdRelation" v-if="baseInfo.isHousehold==0">
|
||||
<ai-select v-model="baseInfo.householdRelation" :selectList="dict.getDict('householdRelation')"/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
<div class="fill">
|
||||
<el-form-item label="户主身份证号:" prop="householdIdNumber" v-if="baseInfo.isHousehold==0">
|
||||
<el-input v-model="baseInfo.householdIdNumber" placeholder="请输入户主身份证号" :maxlength="18"
|
||||
clearable/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-row>
|
||||
<el-form-item label="户籍地:" prop="householdAreaId">
|
||||
<ai-area-select clearable always-show :instance="instance" v-model="baseInfo.householdAreaId"/>
|
||||
<el-form-item v-if="baseInfo.householdAreaId">
|
||||
<el-input v-model="baseInfo.householdAddress" placeholder="详细地址" maxlength="30" show-word-limit
|
||||
clearable/>
|
||||
</el-form-item>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</ai-card>
|
||||
</template>
|
||||
</el-form>
|
||||
</template>
|
||||
<template v-if="params.type !== 'Detail'" #footer>
|
||||
<el-button @click="back">取消</el-button>
|
||||
<el-button type="primary" @click="saveFrom()">保存</el-button>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
<script>
|
||||
import {mapState} from "vuex";
|
||||
import {ID} from "dui/lib/js/utils";
|
||||
|
||||
export default {
|
||||
name: "Add",
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function,
|
||||
params: Object,
|
||||
name: {default: ""}
|
||||
},
|
||||
data() {
|
||||
let IdNumberPass = (rule, value, callback) => {
|
||||
if (value) {
|
||||
if (ID.check(value)) {
|
||||
callback();
|
||||
} else {
|
||||
callback(new Error("身份证号格式错误"));
|
||||
}
|
||||
} else {
|
||||
callback(new Error("请输入身份证号"));
|
||||
}
|
||||
};
|
||||
return {
|
||||
buildingCascader: true,
|
||||
houseCascader: true,
|
||||
navId: 0,
|
||||
girdList: [],
|
||||
baseInfo: {
|
||||
registerStatus: "",
|
||||
tips: [],
|
||||
age: "",
|
||||
girdName: '',
|
||||
girdId: [],
|
||||
birthplaceAreaId: "",
|
||||
currentAddress: "",
|
||||
currentAreaId: "",
|
||||
education: "",
|
||||
faithType: "",
|
||||
fileStatus: "",
|
||||
householdAddress: "",
|
||||
householdAreaId: "",
|
||||
householdIdNumber: "",
|
||||
isHousehold: "",
|
||||
householdRelation: "",
|
||||
id: "",
|
||||
idNumber: "",
|
||||
job: "",
|
||||
logoutDescription: "",
|
||||
logoutReason: "",
|
||||
logoutTime: "",
|
||||
logoutUserId: "",
|
||||
maritalStatus: "",
|
||||
militaryStatus: "",
|
||||
name: "",
|
||||
nation: "",
|
||||
phone: "",
|
||||
photo: "",
|
||||
politicsStatus: "",
|
||||
sex: "",
|
||||
tsrqInfos: []
|
||||
},
|
||||
family: [],
|
||||
familyInfo: {},
|
||||
writeInfo: {
|
||||
id: "",
|
||||
logoutReason: "",
|
||||
logoutDescription: "",
|
||||
fileStatus: "1"
|
||||
},
|
||||
rules: {
|
||||
name: [{required: true, message: "请输入姓名", trigger: "blur"}],
|
||||
idNumber: [
|
||||
{required: true, message: "请输入身份证号", trigger: "blur"}
|
||||
],
|
||||
sex: [{required: true, message: "请选择性别", trigger: "change"}],
|
||||
currentAreaId: [{message: "请选择现住址", required: true, trigger: "change"},
|
||||
{
|
||||
validator: (r, v, cb) => {
|
||||
if (/.+0{3}$/.test(v)) {
|
||||
cb("现住址必须选到村级")
|
||||
} else cb()
|
||||
}, trigger: "blur"
|
||||
}],
|
||||
currentAddress: [{message: "请选择现住址详细地址", required: true}],
|
||||
householdAreaId: [
|
||||
{
|
||||
validator: (r, v, cb) => {
|
||||
if (/.+0{3}$/.test(v) && v) {
|
||||
cb("户籍地必须选到村级")
|
||||
} else cb()
|
||||
}, trigger: "blur"
|
||||
}
|
||||
],
|
||||
phone: [
|
||||
{required: true, message: "请输入联系方式", trigger: "blur"}
|
||||
],
|
||||
girdName: [
|
||||
{required: true, message: "请选择网格", trigger: "change"}
|
||||
],
|
||||
householdName: [
|
||||
{required: true, message: "请选择是否户主", trigger: "change"}
|
||||
],
|
||||
householdRelation: [
|
||||
{required: true, message: "请选择与户主关系", trigger: "change"}
|
||||
],
|
||||
householdIdNumber: [
|
||||
{required: true, validator: IdNumberPass, trigger: "blur"}
|
||||
],
|
||||
householdAddress: [
|
||||
{required: true, message: "请选择户籍地详细地址", trigger: "blur"}
|
||||
]
|
||||
},
|
||||
imgUrl: "",
|
||||
fileList: [],
|
||||
disabledLevel: 0,
|
||||
currentTab: "0"
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(["user"]),
|
||||
isEdit() {
|
||||
return this.params.type === 'Edit'
|
||||
},
|
||||
pageTitle() {
|
||||
return {
|
||||
Edit: '编辑居民信息',
|
||||
Add: '添加居民信息',
|
||||
Detail: '居民信息详情'
|
||||
}[this.params.type]
|
||||
},
|
||||
hasSpecial() {
|
||||
//是否有特殊人员信息
|
||||
return this.baseInfo.tsrqInfos?.length > 0
|
||||
},
|
||||
colConfigs() {
|
||||
return [
|
||||
{
|
||||
label: "与户主关系", align: 'center',
|
||||
render: (h, {row}) => h('p', this.dict.getLabel('householdRelation', row.householdRelation))
|
||||
},
|
||||
{label: "姓名", prop: "name"},
|
||||
{label: "性别", prop: "sex", dict: "sex", align: 'center'},
|
||||
{label: "年龄", prop: "age", align: 'center'},
|
||||
{label: "身份证号", render: (h, {row}) => h('p', ID.hideId(row.idNumber))},
|
||||
{slot: "options"}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
back() {
|
||||
this.$emit('change', {
|
||||
type: 'List'
|
||||
})
|
||||
},
|
||||
onPick (e) {
|
||||
if (e.length) {
|
||||
this.baseInfo.girdName = e[0].girdName
|
||||
} else {
|
||||
this.baseInfo.girdName = ''
|
||||
this.baseInfo.girdId = []
|
||||
}
|
||||
|
||||
this.girdList = e
|
||||
},
|
||||
householdRelationChange() {
|
||||
this.baseInfo.householdIdNumber = "";
|
||||
this.baseInfo.householdRelation = "";
|
||||
},
|
||||
saveFrom(cb) {
|
||||
this.$refs.ruleForm.validate(v => {
|
||||
if (v) {
|
||||
this.saveFromFn().then(() => {
|
||||
if (cb) {
|
||||
cb()
|
||||
this.getDetail()
|
||||
} else {
|
||||
this.back()
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
familyInit() {
|
||||
Object.keys(this.writeInfo).forEach(e => {
|
||||
this.writeInfo[e] = "";
|
||||
});
|
||||
this.$refs.writeInfo.resetFields();
|
||||
},
|
||||
saveFromFn() {
|
||||
let {currentHouseList, householdHouseList, tips} = this.baseInfo
|
||||
return this.instance.post(`/app/appresidentapplet/addOrUpdate`, {
|
||||
residentType: this.$route.query.type,
|
||||
...this.baseInfo,
|
||||
currentHouseList: currentHouseList?.join("|"),
|
||||
householdHouseList: householdHouseList?.join("|"),
|
||||
tips: tips?.join("|"),
|
||||
girdId: this.baseInfo.girdId[0]
|
||||
}).then(res => {
|
||||
if (res?.code == 0) {
|
||||
this.$message.success("保存成功");
|
||||
}
|
||||
})
|
||||
},
|
||||
getDetail() {
|
||||
this.instance.post(`/app/appresidentapplet/queryDetailById?id=${this.params.id}`).then(res => {
|
||||
if (res?.data) {
|
||||
this.baseInfo = {
|
||||
...res.data,
|
||||
girdId: [res.data.girdId]
|
||||
};
|
||||
this.girdList = [{
|
||||
id: res.data.girdId,
|
||||
girdName: res.data.girdName
|
||||
}]
|
||||
}
|
||||
});
|
||||
},
|
||||
handleDelete() {
|
||||
this.$confirm("删掉档案后,\n" +
|
||||
`<span class="username">${this.baseInfo.name}</span>` +
|
||||
" 的历史相关信息可能无法追溯查看,是否确定删除该人员档案?", {
|
||||
title: "档案删除"
|
||||
}).then(() => {
|
||||
this.instance.post(`/app/appresidentapplet/delete?ids=${this.baseInfo.id}`).then(res => {
|
||||
if (res && res.code == 0) {
|
||||
this.$message.success("删除成功");
|
||||
this.$router.push({query: {}});
|
||||
}
|
||||
});
|
||||
}).catch(() => 0)
|
||||
},
|
||||
idChange(val) {
|
||||
if (val.length == 18) {
|
||||
this.IdCard(val);
|
||||
}
|
||||
},
|
||||
IdCard(UUserCard) {
|
||||
if (UUserCard) {
|
||||
const idCard = new ID(UUserCard)
|
||||
this.baseInfo.age = idCard.age
|
||||
this.baseInfo.sex = idCard.sex
|
||||
this.baseInfo.birthday = idCard.birthday
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$dict.load(['sex', 'education', 'politicsStatus', 'job', 'faithType', 'nation', 'maritalStatus', 'militaryStatus', 'householdName', 'householdRelation', ]).then(()=> {
|
||||
this.disabledLevel = this.user.info.areaMap[this.user.info.areaId].length;
|
||||
if (!this.params.id) {
|
||||
// this.baseInfo.householdAreaId = JSON.parse(JSON.stringify(this.user.info.areaId))
|
||||
this.baseInfo.currentAreaId = this.user.info.areaId
|
||||
} else {
|
||||
this.getDetail(this.params.id);
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.residentDetail {
|
||||
font-size: 14px;
|
||||
.AppAnnounceDetail-select {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 32px;
|
||||
line-height: 1;
|
||||
background: #F5F5F5;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #D0D4DC;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
|
||||
|
||||
&:hover {
|
||||
border-color: #26f;
|
||||
}
|
||||
|
||||
& > i {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
line-height: 32px;
|
||||
padding: 0 12px;
|
||||
color: #888888;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
border-right: 1px solid #D0D4DC;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.AppAnnounceDetail-select__input {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: -1;
|
||||
opacity: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.select-right {
|
||||
height: 100%;
|
||||
padding: 0 12px;
|
||||
color: #222222;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
transition: all ease 0.3s;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
.select-left {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
flex: 1;
|
||||
padding: 5px 0 0px 12px;
|
||||
border-right: 1px solid #D0D4DC;
|
||||
border-radius: 4px 0 0 4px;
|
||||
background: #fff;
|
||||
|
||||
em {
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
margin: 0 4px 5px 0;
|
||||
color: #222222;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
span {
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
margin: 0 4px 5px 0;
|
||||
padding: 0 8px;
|
||||
font-size: 12px;
|
||||
color: #222222;
|
||||
background: #F3F4F7;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #D0D4DC;
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep( .AiID ){
|
||||
line-height: unset;
|
||||
|
||||
.el-button--text {
|
||||
padding: 0 8px;
|
||||
height: fit-content;
|
||||
}
|
||||
}
|
||||
|
||||
:deep( .el-form-item ){
|
||||
margin-bottom: 10px;
|
||||
|
||||
.el-form-item {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.el-cascader, .el-select, .el-date-editor {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
:deep( .el-form-item__error ){
|
||||
position: static;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
122
project/shuzipingchang/app/AppResidentInfo/components/Detail.vue
Normal file
122
project/shuzipingchang/app/AppResidentInfo/components/Detail.vue
Normal file
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<ai-detail class="activitiesAdd">
|
||||
<template slot="title">
|
||||
<ai-title title="居民信息详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)"></ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-card title="基本信息">
|
||||
<ai-wrapper class="fill" slot="content">
|
||||
<ai-info-item label="姓名" isLine :value="baseInfo.name"/>
|
||||
<ai-info-item label="照片">
|
||||
<ai-avatar v-model="baseInfo.photo" :editable="false"/>
|
||||
</ai-info-item>
|
||||
<ai-info-item label="性别" :value="dict.getLabel('sex', baseInfo.sex)"/>
|
||||
<ai-info-item label="身份证号" :value="baseInfo.idNumber">
|
||||
<!-- <ai-id mode="show" v-model="baseInfo.idNumber" right-btn class="line-center"/> -->
|
||||
</ai-info-item>
|
||||
<ai-info-item label="出生日期" :value="baseInfo.birthday"/>
|
||||
<ai-info-item label="年龄" :value="baseInfo.age"/>
|
||||
<ai-info-item label="籍贯" :value="baseInfo.birthplaceAreaName"/>
|
||||
<ai-info-item label="民族" :value="dict.getLabel('nation', baseInfo.nation)"/>
|
||||
<ai-info-item label="文化程度" :value="dict.getLabel('education', baseInfo.education)"/>
|
||||
<ai-info-item label="婚姻状况" :value="dict.getLabel('maritalStatus', baseInfo.maritalStatus)"/>
|
||||
<ai-info-item label="政治面貌" :value="dict.getLabel('politicsStatus', baseInfo.politicsStatus)"/>
|
||||
<ai-info-item label="兵役状况" :value="dict.getLabel('militaryStatus', baseInfo.militaryStatus)"/>
|
||||
<ai-info-item label="宗教信仰" :value="dict.getLabel('faithType', baseInfo.faithType)"/>
|
||||
<ai-info-item label="职业" :value="dict.getLabel('job', baseInfo.job)"/>
|
||||
</ai-wrapper>
|
||||
</ai-card>
|
||||
<ai-card title="联络信息" type="flex">
|
||||
<ai-wrapper slot="content">
|
||||
<ai-info-item label="联系方式" :value="baseInfo.phone"/>
|
||||
<ai-info-item label="现住址" isLine :value="[baseInfo.currentAreaName, baseInfo.currentAddress].join('')"/>
|
||||
<ai-info-item label="所属网格" :value="baseInfo.girdName"/>
|
||||
</ai-wrapper>
|
||||
</ai-card>
|
||||
<ai-card title="户籍信息">
|
||||
<ai-wrapper slot="content">
|
||||
<ai-info-item label="是否户主" :value="dict.getLabel('householdName', baseInfo.isHousehold)"/>
|
||||
<template v-if="baseInfo.isHousehold == 0">
|
||||
<ai-info-item label="与户主关系" :value="dict.getLabel('householdRelation', baseInfo.householdRelation)"/>
|
||||
<ai-info-item label="户主身份证号" :value="baseInfo.householdIdNumber"/>
|
||||
</template>
|
||||
<ai-info-item label="户籍地" isLine :value="[baseInfo.householdAreaName, baseInfo.householdAddress].join('')"></ai-info-item>
|
||||
</ai-wrapper>
|
||||
</ai-card>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ID } from 'dui/lib/js/utils'
|
||||
export default {
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object,
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
baseInfo: {},
|
||||
id: ''
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.id = this.params.id
|
||||
|
||||
this.getDetail()
|
||||
},
|
||||
|
||||
methods: {
|
||||
cancel (isRefresh) {
|
||||
this.$emit('change', {
|
||||
type: 'List',
|
||||
isRefresh: !!isRefresh
|
||||
})
|
||||
},
|
||||
|
||||
IdCard (UUserCard) {
|
||||
if (UUserCard) {
|
||||
const idCard = new ID(UUserCard)
|
||||
this.baseInfo.age = idCard.age
|
||||
this.baseInfo.sex = idCard.sex
|
||||
this.baseInfo.birthday = idCard.birthday
|
||||
}
|
||||
},
|
||||
|
||||
getDetail() {
|
||||
this.instance.post(`/app/appresidentapplet/queryDetailById?id=${this.params.id}`).then(res => {
|
||||
if (res.data) {
|
||||
this.baseInfo = {
|
||||
...res.data
|
||||
}
|
||||
this.IdCard(res.data.idNumber)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scope>
|
||||
.activitiesAdd {
|
||||
height: 100%;
|
||||
|
||||
:deep( .amap-logo ){
|
||||
display: none!important;
|
||||
}
|
||||
:deep( .amap-copyright ){
|
||||
display: none!important;
|
||||
}
|
||||
|
||||
:deep( .el-date-editor .el-input ){
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.amap-container {
|
||||
height: 380px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
156
project/shuzipingchang/app/AppResidentInfo/components/List.vue
Normal file
156
project/shuzipingchang/app/AppResidentInfo/components/List.vue
Normal file
@@ -0,0 +1,156 @@
|
||||
<template>
|
||||
<ai-list class="activitiesList">
|
||||
<ai-title
|
||||
slot="title"
|
||||
title="居民信息"
|
||||
isShowBottomBorder
|
||||
isShowArea
|
||||
:hideLevel="$store.state.user.info.areaList.length - 1"
|
||||
v-model="search.areaId"
|
||||
:instance="instance"
|
||||
@change="search.current = 1, getList()">
|
||||
</ai-title>
|
||||
<template #content>
|
||||
<ai-search-bar bottomBorder>
|
||||
<template #left>
|
||||
<el-button type="primary" icon="iconfont iconAdd" @click="toAdd('')">添加</el-button>
|
||||
<ai-import
|
||||
:instance="instance"
|
||||
:dict="dict"
|
||||
type="appresidentapplet"
|
||||
name="居民信息"
|
||||
@success="search.current = 1, getList()">
|
||||
</ai-import>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-input
|
||||
v-model="search.name"
|
||||
size="small"
|
||||
placeholder="姓名/身份证/联系方式"
|
||||
clearable
|
||||
v-throttle="() => {search.current = 1, getList()}"
|
||||
@clear="search.name = '', getList()"
|
||||
suffix-icon="iconfont iconSearch">
|
||||
</el-input>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
:tableData="tableData"
|
||||
:total="search.total"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@getList="getList"
|
||||
:col-configs="colConfigs"
|
||||
:dict="dict">
|
||||
<el-table-column slot="options" label="操作" fixed="right" align="center" width="160px">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click="toDetail(row.id)">详情</el-button>
|
||||
<el-button type="text" @click="toAdd(row.id)">编辑</el-button>
|
||||
<el-button type="text" @click="remove(row.id)">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
search: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
total: 0,
|
||||
name: '',
|
||||
areaId: ''
|
||||
},
|
||||
tableData: []
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
colConfigs() {
|
||||
return [
|
||||
{ label: "姓名", prop: "name", align: "left" },
|
||||
// { label: "性别", prop: "sex", dict: 'sex', align: "center" },
|
||||
{ prop: 'idNumber', label: '身份证号', align: 'center'},
|
||||
// format: v => v.substring(0, 10) + '****' + v.substring(14, 18)
|
||||
// { label: "年龄", prop: "age", align: "center"},
|
||||
{ label: "现住址", prop: "currentAreaName", align: "center" },
|
||||
{ label: "网格", prop: "girdName", align: "center" },
|
||||
{ label: "民族", prop: "nation", align: "center", dict: "nation" },
|
||||
{ label: "文化程度", prop: "education", align: "center", dict: "education" },
|
||||
{ label: "政治面貌", prop: "politicsStatus", align: "center", dict: "politicsStatus" },
|
||||
{ slot: "options", },
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.search.areaId = this.$store.state.user.info.areaId
|
||||
this.$dict.load(['nation', 'education', 'politicsStatus']).then(()=> {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList() {
|
||||
this.instance.post(`/app/appresidentapplet/list`,null, {
|
||||
params: {
|
||||
...this.search,
|
||||
}
|
||||
}).then(res=> {
|
||||
if(res?.data) {
|
||||
this.tableData = res.data.records
|
||||
this.search.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toDetail (id) {
|
||||
this.$emit('change', {
|
||||
type: 'Detail',
|
||||
params: {
|
||||
id: id || '',
|
||||
type: 'Detail'
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
toAdd(id) {
|
||||
this.$emit('change', {
|
||||
type: 'Add',
|
||||
params: {
|
||||
type: id ? 'Edit' : 'Add',
|
||||
id: id || ''
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
remove (id) {
|
||||
this.$confirm('确定删除该数据?').then(() => {
|
||||
this.instance.post(`/app/appresidentapplet/delete?ids=${id}`).then(res=>{
|
||||
if(res.code == 0) {
|
||||
this.$message.success('删除成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.activitiesList {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<div class="AppActivitiesManagement">
|
||||
<keep-alive :include="['List']">
|
||||
<component ref="component" :is="component" :permissions="permissions " @change="onChange" :params="params" :instance="instance" :dict="dict"></component>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import List from './components/List'
|
||||
import Detail from './components/Detail'
|
||||
|
||||
export default {
|
||||
name: 'AppResidentIntegrating',
|
||||
label: '居民积分',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
component: 'List',
|
||||
params: {},
|
||||
include: []
|
||||
}
|
||||
},
|
||||
|
||||
components: {
|
||||
List,
|
||||
Detail
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange (data) {
|
||||
if (data.type === 'Detail') {
|
||||
this.component = 'Detail'
|
||||
this.params = data.params
|
||||
}
|
||||
|
||||
if (data.type === 'List') {
|
||||
this.component = 'List'
|
||||
this.params = data.params
|
||||
|
||||
this.$nextTick(() => {
|
||||
if (data.isRefresh) {
|
||||
this.$refs.component.getList()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.AppActivitiesManagement {
|
||||
height: 100%;
|
||||
background: #F3F6F9;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,181 @@
|
||||
<template>
|
||||
<ai-detail>
|
||||
<template slot="title">
|
||||
<ai-title title="详情" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<el-row style="margin-bottom: 16px;">
|
||||
<div class="card_list">
|
||||
<div class="card">
|
||||
<h2>姓名</h2>
|
||||
<p class="color1">{{ info.userName }}</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>积分余额</h2>
|
||||
<p class="color2">{{ info.integral || 0 }}</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h2>已用积分</h2>
|
||||
<p class="color3">{{ info.usedIntegral || 0 }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</el-row>
|
||||
<ai-card>
|
||||
<ai-title slot="title" title="余额变动明细"/>
|
||||
<template #content>
|
||||
<ai-search-bar>
|
||||
<template #left>
|
||||
<ai-select v-model="search.type" placeholder="请选择类型" @change="search.current = 1, getList()" :selectList="dict.getDict('integralType')"/>
|
||||
</template>
|
||||
<template #right>
|
||||
<ai-download
|
||||
:instance="instance"
|
||||
:url="`/app/appintegraluser/changeIntegralExport?id=${params.id}`"
|
||||
:params="search"
|
||||
fileName="余额变动明细"
|
||||
:disabled="tableData.length == 0">
|
||||
<el-button size="small">导出</el-button>
|
||||
</ai-download>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table :tableData="tableData" :total="total" :current.sync="search.current" :size.sync="search.size"
|
||||
@getList="getList" :col-configs="colConfigs" :dict="dict">
|
||||
<el-table-column slot="changeIntegral" label="变动积分" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<span>{{ row.integralCalcType == 0 ? '-' : '+' }}{{ row.changeIntegral }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column slot="eventDesc" label='事件' align="center" show-overflow-tooltip>
|
||||
<template slot-scope="{ row }">
|
||||
<span>{{ row.eventDesc || row.eventName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-card>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Detail',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
info: {},
|
||||
id: '',
|
||||
search: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
type: ''
|
||||
},
|
||||
total: 0,
|
||||
tableData: []
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
colConfigs() {
|
||||
return [
|
||||
{prop: "doTime", label: '时间', align: "left", width: "200px"},
|
||||
{prop: "integralType", label: '类型', align: "center", dict: "integralType"},
|
||||
{slot: "changeIntegral"},
|
||||
{prop: "nowIntegral", label: '剩余积分', align: "center" },
|
||||
{slot: "eventDesc"},
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
console.log(this.params)
|
||||
this.dict.load('integralType').then(() => {
|
||||
this.getInfo()
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
getInfo (id) {
|
||||
this.instance.post(`/app/appintegraluser/girdDetail?id=${this.params.id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.info = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
getList () {
|
||||
this.instance.post(`/app/appintegraluser/getChangeDetail`, null, {
|
||||
params: {
|
||||
...this.search,
|
||||
id: this.params.id
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancel (isRefresh) {
|
||||
this.$emit('change', {
|
||||
type: 'List',
|
||||
isRefresh: !!isRefresh
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.card_list {
|
||||
display: flex;
|
||||
|
||||
.card {
|
||||
flex: 1;
|
||||
height: 96px;
|
||||
background: #FFFFFF;
|
||||
box-shadow: 0px 4px 6px -2px rgba(15, 15, 21, 0.1500);
|
||||
border-radius: 4px;
|
||||
margin-right: 20px;
|
||||
padding: 16px 24px;
|
||||
box-sizing: border-box;
|
||||
|
||||
h2 {
|
||||
color: #888888;
|
||||
font-weight: 600;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 8px;
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.color1 {
|
||||
color: #2891FF;
|
||||
}
|
||||
|
||||
.color2 {
|
||||
color: #22AA99;
|
||||
}
|
||||
|
||||
.color3 {
|
||||
color: #F8B425;
|
||||
}
|
||||
}
|
||||
|
||||
.card:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,277 @@
|
||||
<template>
|
||||
<ai-list class="notice">
|
||||
<ai-title slot="title" title="居民积分" v-model="search.areaId" isShowBottomBorder isShowArea :hideLevel="hideLevel - 1" @change="search.current = 1, getList()"></ai-title>
|
||||
<template slot="content">
|
||||
<ai-search-bar class="search-bar">
|
||||
<template #left>
|
||||
<el-button type="primary" size="small" icon="iconfont iconAdd" @click="changeIntegral('',0)"> 批量调整积分</el-button>
|
||||
<ai-download
|
||||
:instance="instance"
|
||||
url="/app/appwechatuserqujing/export"
|
||||
:params="params"
|
||||
v-if="permissions('app_appwechatuserqujing_export')"
|
||||
fileName="居民积分"
|
||||
:disabled="tableData.length == 0">
|
||||
<el-button icon="iconfont iconExported" :disabled="tableData.length == 0">导出</el-button>
|
||||
</ai-download>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-input
|
||||
v-model="search.idNumber"
|
||||
class="search-input"
|
||||
size="small"
|
||||
v-throttle="() => {search.current = 1, getList()}"
|
||||
placeholder="姓名/身份证/手机号"
|
||||
clearable
|
||||
@clear="search.current = 1, search.idNumber = '', getList()"
|
||||
suffix-icon="iconfont iconSearch">
|
||||
</el-input>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="total"
|
||||
style="margin-top: 6px;"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@getList="getList">
|
||||
<el-table-column slot="options" width="120px" fixed="right" label="操作" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click="toDetail(row.integralUserId)">详情</el-button>
|
||||
<el-button type="text" @click="changeIntegral(row,1)">调整积分</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
<ai-dialog
|
||||
title="调整积分"
|
||||
:visible.sync="dialog"
|
||||
:destroyOnClose="true"
|
||||
width="720px"
|
||||
@onConfirm="onConfirm"
|
||||
@closed="form={},chooseUserList=[]">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="选择人员" prop="ids" v-if="!isEdit">
|
||||
<ai-person-select :instance="instance" keys="openId" customRightText :customClicker="true" :chooseUserList="chooseUserList"
|
||||
url="/app/appwechatuserqujing/listByFdAppletUser" headerTitle="用户列表"
|
||||
:isMultiple="true" dialogTitle="选择" @selectPerson="selectPerson" class="aipersonselect">
|
||||
<template name="option" v-slot:option="{ item }">
|
||||
<span class="iconfont iconProlife">{{ item.realName }}</span>
|
||||
<ai-id mode="show" :show-eyes="false" :value="item.idNumber"/>
|
||||
</template>
|
||||
</ai-person-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="调整说明" prop="eventDesc">
|
||||
<el-input v-model="form.eventDesc" placeholder="请输入..." type="textarea" :rows="4" show-word-limit
|
||||
maxlength="100"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="integralCalcType">
|
||||
<ai-select v-model="form.integralCalcType" :selectList="dict.getDict('integralCalcType')"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="积分" prop="integral">
|
||||
<el-input v-model.trim="form.integral" placeholder="请输入正数" size="small"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</ai-dialog>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
name: 'List',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
permissions: Function
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
search: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
idNumber: '',
|
||||
areaId: ''
|
||||
},
|
||||
form: {
|
||||
ids: [],
|
||||
eventDesc: "",
|
||||
enclosure: "",
|
||||
integralCalcType: "",
|
||||
integral: ''
|
||||
},
|
||||
dialog: false,
|
||||
chooseUserList: [],
|
||||
total: 0,
|
||||
isEdit: false,
|
||||
colConfigs: [
|
||||
{ prop: 'realName', label: '姓名', align: 'left', width: '200px' },
|
||||
{ prop: 'phone', label: '手机号', align: 'center' },
|
||||
{ prop: 'idNumber', label: '身份证号', align: 'center' },
|
||||
{ prop: 'areaName', label: '所属地区', align: 'center' },
|
||||
{ prop: 'girdName', label: '所属网格', align: 'center' },
|
||||
{ prop: 'integral', label: '剩余积分', align: 'center' },
|
||||
{ prop: 'usedIntegral', label: '已用积分', align: 'center' }
|
||||
],
|
||||
tableData: []
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
|
||||
hideLevel () {
|
||||
return this.user.info.areaList.length || 0
|
||||
},
|
||||
|
||||
params () {
|
||||
return {
|
||||
...this.search,
|
||||
size: 1000
|
||||
}
|
||||
},
|
||||
|
||||
rules() {
|
||||
return {
|
||||
ids: [{required: true, message: '请选择人员', trigger: 'blur'}],
|
||||
eventDesc: [{required: true, message: '请输入调整说明', trigger: 'blur'}],
|
||||
integralCalcType: [{required: true, message: '请选择类型', trigger: 'blur'}],
|
||||
integral: [{required: true, message: '请输入积分', trigger: 'blur' },
|
||||
{pattern: /^([1-9]\d*|0)(\.\d{1,2})?$/, message: '请输入正数且最多只能保留两位小数'}],
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.search.areaId = this.user.info.areaId
|
||||
this.dict.load('integralCalcType').then(() => {
|
||||
this.getList()
|
||||
})
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList () {
|
||||
this.instance.post(`/app/appwechatuserqujing/listByFdAppletUser`, null, {
|
||||
params: {
|
||||
...this.search,
|
||||
areaId: this.search.areaId
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
selectPerson(val) {
|
||||
if (val) {
|
||||
this.personList = val
|
||||
this.form.ids = [...this.personList.map(e => e.openId)]
|
||||
} else {
|
||||
this.form.ids = this.chooseUserList.map(e => e.openId)
|
||||
}
|
||||
},
|
||||
|
||||
changeIntegral(row,type) {
|
||||
this.isEdit = false
|
||||
if(type==0) {
|
||||
this.dialog = true
|
||||
} else if(type ==1) {
|
||||
this.isEdit = true
|
||||
this.chooseUserList = [{
|
||||
openId: row.openId,
|
||||
name: row.realName
|
||||
}]
|
||||
this.form = {
|
||||
ids: this.chooseUserList.map(e => e.openId)
|
||||
}
|
||||
|
||||
this.dialog = true
|
||||
}
|
||||
},
|
||||
|
||||
changeTableSort(col) {
|
||||
if(col.prop === 'integral') { // 剩余积分
|
||||
this.search.sortFiled = 0
|
||||
if(col.order === 'ascending') {
|
||||
this.search.sortRule = true
|
||||
} else if(col.order === 'descending') {
|
||||
this.search.sortRule = false
|
||||
} else if(col.order === null) {
|
||||
this.search.sortRule = ''
|
||||
}
|
||||
} else if(col.prop === 'totalIntegral') { // 累计积分
|
||||
this.search.sortFiled = 1
|
||||
if(col.order === 'ascending') {
|
||||
this.search.sortRule = true
|
||||
} else if(col.order === 'descending') {
|
||||
this.search.sortRule = false
|
||||
} else if(col.order === null) {
|
||||
this.search.sortRule = ''
|
||||
}
|
||||
} else if(col.prop === 'usedIntegral') { // 已用积分
|
||||
this.search.sortFiled = 2
|
||||
if(col.order === 'ascending') {
|
||||
this.search.sortRule = true
|
||||
} else if(col.order === 'descending') {
|
||||
this.search.sortRule = false
|
||||
} else if(col.order === null) {
|
||||
this.search.sortRule = ''
|
||||
}
|
||||
}
|
||||
this.getList()
|
||||
},
|
||||
|
||||
onConfirm() {
|
||||
if(this.flag) return
|
||||
|
||||
if(this.form.file?.length) {
|
||||
this.form.enclosure = this.form.file[0].url
|
||||
}
|
||||
this.$refs.form.validate((valid)=> {
|
||||
if(valid) {
|
||||
this.flag = true
|
||||
this.instance.post(`/app/appintegraluser/changeIntegral`,{
|
||||
ids: this.form.ids,
|
||||
eventDesc: this.form.eventDesc,
|
||||
enclosure: this.form.enclosure, // 附件
|
||||
integralCalcType: this.form.integralCalcType,
|
||||
integral: this.form.integral,
|
||||
integralUserType: 3
|
||||
}).then(res => {
|
||||
if(res?.code == 0) {
|
||||
this.$message.success('调整积分成功')
|
||||
setTimeout(() =>{
|
||||
this.dialog = false
|
||||
this.getList()
|
||||
this.flag = false
|
||||
}, 600)
|
||||
} else {
|
||||
this.flag = false
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
|
||||
toDetail(id) {
|
||||
this.$emit('change', {
|
||||
type: 'Detail',
|
||||
params: {
|
||||
id: id || ''
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
70
project/shuzipingchang/app/AppSubjectSet/AppSubjectSet.vue
Normal file
70
project/shuzipingchang/app/AppSubjectSet/AppSubjectSet.vue
Normal file
@@ -0,0 +1,70 @@
|
||||
<template>
|
||||
<div class="AppSubjectSet">
|
||||
<keep-alive :include="['List']">
|
||||
<component
|
||||
ref="component"
|
||||
:is="component"
|
||||
@change="onChange"
|
||||
:params="params"
|
||||
:instance="instance"
|
||||
:dict="dict"
|
||||
></component>
|
||||
</keep-alive>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import List from "./components/List";
|
||||
import Add from "./components/Add";
|
||||
|
||||
export default {
|
||||
name: "AppSubjectSet",
|
||||
label: "话题设置",
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
component: "List",
|
||||
params: {},
|
||||
include: [],
|
||||
};
|
||||
},
|
||||
|
||||
components: {
|
||||
Add,
|
||||
List,
|
||||
},
|
||||
|
||||
methods: {
|
||||
onChange(data) {
|
||||
if (data.type === "Add") {
|
||||
this.component = "Add";
|
||||
this.params = data.params;
|
||||
}
|
||||
|
||||
if (data.type === "List") {
|
||||
this.component = "List";
|
||||
this.params = data.params;
|
||||
|
||||
this.$nextTick(() => {
|
||||
if (data.isRefresh) {
|
||||
this.$refs.component.getList();
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.AppSubjectSet {
|
||||
height: 100%;
|
||||
background: #f3f6f9;
|
||||
overflow: auto;
|
||||
}
|
||||
</style>
|
||||
128
project/shuzipingchang/app/AppSubjectSet/components/Add.vue
Normal file
128
project/shuzipingchang/app/AppSubjectSet/components/Add.vue
Normal file
@@ -0,0 +1,128 @@
|
||||
<template>
|
||||
<ai-detail class="content-add">
|
||||
<template slot="title">
|
||||
<ai-title :title="params.id ? '编辑话题' : '添加话题'" isShowBack isShowBottomBorder @onBackClick="cancel(false)">
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-card title="基本信息">
|
||||
<template #content>
|
||||
<el-form class="ai-form" :model="form" label-width="120px" ref="form">
|
||||
<el-form-item prop="title" style="width: 100%;" label="话题名称" :rules="[{required: true, message: '请输入话题名称', trigger: 'change'}]">
|
||||
<el-input size="small" placeholder='如“社会保障”仅限4个字' v-model="form.title" maxlength="4" :show-word-limit="true"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="showIndex" style="width: 100%;" label="排序" :rules="[{required: true, message: '请输入排序', trigger: 'change'}]">
|
||||
<el-input-number v-model="form.showIndex" :min="1" :max="100" size="small"></el-input-number>
|
||||
<span class="tips">请输入数字,数字越小排序越前</span>
|
||||
</el-form-item>
|
||||
<el-form-item label="话题描述" prop="description" style="width: 100%;" :rules="[{required: true, message: '请输入发布内容', trigger: 'change'}]">
|
||||
<el-input type="textarea" placeholder="限500字" v-model="form.description" rows="8" maxlength="500" :show-word-limit="true"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="话题图标" prop="files" style="width: 100%;" :rules="[{required: true, message: '请上传话题图标', trigger: 'change'}]">
|
||||
<ai-uploader
|
||||
:instance="instance"
|
||||
v-model="form.files"
|
||||
isShowTip
|
||||
:limit="1">
|
||||
</ai-uploader>
|
||||
</el-form-item>
|
||||
<el-form-item prop="status" style="width: 100%;" label="是否启用" :rules="[{required: true}]">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio label="1">是</el-radio>
|
||||
<el-radio label="0">否</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
</ai-card>
|
||||
</template>
|
||||
<template #footer>
|
||||
<el-button @click="cancel">取消</el-button>
|
||||
<el-button type="primary" @click="confirm">提交</el-button>
|
||||
</template>
|
||||
</ai-detail>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
export default {
|
||||
name: 'Add',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object,
|
||||
params: Object
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
form: {
|
||||
title: '',
|
||||
showIndex: '',
|
||||
description: '',
|
||||
files: [],
|
||||
picUrl: '',
|
||||
status: '1',
|
||||
},
|
||||
isFlag: false
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['user'])
|
||||
},
|
||||
|
||||
created () {
|
||||
if (this.params && this.params.id) {
|
||||
this.id = this.params.id
|
||||
this.getInfo(this.params.id)
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
getInfo (id) {
|
||||
this.instance.post(`/app/appneighborhoodassistancetheme/queryDetailById?id=${id}`).then(res => {
|
||||
if (res.code === 0) {
|
||||
this.form = res.data
|
||||
this.form.files = [{url: res.data.picUrl}]
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
confirm () {
|
||||
if(this.isFlag) return
|
||||
this.$refs.form.validate((valid) => {
|
||||
if (valid) {
|
||||
this.isFlag = true
|
||||
this.instance.post(`/app/appneighborhoodassistancetheme/addOrUpdate`, {
|
||||
...this.form,
|
||||
picUrl: this.form.files[0].url
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('提交成功')
|
||||
setTimeout(() => {
|
||||
this.cancel(true)
|
||||
}, 600)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
cancel (isRefresh) {
|
||||
this.$emit('change', {
|
||||
type: 'List',
|
||||
isRefresh: !!isRefresh
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.tips {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
}
|
||||
</style>
|
||||
144
project/shuzipingchang/app/AppSubjectSet/components/List.vue
Normal file
144
project/shuzipingchang/app/AppSubjectSet/components/List.vue
Normal file
@@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<ai-list class="notice">
|
||||
<template slot="title">
|
||||
<ai-title title="话题设置" isShowBottomBorder>
|
||||
</ai-title>
|
||||
</template>
|
||||
<template slot="content">
|
||||
<ai-search-bar class="search-bar">
|
||||
<template #left>
|
||||
<el-button size="small" type="primary" icon="iconfont iconAdd" @click="toAdd('')">添加话题</el-button>
|
||||
</template>
|
||||
<template #right>
|
||||
<el-input
|
||||
v-model="search.title"
|
||||
class="search-input"
|
||||
size="small"
|
||||
v-throttle="() => {search.current = 1, getList()}"
|
||||
placeholder="请输入话题名称/创建人"
|
||||
clearable
|
||||
@clear="search.current = 1, search.title = '', getList()"
|
||||
suffix-icon="iconfont iconSearch">
|
||||
</el-input>
|
||||
</template>
|
||||
</ai-search-bar>
|
||||
<ai-table
|
||||
:tableData="tableData"
|
||||
:col-configs="colConfigs"
|
||||
:total="total"
|
||||
style="margin-top: 6px;"
|
||||
:current.sync="search.current"
|
||||
:size.sync="search.size"
|
||||
@getList="getList">
|
||||
<el-table-column slot="status" width="120px" label="是否启用" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<el-switch v-model="row.status" @change="changeStatus(row)" active-value="1" inactive-value="0"></el-switch>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column slot="options" width="180px" fixed="right" label="操作" align="center">
|
||||
<template slot-scope="{ row }">
|
||||
<div class="table-options">
|
||||
<el-button type="text" @click="toAdd(row.id)">编辑</el-button>
|
||||
<el-button type="text" @click="remove(row.id)">删除</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</ai-table>
|
||||
</template>
|
||||
</ai-list>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'List',
|
||||
|
||||
props: {
|
||||
instance: Function,
|
||||
dict: Object
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
search: {
|
||||
current: 1,
|
||||
size: 10,
|
||||
title: '',
|
||||
status: ''
|
||||
},
|
||||
total: 10,
|
||||
colConfigs: [
|
||||
{ prop: 'title', label: '话题名称', align: 'left', width: '200' },
|
||||
{ prop: 'description', label: '话题描述', align: 'left', 'show-overflow-tooltip': true},
|
||||
{ prop: 'partakeCount', label: '参与话题数', align: 'center', width: '120' },
|
||||
{ prop: 'showIndex', label: '排序', align: 'center', width: '120' },
|
||||
{ prop: 'createUserName', label: '创建人', align: 'center', width: '120' },
|
||||
{ prop: 'createTime', label: '创建时间', align: 'center', width: '180' },
|
||||
{ slot: 'status'},
|
||||
{ slot: 'options'},
|
||||
],
|
||||
tableData: [],
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
this.getList()
|
||||
},
|
||||
|
||||
methods: {
|
||||
getList() {
|
||||
this.instance.post(`/app/appneighborhoodassistancetheme/list`, null, {
|
||||
params: {
|
||||
...this.search
|
||||
}
|
||||
}).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.tableData = res.data.records
|
||||
this.total = res.data.total
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
remove (id) {
|
||||
this.$confirm('确定删除该话题?').then(() => {
|
||||
this.instance.post(`/app/appneighborhoodassistancetheme/delete?ids=${id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('删除成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
toAdd(id) {
|
||||
this.$emit('change', {
|
||||
type: 'Add',
|
||||
params: {
|
||||
id: id || ''
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
changeStatus(row) {
|
||||
this.$confirm(`确定${row.status == 1 ? '启用' : '关闭'}该话题?`).then(() => {
|
||||
this.instance.post(`/app/appneighborhoodassistancetheme/enable?id=${row.id}`).then(res => {
|
||||
if (res.code == 0) {
|
||||
this.$message.success('操作成功!')
|
||||
this.getList()
|
||||
}
|
||||
})
|
||||
}).catch(() => {
|
||||
this.getList()
|
||||
})
|
||||
// this.instance.post(`/app/appneighborhoodassistancetheme/enable?id=${row.id}`).then(res => {
|
||||
// if (res.code == 0) {
|
||||
// this.$message.success('操作成功!')
|
||||
// this.getList()
|
||||
// }
|
||||
// })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
Reference in New Issue
Block a user