chuangte_bike_newxcx/page_fenbao/yunwei/addyunwei.vue
2026-03-12 13:54:49 +08:00

391 lines
8.9 KiB
Vue

<template>
<view class="page">
<u-navbar :title="tit" :border-bottom="false" :background="bgc" title-color='#000' back-icon-color="#000"
title-size='36' height='50'></u-navbar>
<view class="box">
<view class="title">基本信息</view>
<view class="list">
<view class="list_val">
<view class="" style="padding-top:12rpx">备注名</view>
<input type="text" v-model="beizhu" placeholder="请输入备注名" />
</view>
<view class="list_val" style="position: relative;">
<view class="" style="padding-top:12rpx;width: 176rpx;">身份类型</view>
<input type="text" disabled="false" v-model="sheng" :placeholder="sheng" />
</view>
<view class="list_val">
<view class="" style="padding-top:12rpx">手机号码</view>
<input type="text" v-model="tel" placeholder="请输入手机号码" />
</view>
</view>
<!-- 权限区域 -->
<view class="section-header">
<view class="title">权限</view>
<view class="global-actions" v-if="permissionGroups.length > 0">
<text class="action-btn" @click="handleSelectAllGlobal">全选</text>
<text class="action-divider">|</text>
<text class="action-btn" @click="handleDeselectAllGlobal">取消全选</text>
</view>
</view>
<view v-if="permissionsLoading" class="loading-tip">
<u-loading mode="circle" size="36"></u-loading>
<text style="margin-left: 12rpx; color: #999; font-size: 26rpx;">加载中...</text>
</view>
<view v-for="(group, gi) in permissionGroups" :key="gi" class="permission-group">
<view class="group-header">
<text class="group-name">{{ group.group }}</text>
<view class="group-actions">
<text class="action-btn" @click="handleSelectAllGroup(gi)">全选</text>
<text class="action-divider">|</text>
<text class="action-btn" @click="handleDeselectAllGroup(gi)">取消</text>
</view>
</view>
<view class="swlist">
<view class="swlist_val" v-for="(item, ii) in group.items" :key="ii">
<view class="lt">
<view class="one">{{ item.name }}</view>
<view class="two">{{ item.description }}</view>
</view>
<view class="rt">
<u-switch
v-model="item.checked"
:disabled="item.isDefault"
:active-color="item.isDefault ? '#2b2929' : '#4C97E7'"
size="36"
inactive-color="#eee"
></u-switch>
</view>
</view>
</view>
</view>
<view class="baocun" @click="btncj">{{ tit }}</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
bgc: { backgroundColor: "#fff" },
tel: '',
sheng: '运维',
tit: '创建运维人员',
bili: '',
beizhu: '',
jiamtype: 3,
areaId: '',
jiamid: '',
permissionsLoading: false,
permissionGroups: []
}
},
onLoad(option) {
this.areaId = uni.getStorageSync('adminAreaid')
this.loadPermissions().then(() => {
if (option.item) {
this.tit = '编辑运维人员'
const obj = JSON.parse(option.item)
this.initFormData(obj)
}
})
},
methods: {
/** 从接口加载权限分组 */
loadPermissions() {
this.permissionsLoading = true
return this.$u.get('/bst/areaJoin/permissions').then(res => {
if (res.code === 200 && res.data) {
this.permissionGroups = res.data.map(group => ({
...group,
items: group.items.map(item => ({
...item,
checked: !!item.isDefault
}))
}))
}
}).catch(() => {
uni.showToast({ title: '权限列表加载失败', icon: 'none' })
}).finally(() => {
this.permissionsLoading = false
})
},
/** 初始化表单数据 */
initFormData(obj) {
this.tel = obj.userPhone
this.areaId = obj.areaId
this.jiamid = obj.id
this.beizhu = obj.remark
this.jiamtype = obj.type
this.setPermissionStatus(obj.permissions || [])
},
/** 根据权限 code 数组回填开关状态 */
setPermissionStatus(permissions) {
const permSet = new Set(permissions)
this.permissionGroups.forEach(group => {
group.items.forEach(item => {
if (!item.isDefault) {
item.checked = permSet.has(item.code)
}
})
})
},
/** 全部全选 */
handleSelectAllGlobal() {
this.permissionGroups.forEach(group => {
group.items.forEach(item => { item.checked = true })
})
},
/** 全部取消(保留默认权限) */
handleDeselectAllGlobal() {
this.permissionGroups.forEach(group => {
group.items.forEach(item => {
if (!item.isDefault) item.checked = false
})
})
},
/** 分组全选 */
handleSelectAllGroup(gi) {
this.permissionGroups[gi].items.forEach(item => { item.checked = true })
},
/** 分组取消(保留该组默认权限) */
handleDeselectAllGroup(gi) {
this.permissionGroups[gi].items.forEach(item => {
if (!item.isDefault) item.checked = false
})
},
/** 收集选中的权限 code */
collectPermissions() {
const codes = []
this.permissionGroups.forEach(group => {
group.items.forEach(item => {
if (item.checked) codes.push(item.code)
})
})
return codes
},
/** 构建请求数据 */
buildRequestData() {
return {
id: this.jiamid,
userPhone: this.tel,
areaId: this.areaId,
point: this.bili,
type: 3,
remark: this.beizhu,
permissions: this.collectPermissions()
}
},
/** 处理 API 响应 */
handleApiResponse(res, successMessage) {
if (res.code === 200) {
uni.showToast({ title: successMessage, icon: 'success', duration: 2000 })
setTimeout(() => { uni.navigateBack() }, 2000)
} else {
uni.showToast({ title: res.msg, icon: 'none', duration: 2000 })
}
},
/** 点击创建/编辑 */
async btncj() {
const data = this.buildRequestData()
const isEdit = this.tit === '编辑运维人员'
const apiMethod = isEdit ? 'put' : 'post'
const successMessage = isEdit ? '编辑成功' : '创建成功'
try {
const res = await this.$u[apiMethod]('/bst/areaJoin', data)
this.handleApiResponse(res, successMessage)
} catch (error) {
uni.showToast({ title: '请求失败,请重试', icon: 'none', duration: 2000 })
}
}
}
}
</script>
<style lang="scss">
::v-deep .u-title,
::v-deep .uicon-nav-back {
padding-bottom: 22rpx;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 40rpx;
.title {
margin-top: 0;
}
.global-actions {
display: flex;
align-items: center;
}
}
.action-btn {
font-size: 26rpx;
color: #4C97E7;
padding: 0 10rpx;
}
.action-divider {
font-size: 24rpx;
color: #ccc;
}
.loading-tip {
display: flex;
align-items: center;
justify-content: center;
padding: 40rpx 0;
}
.permission-group {
margin-top: 24rpx;
background: #fff;
border-radius: 24rpx;
padding: 24rpx 28rpx;
box-sizing: border-box;
.group-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
.group-name {
font-size: 30rpx;
font-weight: bold;
color: #3D3D3D;
}
.group-actions {
display: flex;
align-items: center;
}
}
.swlist {
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.swlist_val {
display: flex;
justify-content: space-between;
width: 48%;
min-height: 120rpx;
background: #F4F5F7;
border-radius: 16rpx;
padding: 20rpx 20rpx 20rpx 24rpx;
box-sizing: border-box;
margin-bottom: 16rpx;
}
.lt {
flex: 1;
padding-right: 12rpx;
.one {
font-size: 26rpx;
color: #3D3D3D;
line-height: 1.4;
}
.two {
font-size: 22rpx;
color: #808080;
margin-top: 8rpx;
line-height: 1.4;
}
}
.rt {
display: flex;
align-items: center;
}
}
}
.title {
font-size: 32rpx;
color: #3D3D3D;
margin-top: 40rpx;
}
.page {
width: 750rpx;
.box {
width: 750rpx;
height: 100%;
overflow-y: scroll;
background: #F4F5F7;
padding: 32rpx 36rpx;
box-sizing: border-box;
padding-bottom: 100rpx;
.baocun {
width: 584rpx;
height: 90rpx;
margin: auto;
background: linear-gradient(270deg, #4C97E7 0%, #4C97E7 100%);
border-radius: 54rpx;
margin-top: 80rpx;
margin-bottom: 78rpx;
font-weight: 500;
font-size: 40rpx;
color: #FFFFFF;
text-align: center;
line-height: 90rpx;
}
.list {
width: 680rpx;
background: #FFFFFF;
border-radius: 24rpx;
padding: 46rpx 36rpx;
box-sizing: border-box;
margin-top: 34rpx;
.list_val {
display: flex;
font-size: 32rpx;
color: #3D3D3D;
justify-content: space-between;
margin-bottom: 32rpx;
input {
width: 430rpx;
height: 70rpx;
background: #F0F0F0;
border-radius: 12rpx;
padding-left: 32rpx;
box-sizing: border-box;
font-size: 28rpx;
color: #808080;
}
}
}
}
}
</style>