Commit ebc1053d54d34be586fe774201609b3e656b5bc7

Authored by wuxw
1 parent e9908e30

加入运营员工详情功能

src/App.vue
... ... @@ -476,4 +476,38 @@ ul {
476 476 ul li {
477 477 list-style-type: none;
478 478 }
  479 +
  480 +h2 {
  481 + font-size: 24px;
  482 +}
  483 +
  484 +.h1,
  485 +.h2,
  486 +.h3,
  487 +h1,
  488 +h2,
  489 +h3 {
  490 + margin-top: 20px;
  491 + margin-bottom: 10px;
  492 +}
  493 +
  494 +h1,
  495 +h2,
  496 +h3,
  497 +h4,
  498 +h5,
  499 +h6 {
  500 + font-weight: 100;
  501 +}
  502 +
  503 +h3,
  504 +h4,
  505 +h5 {
  506 + margin-top: 5px;
  507 + font-weight: 600;
  508 +}
  509 +
  510 +h3 {
  511 + font-size: 16px;
  512 +}
479 513 </style>
480 514 \ No newline at end of file
... ...
src/api/staff/aStaffApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 查询员工信息
  4 +export function queryStaffInfos(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/query.staff.infos',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 +
  13 + resolve(res)
  14 +
  15 + }).catch(error => {
  16 + reject(error)
  17 + })
  18 + })
  19 +}
  20 +
  21 +// 重置员工密码
  22 +export function resetStaffPwd(data) {
  23 + return new Promise((resolve, reject) => {
  24 + request({
  25 + url: '/user.resetStaffPwd',
  26 + method: 'post',
  27 + data
  28 + }).then(response => {
  29 + const res = response.data
  30 +
  31 + resolve(res)
  32 +
  33 + }).catch(error => {
  34 + reject(error)
  35 + })
  36 + })
  37 +}
  38 +
  39 +// 修改员工信息
  40 +export function modifyStaff(data) {
  41 + return new Promise((resolve, reject) => {
  42 + request({
  43 + url: '/user.staff.modify',
  44 + method: 'post',
  45 + data
  46 + }).then(response => {
  47 + const res = response.data
  48 +
  49 + resolve(res)
  50 +
  51 + }).catch(error => {
  52 + reject(error)
  53 + })
  54 + })
  55 +}
  56 +
  57 +// 删除员工
  58 +export function deleteStaff(data) {
  59 + return new Promise((resolve, reject) => {
  60 + request({
  61 + url: '/user.staff.delete',
  62 + method: 'post',
  63 + data
  64 + }).then(response => {
  65 + const res = response.data
  66 +
  67 + resolve(res)
  68 +
  69 + }).catch(error => {
  70 + reject(error)
  71 + })
  72 + })
  73 +}
  74 +
  75 +// 获取组织列表
  76 +export function listOrgs(params) {
  77 + return new Promise((resolve, reject) => {
  78 + request({
  79 + url: '/org.listOrgs',
  80 + method: 'get',
  81 + params
  82 + }).then(response => {
  83 + const res = response.data
  84 +
  85 + resolve(res)
  86 +
  87 + }).catch(error => {
  88 + reject(error)
  89 + })
  90 + })
  91 +}
  92 +
  93 +// 获取字典数据
  94 +export function getDict(dictName, dictType) {
  95 + return new Promise((resolve, reject) => {
  96 + request({
  97 + url: '/dict.getDict',
  98 + method: 'get',
  99 + params: { dictName, dictType }
  100 + }).then(response => {
  101 + const res = response.data
  102 +
  103 + resolve(res)
  104 +
  105 + }).catch(error => {
  106 + reject(error)
  107 + })
  108 + })
  109 +}
  110 +
  111 +// 上传文件
  112 +export function uploadImage(data) {
  113 + return new Promise((resolve, reject) => {
  114 + request({
  115 + url: '/uploadImage',
  116 + method: 'post',
  117 + data,
  118 + headers: {
  119 + 'Content-Type': 'multipart/form-data'
  120 + }
  121 + }).then(response => {
  122 + const res = response.data
  123 + if (res.code === 0) {
  124 + resolve(res)
  125 + } else {
  126 + reject(new Error(res.msg || '上传文件失败'))
  127 + }
  128 + }).catch(error => {
  129 + reject(error)
  130 + })
  131 + })
  132 +}
0 133 \ No newline at end of file
... ...
src/api/staff/aStaffDetailApi.js 0 → 100644
  1 +import request from '@/utils/request'
  2 +
  3 +// 获取员工信息
  4 +export function getStaffInfo(params) {
  5 + return new Promise((resolve, reject) => {
  6 + request({
  7 + url: '/query.staff.infos',
  8 + method: 'get',
  9 + params
  10 + }).then(response => {
  11 + const res = response.data
  12 +
  13 + resolve(res)
  14 +
  15 + }).catch(error => {
  16 + reject(error)
  17 + })
  18 + })
  19 +}
  20 +
  21 +// 获取员工组织信息
  22 +export function getStaffOrgs(params) {
  23 + return new Promise((resolve, reject) => {
  24 + request({
  25 + url: '/user.listStaffOrgs',
  26 + method: 'get',
  27 + params
  28 + }).then(response => {
  29 + const res = response.data
  30 +
  31 + resolve(res)
  32 +
  33 + }).catch(error => {
  34 + reject(error)
  35 + })
  36 + })
  37 +}
  38 +
  39 +// 获取员工角色信息
  40 +export function getStaffRoles(params) {
  41 + return new Promise((resolve, reject) => {
  42 + request({
  43 + url: '/user.listStaffRoles',
  44 + method: 'get',
  45 + params
  46 + }).then(response => {
  47 + const res = response.data
  48 +
  49 + resolve(res)
  50 +
  51 + }).catch(error => {
  52 + reject(error)
  53 + })
  54 + })
  55 +}
  56 +
  57 +// 获取员工权限信息
  58 +export function getStaffPrivileges(params) {
  59 + return new Promise((resolve, reject) => {
  60 + request({
  61 + url: '/query.user.privilege',
  62 + method: 'get',
  63 + params
  64 + }).then(response => {
  65 + const res = response.data
  66 +
  67 + resolve(res)
  68 +
  69 + }).catch(error => {
  70 + reject(error)
  71 + })
  72 + })
  73 +}
  74 +
  75 +// 获取员工关联小区
  76 +export function listStaffCommunities(params) {
  77 + return new Promise((resolve, reject) => {
  78 + request({
  79 + url: '/role.listAStaffCommunity',
  80 + method: 'get',
  81 + params
  82 + }).then(response => {
  83 + const res = response.data
  84 + if (res.code === 0) {
  85 + resolve(res)
  86 + } else {
  87 + reject(new Error(res.msg || '获取员工小区失败'))
  88 + }
  89 + }).catch(error => {
  90 + reject(error)
  91 + })
  92 + })
  93 +}
  94 +
  95 +// 重置员工密码
  96 +export function resetStaffPassword(data) {
  97 + return new Promise((resolve, reject) => {
  98 + request({
  99 + url: '/user.resetStaffPwd',
  100 + method: 'post',
  101 + data
  102 + }).then(response => {
  103 + const res = response.data
  104 + if (res.code === 0) {
  105 + resolve(res)
  106 + } else {
  107 + reject(new Error(res.msg || '重置密码失败'))
  108 + }
  109 + }).catch(error => {
  110 + reject(error)
  111 + })
  112 + })
  113 +}
  114 +
  115 +// 更新员工信息
  116 +export function updateStaff(data) {
  117 + return new Promise((resolve, reject) => {
  118 + request({
  119 + url: '/user.staff.modify',
  120 + method: 'post',
  121 + data
  122 + }).then(response => {
  123 + const res = response.data
  124 + if (res.code === 0) {
  125 + resolve(res)
  126 + } else {
  127 + reject(new Error(res.msg || '更新员工信息失败'))
  128 + }
  129 + }).catch(error => {
  130 + reject(error)
  131 + })
  132 + })
  133 +}
  134 +
  135 +// 获取字典数据
  136 +export function getDict(dictType, dictCd) {
  137 + return new Promise((resolve, reject) => {
  138 + request({
  139 + url: '/dict/getDict',
  140 + method: 'get',
  141 + params: {
  142 + dictType,
  143 + dictCd
  144 + }
  145 + }).then(response => {
  146 + const res = response.data
  147 + if (res.code === 0) {
  148 + resolve(res)
  149 + } else {
  150 + reject(new Error(res.msg || '获取字典数据失败'))
  151 + }
  152 + }).catch(error => {
  153 + reject(error)
  154 + })
  155 + })
  156 +}
  157 +
  158 +// 获取待关联小区列表
  159 +export function listWaitStaffCommunities(params) {
  160 + return new Promise((resolve, reject) => {
  161 + request({
  162 + url: '/role.listWaitAStaffCommunity',
  163 + method: 'get',
  164 + params
  165 + }).then(response => {
  166 + const res = response.data
  167 + if (res.code === 0) {
  168 + resolve(res)
  169 + } else {
  170 + reject(new Error(res.msg || '获取待关联小区失败'))
  171 + }
  172 + }).catch(error => {
  173 + reject(error)
  174 + })
  175 + })
  176 +}
  177 +
  178 +// 保存员工小区关联
  179 +export function saveStaffCommunity(data) {
  180 + return new Promise((resolve, reject) => {
  181 + request({
  182 + url: '/role.saveStaffCommunity',
  183 + method: 'post',
  184 + data
  185 + }).then(response => {
  186 + const res = response.data
  187 + if (res.code === 0) {
  188 + resolve(res)
  189 + } else {
  190 + reject(new Error(res.msg || '保存员工小区失败'))
  191 + }
  192 + }).catch(error => {
  193 + reject(error)
  194 + })
  195 + })
  196 +}
  197 +
  198 +// 删除员工小区关联
  199 +export function deleteStaffCommunity(data) {
  200 + return new Promise((resolve, reject) => {
  201 + request({
  202 + url: '/role.deleteStaffCommunity',
  203 + method: 'post',
  204 + data
  205 + }).then(response => {
  206 + const res = response.data
  207 + if (res.code === 0) {
  208 + resolve(res)
  209 + } else {
  210 + reject(new Error(res.msg || '删除员工小区失败'))
  211 + }
  212 + }).catch(error => {
  213 + reject(error)
  214 + })
  215 + })
  216 +}
0 217 \ No newline at end of file
... ...
src/components/staff/aStaffDetailCommunitys.vue 0 → 100644
  1 +<template>
  2 + <div >
  3 + <el-row>
  4 + <el-col :span="24" class="text-right">
  5 + <el-button type="primary" size="small" @click="openAddStaffCommunityModal">
  6 + {{ $t('aStaffDetailCommunitys.relateCommunity') }}
  7 + </el-button>
  8 + </el-col>
  9 + </el-row>
  10 +
  11 + <div class="margin-top">
  12 + <el-table :data="communitys" border style="width: 100%">
  13 + <el-table-column prop="staffName" :label="$t('aStaffDetailCommunitys.staffName')" align="center" />
  14 + <el-table-column prop="staffId" :label="$t('aStaffDetailCommunitys.staffId')" align="center" />
  15 + <el-table-column prop="communityId" :label="$t('aStaffDetailCommunitys.communityId')" align="center" />
  16 + <el-table-column prop="communityName" :label="$t('aStaffDetailCommunitys.communityName')" align="center" />
  17 + <el-table-column :label="$t('aStaffDetailCommunitys.operation')" align="center" width="120">
  18 + <template slot-scope="scope">
  19 + <el-button type="text" size="small" @click="openDeleteRoleCommunityModel(scope.row)">
  20 + {{ $t('aStaffDetailCommunitys.delete') }}
  21 + </el-button>
  22 + </template>
  23 + </el-table-column>
  24 + </el-table>
  25 +
  26 + <el-row class="margin-top">
  27 + <el-col :span="12"></el-col>
  28 + <el-col :span="12" class="text-right">
  29 + <el-pagination :current-page.sync="pagination.current" :page-sizes="[10, 20, 30, 50]"
  30 + :page-size="pagination.size" :total="pagination.total" layout="total, sizes, prev, pager, next, jumper"
  31 + @size-change="handleSizeChange" @current-change="handleCurrentChange" />
  32 + </el-col>
  33 + </el-row>
  34 + </div>
  35 +
  36 + <add-a-staff-community ref="addCommunity" @success="handleAddCommunitySuccess" />
  37 + <delete-a-staff-community ref="deleteCommunity" @success="handleDeleteCommunitySuccess" />
  38 + </div>
  39 +</template>
  40 +
  41 +<script>
  42 +import { listStaffCommunities } from '@/api/staff/aStaffDetailApi'
  43 +import AddAStaffCommunity from '@/components/staff/addAStaffCommunity'
  44 +import DeleteAStaffCommunity from '@/components/staff/deleteAStaffCommunity'
  45 +
  46 +export default {
  47 + name: 'AStaffDetailCommunitys',
  48 + props: {
  49 + staffId: {
  50 + type: String,
  51 + required: true
  52 + }
  53 + },
  54 + data() {
  55 + return {
  56 + communitys: [],
  57 + pagination: {
  58 + current: 1,
  59 + size: 10,
  60 + total: 0
  61 + }
  62 + }
  63 + },
  64 + watch: {
  65 + staffId: {
  66 + immediate: true,
  67 + handler(newVal) {
  68 + if (newVal) {
  69 + this.loadData()
  70 + }
  71 + }
  72 + }
  73 + },
  74 + components:{
  75 + AddAStaffCommunity,
  76 + DeleteAStaffCommunity,
  77 + },
  78 + methods: {
  79 + async loadData() {
  80 + try {
  81 + const response = await listStaffCommunities({
  82 + staffId: this.staffId,
  83 + page: this.pagination.current,
  84 + row: this.pagination.size
  85 + })
  86 + this.communitys = response.data || []
  87 + this.pagination.total = response.records || 0
  88 + } catch (error) {
  89 + this.$message.error(this.$t('aStaffDetailCommunitys.loadError'))
  90 + }
  91 + },
  92 + openAddStaffCommunityModal() {
  93 + this.$refs.addCommunity.open({
  94 + staffId: this.staffId
  95 + })
  96 + },
  97 + openDeleteRoleCommunityModel(community) {
  98 + this.$refs.deleteCommunity.open(community)
  99 + },
  100 + handleSizeChange(size) {
  101 + this.pagination.size = size
  102 + this.loadData()
  103 + },
  104 + handleCurrentChange(page) {
  105 + this.pagination.current = page
  106 + this.loadData()
  107 + },
  108 + handleAddCommunitySuccess() {
  109 + this.loadData()
  110 + this.$message.success(this.$t('aStaffDetailList.addCommunitySuccess'))
  111 + },
  112 + handleDeleteCommunitySuccess() {
  113 + this.loadData()
  114 + this.$message.success(this.$t('aStaffDetailList.deleteCommunitySuccess'))
  115 + }
  116 + }
  117 +}
  118 +</script>
  119 +
... ...
src/components/staff/addAStaffCommunity.vue 0 → 100644
  1 +<template>
  2 + <el-dialog :title="$t('addAStaffCommunity.community')" :visible.sync="visible" width="60%" :before-close="handleClose">
  3 + <el-card>
  4 + <el-row>
  5 + <el-col :span="12">
  6 + <el-input v-model="searchForm.communityName" :placeholder="$t('addAStaffCommunity.searchPlaceholder')" clearable
  7 + @keyup.enter.native="searchCommunities">
  8 + <el-button slot="append" icon="el-icon-search" @click="searchCommunities" />
  9 + </el-input>
  10 + </el-col>
  11 + </el-row>
  12 +
  13 + <el-table class="margin-top" :data="communities" border style="width: 100%">
  14 + <el-table-column width="55">
  15 + <template slot-scope="scope">
  16 + <el-checkbox v-model="scope.row.checked" @change="handleCheckChange(scope.row)" />
  17 + </template>
  18 + </el-table-column>
  19 + <el-table-column prop="communityId" :label="$t('addAStaffCommunity.communityId')" align="center" />
  20 + <el-table-column prop="name" :label="$t('addAStaffCommunity.communityName')" align="center" />
  21 + <el-table-column prop="address" :label="$t('addAStaffCommunity.communityAddress')" align="center" />
  22 + </el-table>
  23 +
  24 + <el-pagination class="margin-top" :current-page.sync="pagination.current" :page-sizes="[10, 20, 30, 50]"
  25 + :page-size="pagination.size" :total="pagination.total" layout="total, sizes, prev, pager, next, jumper"
  26 + @size-change="handleSizeChange" @current-change="handleCurrentChange" />
  27 + </el-card>
  28 +
  29 + <div slot="footer" class="dialog-footer">
  30 + <el-button @click="handleClose">{{ $t('addAStaffCommunity.cancel') }}</el-button>
  31 + <el-button type="primary" @click="addStaffCommunity">{{ $t('addAStaffCommunity.submit') }}</el-button>
  32 + </div>
  33 + </el-dialog>
  34 +</template>
  35 +
  36 +<script>
  37 +import { listWaitStaffCommunities, saveStaffCommunity } from '@/api/staff/aStaffDetailApi'
  38 +
  39 +export default {
  40 + name: 'AddAStaffCommunity',
  41 + data() {
  42 + return {
  43 + visible: false,
  44 + searchForm: {
  45 + communityName: ''
  46 + },
  47 + communities: [],
  48 + selectedCommunities: [],
  49 + staffId: '',
  50 + pagination: {
  51 + current: 1,
  52 + size: 10,
  53 + total: 0
  54 + }
  55 + }
  56 + },
  57 + methods: {
  58 + open(params) {
  59 + this.staffId = params.staffId
  60 + this.visible = true
  61 + this.loadCommunities()
  62 + },
  63 + handleClose() {
  64 + this.visible = false
  65 + this.resetForm()
  66 + },
  67 + resetForm() {
  68 + this.searchForm.communityName = ''
  69 + this.communities = []
  70 + this.selectedCommunities = []
  71 + this.pagination.current = 1
  72 + this.pagination.total = 0
  73 + },
  74 + async loadCommunities() {
  75 + try {
  76 + const response = await listWaitStaffCommunities({
  77 + staffId: this.staffId,
  78 + page: this.pagination.current,
  79 + row: this.pagination.size,
  80 + nameLike: this.searchForm.communityName
  81 + })
  82 + this.communities = (response.data || []).map(item => {
  83 + return {
  84 + ...item,
  85 + checked: false
  86 + }
  87 + })
  88 + this.pagination.total = response.records || 0
  89 + } catch (error) {
  90 + this.$message.error(this.$t('addAStaffCommunity.loadError'))
  91 + }
  92 + },
  93 + searchCommunities() {
  94 + this.pagination.current = 1
  95 + this.loadCommunities()
  96 + },
  97 + handleCheckChange(row) {
  98 + if (row.checked) {
  99 + this.selectedCommunities.push({
  100 + communityId: row.communityId,
  101 + communityName: row.name
  102 + })
  103 + } else {
  104 + this.selectedCommunities = this.selectedCommunities.filter(
  105 + item => item.communityId !== row.communityId
  106 + )
  107 + }
  108 + },
  109 + handleSizeChange(size) {
  110 + this.pagination.size = size
  111 + this.loadCommunities()
  112 + },
  113 + handleCurrentChange(page) {
  114 + this.pagination.current = page
  115 + this.loadCommunities()
  116 + },
  117 + async addStaffCommunity() {
  118 + if (this.selectedCommunities.length === 0) {
  119 + this.$message.warning(this.$t('addAStaffCommunity.selectCommunity'))
  120 + return
  121 + }
  122 +
  123 + try {
  124 + await saveStaffCommunity({
  125 + staffId: this.staffId,
  126 + communitys: this.selectedCommunities
  127 + })
  128 + this.$message.success(this.$t('addAStaffCommunity.addSuccess'))
  129 + this.handleClose()
  130 + this.$emit('success')
  131 + } catch (error) {
  132 + this.$message.error(this.$t('addAStaffCommunity.addError'))
  133 + }
  134 + }
  135 + }
  136 +}
  137 +</script>
  138 +
... ...
src/components/staff/deleteAStaffCommunity.vue 0 → 100644
  1 +<template>
  2 + <el-dialog
  3 + :title="$t('deleteAStaffCommunity.confirmOperation')"
  4 + :visible.sync="visible"
  5 + width="30%"
  6 + :before-close="handleClose">
  7 + <div class="text-center">
  8 + <p>{{ $t('deleteAStaffCommunity.confirmDelete') }}</p>
  9 + </div>
  10 + <span slot="footer" class="dialog-footer">
  11 + <el-button @click="handleClose">{{ $t('deleteAStaffCommunity.cancel') }}</el-button>
  12 + <el-button type="primary" @click="deleteStaffCommunity">{{ $t('deleteAStaffCommunity.confirm') }}</el-button>
  13 + </span>
  14 + </el-dialog>
  15 +</template>
  16 +
  17 +<script>
  18 +import { deleteStaffCommunity } from '@/api/staff/aStaffDetailApi'
  19 +
  20 +export default {
  21 + name: 'DeleteAStaffCommunity',
  22 + data() {
  23 + return {
  24 + visible: false,
  25 + community: {}
  26 + }
  27 + },
  28 + methods: {
  29 + open(community) {
  30 + this.community = community
  31 + this.visible = true
  32 + },
  33 + handleClose() {
  34 + this.visible = false
  35 + },
  36 + async deleteStaffCommunity() {
  37 + try {
  38 + await deleteStaffCommunity(this.community)
  39 + this.$message.success(this.$t('deleteAStaffCommunity.deleteSuccess'))
  40 + this.visible = false
  41 + this.$emit('success')
  42 + } catch (error) {
  43 + this.$message.error(this.$t('deleteAStaffCommunity.deleteError'))
  44 + }
  45 + }
  46 + }
  47 +}
  48 +</script>
  49 +
  50 +<i18n>
  51 +{
  52 + "en": {
  53 + "deleteAStaffCommunity": {
  54 + "confirmOperation": "Confirm Your Operation",
  55 + "confirmDelete": "Are you sure you want to delete this community?",
  56 + "cancel": "Cancel",
  57 + "confirm": "Confirm Delete",
  58 + "deleteSuccess": "Community deleted successfully",
  59 + "deleteError": "Failed to delete community"
  60 + }
  61 + },
  62 + "zh": {
  63 + "deleteAStaffCommunity": {
  64 + "confirmOperation": "请确认您的操作",
  65 + "confirmDelete": "确定删除隶属小区?",
  66 + "cancel": "点错了",
  67 + "confirm": "确认删除",
  68 + "deleteSuccess": "小区删除成功",
  69 + "deleteError": "小区删除失败"
  70 + }
  71 + }
  72 +}
  73 +</i18n>
0 74 \ No newline at end of file
... ...
src/components/staff/deleteStaff.vue
1 1 <!-- components/staff/deleteStaff.vue -->
2 2 <template>
3   - <el-dialog
4   - :title="$t('staff.confirmOperation')"
5   - :visible.sync="visible"
6   - width="40%"
7   - @close="handleClose"
8   - >
9   - <div class="text-center">
10   - <p>{{ $t('staff.confirmDelete') }}</p>
11   - </div>
12   - <span slot="footer" class="dialog-footer">
13   - <el-button @click="handleClose">{{ $t('staff.wrongClick') }}</el-button>
14   - <el-button type="danger" @click="deleteStaff">{{ $t('staff.confirmDeleteAction') }}</el-button>
15   - </span>
16   - </el-dialog>
17   - </template>
18   -
19   - <script>
20   - import { deleteStaff } from '@/api/staff/staffApi'
21   -
22   - export default {
23   - name: 'DeleteStaff',
24   - props: {
25   - visible: {
26   - type: Boolean,
27   - default: false
28   - },
29   - staffInfo: {
30   - type: Object,
31   - default: () => ({})
32   - }
  3 + <el-dialog
  4 + :title="$t('staff.confirmOperation')"
  5 + :visible.sync="visible"
  6 + width="40%"
  7 + @close="handleClose"
  8 + >
  9 + <div class="text-center">
  10 + <p>{{ $t('staff.confirmDelete') }}</p>
  11 + </div>
  12 + <span slot="footer" class="dialog-footer">
  13 + <el-button @click="handleClose">{{ $t('staff.wrongClick') }}</el-button>
  14 + <el-button type="danger" @click="deleteStaff">{{ $t('staff.confirmDeleteAction') }}</el-button>
  15 + </span>
  16 + </el-dialog>
  17 +</template>
  18 +
  19 +<script>
  20 +import { deleteStaff } from '@/api/staff/staffApi'
  21 +
  22 +export default {
  23 + name: 'DeleteStaff',
  24 + props: {
  25 + visible: {
  26 + type: Boolean,
  27 + default: false
33 28 },
34   - data() {
35   - return {
36   - loading: false
37   - }
  29 + staffInfo: {
  30 + type: Object,
  31 + default: () => ({})
  32 + }
  33 + },
  34 + data() {
  35 + return {
  36 + loading: false
  37 + }
  38 + },
  39 + methods: {
  40 + handleClose() {
  41 + this.$emit('update:visible', false)
38 42 },
39   - methods: {
40   - handleClose() {
41   - this.$emit('update:visible', false)
42   - },
43   - async deleteStaff() {
44   - try {
45   - this.loading = true
46   - await deleteStaff({
47   - userId: this.staffInfo.userId
48   - })
49   - this.$message.success(this.$t('staff.deleteSuccess'))
50   - this.$emit('success')
51   - this.handleClose()
52   - } catch (error) {
53   - this.$message.error(error.message)
54   - } finally {
55   - this.loading = false
56   - }
  43 + async deleteStaff() {
  44 + try {
  45 + this.loading = true
  46 + await deleteStaff({
  47 + userId: this.staffInfo.userId
  48 + })
  49 + this.$message.success(this.$t('staff.deleteSuccess'))
  50 + this.$emit('success')
  51 + this.handleClose()
  52 + } catch (error) {
  53 + this.$message.error(error.message)
  54 + } finally {
  55 + this.loading = false
57 56 }
58 57 }
59 58 }
60   - </script>
61 59 \ No newline at end of file
  60 +}
  61 +</script>
... ...
src/components/staff/editStaff.vue
1 1 <!-- components/staff/editStaff.vue -->
2 2 <template>
3   - <el-dialog
4   - :title="$t('staff.modifyStaff')"
5   - :visible.sync="visible"
6   - width="50%"
7   - @close="handleClose"
8   - >
9   - <el-form ref="form" :model="editStaffInfo" label-width="120px">
10   - <el-row :gutter="20">
11   - <el-col :span="12">
12   - <el-form-item :label="$t('staff.name')" prop="username">
13   - <el-input
14   - v-model="editStaffInfo.username"
15   - :placeholder="$t('staff.requiredName')"
16   - />
17   - </el-form-item>
18   - <el-form-item :label="$t('staff.email')" prop="email">
19   - <el-input
20   - v-model="editStaffInfo.email"
21   - :placeholder="$t('staff.optionalEmail')"
22   - />
23   - </el-form-item>
24   - <el-form-item :label="$t('staff.phone')" prop="tel">
25   - <el-input
26   - v-model="editStaffInfo.tel"
27   - :placeholder="$t('staff.requiredPhone')"
28   - />
29   - </el-form-item>
30   - <el-form-item :label="$t('staff.gender')" prop="sex">
31   - <el-select
32   - v-model="editStaffInfo.sex"
33   - :placeholder="$t('staff.requiredGender')"
34   - style="width: 100%"
35   - >
36   - <el-option :value="0" :label="$t('staff.male')" />
37   - <el-option :value="1" :label="$t('staff.female')" />
38   - </el-select>
39   - </el-form-item>
40   - <el-form-item :label="$t('staff.address')" prop="address">
41   - <el-input
42   - v-model="editStaffInfo.address"
43   - :placeholder="$t('staff.requiredAddress')"
44   - />
45   - </el-form-item>
46   - </el-col>
47   - <el-col :span="12" style="text-align: center">
48   - <el-image
49   - style="width: 200px; height: 200px"
50   - :src="editStaffInfo.photoUrl"
51   - fit="cover"
  3 + <el-dialog
  4 + :title="$t('staff.modifyStaff')"
  5 + :visible.sync="visible"
  6 + width="50%"
  7 + @close="handleClose"
  8 + >
  9 + <el-form ref="form" :model="editStaffInfo" label-width="120px">
  10 + <el-row :gutter="20">
  11 + <el-col :span="12">
  12 + <el-form-item :label="$t('staff.name')" prop="username">
  13 + <el-input
  14 + v-model="editStaffInfo.username"
  15 + :placeholder="$t('staff.requiredName')"
  16 + />
  17 + </el-form-item>
  18 + <el-form-item :label="$t('email')" prop="email">
  19 + <el-input
  20 + v-model="editStaffInfo.email"
  21 + :placeholder="$t('staff.optionalEmail')"
  22 + />
  23 + </el-form-item>
  24 + <el-form-item :label="$t('staff.phone')" prop="tel">
  25 + <el-input
  26 + v-model="editStaffInfo.tel"
  27 + :placeholder="$t('staff.requiredPhone')"
  28 + />
  29 + </el-form-item>
  30 + <el-form-item :label="$t('staff.gender')" prop="sex">
  31 + <el-select
  32 + v-model="editStaffInfo.sex"
  33 + :placeholder="$t('staff.requiredGender')"
  34 + style="width: 100%"
52 35 >
53   - <div slot="error" class="image-slot">
54   - <i class="el-icon-picture-outline"></i>
55   - </div>
56   - </el-image>
57   - <div style="margin-top: 20px">
58   - <el-upload
59   - action=""
60   - :auto-upload="false"
61   - :show-file-list="false"
62   - :on-change="handlePhotoChange"
63   - >
64   - <el-button type="primary">{{ $t('staff.uploadPhoto') }}</el-button>
65   - </el-upload>
  36 + <el-option :value="0" :label="$t('staff.male')" />
  37 + <el-option :value="1" :label="$t('staff.female')" />
  38 + </el-select>
  39 + </el-form-item>
  40 + <el-form-item :label="$t('staff.address')" prop="address">
  41 + <el-input
  42 + v-model="editStaffInfo.address"
  43 + :placeholder="$t('staff.requiredAddress')"
  44 + />
  45 + </el-form-item>
  46 + </el-col>
  47 + <el-col :span="12" style="text-align: center">
  48 + <el-image
  49 + style="width: 200px; height: 200px"
  50 + :src="editStaffInfo.photoUrl"
  51 + fit="cover"
  52 + >
  53 + <div slot="error" class="image-slot">
  54 + <i class="el-icon-picture-outline"></i>
66 55 </div>
67   - </el-col>
68   - </el-row>
69   - </el-form>
70   - <span slot="footer" class="dialog-footer">
71   - <el-button @click="handleClose">{{ $t('staff.cancel') }}</el-button>
72   - <el-button type="primary" @click="editStaffSubmit">{{ $t('staff.edit') }}</el-button>
73   - </span>
74   - </el-dialog>
75   - </template>
76   -
77   - <script>
78   - import { modifyStaff } from '@/api/staff/staffApi'
79   -
80   - export default {
81   - name: 'EditStaff',
82   - props: {
83   - visible: {
84   - type: Boolean,
85   - default: false
86   - },
87   - staffInfo: {
88   - type: Object,
89   - default: () => ({})
90   - }
  56 + </el-image>
  57 + <div style="margin-top: 20px">
  58 + <el-upload
  59 + action=""
  60 + :auto-upload="false"
  61 + :show-file-list="false"
  62 + :on-change="handlePhotoChange"
  63 + >
  64 + <el-button type="primary">{{ $t('staff.uploadPhoto') }}</el-button>
  65 + </el-upload>
  66 + </div>
  67 + </el-col>
  68 + </el-row>
  69 + </el-form>
  70 + <span slot="footer" class="dialog-footer">
  71 + <el-button @click="handleClose">{{ $t('staff.cancel') }}</el-button>
  72 + <el-button type="primary" @click="editStaffSubmit">{{ $t('staff.edit') }}</el-button>
  73 + </span>
  74 + </el-dialog>
  75 +</template>
  76 +
  77 +<script>
  78 +import { modifyStaff } from '@/api/staff/staffApi'
  79 +
  80 +export default {
  81 + name: 'EditStaff',
  82 + props: {
  83 + visible: {
  84 + type: Boolean,
  85 + default: false
91 86 },
92   - data() {
93   - return {
94   - loading: false,
95   - editStaffInfo: {
96   - userId: '',
97   - username: '',
98   - email: '',
99   - tel: '',
100   - sex: '',
101   - address: '',
102   - photo: '',
103   - photoUrl: '',
104   - relCd: '',
105   - relCds: [],
106   - branchOrgs: [],
107   - departmentOrgs: [],
108   - parentOrgId: '',
109   - parentOrgName: '',
110   - parentTwoOrgId: '',
111   - orgNewName: '',
112   - orgId: ''
113   - }
  87 + staffInfo: {
  88 + type: Object,
  89 + default: () => ({})
  90 + }
  91 + },
  92 + data() {
  93 + return {
  94 + loading: false,
  95 + editStaffInfo: {
  96 + userId: '',
  97 + username: '',
  98 + email: '',
  99 + tel: '',
  100 + sex: '',
  101 + address: '',
  102 + photo: '',
  103 + photoUrl: '',
  104 + relCd: '',
  105 + relCds: [],
  106 + branchOrgs: [],
  107 + departmentOrgs: [],
  108 + parentOrgId: '',
  109 + parentOrgName: '',
  110 + parentTwoOrgId: '',
  111 + orgNewName: '',
  112 + orgId: ''
114 113 }
115   - },
116   - watch: {
117   - staffInfo: {
118   - immediate: true,
119   - handler(val) {
120   - if (val) {
121   - this.editStaffInfo = {
122   - ...val,
123   - username: val.name,
124   - photoUrl: val.faceUrl || '/img/noPhoto.jpg'
125   - }
  114 + }
  115 + },
  116 + watch: {
  117 + staffInfo: {
  118 + immediate: true,
  119 + handler(val) {
  120 + if (val) {
  121 + this.editStaffInfo = {
  122 + ...val,
  123 + username: val.name,
  124 + photoUrl: val.faceUrl || '/img/noPhoto.jpg'
126 125 }
127 126 }
128 127 }
  128 + }
  129 + },
  130 + methods: {
  131 + open(row){
  132 + this.editStaffInfo = {
  133 + ...row,
  134 + username: row.name,
  135 + photoUrl: row.faceUrl || '/img/noPhoto.jpg'
  136 + }
  137 + this.visible = true
129 138 },
130   - methods: {
131   - handleClose() {
132   - this.$emit('update:visible', false)
133   - },
134   - handlePhotoChange(file) {
135   - if (file.size > 2 * 1024 * 1024) {
136   - this.$message.error(this.$t('staff.photoSizeLimit'))
137   - return false
138   - }
139   -
140   - const reader = new FileReader()
141   - reader.onload = (e) => {
142   - this.editStaffInfo.photoUrl = e.target.result
143   - // Here you would typically upload the file to server
144   - // and set editStaffInfo.photo to the returned file ID
145   - this.editStaffInfo.photo = file.uid // Temporary, replace with actual file ID
146   - }
147   - reader.readAsDataURL(file.raw)
148   - },
149   - validateForm() {
150   - if (!this.editStaffInfo.username) {
151   - this.$message.error(this.$t('staff.requiredName'))
152   - return false
153   - }
154   - if (!this.editStaffInfo.tel) {
155   - this.$message.error(this.$t('staff.requiredPhone'))
156   - return false
157   - }
158   - if (this.editStaffInfo.sex === '') {
159   - this.$message.error(this.$t('staff.requiredGender'))
160   - return false
161   - }
162   - if (!this.editStaffInfo.address) {
163   - this.$message.error(this.$t('staff.requiredAddress'))
164   - return false
  139 + handleClose() {
  140 + this.$emit('update:visible', false)
  141 + },
  142 + handlePhotoChange(file) {
  143 + if (file.size > 2 * 1024 * 1024) {
  144 + this.$message.error(this.$t('staff.photoSizeLimit'))
  145 + return false
  146 + }
  147 +
  148 + const reader = new FileReader()
  149 + reader.onload = (e) => {
  150 + this.editStaffInfo.photoUrl = e.target.result
  151 + // Here you would typically upload the file to server
  152 + // and set editStaffInfo.photo to the returned file ID
  153 + this.editStaffInfo.photo = file.uid // Temporary, replace with actual file ID
  154 + }
  155 + reader.readAsDataURL(file.raw)
  156 + },
  157 + validateForm() {
  158 + if (!this.editStaffInfo.username) {
  159 + this.$message.error(this.$t('staff.requiredName'))
  160 + return false
  161 + }
  162 + if (!this.editStaffInfo.tel) {
  163 + this.$message.error(this.$t('staff.requiredPhone'))
  164 + return false
  165 + }
  166 + if (this.editStaffInfo.sex === '') {
  167 + this.$message.error(this.$t('staff.requiredGender'))
  168 + return false
  169 + }
  170 + if (!this.editStaffInfo.address) {
  171 + this.$message.error(this.$t('staff.requiredAddress'))
  172 + return false
  173 + }
  174 + return true
  175 + },
  176 + async editStaffSubmit() {
  177 + if (!this.validateForm()) return
  178 +
  179 + try {
  180 + this.loading = true
  181 + const data = {
  182 + ...this.editStaffInfo,
  183 + name: this.editStaffInfo.username,
  184 + staffId: this.editStaffInfo.userId
165 185 }
166   - return true
167   - },
168   - async editStaffSubmit() {
169   - if (!this.validateForm()) return
170 186  
171   - try {
172   - this.loading = true
173   - const data = {
174   - ...this.editStaffInfo,
175   - name: this.editStaffInfo.username,
176   - staffId: this.editStaffInfo.userId
177   - }
178   -
179   - await modifyStaff(data)
180   - this.$message.success(this.$t('staff.modifySuccess'))
181   - this.$emit('success')
182   - this.handleClose()
183   - } catch (error) {
184   - this.$message.error(error.message)
185   - } finally {
186   - this.loading = false
187   - }
  187 + await modifyStaff(data)
  188 + this.visible =false
  189 + this.$message.success(this.$t('staff.modifySuccess'))
  190 + this.$emit('success')
  191 + this.handleClose()
  192 + } catch (error) {
  193 + this.$message.error(error.message)
  194 + } finally {
  195 + this.loading = false
188 196 }
189 197 }
190 198 }
191   - </script>
192 199 \ No newline at end of file
  200 +}
  201 +</script>
... ...
src/components/staff/resetStaffPwd.vue
1 1 <!-- components/staff/resetStaffPwd.vue -->
2 2 <template>
3   - <el-dialog
4   - :title="$t('staff.confirmOperation')"
5   - :visible.sync="visible"
6   - width="30%"
7   - @close="handleClose"
8   - >
9   - <div class="text-center">
10   - <p>{{ $t('staff.confirmResetPassword') }}?</p>
11   - </div>
12   - <span slot="footer" class="dialog-footer">
13   - <el-button @click="handleClose">{{ $t('staff.wrongClick') }}</el-button>
14   - <el-button type="primary" @click="resetStaffPwd">{{ $t('staff.confirmReset') }}</el-button>
15   - </span>
16   - </el-dialog>
17   - </template>
18   -
19   - <script>
20   - import { resetStaffPwd } from '@/api/staff/staffApi'
21   -
22   - export default {
23   - name: 'ResetStaffPwd',
24   - props: {
25   - visible: {
26   - type: Boolean,
27   - default: false
28   - },
29   - staffInfo: {
30   - type: Object,
31   - default: () => ({})
32   - }
  3 + <el-dialog
  4 + :title="$t('staff.confirmOperation')"
  5 + :visible.sync="visible"
  6 + width="30%"
  7 + @close="handleClose"
  8 + >
  9 + <div class="text-center">
  10 + <p>{{ $t('staff.confirmResetPassword') }}?</p>
  11 + </div>
  12 + <span slot="footer" class="dialog-footer">
  13 + <el-button @click="handleClose">{{ $t('staff.wrongClick') }}</el-button>
  14 + <el-button type="primary" @click="resetStaffPwd">{{ $t('staff.confirmReset') }}</el-button>
  15 + </span>
  16 + </el-dialog>
  17 +</template>
  18 +
  19 +<script>
  20 +import { resetStaffPwd } from '@/api/staff/staffApi'
  21 +
  22 +export default {
  23 + name: 'ResetStaffPwd',
  24 + props: {
  25 + visible: {
  26 + type: Boolean,
  27 + default: false
33 28 },
34   - data() {
35   - return {
36   - loading: false
37   - }
  29 + staffInfo: {
  30 + type: Object,
  31 + default: () => ({})
  32 + }
  33 + },
  34 + data() {
  35 + return {
  36 + loading: false
  37 + }
  38 + },
  39 + methods: {
  40 + open(row){
  41 + this.visible = true
  42 + this.staffInfo = {...row}
  43 + },
  44 + handleClose() {
  45 + this.visible = false
  46 + this.$emit('update:visible', false)
38 47 },
39   - methods: {
40   - handleClose() {
41   - this.$emit('update:visible', false)
42   - },
43   - async resetStaffPwd() {
44   - try {
45   - this.loading = true
46   - const data = {
47   - communityId: '-1',
48   - staffId: this.staffInfo.userId
49   - }
50   -
51   - const res = await resetStaffPwd(data)
52   - this.$message.success(
53   - this.$t('staff.resetPasswordSuccess', { pwd: res.pwd }),
54   - 10000
55   - )
56   - this.$emit('success')
57   - this.handleClose()
58   - } catch (error) {
59   - this.$message.error(error.message)
60   - } finally {
61   - this.loading = false
  48 + async resetStaffPwd() {
  49 + try {
  50 + this.loading = true
  51 + const data = {
  52 + communityId: '-1',
  53 + staffId: this.staffInfo.userId
62 54 }
  55 +
  56 + const res = await resetStaffPwd(data)
  57 + this.$message.success(
  58 + this.$t('staff.resetPasswordSuccess', { pwd: res.pwd }),
  59 + 10000
  60 + )
  61 + this.$emit('success')
  62 + this.handleClose()
  63 + } catch (error) {
  64 + this.$message.error(error.message)
  65 + } finally {
  66 + this.loading = false
63 67 }
64 68 }
65 69 }
66   - </script>
67 70 \ No newline at end of file
  71 +}
  72 +</script>
... ...
src/components/staff/staffDetailOrgPrivilege.vue 0 → 100644
  1 +<template>
  2 + <el-row class="margin-top" :gutter="20">
  3 + <el-col :span="18">
  4 + <el-card>
  5 + <div class="text-left">
  6 + <h5>{{ $t('staffDetailOrgPrivilege.relatedOrg') }}</h5>
  7 + <el-row v-for="(item, index) in orgs" :key="index" class="margin-top">
  8 + <el-col :span="12">{{ $t('staffDetailOrgPrivilege.org') }}:{{ item.orgName }}</el-col>
  9 + <el-col :span="12">{{ $t('staffDetailOrgPrivilege.position') }}:{{ item.relCdName }}</el-col>
  10 + </el-row>
  11 + </div>
  12 + </el-card>
  13 +
  14 + <el-card class="margin-top">
  15 + <div class="text-left">
  16 + <h5>{{ $t('staffDetailOrgPrivilege.relatedRole') }}</h5>
  17 + <el-row v-for="(item, index) in roles" :key="index">
  18 + <el-col :span="24">
  19 + <p v-if="item.roleCommunityDtoList.length > 0">{{ item.roleName }}</p>
  20 + </el-col>
  21 + </el-row>
  22 + </div>
  23 + </el-card>
  24 + </el-col>
  25 +
  26 + <el-col :span="6">
  27 + <el-card>
  28 + <div class="mail-box-header border-radius-top text-left">
  29 + <h2>{{ $t('staffDetailOrgPrivilege.staffPrivilege') }}</h2>
  30 + </div>
  31 +
  32 + <el-tree :data="privilegesTree" node-key="id" default-expand-all :props="treeProps" :expand-on-click-node="false">
  33 + </el-tree>
  34 + </el-card>
  35 + </el-col>
  36 + </el-row>
  37 +</template>
  38 +
  39 +<script>
  40 +import { getStaffOrgs, getStaffRoles, getStaffPrivileges } from '@/api/staff/aStaffDetailApi'
  41 +
  42 +export default {
  43 + name: 'StaffDetailOrgPrivilege',
  44 + props: {
  45 + staffId: {
  46 + type: String,
  47 + required: true
  48 + }
  49 + },
  50 + data() {
  51 + return {
  52 + orgs: [],
  53 + roles: [],
  54 + privileges: [],
  55 + privilegesTree: [],
  56 + treeProps: {
  57 + children: 'children',
  58 + label: 'text'
  59 + }
  60 + }
  61 + },
  62 + watch: {
  63 + staffId: {
  64 + immediate: true,
  65 + handler(newVal) {
  66 + if (newVal) {
  67 + this.loadData()
  68 + }
  69 + }
  70 + }
  71 + },
  72 + methods: {
  73 + async loadData() {
  74 + await Promise.all([
  75 + this.loadStaffOrgs(),
  76 + this.loadStaffRoles(),
  77 + this.loadStaffPrivileges()
  78 + ])
  79 + this.buildPrivilegesTree()
  80 + },
  81 + async loadStaffOrgs() {
  82 + try {
  83 + const response = await getStaffOrgs({
  84 + staffId: this.staffId,
  85 + page: 1,
  86 + row: 999
  87 + })
  88 + this.orgs = response.data || []
  89 + } catch (error) {
  90 + this.$message.error(this.$t('staffDetailOrgPrivilege.loadOrgsError'))
  91 + }
  92 + },
  93 + async loadStaffRoles() {
  94 + try {
  95 + const response = await getStaffRoles({
  96 + staffId: this.staffId,
  97 + page: 1,
  98 + row: 999
  99 + })
  100 + this.roles = response.data || []
  101 + } catch (error) {
  102 + this.$message.error(this.$t('staffDetailOrgPrivilege.loadRolesError'))
  103 + }
  104 + },
  105 + async loadStaffPrivileges() {
  106 + try {
  107 + const response = await getStaffPrivileges({
  108 + staffId: this.staffId
  109 + })
  110 + this.privileges = response.datas || []
  111 + } catch (error) {
  112 + this.$message.error(this.$t('staffDetailOrgPrivilege.loadPrivilegesError'))
  113 + }
  114 + },
  115 + buildPrivilegesTree() {
  116 + const groupMap = new Map()
  117 +
  118 + // 构建组节点
  119 + this.privileges.forEach(item => {
  120 + if (!groupMap.has(item.gId)) {
  121 + groupMap.set(item.gId, {
  122 + id: `g_${item.gId}`,
  123 + gId: item.gId,
  124 + text: item.gName,
  125 + children: []
  126 + })
  127 + }
  128 + })
  129 +
  130 + // 构建菜单节点
  131 + this.privileges.forEach(item => {
  132 + const group = groupMap.get(item.gId)
  133 + let menu = group.children.find(m => m.mId === item.mId)
  134 +
  135 + if (!menu) {
  136 + menu = {
  137 + id: `m_${item.mId}`,
  138 + mId: item.mId,
  139 + text: item.mName,
  140 + children: []
  141 + }
  142 + group.children.push(menu)
  143 + }
  144 +
  145 + // 添加权限节点
  146 + menu.children.push({
  147 + id: `p_${item.pId}`,
  148 + pId: item.pId,
  149 + text: item.pName
  150 + })
  151 + })
  152 +
  153 + this.privilegesTree = Array.from(groupMap.values())
  154 + }
  155 + }
  156 +}
  157 +</script>
  158 +
... ...
src/i18n/index.js
... ... @@ -112,6 +112,8 @@ import { messages as supplierTypeManageMessages } from &#39;../views/scm/supplierTyp
112 112 import { messages as supplierManageMessages } from '../views/scm/supplierManageLang'
113 113 import { messages as supplierCouponMessages } from '../views/scm/supplierCouponLang'
114 114 import { messages as supplierCouponBuyMessages } from '../views/scm/supplierCouponBuyLang'
  115 +import { messages as aStaffMessages } from '../views/staff/aStaffLang'
  116 +import { messages as aStaffDetailMessages } from '../views/staff/aStaffDetailLang'
115 117  
116 118 Vue.use(VueI18n)
117 119  
... ... @@ -228,6 +230,8 @@ const messages = {
228 230 ...supplierManageMessages.en,
229 231 ...supplierCouponMessages.en,
230 232 ...supplierCouponBuyMessages.en,
  233 + ...aStaffMessages.en,
  234 + ...aStaffDetailMessages.en,
231 235 },
232 236 zh: {
233 237 ...loginMessages.zh,
... ... @@ -340,6 +344,8 @@ const messages = {
340 344 ...supplierManageMessages.zh,
341 345 ...supplierCouponMessages.zh,
342 346 ...supplierCouponBuyMessages.zh,
  347 + ...aStaffMessages.zh,
  348 + ...aStaffDetailMessages.zh,
343 349 }
344 350 }
345 351  
... ...
src/main.js
... ... @@ -5,11 +5,23 @@ import ElementUI from &#39;element-ui&#39;
5 5 import 'element-ui/lib/theme-chalk/index.css'
6 6 import i18n from './i18n'
7 7  
8   -Vue.prototype.hasPrivilege = function(privilegeCode) {
9   - // 这里实现你的权限检查逻辑
10   - // 例如从 Vuex store 或本地存储中获取用户权限列表
11   - const userPrivileges = []
12   - return userPrivileges.includes(privilegeCode)
  8 +Vue.prototype.hasPrivilege = function(_privaleges) {
  9 + // 确保 _privaleges 是数组,如果不是则转换为数组
  10 + const privilegesToCheck = Array.isArray(_privaleges) ? _privaleges : [_privaleges];
  11 +
  12 + // 从本地存储获取用户权限
  13 + let userPrivileges = localStorage.getItem('hc_staff_privilege');
  14 +
  15 + // 如果存在用户权限,则转换为数组
  16 + if (userPrivileges) {
  17 + userPrivileges = userPrivileges.split(',');
  18 + } else {
  19 + // 如果没有权限数据,直接返回 false
  20 + return false;
  21 + }
  22 +
  23 + // 检查用户是否有任一所需权限
  24 + return privilegesToCheck.some(item => userPrivileges.includes(item));
13 25 }
14 26 Vue.prototype.toDoc = function(url) {
15 27 window.open('http://www.homecommunity.cn/'+url, '_blank')
... ...
src/router/index.js
... ... @@ -542,10 +542,20 @@ const routes = [
542 542 component: () => import('@/views/scm/supplierCouponList.vue')
543 543 },
544 544 {
545   - path:'/pages/scm/supplierCouponBuy',
546   - name:'/pages/scm/supplierCouponBuy',
  545 + path: '/pages/scm/supplierCouponBuy',
  546 + name: '/pages/scm/supplierCouponBuy',
547 547 component: () => import('@/views/scm/supplierCouponBuyList.vue')
548   - },
  548 + },
  549 + {
  550 + path: '/pages/staff/aStaff',
  551 + name: '/pages/staff/aStaff',
  552 + component: () => import('@/views/staff/aStaffList.vue')
  553 + },
  554 + {
  555 + path: '/views/staff/aStaffDetail',
  556 + name: '/views/staff/aStaffDetail',
  557 + component: () => import('@/views/staff/aStaffDetailList.vue')
  558 + },
549 559 // 其他子路由可以在这里添加
550 560 ]
551 561 },
... ...
src/views/scm/supplierCouponBuyLang.js
... ... @@ -27,9 +27,6 @@ export const messages = {
27 27 remark: 'Remark'
28 28 },
29 29 fetchError: 'Failed to fetch coupon purchase records'
30   - },
31   - common: {
32   - search: 'Search'
33 30 }
34 31 },
35 32 zh: {
... ... @@ -60,9 +57,6 @@ export const messages = {
60 57 remark: '备注'
61 58 },
62 59 fetchError: '获取优惠券购买记录失败'
63   - },
64   - common: {
65   - search: '查询'
66 60 }
67 61 }
68 62 }
69 63 \ No newline at end of file
... ...
src/views/staff/aStaffDetailLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + aStaffDetailList: {
  4 + staffInfo: 'Staff Information',
  5 + back: 'Back',
  6 + edit: 'Edit',
  7 + resetPwd: 'Reset Password',
  8 + staffId: 'Staff ID',
  9 + userName: 'Name',
  10 + idCard: 'ID Card',
  11 + tel: 'Phone',
  12 + sex: 'Gender',
  13 + male: 'Male',
  14 + female: 'Female',
  15 + address: 'Address',
  16 + orgPrivilege: 'Organization Privilege',
  17 + community: 'Community',
  18 + loadError: 'Failed to load staff information',
  19 + resetSuccess: 'Password reset successful',
  20 + editSuccess: 'Staff information updated',
  21 + addCommunitySuccess: 'Community added successfully',
  22 + deleteCommunitySuccess: 'Community removed successfully'
  23 + },
  24 + "staffDetailOrgPrivilege": {
  25 + "relatedOrg": "Related Organization",
  26 + "org": "Organization",
  27 + "position": "Position",
  28 + "relatedRole": "Related Roles",
  29 + "staffPrivilege": "Staff Privileges",
  30 + "loadOrgsError": "Failed to load organizations",
  31 + "loadRolesError": "Failed to load roles",
  32 + "loadPrivilegesError": "Failed to load privileges"
  33 + },
  34 + "aStaffDetailCommunitys": {
  35 + "relateCommunity": "Relate Community",
  36 + "staffName": "Staff Name",
  37 + "staffId": "Staff ID",
  38 + "communityId": "Community ID",
  39 + "communityName": "Community Name",
  40 + "operation": "Operation",
  41 + "delete": "Delete",
  42 + "loadError": "Failed to load community data"
  43 + },
  44 + "addAStaffCommunity": {
  45 + "community": "Community",
  46 + "searchPlaceholder": "Enter community name",
  47 + "communityId": "Community ID",
  48 + "communityName": "Community Name",
  49 + "communityAddress": "Community Address",
  50 + "cancel": "Cancel",
  51 + "submit": "Submit",
  52 + "loadError": "Failed to load community data",
  53 + "selectCommunity": "Please select at least one community",
  54 + "addSuccess": "Community added successfully",
  55 + "addError": "Failed to add community"
  56 + },
  57 + "deleteAStaffCommunity": {
  58 + "confirmOperation": "Confirm Your Operation",
  59 + "confirmDelete": "Are you sure you want to delete this community?",
  60 + "cancel": "Cancel",
  61 + "confirm": "Confirm Delete",
  62 + "deleteSuccess": "Community deleted successfully",
  63 + "deleteError": "Failed to delete community"
  64 + }
  65 + },
  66 + zh: {
  67 + aStaffDetailList: {
  68 + staffInfo: '员工信息',
  69 + back: '返回',
  70 + edit: '修改',
  71 + resetPwd: '重置密码',
  72 + staffId: '编号',
  73 + userName: '名称',
  74 + idCard: '身份证',
  75 + tel: '手机',
  76 + sex: '性别',
  77 + male: '男',
  78 + female: '女',
  79 + address: '住址',
  80 + orgPrivilege: '组织权限',
  81 + community: '小区',
  82 + loadError: '加载员工信息失败',
  83 + resetSuccess: '密码重置成功',
  84 + editSuccess: '员工信息修改成功',
  85 + addCommunitySuccess: '小区关联成功',
  86 + deleteCommunitySuccess: '小区删除成功'
  87 + },
  88 + "staffDetailOrgPrivilege": {
  89 + "relatedOrg": "关联组织",
  90 + "org": "组织",
  91 + "position": "岗位",
  92 + "relatedRole": "关联角色",
  93 + "staffPrivilege": "员工权限",
  94 + "loadOrgsError": "加载组织失败",
  95 + "loadRolesError": "加载角色失败",
  96 + "loadPrivilegesError": "加载权限失败"
  97 + },
  98 + "aStaffDetailCommunitys": {
  99 + "relateCommunity": "关联小区",
  100 + "staffName": "员工名称",
  101 + "staffId": "员工编号",
  102 + "communityId": "小区编号",
  103 + "communityName": "小区名称",
  104 + "operation": "操作",
  105 + "delete": "删除",
  106 + "loadError": "加载小区数据失败"
  107 + },
  108 + "addAStaffCommunity": {
  109 + "community": "小区",
  110 + "searchPlaceholder": "输入小区名称",
  111 + "communityId": "小区ID",
  112 + "communityName": "小区名称",
  113 + "communityAddress": "小区地址",
  114 + "cancel": "取消",
  115 + "submit": "提交",
  116 + "loadError": "加载小区数据失败",
  117 + "selectCommunity": "请至少选择一个小区",
  118 + "addSuccess": "小区关联成功",
  119 + "addError": "小区关联失败"
  120 + },
  121 + "deleteAStaffCommunity": {
  122 + "confirmOperation": "请确认您的操作",
  123 + "confirmDelete": "确定删除隶属小区?",
  124 + "cancel": "点错了",
  125 + "confirm": "确认删除",
  126 + "deleteSuccess": "小区删除成功",
  127 + "deleteError": "小区删除失败"
  128 + }
  129 + }
  130 +}
0 131 \ No newline at end of file
... ...
src/views/staff/aStaffDetailList.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <el-card class="box-card">
  4 + <div class="flex justify-between">
  5 + <div class="text-title">{{ $t('aStaffDetailList.staffInfo') }}</div>
  6 + <div>
  7 + <el-button type="primary" size="small" style="margin-left:10px" @click="goBack">
  8 + <i class="el-icon-close"></i>{{ $t('aStaffDetailList.back') }}
  9 + </el-button>
  10 + <el-button v-if="hasPrivilege('502022082992300002,502022101832220184')" type="primary" size="small"
  11 + style="margin-left:10px" @click="openEditStaffModel">
  12 + <i class="el-icon-edit"></i>{{ $t('aStaffDetailList.edit') }}
  13 + </el-button>
  14 + <el-button type="primary" size="small" style="margin-left:10px" @click="resetStaffPwd">
  15 + <i class="el-icon-refresh"></i>{{ $t('aStaffDetailList.resetPwd') }}
  16 + </el-button>
  17 + </div>
  18 + </div>
  19 +
  20 + <div class="margin-top flex justify-start">
  21 + <div class="text-center vc-float-left" style="width: 150px;" v-if="staffDetailInfo.photo">
  22 + <img width="120px" height="140px" class="border-radius" :src="staffDetailInfo.photo" @error="errorLoadImg" />
  23 + </div>
  24 + <div class="text-center vc-float-left" style="width: 150px;" v-else>
  25 + <img width="120px" height="140px" class="border-radius" src="/img/noPhoto.jpg" />
  26 + </div>
  27 + <el-row style="min-height: 160px;width: 100%; " class="text-left">
  28 + <el-col :span="24">
  29 + <el-row class="margin-bottom margin-top">
  30 + <el-col :span="8">
  31 + <div class="form-group">
  32 + <label class="col-form-label">{{ $t('aStaffDetailList.staffId') }}:</label>
  33 + <label>{{ staffDetailInfo.staffId }}</label>
  34 + </div>
  35 + </el-col>
  36 + <el-col :span="8">
  37 + <div class="form-group">
  38 + <label class="col-form-label">{{ $t('aStaffDetailList.userName') }}:</label>
  39 + <label>{{ staffDetailInfo.userName }}</label>
  40 + </div>
  41 + </el-col>
  42 + <el-col :span="8">
  43 + <div class="form-group">
  44 + <label class="col-form-label">{{ $t('aStaffDetailList.idCard') }}:</label>
  45 + <label>{{ staffDetailInfo.idCard }}</label>
  46 + </div>
  47 + </el-col>
  48 + </el-row>
  49 + <el-row>
  50 + <el-col :span="8">
  51 + <div class="form-group">
  52 + <label class="col-form-label">{{ $t('aStaffDetailList.tel') }}:</label>
  53 + <label>{{ staffDetailInfo.tel }}</label>
  54 + </div>
  55 + </el-col>
  56 + <el-col :span="8">
  57 + <div class="form-group">
  58 + <label class="col-form-label">{{ $t('aStaffDetailList.sex') }}:</label>
  59 + <label>{{ staffDetailInfo.sex == '0' ? $t('aStaffDetailList.male') : $t('aStaffDetailList.female')
  60 + }}</label>
  61 + </div>
  62 + </el-col>
  63 + <el-col :span="8">
  64 + <div class="form-group">
  65 + <label class="col-form-label">{{ $t('aStaffDetailList.address') }}:</label>
  66 + <label>{{ staffDetailInfo.address }}</label>
  67 + </div>
  68 + </el-col>
  69 + </el-row>
  70 + </el-col>
  71 + </el-row>
  72 + </div>
  73 +
  74 + <divider />
  75 +
  76 + <div class="margin-top-sm">
  77 + <el-tabs v-model="staffDetailInfo.currentTab">
  78 + <el-tab-pane :label="$t('aStaffDetailList.orgPrivilege')" name="staffDetailOrgPrivilege"></el-tab-pane>
  79 + <el-tab-pane :label="$t('aStaffDetailList.community')" name="aStaffDetailCommunitys"></el-tab-pane>
  80 + </el-tabs>
  81 + </div>
  82 + <div v-if="staffDetailInfo.currentTab !== 'staffDetailOrgPrivilege'">
  83 + <a-staff-detail-communitys ref="communitys" :staff-id="staffDetailInfo.staffId" />
  84 + </div>
  85 + </el-card>
  86 +
  87 + <div v-if="staffDetailInfo.currentTab === 'staffDetailOrgPrivilege'">
  88 + <staff-detail-org-privilege ref="orgPrivilege" :staff-id="staffDetailInfo.staffId" />
  89 + </div>
  90 +
  91 +
  92 + <reset-staff-pwd ref="resetPwd" @success="handleResetSuccess" />
  93 + <edit-staff ref="editStaff" @success="handleEditSuccess" />
  94 + </div>
  95 +</template>
  96 +
  97 +<script>
  98 +import { getStaffInfo } from '@/api/staff/aStaffDetailApi'
  99 +import StaffDetailOrgPrivilege from '@/components/staff/staffDetailOrgPrivilege'
  100 +import AStaffDetailCommunitys from '@/components/staff/aStaffDetailCommunitys'
  101 +import ResetStaffPwd from '@/components/staff/resetStaffPwd'
  102 +import EditStaff from '@/components/staff/editStaff'
  103 +
  104 +import divider from '@/components/system/divider'
  105 +
  106 +export default {
  107 + name: 'AStaffDetailList',
  108 + components: {
  109 + StaffDetailOrgPrivilege,
  110 + AStaffDetailCommunitys,
  111 + ResetStaffPwd,
  112 + EditStaff,
  113 + divider
  114 + },
  115 + data() {
  116 + return {
  117 + staffDetailInfo: {
  118 + staffId: '',
  119 + userName: '',
  120 + idCard: '',
  121 + tel: '',
  122 + sex: '',
  123 + address: '',
  124 + photo: '/img/noPhoto.jpg',
  125 + currentTab: 'staffDetailOrgPrivilege'
  126 + }
  127 + }
  128 + },
  129 + created() {
  130 + this.staffDetailInfo.staffId = this.$route.query.staffId
  131 + if (this.staffDetailInfo.staffId) {
  132 + this.loadStaffInfo()
  133 + }
  134 + },
  135 + methods: {
  136 + async loadStaffInfo() {
  137 + try {
  138 + const response = await getStaffInfo({
  139 + staffId: this.staffDetailInfo.staffId,
  140 + row: 1,
  141 + page: 1
  142 + })
  143 + Object.assign(this.staffDetailInfo, response.staffs[0])
  144 + //this.staffDetailInfo.photo = `/callComponent/download/getFile/fileByObjId?objId=${this.staffDetailInfo.staffId}&communityId=${this.$store.getters.communityId}&fileTypeCd=12000&time=${new Date().getTime()}`
  145 + } catch (error) {
  146 + this.$message.error(this.$t('aStaffDetailList.loadError'))
  147 + }
  148 + },
  149 + goBack() {
  150 + this.$router.go(-1)
  151 + },
  152 + openEditStaffModel() {
  153 + this.$refs.editStaff.open(this.staffDetailInfo)
  154 + },
  155 + resetStaffPwd() {
  156 + this.$refs.resetPwd.open({
  157 + userId: this.staffDetailInfo.staffId,
  158 + name: this.staffDetailInfo.userName
  159 + })
  160 + },
  161 + errorLoadImg() {
  162 + this.staffDetailInfo.photo = "/img/noPhoto.jpg"
  163 + },
  164 + handleResetSuccess() {
  165 + this.$message.success(this.$t('aStaffDetailList.resetSuccess'))
  166 + },
  167 + handleEditSuccess() {
  168 + this.loadStaffInfo()
  169 + this.$message.success(this.$t('aStaffDetailList.editSuccess'))
  170 + },
  171 +
  172 + }
  173 +}
  174 +</script>
  175 +
  176 +<style scoped>
  177 +.margin-top {
  178 + margin-top: 20px;
  179 +}
  180 +
  181 +.margin-top-sm {
  182 + margin-top: 10px;
  183 +}
  184 +
  185 +.text-title {
  186 + font-size: 18px;
  187 + font-weight: bold;
  188 +}
  189 +
  190 +.vc-float-left {
  191 + float: left;
  192 +}
  193 +
  194 +.border-radius {
  195 + border-radius: 4px;
  196 +}
  197 +
  198 +.vc-line-primary {
  199 + height: 1px;
  200 + background-color: #409EFF;
  201 + margin: 20px 0;
  202 +}
  203 +</style>
0 204 \ No newline at end of file
... ...
src/views/staff/aStaffLang.js 0 → 100644
  1 +export const messages = {
  2 + en: {
  3 + staff: {
  4 + searchConditions: 'Search Conditions',
  5 + staffIdPlaceholder: 'Enter Staff ID',
  6 + staffNamePlaceholder: 'Enter Staff Name',
  7 + phonePlaceholder: 'Enter Phone Number',
  8 + search: 'Search',
  9 + staffInfo: 'Staff Information',
  10 + add: 'Add',
  11 + staffId: 'Staff ID',
  12 + name: 'Name',
  13 + phone: 'Phone',
  14 + relatedOrg: 'Related Organization',
  15 + position: 'Position',
  16 + idCard: 'ID Card',
  17 + address: 'Address',
  18 + gender: 'Gender',
  19 + male: 'Male',
  20 + female: 'Female',
  21 + operations: 'Operations',
  22 + edit: 'Edit',
  23 + resetPwd: 'Reset Password',
  24 + delete: 'Delete',
  25 + details: 'Details',
  26 + tip: 'Tip: The default password for new employees is 123456. After assigning roles and permissions to the community and associating roles with employees, they can log in.',
  27 + confirmOperation: 'Please confirm your operation',
  28 + confirmReset: 'Are you sure to reset the password?',
  29 + confirmResetPassword: 'Are you sure to reset the password?',
  30 + cancel: 'Cancel',
  31 + confirmResetBtn: 'Confirm Reset',
  32 + editStaff: 'Edit Staff',
  33 + requiredName: 'Required, enter staff name',
  34 + requiredPosition: 'Required, select position',
  35 + optionalIdCard: 'Optional, enter ID card',
  36 + requiredPhone: 'Required, enter phone number',
  37 + requiredGender: 'Required, select gender',
  38 + requiredAddress: 'Required, enter address',
  39 + uploadPhoto: 'Upload Photo',
  40 + confirmDelete: 'Are you sure to delete? Before deleting an employee, please confirm that the employee has completed the relevant approval process. After deletion, the relevant process cannot continue. Please operate with caution!',
  41 + confirmDeleteBtn: 'Confirm Delete'
  42 + }
  43 + },
  44 + zh: {
  45 + staff: {
  46 + searchConditions: '查询条件',
  47 + staffIdPlaceholder: '请输入员工ID',
  48 + staffNamePlaceholder: '请输入员工名称',
  49 + phonePlaceholder: '请输入手机号',
  50 + search: '查询',
  51 + staffInfo: '员工信息',
  52 + add: '添加',
  53 + staffId: '员工编号',
  54 + name: '名称',
  55 + phone: '手机号',
  56 + relatedOrg: '关联组织',
  57 + position: '岗位',
  58 + idCard: '身份证',
  59 + address: '地址',
  60 + gender: '性别',
  61 + male: '男',
  62 + female: '女',
  63 + operations: '操作',
  64 + edit: '修改',
  65 + resetPwd: '重置密码',
  66 + delete: '删除',
  67 + details: '详情',
  68 + tip: '温馨提示:新添加员工默认密码为123456,角色权限分配小区并且角色关联员工后可登录',
  69 + confirmOperation: '请确认您的操作',
  70 + confirmReset: '确认是否重置密码',
  71 + confirmResetPassword: '确认是否重置密码',
  72 + cancel: '点错了',
  73 + confirmResetBtn: '确认重置',
  74 + editStaff: '修改员工',
  75 + requiredName: '必填,请填写员工名称',
  76 + requiredPosition: '必填,请选择岗位',
  77 + optionalIdCard: '可选,请填写身份证',
  78 + requiredPhone: '必填,请填写手机号码',
  79 + requiredGender: '必填,请选择员工性别',
  80 + requiredAddress: '必填,请填写家庭住址',
  81 + uploadPhoto: '上传照片',
  82 + confirmDelete: '确认是否删除,删除员工前请确认员工已完成相关审批流程,删除后相关流程将无法继续进行,请慎重操作!',
  83 + confirmDeleteBtn: '确认删除'
  84 + }
  85 + }
  86 +}
0 87 \ No newline at end of file
... ...
src/views/staff/aStaffList.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <el-card class="box-card margin-bottom">
  4 + <div slot="header" class="clearfix flex justify-between">
  5 + <span>{{ $t('staff.searchConditions') }}</span>
  6 + </div>
  7 + <el-row :gutter="20">
  8 + <el-col :span="6">
  9 + <el-input :placeholder="$t('staff.staffIdPlaceholder')" v-model="searchConditions.staffId" clearable />
  10 + </el-col>
  11 + <el-col :span="6">
  12 + <el-input :placeholder="$t('staff.staffNamePlaceholder')" v-model="searchConditions.name" clearable />
  13 + </el-col>
  14 + <el-col :span="6">
  15 + <el-input :placeholder="$t('staff.phonePlaceholder')" v-model="searchConditions.tel" clearable />
  16 + </el-col>
  17 + <el-col :span="6">
  18 + <el-button type="primary" @click="queryStaff">
  19 + {{ $t('staff.search') }}
  20 + </el-button>
  21 + </el-col>
  22 + </el-row>
  23 + </el-card>
  24 +
  25 + <el-card class="box-card">
  26 + <div slot="header" class="clearfix flex justify-between">
  27 + <span>{{ $t('staff.staffInfo') }}</span>
  28 + <el-button v-if="hasPrivilege(['502022082992310001', '502022101889270183'])" type="primary" size="small"
  29 + class="float-right" @click="openAddStaffPage">
  30 + {{ $t('staff.add') }}
  31 + </el-button>
  32 + </div>
  33 +
  34 + <el-table :data="staffList" border style="width: 100%">
  35 + <el-table-column prop="userId" :label="$t('staff.staffId')" align="center" />
  36 + <el-table-column prop="name" :label="$t('staff.name')" align="center" />
  37 + <el-table-column prop="tel" :label="$t('staff.phone')" align="center" />
  38 + <el-table-column prop="orgName" :label="$t('staff.relatedOrg')" align="center" />
  39 + <el-table-column prop="relCdName" :label="$t('staff.position')" align="center" />
  40 + <el-table-column prop="idCard" :label="$t('staff.idCard')" align="center" />
  41 + <el-table-column prop="address" :label="$t('staff.address')" align="center" />
  42 + <el-table-column :label="$t('staff.gender')" align="center">
  43 + <template slot-scope="scope">
  44 + {{ scope.row.sex === 0 ? $t('staff.male') : $t('staff.female') }}
  45 + </template>
  46 + </el-table-column>
  47 + <el-table-column :label="$t('staff.operations')" align="center" width="300">
  48 + <template slot-scope="scope">
  49 + <el-button v-if="hasPrivilege(['502022082992300002', '502022101832220184'])" size="mini"
  50 + @click="openEditStaff(scope.row)">
  51 + {{ $t('staff.edit') }}
  52 + </el-button>
  53 + <el-button size="mini" @click="openResetPwd(scope.row)">
  54 + {{ $t('staff.resetPwd') }}
  55 + </el-button>
  56 + <el-button
  57 + v-if="scope.row.relCd !== '600311000001' && hasPrivilege(['502022082920350003', '502022101887680185'])"
  58 + size="mini" type="danger" @click="openDeleteStaff(scope.row)">
  59 + {{ $t('staff.delete') }}
  60 + </el-button>
  61 + <el-button size="mini" type="info" @click="openStaffDetail(scope.row)">
  62 + {{ $t('staff.details') }}
  63 + </el-button>
  64 + </template>
  65 + </el-table-column>
  66 + </el-table>
  67 +
  68 + <el-row class="margin-top">
  69 + <el-col :span="16">
  70 + <div class="tip-text">{{ $t('staff.tip') }}</div>
  71 + </el-col>
  72 + <el-col :span="8" class="text-right">
  73 + <el-pagination :current-page="pagination.current" :page-sizes="[10, 20, 30, 50]" :page-size="pagination.size"
  74 + :total="pagination.total" layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange"
  75 + @current-change="handlePageChange" />
  76 + </el-col>
  77 + </el-row>
  78 + </el-card>
  79 +
  80 + <reset-staff-pwd ref="resetPwdDialog" @success="queryStaff" />
  81 + <edit-staff ref="editStaffDialog" @success="queryStaff" />
  82 + <delete-staff ref="deleteStaffDialog" @success="queryStaff" />
  83 + </div>
  84 +</template>
  85 +
  86 +<script>
  87 +import { queryStaffInfos } from '@/api/staff/aStaffApi'
  88 +import ResetStaffPwd from '@/components/staff/resetStaffPwd'
  89 +import EditStaff from '@/components/staff/editStaff'
  90 +import DeleteStaff from '@/components/staff/deleteStaff'
  91 +import { getDict } from '@/api/community/communityApi'
  92 +
  93 +export default {
  94 + name: 'AStaffList',
  95 + components: {
  96 + ResetStaffPwd,
  97 + EditStaff,
  98 + DeleteStaff
  99 + },
  100 + data() {
  101 + return {
  102 + searchConditions: {
  103 + staffId: '',
  104 + name: '',
  105 + tel: ''
  106 + },
  107 + staffList: [],
  108 + pagination: {
  109 + current: 1,
  110 + size: 10,
  111 + total: 0
  112 + },
  113 + relCds: []
  114 + }
  115 + },
  116 + created() {
  117 + this.getDictData()
  118 + this.queryStaff()
  119 + },
  120 + methods: {
  121 + async getDictData() {
  122 + try {
  123 + const res = await getDict('u_org_staff_rel', 'rel_cd')
  124 + if (res.code === 0) {
  125 + this.relCds = res.data
  126 + }
  127 + } catch (error) {
  128 + console.error('获取字典数据失败:', error)
  129 + }
  130 + },
  131 + async queryStaff() {
  132 + try {
  133 + const params = {
  134 + ...this.searchConditions,
  135 + page: this.pagination.current,
  136 + row: this.pagination.size
  137 + }
  138 +
  139 + const res = await queryStaffInfos(params)
  140 + console.log(res)
  141 +
  142 + this.staffList = res.staffs.map(staff => {
  143 + const relCdItem = this.relCds.find(item => item.statusCd === staff.relCd)
  144 + return {
  145 + ...staff,
  146 + relCdName: relCdItem ? relCdItem.name : ''
  147 + }
  148 + })
  149 + this.pagination.total = res.data.total
  150 +
  151 + } catch (error) {
  152 + console.error('查询员工信息失败:', error)
  153 + }
  154 + },
  155 + openResetPwd(staff) {
  156 + this.$refs.resetPwdDialog.open(staff)
  157 + },
  158 + openEditStaff(staff) {
  159 + this.$refs.editStaffDialog.open(staff)
  160 + },
  161 + openDeleteStaff(staff) {
  162 + this.$refs.deleteStaffDialog.open(staff)
  163 + },
  164 + openStaffDetail(staff) {
  165 + this.$router.push(`/views/staff/aStaffDetail?staffId=${staff.userId}`)
  166 + },
  167 + openAddStaffPage() {
  168 + this.$router.push('/views/staff/addStaff')
  169 + },
  170 + handleSizeChange(size) {
  171 + this.pagination.size = size
  172 + this.queryStaff()
  173 + },
  174 + handlePageChange(page) {
  175 + this.pagination.current = page
  176 + this.queryStaff()
  177 + },
  178 +
  179 + }
  180 +}
  181 +</script>
  182 +
  183 +<style scoped>
  184 +.box-card {
  185 + margin-bottom: 20px;
  186 +}
  187 +
  188 +.float-right {
  189 + float: right;
  190 +}
  191 +
  192 +.margin-top {
  193 + margin-top: 20px;
  194 +}
  195 +
  196 +.margin-bottom {
  197 + margin-bottom: 20px;
  198 +}
  199 +
  200 +.text-right {
  201 + text-align: right;
  202 +}
  203 +
  204 +.tip-text {
  205 + color: #999;
  206 + font-size: 12px;
  207 + padding: 10px 0;
  208 +}
  209 +</style>
0 210 \ No newline at end of file
... ...