调整下工程结构

This commit is contained in:
aixianling
2024-10-31 14:45:19 +08:00
parent 35894eefe4
commit fc9864bb7d
71 changed files with 0 additions and 2741 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 373 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,216 +0,0 @@
<template>
<section class="multiplyArea">
<AiTopFixed>
<u-search placeholder="搜索" v-model="search" :show-action="false"/>
<span v-for="(item, index) in selectList" :key="index"><span v-if="index" style="margin:0 4px;">/</span>
<span class="color-3F8DF5" @click="selectListClick(item, index)" v-text="item.name"/>
</span>
</AiTopFixed>
<div class="header-middle">
<div class="showTypes">
<div v-if="options.length > 0">
<div class="cards" v-for="(item, index) in optionsList" :key="index" @click="getChildren(item)">
<div class="checkbox" :class="{checked:item.isChecked}" @click.stop="handleCheck(item)"/>
<div class="cardRight fill">
<div class="applicationNames fill">{{ item.name }}</div>
<u-icon v-if="item.type<valueLevel" name="arrow-right" color="#ddd"/>
</div>
</div>
</div>
<AiEmpty description="暂无数据" class="emptyWrap" v-else/>
</div>
</div>
<u-gap height="118"/>
<div class="footer">
<div class="btn cancel" @click="selectAll">全选</div>
<div class="btn cancel" @click="cancelAll">清空</div>
<div class="btn cancel" @click="back">取消</div>
<div class="btn" @click="confirm">确定选择</div>
</div>
</section>
</template>
<script>
export default {
name: "multiplyArea",
data() {
return {
search: "",
options: [],
selectList: [],
selected: {}
}
},
computed: {
optionsList() {
let {search} = this
return this.options.filter(e => !search || e.name.indexOf(search) > -1)
},
valueLevel() {
return this.$route.query.valueLevel || 5
},
extra: v => v.$route.query.extra
},
methods: {
getOptionsByRoot() {
let {areaId, all} = this.$route.query, action = "/admin/area/queryAreaByParentId"
if (all == true || !areaId) {
action = "/admin/area/queryProvinceList"
}
this.selectList = [{name: "可选范围", id: areaId}]
this.$http.post(action, null, {
withoutToken: true, params: {id: areaId}
}).then(res => {
if (res?.data) {
this.options = res.data.map(e => ({...e, isChecked: !!this.selected[e.id]}))
}
})
},
getChildren(row) {
let {id, type} = row
if (type < this.valueLevel && !row.locked) {
row.locked = true
this.$http.post("/admin/area/queryAreaByParentId", null, {
withoutToken: true, params: {id}
}).then(res => {
if (res?.data) {
this.selectList.push(row)
this.options = res.data.map(e => ({...e, isChecked: !!this.selected[e.id]}))
}
}).finally(() => row.locked = false)
} else if (this.extra && !row.locked) {
row.locked = true
this.$http.post("/admin/appresident/queryAreaIdGroup", null, {
params: {currentAreaId: id}
}).then(res => {
if (res?.data) {
this.selectList.push(row)
this.options = res.data.map(e => ({...e, isChecked: !!this.selected[e.id]}))
}
}).finally(() => row.locked = false)
}
},
selectListClick(row, index) {
if (index == 0) { //第一级别
this.getOptionsByRoot()
} else {
this.selectList.splice(index, 5)
this.getChildren(row)
}
},
handleCheck(row, value) {
if (value > -1) {
row.isChecked = Boolean(value)
} else row.isChecked = !row.isChecked
if (row.isChecked) {
this.$set(this.selected, row.id, row)
} else {
delete this.selected[row.id]
}
},
confirm() {
uni.$emit("selectArea", Object.keys(this.selected))
this.back()
},
selectAll() {
this.optionsList.map(e => this.handleCheck(e, 1))
},
cancelAll() {
this.optionsList.map(e => this.handleCheck(e, 0))
},
back() {
uni.navigateBack({})
}
},
created() {
[this.$route.query.value].filter(e => !!e).flat().map(id => this.$set(this.selected, id, {id}))
this.getOptionsByRoot()
}
}
</script>
<style lang="scss" scoped>
.multiplyArea {
.color-3F8DF5 {
color: #3F8DF5;
}
.header-middle {
.showTypes {
.empty-div {
height: 16px;
background: #f5f5f5;
}
.cards {
display: flex;
align-items: center;
height: 120px;
line-height: 120px;
padding: 0 0 0 32px;
.checkbox {
width: 48px;
height: 48px;
background-image: url("./img/xz.png");
background-size: 100%;
&.checked {
background-image: url("./img/xzh.png");
}
}
.cardRight {
display: flex;
justify-content: space-between;
align-items: center;
margin-left: 32px;
border-bottom: 1px solid #e4e5e6;
padding-right: 16px;
box-sizing: border-box;
.applicationNames {
font-size: 36px;
font-weight: 500;
color: #333333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
}
.footer {
width: 100%;
height: 118px;
background: #F4F8FB;
position: fixed;
left: 0;
bottom: 0;
text-align: right;
.btn {
display: inline-block;
padding: 0 32px;
height: 80px;
line-height: 80px;
background: #1365DD;
border-radius: 4px;
text-align: center;
font-size: 32px;
font-family: PingFangSC-Regular, PingFang SC;
color: #FFF;
margin: 20px 34px 0 0;
&.cancel {
background: #fff;
color: #333;
border: 1px solid #ddd;
}
}
}
}
</style>

View File

@@ -1,157 +0,0 @@
<template>
<section class="sealDrawer">
<slot name="tools"/>
<div v-if="drawPlaceholder" class="placeholder">{{ placeholder }}</div>
<canvas disable-scroll type="canvas" canvas-id="drawer" id="drawer" @mousedown.stop="handleDrawStart"
@mouseup.stop="handleDrawEnd" @mouseleave="handleDrawEnd" @mousemove.stop="handleDrawing"
@touchstart.stop="handleDrawStart" @touchend.stop="handleDrawEnd" @touchmove="handleDrawing"/>
<AiBottomBtn v-if="isVertical">
<div flex>
<div class="fill text reset" @click.stop="handleClean">重写</div>
<div class="fill text" @click.stop="submit">提交</div>
</div>
</AiBottomBtn>
<template v-else>
<div class="resetSignature left" @click.stop="handleClean">重写</div>
<div class="resetSignature" @click.stop="submit">提交</div>
</template>
</section>
</template>
<script>
export default {
name: "sealDrawer",
appName: "签名",
props: {
placeholder: {type: String, default: "请在此处清晰书写你的签名"},
},
data() {
return {
drawing: false,//判断是否处于绘画中
drawer: {},
drawPlaceholder: true,
isVertical: true
}
},
watch: {
drawing() {
this.drawPlaceholder = false
}
},
mounted() {
window.onresize = () => {
this.isVertical = ![90, -90].includes(window.orientation)
}
this.initDrawer()
},
methods: {
initDrawer() {
this.$nextTick(() => {
let canvas = uni.createCanvasContext("drawer")
if (canvas) {
this.drawer = canvas
this.drawer.setLineWidth(3)
this.drawer.setShadow(0, 0, 2, '#333')
this.drawer.setStrokeStyle('#333')
}
})
},
handleDrawStart(e) {
this.drawing = true
const {x, y} = e.changedTouches?.[0] || {}
this.drawer?.beginPath()
this.drawer?.moveTo(x, y)
},
handleDrawEnd() {
this.drawing = false
},
handleDrawing(e) {
if (this.drawing) {
const {x, y} = e.changedTouches?.[0] || {}
// // 连接到移动的位置并上色
this.drawer.lineTo(x, y)
this.drawer.stroke()
this.drawer.draw(true)
this.drawer?.beginPath()
this.drawer?.moveTo(x, y)
}
},
handleClean() {
this.drawer.clearRect(0, 0, document.body.clientWidth, document.body.clientHeight)
this.drawer.draw()
this.drawPlaceholder = true
},
submit() {
uni.canvasToTempFilePath({
canvasId: 'drawer',
quality: 1,
success: res => {
// 在H5平台下tempFilePath 为 base64
const result = res.tempFilePath
uni.navigateBack({
success: () => {
uni.$emit("pagePicker:custom", result)
}
})
}
})
}
}
}
</script>
<style lang="scss" scoped>
.sealDrawer {
height: 100vh;
width: 100vw;
overflow: hidden;
background: #F7F7F7;
position: relative;
#drawer {
width: 100%;
height: 100%;
display: block;
cursor: crosshair;
}
.resetSignature {
position: absolute;
width: 152px;
height: 64px;
background: rgba(#000, .5);
border-radius: 32px;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
cursor: pointer;
right: 16px;
top: 16px;
font-size: 32px;
z-index: 2;
&.left {
right: unset;
left: 16px;
}
}
.placeholder {
pointer-events: none;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
max-width: 407px;
text-align: center;
font-size: 64px;
color: #DDDDDD;
}
::v-deep.reset {
background-color: #fff;
color: #333;
}
}
</style>

View File

@@ -1,343 +0,0 @@
<template>
<section class="selectArea">
<div class="areaSelector">
<div class="fixedTop">
<b>选择地区</b>
<em>选择区域</em>
<div class="selectedArea">
<p v-if="hasSelected" v-text="fullArea.map(e=>e.name).join('')"/>
<p v-else>请选择</p>
</div>
<div/>
<span v-if="all" v-text="`省`" @click="selectNode({}, -1)"/>
<span v-for="(area,i) in typeLabels" :key="area.id"
v-text="area.levelLabel" @click="selectNode(area, i)"/>
</div>
</div>
<scroll-view class="fill pendingList" scroll-y>
<div class="pendingItem flexRow" flex v-for="op in pending" :key="op.id" @tap.stop="getChild(op)">
<div class="fill" :class="{ self: index == op.id }" v-html="op.name"/>
<u-icon v-if="index == op.id" name="checkbox-mark" color="#4181FF"/>
</div>
<AiEmpty v-if="pending.length==0" description="无下级地区数据"/>
</scroll-view>
<div class="bottomBtns">
<div @click.stop="back">取消</div>
<div class="primary fill" @click.stop="handleSelect">确定</div>
</div>
</section>
</template>
<script>
export default {
name: "selectArea",
appName: "选择地区",
computed: {
dataRange() {
return this.all || this.disabled ? 0 : this.getAreaType(this.root)
},
root() {
return this.areaId || this.$areaId
},
pending() {
return this.list?.map(e => ({...e, levelLabel: this.levelLabels[e.type]})) || []
},
hasSelected() {
return this.fullArea?.length > 0
},
hasLastLevelValue() {
return this.fullArea.some(e => e.type >= this.valueLevel)
},
typeLabels() {
return this.fullArea.filter(e => e.type < this.valueLevel)
}
},
data() {
Object.keys(this.$route.query).map(k => this.$route.query[k] = this.$route.query[k] == "false" ? false : this.$route.query[k])
return {
...this.$route.query,
fullArea: [],
index: '',
list: [],
levelLabels: ["省", "市", "县/区", "镇/街道", "村/社区"],
selected: {},
}
},
watch: {
root(v) {
v && (this.getFullArea(v))
}
},
methods: {
getInfo(areaId) {
return areaId && this.$http.post('/admin/area/getAllParentAreaId', null, {
withoutToken: true,
params: {areaId},
}).then(res => {
if (res?.data) {
res.data.forEach((e) => {
e && (e.levelLabel = this.levelLabels[e.type])
})
return res.data.reverse()
}
})
},
getFullArea(areaId) {
return this.fullArea?.length > 0 ? Promise.resolve(this.fullArea) : this.getInfo(areaId).then(meta => {
if (meta.length > 1) {
this.fullArea = meta.slice(this.dataRange)
} else {
this.fullArea = meta
}
return this.fullArea
})
},
getChildAreas(id) {
id && this.$http.post('/admin/area/queryAreaByParentId', null, {
withoutToken: true,
params: {id},
}).then((res) => {
if (res?.data) {
this.list = res.data
if (this.selectRoot) {
if (this.hasLastLevelValue) {
let parent = JSON.parse(JSON.stringify(this.fullArea?.slice(-2)?.[0]))
this.list.unshift(parent)
} else {
let parent = JSON.parse(JSON.stringify(this.fullArea?.slice(-1)?.[0]))
this.list.unshift(parent)
}
}
}
})
},
getProvinces() {
this.$http.post('/admin/area/queryProvinceList', null, {withoutToken: true}).then((res) => {
if (res?.data) {
this.list = res.data
}
})
},
handleSelect() {
let {selected, fullArea} = this
uni.$emit("selectArea", {...selected, fullArea})
this.back()
},
getChild(op) {
if (op.id != this.index) {
this.selected = op
this.index = op.id
let {length} = this.fullArea
if (op.type == this.valueLevel) {
if (this.hasLastLevelValue) {
this.fullArea.splice(length - 1, 1, op)
} else this.fullArea.push(op)
} else if (op.type < this.valueLevel) {
if (this.hasLastLevelValue) {
this.fullArea.splice(length - 1, 1)
} else {
this.fullArea.push(op)
this.getChildAreas(op.id)
}
}
}
},
selectNode(area, i) {
let deleteCount = this.fullArea.length - i
if (deleteCount > 0) {
this.fullArea.splice(i + 1, deleteCount)
}
if (this.all && !area.id) {
this.index = ''
this.getProvinces()
} else {
this.index = area.id
this.getChildAreas(area.id)
}
},
handleInit() {
//初始化
this.index = this.value || this.root
if (!this.disabled) {
if (this.value) {
this.getFullArea(this.value).then(() => {
let area = this.fullArea.find(e => e.id == this.value) || {}
//当前选择列表必须是可选范围内的值
let top = area.type == this.valueLevel ? area.parentId : area.id
if (this.getAreaType(top) >= this.dataRange) {
this.getChildAreas(top)
}
})
} else if (this.all) {
this.getProvinces()
} else {
this.getFullArea(this.root).then(() => {
this.getChildAreas(this.root)
})
}
}
},
back() {
uni.navigateBack({})
},
getAreaType(area) {
let rules = [10, 8, 6, 3, 0], level = 0
if (area) {
rules.some((e, i) => {
let reg = new RegExp(`0{${e}}`, 'g')
if (reg.test(area)) {
return (level = i)
}
})
}
return level
}
},
created() {
this.handleInit()
}
}
</script>
<style lang="scss" scoped>
.selectArea {
display: flex;
flex-direction: column;
height: 100vh;
background: #fff;
::v-deep .areaSelector {
display: flex;
align-items: center;
span {
cursor: pointer;
color: #333;
font-weight: bold;
line-height: 112px;
margin-right: 72px;
position: relative;
&:last-of-type {
margin-right: 0;
&:after {
content: " ";
display: block;
position: absolute;
bottom: -26px;
left: 50%;
transform: translate(-50%, 100%);
width: 40px;
height: 8px;
background: #4181FF;
border-radius: 4px;
}
}
}
b {
display: block;
width: 100%;
line-height: 96px;
text-align: center;
}
em {
font-style: normal;
font-size: 24px;
font-weight: 400;
color: #999999;
line-height: 34px;
}
.selectedArea {
display: flex;
align-items: center;
width: fit-content;
max-width: calc(100vw - 128px);
padding: 0 32px;
height: 80px;
background: #ECF2FF;
border-radius: 40px;
font-size: 32px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #4181FF !important;
margin: 16px 0 32px;
white-space: nowrap;
& > p {
overflow: hidden;
text-overflow: ellipsis;
direction: rtl;
}
}
.fixedTop {
top: 0;
width: 100vw;
left: 0;
background: #fff;
border-bottom: 4px solid #f5f5f5;
z-index: 1;
text-align: start;
padding: 0 32px;
box-sizing: border-box;
}
}
::v-deep .pendingList {
padding: 0 32px;
box-sizing: border-box;
.emptyWrap {
width: 100%;
}
.pendingItem {
color: #333;
height: 84px;
text-align: start;
.self {
font-weight: bold;
}
}
}
::v-deep.bottomBtns {
width: 100vw;
display: flex;
align-items: center;
text-align: center;
height: 120px;
font-size: 34px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #3671EE;
background: #fff;
padding: 0 32px;
box-sizing: border-box;
& > div {
padding: 0 92px;
line-height: 88px;
height: 88px;
border: 1px solid #A0C0FF;
border-radius: 16px;
&.primary {
color: #fff;
background: #4181FF;
border-color: #4181FF;
}
& + div {
margin-left: 32px;
}
}
}
}
</style>

View File

@@ -1,182 +0,0 @@
<template>
<div class="selectDept">
<AiTopFixed>
<AiTreePath :node="cursor" :paths="depts.map" :prop="{parent:'parentid'}" @click="changeList"/>
</AiTopFixed>
<div class="user-list">
<template v-if="list.length>0">
<div class="item" v-for="(item, index) in list" :key="index" flex>
<div class="select-img" @click="checkClick(item)">
<img :src="item.isCheck ? checkIcon : cirIcon" alt="">
</div>
<div class="user-info fill" flex @click="getCursor(item)">
<div class="fill" v-text="item.name"/>
<u-icon v-if="Array.isArray(item.children)" class="mar-r16" name="arrow-right" size="40" color="#999"/>
</div>
</div>
</template>
<template v-else>
<AiEmpty/>
<div class="pad-b118"/>
</template>
</div>
<div class="pad-b118"/>
<div class="footer">
<div class="btn" @click="confirm">确定选择</div>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: "selectDept",
appName: "选择部门",
data() {
return {
current: 1,
total: 0,
name: '',
list: [],
depts: [],
cirIcon: require('./img/xz.png'),
checkIcon: require('./img/xzh.png'),
selected: [],
cursor: {}
}
},
computed: {
...mapState(['user']),
isSingle: v => !!v.$route.query.single,
nodeKey: v => v.$route.query.nodeKey || "idNumber",
isRequire: v => v.$route.query.isRequire || 1,
isAuth: v => !!v.$route.query.isAuth, //是否只能选择自己当前部门及以下
},
onLoad(query) {
console.log(query)
if (query.selected) {
this.selected = query.selected?.split(",").map(e => Number(e)) || []
}
this.getList()
},
methods: {
getList() {
var url = this.isAuth ? `/app/wxcp/wxdepartment/listByUser?name=${this.name}` : `/app/wxcp/wxdepartment/listAll?name=${this.name}`
this.$http.post(url).then(res => {
if (res?.data) {
res.data.forEach(e => e.isCheck = this.selected.includes(e[this.nodeKey]))
this.depts = new this.$tree(res.data, {parent: 'parentid'})
this.list = this.depts.tree
}
})
},
checkClick(item) {
if (this.isSingle && this.isRequire == 1) {
this.depts.every(e => {
e.isCheck = item.id == e.id
})
} else item.isCheck = !item.isCheck
},
confirm() {
let checkList = []
this.depts.every((item) => {
if (item.isCheck) {
checkList.push(item)
}
})
if (!checkList.length && this.isRequire == 1) {
return this.$u.toast('请先选择部门')
} else {
uni.navigateBack({
success: () => {
uni.$emit("pagePicker:dept", checkList)
}
})
}
},
changeList(item) {
if (item == "all") {
this.cursor = {}
this.list = this.depts.tree
} else {
this.cursor = item
this.list = item.children
}
},
getCursor(item) {
if (item.children?.length > 0) {
this.cursor = item
this.list = item.children
}
}
},
}
</script>
<style lang="scss" scoped>
.selectDept {
::v-deep .AiTopFixed .u-search {
margin-bottom: 0 !important;
}
.pad-b118 {
padding-bottom: 118px;
}
.user-list {
background-color: #fff;
.item {
width: 100vw;
.select-img {
display: inline-block;
img {
width: 48px;
height: 48px;
margin: 12px 36px 12px 30px;
vertical-align: middle;
}
}
.user-info {
padding: 20px 0 20px 0;
height: 100%;
border-bottom: 1px solid #E4E5E6;
font-size: 36px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333;
line-height: 74px;
}
}
}
.footer {
width: 100%;
height: 118px;
background: #F4F8FB;
position: fixed;
left: 0;
bottom: 0;
text-align: right;
.btn {
display: inline-block;
width: 192px;
height: 80px;
line-height: 80px;
background: #1365DD;
border-radius: 4px;
text-align: center;
font-size: 32px;
font-family: PingFangSC-Regular, PingFang SC;
color: #FFF;
margin: 20px 34px 0 0;
}
}
}
</style>

View File

@@ -1,303 +0,0 @@
<template>
<section class="selectDeptUser">
<div class="header-middle">
<div class="hint">
<span v-for="(item, index) in selectDeptPath" :key="index">
<span v-if="index>0" class="mar-h4">/</span>
<span class="color-3F8DF5" @click="deptNameClick(item, index)">{{ item.name }}</span>
</span>
</div>
<div class="cards" v-for="item in treeList" :key="item.id" @click="itemClick(item)">
<div class="imges">
<div class="imgselect" v-if="type == 1" :class="{checked:item.isChecked}" />
<img src="./img/gird--select-icon.png" alt="" class="avatras"/>
</div>
<div class="rightes">
<div class="applicationNames">{{ item.name }}</div>
<img src="./img/right-icon.png" alt="" class="imgs"/>
</div>
</div>
<div v-if="type == 0">
<div class="userCards" v-for="(e, userIndex) in userList" :key="e.id">
<div class="imges">
<div class="imgselect" :class="{checked:e.isChecked}" @click.stop="itemCheck(e, 'user', userIndex)"/>
<img src="./img/tx@2x.png" alt="" class="avatras"/>
</div>
<div class="rights fill">
<div class="applicationNames" v-text="e.name"></div>
<div class="idNumbers">{{ e.phone }}</div>
</div>
</div>
</div>
<AiEmpty description="暂无数据" v-if="!hasData"/>
</div>
<div class="subBtn" @click="submit">
<div>确定选择</div>
</div>
</section>
</template>
<script>
import { mapState } from "vuex";
export default {
name: "selectDeptUser",
appName: "选择人员",
data() {
return {
selected: [],
allData: null,
treeList: [],
selectDeptPath: [],
userList: [],
type: 0,
}
},
computed: {
isSingle: v => !!v.$route.query.single,
nodeKey: v => v.$route.query.nodeKey || "id",
isRequire: v => v.$route.query.isRequire || 1,
hasData() {
return this.treeList?.length > 0 || this.userList?.length > 0
},
...mapState(['user'])
},
onLoad(query) {
if (query.selected) {
this.selected = query.selected?.split(",") || []
}
this.getListAll()
},
methods: {
isSelected(id) {
return !!this.selected.find(e => e == id)
},
getListAll() {
this.$http.post('/app/wxcp/wxdepartment/listAllByCorp').then((res) => {
if (res?.data) {
let parents = res.data.map(e => e.parentid)
this.allData = res.data.map(e => ({...e, hasChildren: parents.includes(e.id), isChecked: this.isSelected(e.id)}))
this.deptInit()
}
})
},
deptInit() {
this.treeList = this.allData.filter(e => !e.parentid)
this.selectDeptPath = [{name: "可选范围", id: ''}]
},
itemClick({id, name, corpId}) {
let index = this.selectDeptPath.findIndex(e => e.id == id && e.corpId == corpId)
if (index == -1) {
this.selectDeptPath.push({name, id, corpId})
this.getDeptsAndUsersByParent(id, corpId)
}
},
getDeptsAndUsersByParent(departmentId, corpId) {
this.treeList = this.allData.filter(e => e.parentid == departmentId && e.corpId == corpId)
this.userList = []
this.$http.post(`/app/wxcp/wxuser/listByDeptId`, null, {
params: {departmentId, status: 1, cid: corpId}
}).then(res => {
if (res?.data) {
this.userList = res.data.map(e => ({...e, isChecked: this.isSelected(e.id, e.corpId)}))
}
})
},
deptNameClick(row, index) {
this.userList = []
if (!index) { //第一级别
this.deptInit()
} else {
let length = this.selectDeptPath.length - index
this.selectDeptPath.splice(index + 1, length)
this.getDeptsAndUsersByParent(row.id, row.corpId)
}
},
itemCheck(row, kind, index) {
if(this.isSingle) {
this.selected = []
this.userList.map((item) => {
item.isChecked = false
})
this.userList[index].isChecked = true
this.selected.push({...row, kind})
} else {
row.isChecked = !row.isChecked
if (row.isChecked) {
this.selected.push({...row, kind})
} else {
let index = this.selected.findIndex(e => e.id == row.id)
this.selected.splice(index, 1)
}
}
this.$forceUpdate()
},
submit() {
if(![this.selected].flat().length) {
return this.$u.toast('请选择人员')
}
uni.navigateBack({
success: () => {
uni.$emit("pagePicker:deptUser", this.selected)
}
})
},
}
}
</script>
<style lang="scss" scoped>
.selectDeptUser {
height: 100%;
background: #fff;
.header-top {
background: #fff;
padding: 20px 32px;
}
.header-middle {
padding-bottom: 140px;
.hint {
padding: 28px 20px 28px 32px;
line-height: 56px;
box-shadow: 0 1px 0 0 #e4e5e6;
font-size: 30px;
font-weight: 500;
word-break: break-all;
}
.empty-div {
height: 16px;
background: #f5f5f5;
}
.imges {
display: flex;
align-items: center;
.imgselect {
width: 48px;
height: 48px;
vertical-align: middle;
background-image: url("./img/xz.png");
background-position: center;
background-size: 100% 100%;
&.checked {
background-image: url("./img/xzh.png");
}
}
.avatras {
width: 74px;
height: 74px;
border-radius: 8px;
margin-left: 36px;
}
}
.cards {
display: flex;
align-items: center;
height: 120px;
line-height: 120px;
padding: 0 0 0 32px;
img {
width: 74px;
height: 74px;
border-radius: 8px;
}
.rightes {
width: calc(100% - 160px);
display: flex;
align-items: center;
margin-left: 32px;
border-bottom: 1px solid #e4e5e6;
.applicationNames {
flex: 1;
min-width: 0;
font-size: 36px;
font-weight: 500;
color: #333333;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.imgs {
flex-shrink: 0;
width: 40px;
height: 40px;
margin-right: 20px;
}
}
}
.userCards {
display: flex;
align-items: center;
height: 120px;
line-height: 120px;
padding: 0 0 0 32px;
.rights {
display: flex;
justify-content: space-between;
align-items: center;
margin-left: 32px;
border-bottom: 1px solid #e4e5e6;
padding-right: 40px;
height: inherit;
.applicationNames {
font-size: 36px;
font-weight: 500;
color: #333333;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.idNumbers {
color: #666;
}
}
}
}
.subBtn {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 118px;
background: #f4f8fb;
div {
width: 192px;
height: 80px;
line-height: 80px;
text-align: center;
background: #1365dd;
border-radius: 4px;
font-size: 32px;
color: #fff;
margin: 20px 34px 0 0;
float: right;
}
}
.color-3F8DF5 {
color: #3F8DF5;
}
.mar-h4 {
margin: 0 4px;
}
}
</style>

View File

@@ -1,287 +0,0 @@
<template>
<div class="SelectGird">
<div class="header-middle">
<div class="hint">
<span v-for="(item, index) in selectList" :key="index">
<span v-if="index" class="mar-h8" v-text="`/`"/>
<span style="color:#3F8DF5" @click="girdNameClick(item, index)" v-text="item.girdName"/>
</span>
</div>
<div class="showTypes">
<div v-if="options.length > 0">
<div class="cards" v-for="(item, index) in options" :key="index" @click="itemClick(item)">
<div class="imges">
<img src="./img/xzh.png" alt="" class="imgselect" v-if="item.isChecked"
@click.stop="girdClick(item, index)"/>
<img src="./img/xz.png" alt="" class="imgselect" v-else @click.stop="girdClick(item, index)"/>
<img src="./img/gird--select-icon.png" alt="" class="avatras"/>
</div>
<div class="rightes fill">
<div class="applicationNames fill">{{ item.girdName }}</div>
</div>
</div>
</div>
<AiEmpty :description="isGridMember?`暂无数据`:`当前人员不是网格员或网格长`" class="emptyWrap" v-else/>
</div>
</div>
<!-- <div style="padding-bottom: 70px;"></div> -->
<div class="subBtn" flex>
<div v-if="clearable" class="cancel" @click="cancel">清空</div>
<div @click="submit">确定选择</div>
</div>
</div>
</template>
<script>
import {mapState} from "vuex";
export default {
name: 'SelectGird',
appName: "网格选择",
data() {
return {
SelectGird: {},
allData: null,
options: [],
selectList: [],
parentGirdId: '',
isFormMap: 0, //1为网格地图 一级不允许选中
}
},
computed: {
...mapState(['user']),
isMyGirds() {
return this.$route?.query.self == true
},
isGridMember() {
return this.user.girdCheckType > 0
},
//是否是网格员申报
isApply: v => v.$route?.query.formType == 2,
clearable: v => v.$route?.query.clearable,
selected: v => [v.$route?.query.selected].flat()
},
onLoad(option) {
if (option.isFormMap) {
this.isFormMap = option.isFormMap
}
this.isGridMember || this.isApply ? this.getAllGrids() : this.$u.toast('当前人员不是网格员或网格长')
},
methods: {
getAllGrids() {
uni.showLoading({title: "数据加载中...", mask: true})
this.selectList = []
let {girdMemberId} = this.user,
url = `/app/appgirdmemberinfo/queryMyGirdListByLevel2AndUser`,
params = {girdMemberId}
if (this.isApply) {
url = `/app/appgirdinfo/listByInfo`
params = {}
}
if (this.isMyGirds) {
url = `/app/appgirdmemberinfo/queryMyGirdListByLevel2`
}
if (this.$route.query.action) {
url = this.$route.query.action
}
this.$http.post(url, null, {params}).then((res) => {
if (res?.data) {
let parents = res.data.map(e => e.parentGirdId)
console.log(parents)
this.allData = res.data.map(e => ({...e, hasChildren: parents.includes(e.id)}))
this.treeInit()
if (this.$route.query.selected) { //确认按钮弹窗报错
this.allData.map((item) => {
if (item.id == this.$route.query.selected) {
this.SelectGird = item
}
})
}
}
}).finally(() => uni.hideLoading())
},
treeInit(isClick) {
let last = uni.getStorageSync("lastSelectedGrid")
if (!isClick && last && !this.isApply) {
this.$http.post("/app/appgirdinfo/listFatherGirdInfo", null, {
params: {girdId: last}
}).then(res => {
if (res?.data) {
this.selectList = [{
girdName: '可选范围',
id: ''
}, res.data.filter(e => !!this.allData.find(a => a.id == e.id))].flat()
this.getGridsByGridMemberAndParent({id: last})
}
})
} else {
this.options = this.allData.filter((e, i, arr) => !arr.map(e => e.id).includes(e.parentGirdId) || this.isMyGirds)
this.options.map((item) => item.isChecked = this.selected.includes(item.id))
let obj = {girdName: '可选范围', id: ''}
this.selectList.push(obj)
}
},
itemClick(row) {
if (row.hasChildren) {
let obj = {
girdName: row.girdName,
id: row.id,
}
this.selectList.push(obj)
this.getGridsByGridMemberAndParent(row)
}
},
getGridsByGridMemberAndParent(row) {
let {id: parentGirdId} = row
this.options = this.allData.filter(e => e.parentGirdId == parentGirdId)
this.options.map((item) => item.isChecked = this.selected.includes(item.id))
},
girdNameClick(row, index) {
if (!index) { //第一级别
this.selectList = []
this.treeInit(true)
} else {
this.selectList.splice(index + 1, 8)
this.getGridsByGridMemberAndParent(row)
}
},
girdClick(row, index) {
if (this.options[index].isChecked) {//取消
this.options[index].isChecked = false
this.SelectGird = {}
} else {
this.options.map((item) => {
item.isChecked = false
})
this.options[index].isChecked = true
this.SelectGird = row
}
this.$forceUpdate()
},
submit() {
if (this.SelectGird.id != null) {
if (!this.isApply && !this.isMyGirds) {
uni.setStorageSync("lastSelectedGrid", this.SelectGird.parentGirdId)
}
uni.navigateBack({
success: () => {
uni.$emit("pagePicker:gird", this.SelectGird)
}
})
} else {
return this.$u.toast('请选择网格')
}
},
cancel() {
this.SelectGird = {}
uni.navigateBack({
success: () => {
uni.$emit("pagePicker:gird", this.SelectGird)
}
})
}
}
}
</script>
<style scoped lang="scss">
.SelectGird {
min-height: 100vh;
background: #fff;
padding-bottom: 140px;
box-sizing: border-box;
.header-middle {
.hint {
padding: 28px 20px 28px 32px;
line-height: 56px;
box-shadow: 0px 1px 0px 0px #e4e5e6;
font-size: 30px;
font-weight: 500;
word-break: break-all;
}
.showTypes {
.cards {
display: flex;
align-items: center;
height: 120px;
line-height: 120px;
// background: pink;
padding: 0 0 0 32px;
.imges {
display: flex;
align-items: center;
// width: 200px;
.imgselect {
width: 48px;
height: 48px;
vertical-align: middle;
}
.avatras {
width: 74px;
height: 74px;
border-radius: 8px;
margin-left: 36px;
}
}
img {
width: 74px;
height: 74px;
border-radius: 8px;
}
.rightes {
display: flex;
border-bottom: 1px solid #e4e5e6;
padding: 0 16px;
.applicationNames {
display: inline-block;
font-size: 36px;
font-weight: 500;
color: #333333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
vertical-align: bottom;
}
}
}
}
}
.subBtn {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 118px;
background: #f4f8fb;
justify-content: flex-end;
div {
width: 192px;
height: 80px;
line-height: 80px;
text-align: center;
border: 2px solid #1365dd;
background: #1365dd;
border-radius: 4px;
font-size: 32px;
color: #fff;
margin-right: 32px;
&.cancel {
color: #333;
background: #fff;
border-color: #ddd;
}
}
}
}
</style>

View File

@@ -1,304 +0,0 @@
<template>
<section class="selectGridMember">
<div class="header-middle">
<div class="hint">
<span v-for="(item, index) in selectGridPath" :key="index"><span v-if="index" style="margin:0 4px;">/</span><span
style="color:#3F8DF5" @click="girdNameClick(item, index)">{{ item.girdName }}</span></span>
</div>
<div class="cards" v-for="(item, index) in treeList" :key="item.id" @click="itemClick(item)">
<div class="imges">
<!-- <img src="./img/xzh.png" alt="" class="imgselect" v-if="item.isChecked" @click.stop="girdClick(item, index)"/>
<img src="./img/xz.png" alt="" class="imgselect" v-else @click.stop="girdClick(item, index)"/> -->
<img src="./img/gird--select-icon.png" alt="" class="avatras"/>
</div>
<div class="rightes">
<div class="applicationNames">{{ item.girdName }}</div>
<u-icon class="mar-r16" name="arrow-right" color="#ddd"/>
</div>
</div>
<div class="userCards" v-for="(e, index) in userList" :key="e.id">
<div class="imges">
<img src="./img/xzh.png" alt="" class="imgselect" v-if="e.isChecked" @click="userClick(e, index)"/>
<img src="./img/xz.png" alt="" class="imgselect" v-else @click="userClick(e, index)"/>
<img src="./img/user-img.png" alt="" class="avatras"/>
</div>
<div class="rights fill">
<div class="applicationNames" v-text="e.name"/>
<div class="idNumbers">{{ e.phone }}</div>
</div>
</div>
<AiEmpty description="暂无数据" v-if="!hasData"/>
</div>
<div class="subBtn" @click="submit">
<div>确定选择</div>
</div>
</section>
</template>
<script>
export default {
name: "selectGridMember",
appName: "选择人员(网格成员)",
data() {
return {
selected: {},
allData: null,
treeList: [],
selectGridPath: [],
userList: [],
}
},
computed: {
hasData() {
return this.treeList?.length > 0 || this.userList?.length > 0
}
},
onLoad() {
this.selected.girdId = this.$route.query.id
this.getAllGrids()
},
onShow() {
document.title = '选择人员'
},
methods: {
getAllGrids() {
uni.showLoading({title: "数据加载中...", mask: true})
this.$http.post('/app/appgirdinfo/listByInfo').then((res) => {
if (res?.data) {
let parents = res.data.map(e => e.parentGirdId)
this.allData = res.data.map(e => ({...e, hasChildren: parents.includes(e.id)}))
this.gridInit()
}
}).finally(() => uni.hideLoading())
},
gridInit() {
this.treeList = this.allData.filter(e => !e.parentGirdId)
this.selectGridPath = [{girdName: "可选范围", id: ''}]
},
itemClick({id, girdName}) {
this.selectGridPath.push({girdName, id})
this.getGridsAndUsersByParent(id)
},
getGridsAndUsersByParent(id) {
this.treeList = this.allData.filter(e => e.parentGirdId == id)
this.userList = []
this.$http.post(`/app/appgirdmemberinfo/listByGirdIdByThree?girdId=${id}`).then((res) => {
if (res?.data) {
this.userList = res.data.map(e => ({...e, isChecked: e.girdId == this.selected.girdId}))
this.userList.map((item) => {
if(item.isChecked) {
this.selected = {...item}
}
})
}
})
},
girdNameClick(row, index) {
this.userList = []
if (!index) { //第一级别
this.gridInit()
} else {
let length = this.selectGridPath.length - index
this.selectGridPath.splice(index, length)
this.getGridsAndUsersByParent(row.id)
}
},
girdClick(row, index) {
if (this.treeList[index].isChecked) {//取消
this.treeList[index].isChecked = false
this.selected = {}
} else {
this.treeList.map((item, i) => {
item.isChecked = index == i
})
this.selected = {...row, kind: "grid"}
}
this.$forceUpdate()
},
userClick(row, index) {
if (this.userList[index].isChecked) {//取消
this.userList[index].isChecked = false
this.selected = {}
} else {
this.userList.map((item, i) => {
item.isChecked = index == i
})
this.selected = {...row, kind: "user"}
}
this.$forceUpdate()
},
submit() {
if (this.selected.id) {
uni.navigateBack({
success: () => {
uni.$emit("pagePicker:gridUser", this.selected)
}
})
} else {
return this.$u.toast('请选择网格员')
}
},
}
}
</script>
<style lang="scss" scoped>
.selectGridMember {
height: 100%;
background: #fff;
.header-top {
background: #fff;
padding: 20px 32px;
}
.header-middle {
padding-bottom: 140px;
.hint {
padding: 28px 20px 28px 32px;
line-height: 56px;
box-shadow: 0 1px 0 0 #e4e5e6;
font-size: 30px;
font-weight: 500;
word-break: break-all;
}
.empty-div {
height: 16px;
background: #f5f5f5;
}
.cards {
display: flex;
align-items: center;
height: 120px;
line-height: 120px;
padding: 0 0 0 32px;
.imges {
display: flex;
align-items: center;
.imgselect {
width: 48px;
height: 48px;
vertical-align: middle;
}
.avatras {
width: 74px;
height: 74px;
border-radius: 8px;
margin-left: 36px;
}
}
img {
width: 74px;
height: 74px;
border-radius: 8px;
}
.rightes {
width: calc(100% - 160px);
display: flex;
align-items: center;
margin-left: 32px;
border-bottom: 1px solid #e4e5e6;
.applicationNames {
flex: 1;
min-width: 0;
font-size: 36px;
font-weight: 500;
color: #333333;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.imgs {
flex-shrink: 0;
width: 40px;
height: 40px;
margin-right: 20px;
}
}
}
.userCards {
display: flex;
align-items: center;
height: 120px;
line-height: 120px;
padding: 0 0 0 32px;
.imges {
display: flex;
align-items: center;
.imgselect {
width: 48px;
height: 48px;
}
.avatras {
width: 74px;
height: 74px;
border-radius: 8px;
margin-left: 36px;
}
}
.rights {
display: flex;
justify-content: space-between;
align-items: center;
margin-left: 32px;
border-bottom: 1px solid #e4e5e6;
padding-right: 40px;
height: inherit;
.applicationNames {
font-size: 36px;
font-weight: 500;
color: #333333;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.idNumbers {
color: #666;
}
}
}
}
.subBtn {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 118px;
background: #f4f8fb;
div {
width: 192px;
height: 80px;
line-height: 80px;
text-align: center;
background: #1365dd;
border-radius: 4px;
font-size: 32px;
color: #fff;
margin: 20px 34px 0 0;
float: right;
}
}
}
</style>

View File

@@ -1,299 +0,0 @@
<template>
<section class="selectGridMember">
<div class="header-middle">
<div class="hint">
<span v-for="(item, index) in selectGridPath" :key="index"><span v-if="index" style="margin:0 4px;">/</span><span
style="color:#3F8DF5" @click="girdNameClick(item, index)">{{ item.girdName }}</span></span>
</div>
<div class="cards" v-for="(item, index) in treeList" :key="item.id" @click="itemClick(item)">
<div class="imges">
<img src="./img/xzh.png" alt="" class="imgselect" v-if="item.isChecked" @click.stop="girdClick(item, index)"/>
<img src="./img/xz.png" alt="" class="imgselect" v-else @click.stop="girdClick(item, index)"/>
<img src="./img/gird--select-icon.png" alt="" class="avatras"/>
</div>
<div class="rightes">
<div class="applicationNames">{{ item.girdName }}</div>
<u-icon class="mar-r16" name="arrow-right" color="#ddd"/>
</div>
</div>
<div class="userCards" v-for="(e, index) in userList" :key="e.id">
<div class="imges">
<img src="./img/xzh.png" alt="" class="imgselect" v-if="e.isChecked" @click="userClick(e, index)"/>
<img src="./img/xz.png" alt="" class="imgselect" v-else @click="userClick(e, index)"/>
<img src="./img/user-img.png" alt="" class="avatras"/>
</div>
<div class="rights fill">
<div class="applicationNames" v-text="e.name"/>
<div class="idNumbers">{{ e.phone }}</div>
</div>
</div>
<AiEmpty description="暂无数据" v-if="!hasData"/>
</div>
<div class="subBtn" @click="submit">
<div>确定选择</div>
</div>
</section>
</template>
<script>
export default {
name: "selectGridMember",
appName: "选择人员(网格成员)",
data() {
return {
selected: {},
allData: null,
treeList: [],
selectGridPath: [],
userList: [],
}
},
computed: {
hasData() {
return this.treeList?.length > 0 || this.userList?.length > 0
}
},
onLoad() {
this.selected.id = this.$route.query.id
this.getAllGrids()
},
onShow() {
document.title = '选择人员'
},
methods: {
getAllGrids() {
uni.showLoading({title: "数据加载中...", mask: true})
this.$http.post('/app/appgirdinfo/listByInfo').then((res) => {
if (res?.data) {
let parents = res.data.map(e => e.parentGirdId)
this.allData = res.data.map(e => ({...e, hasChildren: parents.includes(e.id)}))
this.gridInit()
}
}).finally(() => uni.hideLoading())
},
gridInit() {
this.treeList = this.allData.filter(e => !e.parentGirdId)
this.selectGridPath = [{girdName: "可选范围", id: ''}]
},
itemClick({id, girdName}) {
this.selectGridPath.push({girdName, id})
this.getGridsAndUsersByParent(id)
},
getGridsAndUsersByParent(id) {
this.treeList = this.allData.filter(e => e.parentGirdId == id)
this.userList = []
this.$http.post(`/app/appgirdmemberinfo/listByGirdIdByThree?girdId=${id}`).then((res) => {
if (res?.data) {
this.userList = res.data.map(e => ({...e, isChecked: e.id == this.selected.id}))
}
})
},
girdNameClick(row, index) {
this.userList = []
if (!index) { //第一级别
this.gridInit()
} else {
let length = this.selectGridPath.length - index
this.selectGridPath.splice(index, length)
this.getGridsAndUsersByParent(row.id)
}
},
girdClick(row, index) {
if (this.treeList[index].isChecked) {//取消
this.treeList[index].isChecked = false
this.selected = {}
} else {
this.treeList.map((item, i) => {
item.isChecked = index == i
})
this.selected = {...row, kind: "grid"}
}
this.$forceUpdate()
},
userClick(row, index) {
if (this.userList[index].isChecked) {//取消
this.userList[index].isChecked = false
this.selected = {}
} else {
this.userList.map((item, i) => {
item.isChecked = index == i
})
this.selected = {...row, kind: "user"}
}
this.$forceUpdate()
},
submit() {
if (this.selected.id != null) {
uni.navigateBack({
success: () => {
uni.$emit("pagePicker:gridUser", this.selected)
}
})
} else {
return this.$u.toast('请选择网格或网格员')
}
},
}
}
</script>
<style lang="scss" scoped>
.selectGridMember {
height: 100%;
background: #fff;
.header-top {
background: #fff;
padding: 20px 32px;
}
.header-middle {
padding-bottom: 140px;
.hint {
padding: 28px 20px 28px 32px;
line-height: 56px;
box-shadow: 0 1px 0 0 #e4e5e6;
font-size: 30px;
font-weight: 500;
word-break: break-all;
}
.empty-div {
height: 16px;
background: #f5f5f5;
}
.cards {
display: flex;
align-items: center;
height: 120px;
line-height: 120px;
padding: 0 0 0 32px;
.imges {
display: flex;
align-items: center;
.imgselect {
width: 48px;
height: 48px;
vertical-align: middle;
}
.avatras {
width: 74px;
height: 74px;
border-radius: 8px;
margin-left: 36px;
}
}
img {
width: 74px;
height: 74px;
border-radius: 8px;
}
.rightes {
width: calc(100% - 160px);
display: flex;
align-items: center;
margin-left: 32px;
border-bottom: 1px solid #e4e5e6;
.applicationNames {
flex: 1;
min-width: 0;
font-size: 36px;
font-weight: 500;
color: #333333;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.imgs {
flex-shrink: 0;
width: 40px;
height: 40px;
margin-right: 20px;
}
}
}
.userCards {
display: flex;
align-items: center;
height: 120px;
line-height: 120px;
padding: 0 0 0 32px;
.imges {
display: flex;
align-items: center;
.imgselect {
width: 48px;
height: 48px;
}
.avatras {
width: 74px;
height: 74px;
border-radius: 8px;
margin-left: 36px;
}
}
.rights {
display: flex;
justify-content: space-between;
align-items: center;
margin-left: 32px;
border-bottom: 1px solid #e4e5e6;
padding-right: 40px;
height: inherit;
.applicationNames {
font-size: 36px;
font-weight: 500;
color: #333333;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.idNumbers {
color: #666;
}
}
}
}
.subBtn {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 118px;
background: #f4f8fb;
div {
width: 192px;
height: 80px;
line-height: 80px;
text-align: center;
background: #1365dd;
border-radius: 4px;
font-size: 32px;
color: #fff;
margin: 20px 34px 0 0;
float: right;
}
}
}
</style>

View File

@@ -1,202 +0,0 @@
<template>
<div class="selectParty">
<AiTopFixed>
<u-search placeholder="搜索" v-model="name" :show-action="false" @change="getListInit"></u-search>
</AiTopFixed>
<div class="user-list">
<template v-if="list.length>0">
<div class="item" v-for="(item, index) in list" :key="index">
<div class="select-img" @click="checkClick(index)">
<img :src="item.isCheck ? checkIcon : cirIcon" alt="">
</div>
<div class="user-info">
<img :src="item.photo" alt="" v-if="item.photo">
<img src="./img/user-img.png" alt="" v-else>{{ item.name }}
</div>
</div>
</template>
<template v-else>
<AiEmpty />
<div class="pad-b118"/>
</template>
</div>
<div class="pad-b118"/>
<div class="footer">
<div class="btn" @click="confirm">确定选择</div>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: "selectParty",
appName: "人员选择器(党员)",
data() {
return {
current: 1,
name: '',
list: [],
cirIcon: require('./img/xz.png'),
checkIcon: require('./img/xzh.png'),
selected: []
}
},
computed: {
...mapState(['user']),
isSingle() {
return this.$route.query.single
}
},
onLoad(query) {
if (query.selected) {
this.selected = query.selected?.split(",") || []
}
this.getList()
},
methods: {
getListInit() {
this.list = []
this.current = 1
this.getList()
},
getList() {
var url = this.$route.query.isFourParty ? '/app/appparty/listByFourParty?size=9999' : '/app/appparty/list'
this.$http.post(url, null, {
params: {
current: this.current,
size: 15,
areaId: this.user.areaId,
con: this.name,
name: this.name
}
}).then(res => {
if (res?.data) {
if (this.current > 1 && this.current > res.data.pages) {
return
}
if(this.$route.query.isFourParty) {
res.data.forEach(e => {
e.isCheck = this.selected.includes(e.idNumber)
})
this.list = res.data
}else {
res.data.records.forEach(e => {
e.isCheck = this.selected.includes(e.idNumber)
})
this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records
}
}
})
},
checkClick(index) {
if (this.isSingle) {
this.list.map((e, i) => {
e.isCheck = i == index;
})
} else this.list[index].isCheck = !this.list[index].isCheck
},
confirm() {
let checkList = []
this.list.map((item) => {
if (item.isCheck) {
checkList.push(item)
}
})
if (!checkList.length) {
return this.$u.toast('请先选择人员')
} else {
uni.navigateBack({
success: () => {
uni.$emit("pagePicker:party", checkList)
}
})
}
}
},
onReachBottom() {
if(this.$route.query.isFourParty) {
return
}
this.current++
this.getList()
},
}
</script>
<style lang="scss" scoped>
.selectParty {
::v-deep .AiTopFixed .u-search {
margin-bottom: 0 !important;
}
.pad-b118 {
padding-bottom: 118px;
}
.user-list {
background-color: #fff;
.item {
.select-img {
display: inline-block;
img {
width: 48px;
height: 48px;
margin: 12px 36px 12px 30px;
vertical-align: middle;
}
}
.user-info {
display: inline-block;
padding: 20px 0 20px 0;
width: calc(100% - 114px);
height: 100%;
border-bottom: 1px solid #E4E5E6;
font-size: 36px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333;
line-height: 74px;
img {
width: 74px;
height: 74px;
border-radius: 8px;
margin-right: 34px;
vertical-align: bottom;
}
}
}
}
.footer {
width: 100%;
height: 118px;
background: #F4F8FB;
position: fixed;
left: 0;
bottom: 0;
text-align: right;
.btn {
display: inline-block;
width: 192px;
height: 80px;
line-height: 80px;
background: #1365DD;
border-radius: 4px;
text-align: center;
font-size: 32px;
font-family: PingFangSC-Regular, PingFang SC;
color: #FFF;
margin: 20px 34px 0 0;
}
}
}
</style>

View File

@@ -1,189 +0,0 @@
<template>
<div class="selectResident">
<AiTopFixed>
<u-search placeholder="搜索" v-model="name" :show-action="false" @change="getList"></u-search>
</AiTopFixed>
<div class="user-list">
<template v-if="list.length>0">
<div class="item" v-for="(item, index) in list" :key="index">
<div class="select-img" @click="checkClick(index)">
<img :src="item.isCheck ? checkIcon : cirIcon" alt="">
</div>
<div class="user-info">
<img :src="item.photo" alt="" v-if="item.photo">
<img src="./img/user-img.png" alt="" v-else>{{ item.name }}
</div>
</div>
</template>
<template v-else>
<AiEmpty />
<div class="pad-b118"/>
</template>
</div>
<div class="pad-b118"/>
<div class="footer">
<div class="btn" @click="confirm">确定选择</div>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: "selectResident",
appName: "选择人员",
data() {
return {
current: 1,
name: '',
list: [],
cirIcon: require('./img/xz.png'),
checkIcon: require('./img/xzh.png'),
selected: []
}
},
computed: {
...mapState(['user']),
isSingle() {
return this.$route.query.single
}
},
onLoad(query) {
if (query.selected) {
this.selected = query.selected?.split(",") || []
}
this.getList()
},
methods: {
getList() {
console.log(this.$route.query)
let {householdName, auditStatus} = this.$route.query
this.$http.post(`/app/appresident/list`, null, {
params: {
current: this.current,
size: 20,
areaId: this.user.areaId,
con: this.name,
householdName,
auditStatus: auditStatus || ''
}
}).then(res => {
if (res?.data) {
res.data.records.forEach(e => {
e.isCheck = this.selected.includes(e.idNumber)
})
if (this.current > 1 && this.current > res.data.pages) {
return
}
this.list = this.current > 1 ? [...this.list, ...res.data.records] : res.data.records
}
})
},
checkClick(index) {
if (this.isSingle) {
this.list.map((e, i) => {
e.isCheck = i == index;
})
} else this.list[index].isCheck = !this.list[index].isCheck
},
confirm() {
let checkList = []
this.list.map((item) => {
if (item.isCheck) {
checkList.push(item)
}
})
if (!checkList.length) {
return this.$u.toast('请先选择人员')
} else {
uni.navigateBack({
success: () => {
uni.$emit("pagePicker:resident", checkList)
}
})
}
}
},
onReachBottom() {
this.current++
this.getList()
},
}
</script>
<style lang="scss" scoped>
.selectResident {
::v-deep .AiTopFixed .u-search {
margin-bottom: 0 !important;
}
.pad-b118 {
padding-bottom: 118px;
}
.user-list {
.item {
background-color: #fff;
.select-img {
display: inline-block;
img {
width: 48px;
height: 48px;
margin: 12px 36px 12px 30px;
vertical-align: middle;
}
}
.user-info {
display: inline-block;
padding: 20px 0 20px 0;
width: calc(100% - 114px);
height: 100%;
border-bottom: 1px solid #E4E5E6;
font-size: 36px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333;
line-height: 74px;
img {
width: 74px;
height: 74px;
border-radius: 8px;
margin-right: 34px;
vertical-align: bottom;
}
}
}
}
.footer {
width: 100%;
height: 118px;
background: #F4F8FB;
position: fixed;
left: 0;
bottom: 0;
text-align: right;
.btn {
display: inline-block;
width: 192px;
height: 80px;
line-height: 80px;
background: #1365DD;
border-radius: 4px;
text-align: center;
font-size: 32px;
font-family: PingFangSC-Regular, PingFang SC;
color: #FFF;
margin: 20px 34px 0 0;
}
}
}
</style>

View File

@@ -1,197 +0,0 @@
<template>
<div class="selectResident">
<AiTopFixed>
<u-search placeholder="搜索" v-model="name" :show-action="false" @change="current=1,getList()"/>
</AiTopFixed>
<div class="user-list">
<template v-if="list.length>0">
<div class="item" v-for="(item, index) in list" :key="index">
<div class="select-img" @click="checkClick(index)">
<img :src="item.isCheck ? checkIcon : cirIcon" alt="">
</div>
<div class="user-info">
<img :src="item.photo" alt="" v-if="item.photo">
<img src="./img/user-img.png" alt="" v-else>
{{ item.name }}
<span v-if="isShowPhone && item.mobile">({{item.mobile}})</span>
<span v-if="isShowPhone && item.phone && !item.mobile">({{item.phone}})</span>
</div>
</div>
</template>
<template v-else>
<AiEmpty/>
<div class="pad-b118"/>
</template>
</div>
<div class="pad-b118"/>
<div class="footer">
<div class="btn" @click="confirm">确定选择</div>
</div>
</div>
</template>
<script>
import {mapState} from 'vuex'
export default {
name: "selectResident",
appName: "选择员工",
data() {
return {
current: 1,
total: 0,
name: '',
list: [],
cirIcon: require('./img/xz.png'),
checkIcon: require('./img/xzh.png'),
selected: [],
}
},
computed: {
...mapState(['user']),
isSingle() {
return this.$route.query.single
},
nodeKey() {
return this.$route.query.nodeKey || "idNumber"
},
isRequire() {
return this.$route.query.isRequire || 1
},
isShowPhone() {
return this.$route.query.isShowPhone
},
},
onLoad(query) {
if (query.selected) {
this.selected = query.selected?.split(",") || []
}
this.getList()
},
onShow() {
document.title = this.nodeKey == 'openId' ? '选择居民' : '选择员工'
},
methods: {
getList() {
let {current, total, name: con, $route: {query: {action = `/admin/user/userIntegralList`}}} = this
if ((!total && current == 1) || current <= total) {
action = decodeURIComponent(action)
this.$http.post(action, null, {
params: {current, size: 20, con}
}).then(res => {
if (res?.data) {
this.total = res.data.pages || 0
res.data.records.forEach(e => {
e.isCheck = this.selected.includes(e[this.nodeKey])
})
this.list = [current == 1 ? [] : this.list, res.data.records || []].flat()
}
})
}
},
checkClick(index) {
if (this.isSingle) {
this.list.map((e, i) => {
e.isCheck = i == index;
})
} else this.list[index].isCheck = !this.list[index].isCheck
},
confirm() {
let checkList = []
this.list.map((item) => {
if (item.isCheck) {
checkList.push(item)
}
})
if (!checkList.length && this.isRequire == 1) {
return this.$u.toast('请先选择人员')
} else {
uni.navigateBack({
success: () => {
uni.$emit("pagePicker:sysUser", checkList)
}
})
}
}
},
onReachBottom() {
this.current++
this.getList()
},
}
</script>
<style lang="scss" scoped>
.selectResident {
::v-deep .AiTopFixed .u-search {
margin-bottom: 0 !important;
}
.pad-b118 {
padding-bottom: 118px;
}
.user-list {
background-color: #fff;
.item {
.select-img {
display: inline-block;
img {
width: 48px;
height: 48px;
margin: 12px 36px 12px 30px;
vertical-align: middle;
}
}
.user-info {
display: inline-block;
padding: 20px 0 20px 0;
width: calc(100% - 114px);
height: 100%;
border-bottom: 1px solid #E4E5E6;
font-size: 36px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333;
line-height: 74px;
img {
width: 74px;
height: 74px;
border-radius: 8px;
margin-right: 34px;
vertical-align: bottom;
}
}
}
}
.footer {
width: 100%;
height: 118px;
background: #F4F8FB;
position: fixed;
left: 0;
bottom: 0;
text-align: right;
.btn {
display: inline-block;
width: 192px;
height: 80px;
line-height: 80px;
background: #1365DD;
border-radius: 4px;
text-align: center;
font-size: 32px;
font-family: PingFangSC-Regular, PingFang SC;
color: #FFF;
margin: 20px 34px 0 0;
}
}
}
</style>

View File

@@ -1,62 +0,0 @@
<template>
<section class="submitEvaluation">
<AiGroup>
<AiItem label="评价分数" top-label required>
<u-rate v-model="form.score" :size="64" active-color="#F8B425" :min-count="1" inactive-icon="star-fill"/>
</AiItem>
</AiGroup>
<u-gap height="24"/>
<AiGroup>
<AiItem label="评价详情" top-label required>
<u-input type="textarea" v-model="form.content" placeholder="请简要描述..."/>
</AiItem>
</AiGroup>
<u-gap height="24"/>
<AiGroup>
<AiItem label="附件" top-label>
<AiUploader v-model="form.files" :limit="9" multiple/>
</AiItem>
</AiGroup>
<div class="fixed-bottom">
<div class="bottomBtn" @click="submit">提交</div>
</div>
</section>
</template>
<script>
export default {
name: "submitEvaluation",
appName: "提交评价",
data() {
return {
form: {
files: []
}
}
},
methods: {
submit() {
if (!this.form.score) {
return this.$u.toast("请选择评价分数!")
}
if (!this.form.content) {
return this.$u.toast("请填写评价详情!")
}
this.$http.post("/app/appbusinesscompletionevaluation/addOrUpdate", this.form).then(res => {
if (res?.code == 0) {
this.$u.toast("提交成功!")
setTimeout(() => uni.navigateBack({}), 1500)
}
})
}
},
onLoad(params) {
this.form.bizId = params.bid
}
}
</script>
<style lang="scss" scoped>
.submitEvaluation {
}
</style>

View File

Before

Width:  |  Height:  |  Size: 984 B

After

Width:  |  Height:  |  Size: 984 B