Browse Source

代理商,单位,群组,用户基础

master
xh 1 week ago
parent
commit
79394e72e2
  1. 29
      web/.env.fbw
  2. 1
      web/package.json
  3. 137
      web/src/api/interphone/README.md
  4. 130
      web/src/api/interphone/agent.ts
  5. 99
      web/src/api/interphone/broadcast.ts
  6. 237
      web/src/api/interphone/group.ts
  7. 65
      web/src/api/interphone/location.ts
  8. 45
      web/src/api/interphone/log.ts
  9. 41
      web/src/api/interphone/notice.ts
  10. 85
      web/src/api/interphone/org.ts
  11. 71
      web/src/api/interphone/profile.ts
  12. 44
      web/src/api/interphone/record.ts
  13. 223
      web/src/api/interphone/terminal.ts
  14. 10
      web/src/api/interphone/types.ts
  15. 105
      web/src/views/interphone/agent/AgentBalanceDialog.vue
  16. 58
      web/src/views/interphone/agent/AgentDetail.vue
  17. 142
      web/src/views/interphone/agent/AgentForm.vue
  18. 161
      web/src/views/interphone/agent/index.vue
  19. 179
      web/src/views/interphone/group/GroupForm.vue
  20. 166
      web/src/views/interphone/group/index.vue
  21. 167
      web/src/views/interphone/org/OrgForm.vue
  22. 160
      web/src/views/interphone/org/index.vue
  23. 209
      web/src/views/interphone/terminal/TerminalForm.vue
  24. 226
      web/src/views/interphone/terminal/index.vue

29
web/.env.fbw

@ -0,0 +1,29 @@
NODE_ENV=development
VITE_DEV=true
# 请求路径
# VITE_BASE_URL='https://mobile.zdhlcn.com'
# VITE_BASE_URL='https://lock.zdhlcn.com:9807'
VITE_BASE_URL=http://fbw.adtk.cn:28899
# 文件上传类型:server - 后端上传, client - 前端直连上传,仅支持S3服务
VITE_UPLOAD_TYPE=server
# 接口地址
VITE_API_URL=/admin-api
# 是否删除debugger
VITE_DROP_DEBUGGER=false
# 是否删除console.log
VITE_DROP_CONSOLE=false
# 是否sourcemap
VITE_SOURCEMAP=true
# 打包路径
VITE_BASE_PATH=/
# 输出路径
VITE_OUT_DIR=dist

1
web/package.json

@ -5,6 +5,7 @@
"scripts": {
"i": "pnpm install",
"dev": "vite --mode dev",
"dev:fbw": "vite --mode fbw",
"dev:test": "vite --mode test",
"ts:check": "vue-tsc --noEmit",
"build:dev": "vite build --mode dev",

137
web/src/api/interphone/README.md

@ -0,0 +1,137 @@
{
"meta": {
"description": "对讲机管理平台 API 列表 (精简版)",
"note": "所有接口均需携带 access_token 和 openid,此处已省略"
},
"apis": [
{
"module": "Auth",
"endpoints": [
{ "name": "获取验证码图片", "url": "/interphone/open-api/auth/getImg", "method": "GET", "params": [] },
{ "name": "校验验证码", "url": "/interphone/open-api/auth/verifyImageCode", "method": "GET", "params": ["token", "x"] },
{ "name": "用户登录", "url": "/interphone/open-api/auth/access_token", "method": "GET", "params": ["username", "password", "user_type", "appId", "appSecret", "token", "x"] }
]
},
{
"module": "Profile",
"endpoints": [
{ "name": "个人信息(代理商)", "url": "/interphone/open-api/profile/agent", "method": "GET", "params": [] },
{ "name": "个人信息(单位)", "url": "/interphone/open-api/profile/org", "method": "GET", "params": [] },
{ "name": "修改密码", "url": "/interphone/open-api/profile/password", "method": "POST", "params": ["oldpwd", "newpwd"] },
{ "name": "数据统计", "url": "/interphone/open-api/profile/faststats", "method": "GET", "params": [] },
{ "name": "修改代理商信息", "url": "/interphone/open-api/agent/ModifyingAgentInformation", "method": "POST", "params": ["agentId", "contact", "provinceid"] }
]
},
{
"module": "Agent",
"endpoints": [
{ "name": "代理商列表", "url": "/interphone/open-api/agent/list", "method": "GET", "params": ["pageNo", "pageSize", "name"] },
{ "name": "添加代理商", "url": "/interphone/open-api/agent/add", "method": "POST", "params": ["name", "loginname", "password", "contact", "countryid", "address"] },
{ "name": "代理商详情", "url": "/interphone/open-api/agent/detail", "method": "GET", "params": ["id"] },
{ "name": "修改代理商", "url": "/interphone/open-api/agent/updateAgent", "method": "POST", "params": ["agentId", "name", "contact", "countryid"] },
{ "name": "点卡充值", "url": "/interphone/open-api/agent/blance/add", "method": "POST", "params": ["agentId", "chargetype", "count"] },
{ "name": "点卡收回", "url": "/interphone/open-api/agent/cardRecovery", "method": "POST", "params": ["agentId", "cardType", "recoveryNumber"] },
{ "name": "获取下级代理商名", "url": "/interphone/open-api/agent/getAgentName", "method": "GET", "params": [] },
{ "name": "获取群组名称", "url": "/interphone/open-api/group/getGroupName", "method": "GET", "params": ["orgId", "isactive"] },
{ "name": "查询下级用户", "url": "/interphone/open-api/terminal/querySubordinateUser", "method": "GET", "params": ["pageNo", "pageSize", "agentId", "orgid", "groupid", "userName", "account"] }
]
},
{
"module": "Org",
"endpoints": [
{ "name": "单位列表", "url": "/interphone/open-api/agent/orgs", "method": "GET", "params": ["pageNo", "pageSize", "name"] },
{ "name": "添加单位", "url": "/interphone/open-api/org/add", "method": "POST", "params": ["name", "loginname", "password", "contact", "phone", "address", "isDefault", "defaultName"] },
{ "name": "修改单位", "url": "/interphone/open-api/org/xiugaiUnit", "method": "POST", "params": ["id", "corgName", "contact", "address"] },
{ "name": "删除单位", "url": "/interphone/open-api/org/deletingUnit", "method": "POST", "params": ["id"] },
{ "name": "单位详情", "url": "/interphone/open-api/org/info", "method": "GET", "params": ["id"] },
{ "name": "获取单位名称", "url": "/interphone/open-api/org/getOrgName", "method": "GET", "params": ["agentId"] }
]
},
{
"module": "Group",
"endpoints": [
{ "name": "群组列表", "url": "/interphone/open-api/group/list", "method": "GET", "params": ["pageNo", "pageSize", "name", "orgname", "org_id", "type"] },
{ "name": "添加群组", "url": "/interphone/open-api/group/add", "method": "POST", "params": ["orgid", "cgName", "cg_speech_limit_second", "remarks"] },
{ "name": "群组详情", "url": "/interphone/open-api/group/detail", "method": "GET", "params": ["id"] },
{ "name": "编辑群组", "url": "/interphone/open-api/group/updateGroup", "method": "POST", "params": ["id", "cgName", "cg_speech_limit_second", "remarks"] },
{ "name": "删除群组", "url": "/interphone/open-api/group/delete", "method": "POST", "params": ["id"] },
{ "name": "获取群组成员", "url": "/interphone/open-api/group/members", "method": "GET", "params": ["id", "username"] },
{ "name": "设置主持人", "url": "/interphone/open-api/group/updateHost", "method": "POST", "params": ["groupId", "hnet_id"] },
{ "name": "获取不在组成员", "url": "/interphone/open-api/group/unmembers", "method": "GET", "params": ["id", "org_id", "username"] },
{ "name": "添加群组成员", "url": "/interphone/open-api/group/members/add", "method": "POST", "params": ["id", "members"] },
{ "name": "移除群组成员", "url": "/interphone/open-api/group/members/remove", "method": "POST", "params": ["id", "members"] },
{ "name": "修改成员优先级", "url": "/interphone/open-api/group/members/priorities", "method": "POST", "params": ["id", "userId", "priorities"] },
{ "name": "获取用户群组", "url": "/interphone/open-api/jsp/queryGroupByUId", "method": "GET", "params": ["id"] },
{ "name": "换群组", "url": "/interphone/open-api/group/joinGroup", "method": "POST", "params": ["userlds", "orgid", "groupid", "isDefault"] },
{ "name": "查询用户群组", "url": "/interphone/open-api/group/groupSelect", "method": "POST", "params": ["orgid", "userId", "state", "zuname"] },
{ "name": "批量添加群组", "url": "/interphone/open-api/group/batchaddgroup", "method": "POST", "params": ["userid", "groupArray"] },
{ "name": "批量移除群组", "url": "/interphone/open-api/group/batchdelete", "method": "POST", "params": ["uogid[]"] },
{ "name": "查询监听状态", "url": "/interphone/open-api/group/queryMonitorGroup", "method": "POST", "params": ["userId", "type", "keyword"] },
{ "name": "添加监听群组", "url": "/interphone/open-api/group/addMonitorGroup", "method": "POST", "params": ["userId", "groupIds"] },
{ "name": "移除监听群组", "url": "/interphone/open-api/group/MonitorGroup", "method": "POST", "params": ["userId", "cgids"] }
]
},
{
"module": "Terminal",
"endpoints": [
{ "name": "导入Excel", "url": "/interphone/open-api/terminal/analysisExcel", "method": "POST", "params": ["file"] },
{ "name": "判断用户存在", "url": "/interphone/open-api/terminal/isAddUser", "method": "POST", "params": ["imei"] },
{ "name": "批量创建用户", "url": "/interphone/open-api/terminal/batch", "method": "POST", "params": ["orgId", "groups", "prefix", "accounts", "beizhu", "cardTypes"] },
{ "name": "用户列表", "url": "/interphone/open-api/terminal/list", "method": "GET", "params": ["pageNo", "pageSize", "org_id", "groupid", "name", "userStatus", "audioStatus", "servicetype", "iccid", "serviceType", "createStartAt", "createEndAt"] },
{ "name": "用户详情", "url": "/interphone/open-api/terminal/detail", "method": "GET", "params": ["id"] },
{ "name": "修改用户", "url": "/interphone/open-api/terminal/updateUser", "method": "POST", "params": ["userId", "beizhu", "orgid", "userName", "userMobile", "enable", "userAudioStatus", "allowcall", "gpsSwitch", "user_type"] },
{ "name": "遥开/遥毙", "url": "/interphone/open-api/terminal/updateUserVoice", "method": "POST", "params": ["userlds", "voice"] },
{ "name": "暂停/开启账号", "url": "/interphone/open-api/terminal/updateUserEnable", "method": "POST", "params": ["userlds", "enable"] },
{ "name": "删除用户", "url": "/interphone/open-api/terminal/deleteUser", "method": "POST", "params": ["userlds"] },
{ "name": "换号", "url": "/interphone/open-api/terminal/changecard", "method": "POST", "params": ["oldAccount", "newAccount"] },
{ "name": "导出未登录", "url": "/interphone/open-api/terminal/exportUserInfo", "method": "GET", "params": ["agentId", "dateType", "platform"] },
{ "name": "开通服务", "url": "/interphone/open-api/terminal/addService", "method": "GET", "params": ["userids", "type", "dateType"] },
{ "name": "删除服务", "url": "/interphone/open-api/terminal/deleteService", "method": "GET", "params": ["userids", "type"] },
{ "name": "服务列表", "url": "/interphone/open-api/terminal/serviceList", "method": "GET", "params": ["pageNo", "pageSize", "user_id"] },
{ "name": "修改服务", "url": "/interphone/open-api/terminal/updateService", "method": "GET", "params": ["user_id", "type", "dateType"] }
]
},
{
"module": "Location",
"endpoints": [
{ "name": "查询定位", "url": "/interphone/open-api/location/locat", "method": "GET", "params": ["id"] },
{ "name": "批量定位", "url": "/interphone/open-api/location/locatBatch", "method": "POST", "params": ["ids"] },
{ "name": "定位列表", "url": "/interphone/open-api/location/locatList", "method": "GET", "params": ["pageNo", "pageSize", "user_id"] },
{ "name": "导出轨迹", "url": "/interphone/open-api/location/locatExport", "method": "GET", "params": ["user_id", "start", "end"] }
]
},
{
"module": "Broadcast",
"endpoints": [
{ "name": "添加广播", "url": "/interphone/open-api/broadcast/add", "method": "POST", "params": ["name", "org_id"] },
{ "name": "修改广播", "url": "/interphone/open-api/broadcast/update", "method": "POST", "params": ["id", "name"] },
{ "name": "删除广播", "url": "/interphone/open-api/broadcast/delete", "method": "POST", "params": ["id"] },
{ "name": "广播列表", "url": "/interphone/open-api/broadcast/list", "method": "GET", "params": ["pageNo", "pageSize", "org_id"] },
{ "name": "广播详情", "url": "/interphone/open-api/broadcast/detail", "method": "GET", "params": ["id"] },
{ "name": "广播成员", "url": "/interphone/open-api/broadcast/members", "method": "GET", "params": ["id"] },
{ "name": "添加广播成员", "url": "/interphone/open-api/broadcast/members/add", "method": "POST", "params": ["id", "members"] },
{ "name": "移除广播成员", "url": "/interphone/open-api/broadcast/members/remove", "method": "POST", "params": ["id", "members"] }
]
},
{
"module": "Log",
"endpoints": [
{ "name": "操作日志", "url": "/interphone/open-api/log/list", "method": "GET", "params": ["pageNo", "pageSize", "type", "start", "end"] },
{ "name": "导出日志", "url": "/interphone/open-api/log/export", "method": "GET", "params": ["type", "start", "end"] }
]
},
{
"module": "Notice",
"endpoints": [
{ "name": "通知列表", "url": "/interphone/open-api/notice/getNotice", "method": "POST", "params": ["type", "startDate", "endDate"] },
{ "name": "未读数", "url": "/interphone/open-api/notice/newUnreadCount", "method": "GET", "params": ["agentId"] }
]
},
{
"module": "SoundRecord",
"endpoints": [
{ "name": "录音查询", "url": "/interphone/open-api/soundRecord/querySoundRecord", "method": "GET", "params": ["orgId", "groupId", "startDate"] }
]
}
]
}

130
web/src/api/interphone/agent.ts

@ -0,0 +1,130 @@
import request from '@/config/axios'
import type { CommonResult } from './types'
/**
*
*/
// 代理商信息
export interface Agent {
id?: string
name?: string
loginname?: string
contact?: string
countryid?: string
address?: string
[key: string]: any
}
// 单位信息
export interface Org {
id?: string
name?: string
[key: string]: any
}
// 查询代理商列表参数
export interface AgentListParams {
pageNo: number
pageSize: number
name?: string
}
// 查询单位列表参数
export interface OrgListParams {
pageNo: number
pageSize: number
name?: string
}
// 添加代理商参数
export interface AddAgentData {
name: string
loginname: string
password: string
contact?: string
countryid?: string
address?: string
}
// 修改代理商参数
export interface UpdateAgentData {
agentId: string
name?: string
contact?: string
countryid?: string
}
// 点卡充值参数
export interface AddBalanceData {
agentId: string
chargetype: string
count: number
}
// 点卡收回参数
export interface CardRecoveryData {
agentId: string
cardType: string
recoveryNumber: number
}
// 查询下级用户参数
export interface SubordinateUserParams {
pageNo: number
pageSize: number
agentId?: string
orgid?: string
groupid?: string
userName?: string
account?: string
}
/**
*
*/
// 查询代理商列表
export const getAgentList = (params: AgentListParams) => {
return request.get({ url: '/interphone/open-api/agent/list', params }).then(res =>JSON.parse(res))
}
// 添加代理商
export const addAgent = (data: AddAgentData) => {
return request.post({ url: '/interphone/open-api/agent/add', data }).then(res =>JSON.parse(res))
}
// 查询代理商详情
export const getAgentDetail = (id: string) => {
return request.get({ url: '/interphone/open-api/agent/detail', params: { id } }).then(res =>JSON.parse(res))
}
// 修改代理商
export const updateAgent = (data: UpdateAgentData) => {
return request.post({ url: '/interphone/open-api/agent/updateAgent', data }).then(res =>JSON.parse(res))
}
// 点卡充值
export const addAgentBalance = (data: AddBalanceData) => {
return request.post({ url: '/interphone/open-api/agent/blance/add', data }).then(res =>JSON.parse(res))
}
// 点卡收回
export const cardRecovery = (data: CardRecoveryData) => {
return request.post({ url: '/interphone/open-api/agent/cardRecovery', data }).then(res =>JSON.parse(res))
}
// 获取下级代理商名
export const getAgentName = () => {
return request.get({ url: '/interphone/open-api/agent/getAgentName' }).then(res =>JSON.parse(res))
}
// 查询单位列表
export const getAgentOrgs = (params: OrgListParams) => {
return request.get({ url: '/interphone/open-api/agent/orgs', params }).then(res =>JSON.parse(res))
}
// 查询下级用户
export const querySubordinateUser = (params: SubordinateUserParams) => {
return request.get({ url: '/interphone/open-api/terminal/querySubordinateUser', params }).then(res =>JSON.parse(res))
}

99
web/src/api/interphone/broadcast.ts

@ -0,0 +1,99 @@
import request from '@/config/axios'
import type { CommonResult } from './types'
/**
* 广
*/
// 广播信息
export interface Broadcast {
id?: string
name?: string
org_id?: string
[key: string]: any
}
// 查询广播列表参数
export interface BroadcastListParams {
pageNo: number
pageSize: number
org_id?: string
}
// 添加广播参数
export interface AddBroadcastData {
name: string
org_id: string
}
// 修改广播参数
export interface UpdateBroadcastData {
id: string
name?: string
}
// 删除广播参数
export interface DeleteBroadcastData {
id: string
}
// 获取广播成员参数
export interface GetBroadcastMembersParams {
id: string
}
// 添加广播成员参数
export interface AddBroadcastMembersData {
id: string
members: string[]
}
// 移除广播成员参数
export interface RemoveBroadcastMembersData {
id: string
members: string[]
}
/**
* 广
*/
// 添加广播
export const addBroadcast = (data: AddBroadcastData) => {
return request.post<CommonResult>({ url: '/interphone/open-api/broadcast/add', data })
}
// 修改广播
export const updateBroadcast = (data: UpdateBroadcastData) => {
return request.post<CommonResult>({ url: '/interphone/open-api/broadcast/update', data })
}
// 删除广播
export const deleteBroadcast = (data: DeleteBroadcastData) => {
return request.post<CommonResult>({ url: '/interphone/open-api/broadcast/delete', data })
}
// 广播列表
export const getBroadcastList = (params: BroadcastListParams) => {
return request.get<CommonResult>({ url: '/interphone/open-api/broadcast/list', params })
}
// 广播详情
export const getBroadcastDetail = (id: string) => {
return request.get<CommonResult>({ url: '/interphone/open-api/broadcast/detail', params: { id } })
}
// 广播成员
export const getBroadcastMembers = (id: string) => {
return request.get<CommonResult>({ url: '/interphone/open-api/broadcast/members', params: { id } })
}
// 添加广播成员
export const addBroadcastMembers = (data: AddBroadcastMembersData) => {
return request.post<CommonResult>({ url: '/interphone/open-api/broadcast/members/add', data })
}
// 移除广播成员
export const removeBroadcastMembers = (data: RemoveBroadcastMembersData) => {
return request.post<CommonResult>({ url: '/interphone/open-api/broadcast/members/remove', data })
}

237
web/src/api/interphone/group.ts

@ -0,0 +1,237 @@
import request from '@/config/axios'
import type { CommonResult } from './types'
/**
*
*/
// 群组信息
export interface Group {
id?: string
name?: string
orgId?: string
orgname?: string
type?: string
cg_speech_limit_second?: number
remarks?: string
[key: string]: any
}
// 查询群组列表参数
export interface GroupListParams {
pageNo: number
pageSize: number
name?: string
orgname?: string
org_id?: string
type?: string
}
// 新增群组参数
export interface AddGroupData {
orgid: string
cgName: string
cg_speech_limit_second?: number
remarks?: string
}
// 编辑群组参数
export interface UpdateGroupData {
id: string
cgName?: string
cg_speech_limit_second?: number
remarks?: string
}
// 删除群组参数
export interface DeleteGroupData {
id: string
}
// 获取群组成员参数
export interface GetGroupMembersParams {
id: string
username?: string
}
// 设置主持人参数
export interface UpdateHostData {
groupId: string
hnet_id: string
}
// 获取不在组成员参数
export interface GetUnmembersParams {
id: string
org_id?: string
username?: string
}
// 添加群组成员参数
export interface AddGroupMembersData {
id: string
members: string[]
}
// 移除群组成员参数
export interface RemoveGroupMembersData {
id: string
members: string[]
}
// 修改成员优先级参数
export interface UpdateMemberPriorityData {
id: string
userId: string
priorities: number
}
// 换群组参数
export interface JoinGroupData {
userlds: string[]
orgid: string
groupid: string
isDefault?: string
}
// 查询用户群组参数
export interface QueryUserGroupData {
orgid: string
userId: string
state?: string
zuname?: string
}
// 批量添加群组参数
export interface BatchAddGroupData {
userid: string
groupArray: string[]
}
// 批量移除群组参数
export interface BatchDeleteGroupData {
uogid: string[]
}
// 查询监听状态参数
export interface QueryMonitorGroupData {
userId: string
type?: string
keyword?: string
}
// 添加监听群组参数
export interface AddMonitorGroupData {
userId: string
groupIds: string[]
}
// 移除监听群组参数
export interface RemoveMonitorGroupData {
userId: string
cgids: string[]
}
/**
*
*/
// 查询群组列表
export const getGroupList = (params: GroupListParams) : Promise<CommonResult<Group[]>>=> {
return request.get({ url: '/interphone/open-api/group/list', params }).then(res =>JSON.parse(res))
}
// 添加群组
export const addGroup = (data: AddGroupData) => {
return request.post({ url: '/interphone/open-api/group/add', data }).then(res =>JSON.parse(res))
}
// 查询群组详情
export const getGroupDetail = (id: string) => {
return request.get({ url: '/interphone/open-api/group/detail', params: { id } }).then(res =>JSON.parse(res))
}
// 编辑群组
export const updateGroup = (data: UpdateGroupData) => {
return request.post({ url: '/interphone/open-api/group/updateGroup', data }).then(res =>JSON.parse(res))
}
// 删除群组
export const deleteGroup = (data: DeleteGroupData) => {
return request.post({ url: '/interphone/open-api/group/delete', data }).then(res =>JSON.parse(res))
}
// 获取群组成员
export const getGroupMembers = (params: GetGroupMembersParams) => {
return request.get({ url: '/interphone/open-api/group/members', params }).then(res =>JSON.parse(res))
}
// 设置主持人
export const updateHost = (data: UpdateHostData) => {
return request.post({ url: '/interphone/open-api/group/updateHost', data }).then(res =>JSON.parse(res))
}
// 获取不在组成员
export const getUnmembers = (params: GetUnmembersParams) => {
return request.get({ url: '/interphone/open-api/group/unmembers', params }).then(res =>JSON.parse(res))
}
// 添加群组成员
export const addGroupMembers = (data: AddGroupMembersData) => {
return request.post({ url: '/interphone/open-api/group/members/add', data }).then(res =>JSON.parse(res))
}
// 移除群组成员
export const removeGroupMembers = (data: RemoveGroupMembersData) => {
return request.post({ url: '/interphone/open-api/group/members/remove', data }).then(res =>JSON.parse(res))
}
// 修改成员优先级
export const updateMemberPriority = (data: UpdateMemberPriorityData) => {
return request.post({ url: '/interphone/open-api/group/members/priorities', data }).then(res =>JSON.parse(res))
}
// 查询用户群组
export const queryGroupByUid = (id: string) => {
return request.get({ url: '/interphone/open-api/jsp/queryGroupByUId', params: { id } }).then(res =>JSON.parse(res))
}
// 换群组
export const joinGroup = (data: JoinGroupData) => {
return request.post({ url: '/interphone/open-api/group/joinGroup', data }).then(res =>JSON.parse(res))
}
// 查询用户群组
export const queryUserGroup = (data: QueryUserGroupData) => {
return request.post({ url: '/interphone/open-api/group/groupSelect', data }).then(res =>JSON.parse(res))
}
// 批量添加群组
export const batchAddGroup = (data: BatchAddGroupData) => {
return request.post({ url: '/interphone/open-api/group/batchaddgroup', data }).then(res =>JSON.parse(res))
}
// 批量移除群组
export const batchDeleteGroup = (data: BatchDeleteGroupData) => {
return request.post({ url: '/interphone/open-api/group/batchdelete', data }).then(res =>JSON.parse(res))
}
// 查询监听状态
export const queryMonitorGroup = (data: QueryMonitorGroupData) => {
return request.post({ url: '/interphone/open-api/group/queryMonitorGroup', data }).then(res =>JSON.parse(res))
}
// 添加监听群组
export const addMonitorGroup = (data: AddMonitorGroupData) => {
return request.post({ url: '/interphone/open-api/group/addMonitorGroup', data }).then(res =>JSON.parse(res))
}
// 移除监听群组
export const removeMonitorGroup = (data: RemoveMonitorGroupData) => {
return request.post({ url: '/interphone/open-api/group/MonitorGroup', data }).then(res =>JSON.parse(res))
}
// 查询群组名称
export const getGroupName = (params: { orgId: string; isactive?: string })=> {
return request.get({ url: '/interphone/open-api/group/getGroupName', params }).then(res =>JSON.parse(res))
}

65
web/src/api/interphone/location.ts

@ -0,0 +1,65 @@
import request from '@/config/axios'
import type { CommonResult } from './types'
/**
*
*/
// 定位信息
export interface Location {
id?: string
user_id?: string
latitude?: number
longitude?: number
address?: string
createTime?: string
[key: string]: any
}
// 查询定位参数
export interface GetLocationParams {
id: string
}
// 批量定位参数
export interface BatchLocationData {
ids: string[]
}
// 定位列表参数
export interface LocationListParams {
pageNo: number
pageSize: number
user_id: string
}
// 导出轨迹参数
export interface ExportTrackParams {
user_id: string
start: string
end: string
}
/**
*
*/
// 查询定位
export const getLocation = (id: string) => {
return request.get<CommonResult>({ url: '/interphone/open-api/location/locat', params: { id } })
}
// 批量定位
export const batchLocation = (data: BatchLocationData) => {
return request.post<CommonResult>({ url: '/interphone/open-api/location/locatBatch', data })
}
// 定位列表
export const getLocationList = (params: LocationListParams) => {
return request.get<CommonResult>({ url: '/interphone/open-api/location/locatList', params })
}
// 导出轨迹
export const exportTrack = (params: ExportTrackParams) => {
return request.get<CommonResult>({ url: '/interphone/open-api/location/locatExport', params })
}

45
web/src/api/interphone/log.ts

@ -0,0 +1,45 @@
import request from '@/config/axios'
import type { CommonResult } from './types'
/**
*
*/
// 日志信息
export interface Log {
id?: string
type?: string
content?: string
createTime?: string
[key: string]: any
}
// 操作日志参数
export interface LogListParams {
pageNo: number
pageSize: number
type?: string
start?: string
end?: string
}
// 导出日志参数
export interface ExportLogParams {
type?: string
start?: string
end?: string
}
/**
*
*/
// 操作日志
export const getLogList = (params: LogListParams) => {
return request.get<CommonResult>({ url: '/interphone/open-api/log/list', params })
}
// 导出日志
export const exportLog = (params: ExportLogParams) => {
return request.get<CommonResult>({ url: '/interphone/open-api/log/export', params })
}

41
web/src/api/interphone/notice.ts

@ -0,0 +1,41 @@
import request from '@/config/axios'
import type { CommonResult } from './types'
/**
*
*/
// 通知信息
export interface Notice {
id?: string
type?: string
content?: string
createTime?: string
[key: string]: any
}
// 通知列表参数
export interface NoticeListData {
type?: string
startDate?: string
endDate?: string
}
// 未读数参数
export interface UnreadCountParams {
agentId: string
}
/**
*
*/
// 通知列表
export const getNoticeList = (data: NoticeListData) => {
return request.post<CommonResult>({ url: '/interphone/open-api/notice/getNotice', data })
}
// 未读数
export const getUnreadCount = (params: UnreadCountParams) => {
return request.get<CommonResult>({ url: '/interphone/open-api/notice/newUnreadCount', params })
}

85
web/src/api/interphone/org.ts

@ -0,0 +1,85 @@
import request from '@/config/axios'
import type { CommonResult } from './types'
/**
*
*/
// 单位信息
export interface Org {
id?: string
name?: string
loginname?: string
contact?: string
phone?: string
address?: string
isDefault?: string
defaultName?: string
[key: string]: any
}
// 查询单位列表参数
export interface OrgListParams {
pageNo: number
pageSize: number
name?: string
}
// 添加单位参数
export interface AddOrgData {
name: string
loginname: string
password: string
contact?: string
phone?: string
address?: string
isDefault?: string
defaultName?: string
}
// 修改单位参数
export interface UpdateOrgData {
id: string
corgName?: string
contact?: string
address?: string
}
// 删除单位参数
export interface DeleteOrgData {
id: string
}
/**
*
*/
// 查询单位列表
export const getOrgList = (params: OrgListParams) => {
return request.get({ url: '/interphone/open-api/agent/orgs', params }).then(res =>JSON.parse(res))
}
// 添加单位
export const addOrg = (data: AddOrgData) => {
return request.post({ url: '/interphone/open-api/org/add', data }).then(res =>JSON.parse(res))
}
// 修改单位
export const updateOrg = (data: UpdateOrgData) => {
return request.post({ url: '/interphone/open-api/org/xiugaiUnit', data }).then(res =>JSON.parse(res))
}
// 删除单位
export const deleteOrg = (data: DeleteOrgData) => {
return request.post({ url: '/interphone/open-api/org/deletingUnit', data }).then(res =>JSON.parse(res))
}
// 查询单位详情
export const getOrgDetail = (id: string) => {
return request.get({ url: '/interphone/open-api/org/info', params: { id } }).then(res =>JSON.parse(res))
}
// 获取单位名称
export const getOrgName = (agentId: string) => {
return request.get({ url: '/interphone/open-api/org/getOrgName', params: { agentId } }).then(res =>JSON.parse(res))
}

71
web/src/api/interphone/profile.ts

@ -0,0 +1,71 @@
import request from '@/config/axios'
import type { CommonResult } from './types'
/**
*
*/
// 统计信息
export interface FastStats {
agentCount?: number
orgCount?: number
groupCount?: number
userCount?: number
[key: string]: any
}
// 代理商个人信息
export interface AgentProfile {
id?: string
name?: string
[key: string]: any
}
// 单位个人信息
export interface OrgProfile {
id?: string
name?: string
[key: string]: any
}
// 修改密码参数
export interface UpdatePasswordData {
oldpwd: string
newpwd: string
}
// 修改代理商信息参数
export interface UpdateAgentInfoData {
agentId: string
contact?: string
provinceid?: string
}
/**
*
*/
// 查询代理商单位群组用户统计
export const getFastStats = () => {
return request.get<CommonResult<FastStats>>({ url: '/interphone/open-api/profile/faststats' })
}
// 获取代理商个人信息
export const getAgentProfile = () => {
return request.get<CommonResult<AgentProfile>>({ url: '/interphone/open-api/profile/agent' })
}
// 获取单位个人信息
export const getOrgProfile = () => {
return request.get<CommonResult<OrgProfile>>({ url: '/interphone/open-api/profile/org' })
}
// 修改密码
export const updatePassword = (data: UpdatePasswordData) => {
return request.post<CommonResult>({ url: '/interphone/open-api/profile/password', data })
}
// 修改代理商信息
export const updateAgentInfo = (data: UpdateAgentInfoData) => {
return request.post<CommonResult>({ url: '/interphone/open-api/agent/ModifyingAgentInformation', data })
}

44
web/src/api/interphone/record.ts

@ -0,0 +1,44 @@
import request from '@/config/axios'
import type { CommonResult } from './types'
/**
*
*/
// 录音信息
export interface SoundRecord {
id?: string
orgId?: string
groupId?: string
userId?: string
startDate?: string
[key: string]: any
}
// 查询录音列表参数
export interface RecordListParams {
pageNo?: number
pageSize?: number
[key: string]: any
}
// 查询录音参数
export interface QuerySoundRecordParams {
orgId?: string
groupId?: string
startDate?: string
}
/**
*
*/
// 查询录音列表
export const getRecordList = (params: RecordListParams) => {
return request.get<CommonResult>({ url: '/interphone/open-api/record/list', params })
}
// 录音查询
export const querySoundRecord = (params: QuerySoundRecordParams) => {
return request.get<CommonResult>({ url: '/interphone/open-api/soundRecord/querySoundRecord', params })
}

223
web/src/api/interphone/terminal.ts

@ -0,0 +1,223 @@
import request from '@/config/axios'
import type { CommonResult } from './types'
/**
*
*/
// 对讲用户信息
export interface TerminalUser {
id?: string
name?: string
userName?: string
account?: string
orgId?: string
orgid?: string
groupId?: string
groupid?: string
agentId?: string
imei?: string
userMobile?: string
beizhu?: string
enable?: string
userStatus?: string
audioStatus?: string
servicetype?: string
iccid?: string
userAudioStatus?: string
allowcall?: string
gpsSwitch?: string
user_type?: string
[key: string]: any
}
// 查询对讲用户列表参数
export interface TerminalListParams {
pageNo: number
pageSize: number
org_id?: string
groupid?: string
name?: string
userStatus?: string
audioStatus?: string
servicetype?: string
iccid?: string
serviceType?: string
createStartAt?: string
createEndAt?: string
}
// 导入Excel参数
export interface ImportExcelData {
file: File
}
// 判断用户存在参数
export interface CheckUserExistData {
imei: string
}
// 批量创建用户参数
export interface BatchCreateUsersData {
orgId: string
groups: string
prefix?: string
accounts: string
beizhu?: string
cardTypes?: string
}
// 修改用户信息参数
export interface UpdateTerminalUserData {
userId: string
beizhu?: string
orgid?: string
userName?: string
userMobile?: string
enable?: string
userAudioStatus?: string
allowcall?: string
gpsSwitch?: string
user_type?: string
}
// 遥开/遥毙参数
export interface UpdateUserVoiceData {
userlds: string[]
voice: string
}
// 暂停/开启账号参数
export interface UpdateUserEnableData {
userlds: string[]
enable: string
}
// 删除用户参数
export interface DeleteTerminalUserData {
userlds: string[]
}
// 换号参数
export interface ChangeCardData {
oldAccount: string
newAccount: string
}
// 导出未登录参数
export interface ExportUserInfoParams {
agentId: string
dateType: string
platform?: string
}
// 开通服务参数
export interface AddServiceParams {
userids: string
type: string
dateType: string
}
// 删除服务参数
export interface DeleteServiceParams {
userids: string
type: string
}
// 服务列表参数
export interface ServiceListParams {
pageNo: number
pageSize: number
user_id: string
}
// 修改服务参数
export interface UpdateServiceParams {
user_id: string
type: string
dateType: string
}
/**
*
*/
// 导入Excel
export const importExcel = (data: ImportExcelData) => {
return request.post({ url: '/interphone/open-api/terminal/analysisExcel', data }).then(res =>JSON.parse(res))
}
// 判断用户存在
export const checkUserExist = (data: CheckUserExistData) => {
return request.post({ url: '/interphone/open-api/terminal/isAddUser', data }).then(res =>JSON.parse(res))
}
// 批量创建用户
export const batchCreateUsers = (data: BatchCreateUsersData) => {
return request.post({ url: '/interphone/open-api/terminal/batch', data }).then(res =>JSON.parse(res))
}
// 查询对讲用户列表
export const getTerminalList = (params: TerminalListParams) => {
return request.get({ url: '/interphone/open-api/terminal/list', params }).then(res =>JSON.parse(res))
}
// 查询对讲用户详情
export const getTerminalDetail = (id: string) => {
return request.get({ url: '/interphone/open-api/terminal/detail', params: { id } }).then(res =>JSON.parse(res))
}
// 查询对讲用户在线状态
export const getTerminalUserOnlineStatus = (params: Record<string, any>) => {
return request.get({ url: '/interphone/open-api/terminal/userOnlineStatus', params }).then(res =>JSON.parse(res))
}
// 修改用户信息
export const updateTerminalUser = (data: UpdateTerminalUserData) => {
return request.post({ url: '/interphone/open-api/terminal/updateUser', data }).then(res =>JSON.parse(res))
}
// 遥开/遥毙
export const updateUserVoice = (data: UpdateUserVoiceData) => {
return request.post({ url: '/interphone/open-api/terminal/updateUserVoice', data }).then(res =>JSON.parse(res))
}
// 暂停/开启账号
export const updateUserEnable = (data: UpdateUserEnableData) => {
return request.post({ url: '/interphone/open-api/terminal/updateUserEnable', data }).then(res =>JSON.parse(res))
}
// 删除用户
export const deleteTerminalUser = (data: DeleteTerminalUserData) => {
return request.post({ url: '/interphone/open-api/terminal/deleteUser', data }).then(res =>JSON.parse(res))
}
// 换号
export const changeCard = (data: ChangeCardData) => {
return request.post({ url: '/interphone/open-api/terminal/changecard', data }).then(res =>JSON.parse(res))
}
// 导出未登录
export const exportUserInfo = (params: ExportUserInfoParams) => {
return request.get({ url: '/interphone/open-api/terminal/exportUserInfo', params }).then(res =>JSON.parse(res))
}
// 开通服务
export const addService = (params: AddServiceParams) => {
return request.get({ url: '/interphone/open-api/terminal/addService', params }).then(res =>JSON.parse(res))
}
// 删除服务
export const deleteService = (params: DeleteServiceParams) => {
return request.get({ url: '/interphone/open-api/terminal/deleteService', params }).then(res =>JSON.parse(res))
}
// 服务列表
export const getServiceList = (params: ServiceListParams) => {
return request.get({ url: '/interphone/open-api/terminal/serviceList', params }).then(res =>JSON.parse(res))
}
// 修改服务
export const updateService = (params: UpdateServiceParams) => {
return request.get({ url: '/interphone/open-api/terminal/updateService', params }).then(res =>JSON.parse(res))
}

10
web/src/api/interphone/types.ts

@ -0,0 +1,10 @@
/**
* -
*/
// 通用返回结果
export interface CommonResult<T = any> {
code: number
data: T
msg: string
}

105
web/src/views/interphone/agent/AgentBalanceDialog.vue

@ -0,0 +1,105 @@
<template>
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="500px">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
<el-form-item label="类型" prop="chargetype" v-if="balanceType === 'add'">
<el-select v-model="formData.chargetype" placeholder="请选择充值类型" class="!w-full">
<el-option label="类型1" value="1" />
<el-option label="类型2" value="2" />
</el-select>
</el-form-item>
<el-form-item label="卡类型" prop="cardType" v-if="balanceType === 'recovery'">
<el-select v-model="formData.cardType" placeholder="请选择卡类型" class="!w-full">
<el-option label="卡类型1" value="1" />
<el-option label="卡类型2" value="2" />
</el-select>
</el-form-item>
<el-form-item label="数量" prop="count">
<el-input-number v-model="formData.count" :min="1" placeholder="请输入数量" class="!w-full" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm" :loading="formLoading">确定</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { addAgentBalance, cardRecovery } from '@/api/interphone/agent'
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const balanceType = ref<'add' | 'recovery'>('add') // add - recovery -
const formLoading = ref(false) //
const formData = ref<any>({
agentId: '',
chargetype: '',
cardType: '',
count: 1
})
const formRules = {
chargetype: [{ required: true, message: '请选择充值类型', trigger: 'change' }],
cardType: [{ required: true, message: '请选择卡类型', trigger: 'change' }],
count: [{ required: true, message: '请输入数量', trigger: 'blur' }]
}
const formRef = ref() // Ref
/** 打开弹窗 */
const open = (id: string, type: 'add' | 'recovery') => {
balanceType.value = type
dialogTitle.value = type === 'add' ? '点卡充值' : '点卡收回'
formData.value = {
agentId: id,
chargetype: '',
cardType: '',
count: 1
}
dialogVisible.value = true
}
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
if (!formRef.value) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
let res
if (balanceType.value === 'add') {
res = await addAgentBalance({
agentId: formData.value.agentId,
chargetype: formData.value.chargetype,
count: formData.value.count
})
} else {
res = await cardRecovery({
agentId: formData.value.agentId,
cardType: formData.value.cardType,
recoveryNumber: formData.value.count
})
}
if (res.code === 20001) {
message.success(balanceType.value === 'add' ? '充值成功' : '收回成功')
dialogVisible.value = false
//
emit('success')
} else {
message.error(res.msg || '操作失败')
}
} catch (error) {
console.error('操作失败:', error)
message.error('操作失败')
} finally {
formLoading.value = false
}
}
defineExpose({ open }) // open
</script>

58
web/src/views/interphone/agent/AgentDetail.vue

@ -0,0 +1,58 @@
<template>
<el-dialog v-model="dialogVisible" title="代理商详情" width="800px">
<el-descriptions :column="2" border v-loading="loading">
<el-descriptions-item label="代理商ID">
{{ detailData.id || '-' }}
</el-descriptions-item>
<el-descriptions-item label="代理商名称">
{{ detailData.name || '-' }}
</el-descriptions-item>
<el-descriptions-item label="登录账号">
{{ detailData.loginname || '-' }}
</el-descriptions-item>
<el-descriptions-item label="联系人">
{{ detailData.contact || '-' }}
</el-descriptions-item>
<el-descriptions-item label="地址">
{{ detailData.address || '-' }}
</el-descriptions-item>
<el-descriptions-item label="创建时间">
{{ detailData.createTime || '-' }}
</el-descriptions-item>
</el-descriptions>
<template #footer>
<el-button @click="dialogVisible = false">关闭</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import { getAgentDetail, type Agent } from '@/api/interphone/agent'
const message = useMessage() //
const dialogVisible = ref(false) //
const loading = ref(false) //
const detailData = ref<Agent>({}) //
/** 打开弹窗 */
const open = async (id: string) => {
dialogVisible.value = true
loading.value = true
try {
const res = await getAgentDetail(id)
if (res.code === 20001) {
detailData.value = res.data || {}
} else {
message.error(res.msg || '获取代理商详情失败')
}
} catch (error) {
console.error('获取代理商详情失败:', error)
message.error('获取代理商详情失败')
} finally {
loading.value = false
}
}
defineExpose({ open }) // open
</script>

142
web/src/views/interphone/agent/AgentForm.vue

@ -0,0 +1,142 @@
<template>
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-form-item label="代理商名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入代理商名称" />
</el-form-item>
<el-form-item label="登录账号" prop="loginname" v-if="formType === 'create'">
<el-input v-model="formData.loginname" placeholder="请输入登录账号" />
</el-form-item>
<el-form-item label="密码" prop="password" v-if="formType === 'create'">
<el-input v-model="formData.password" type="password" placeholder="请输入密码" show-password />
</el-form-item>
<el-form-item label="联系人" prop="contact">
<el-input v-model="formData.contact" placeholder="请输入联系人" />
</el-form-item>
<el-form-item label="地址" prop="address">
<el-input v-model="formData.address" placeholder="请输入地址" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm" :loading="formLoading">确定</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import {
getAgentDetail,
addAgent,
updateAgent,
type AddAgentData,
type UpdateAgentData
} from '@/api/interphone/agent'
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref<'create' | 'update'>('create') // create - update -
const formData = ref<any>({
name: '',
loginname: '',
password: '',
contact: '',
address: '',
agentId: ''
})
const formRules = {
name: [{ required: true, message: '请输入代理商名称', trigger: 'blur' }],
loginname: [{ required: true, message: '请输入登录账号', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
}
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (type: 'create' | 'update', id?: string) => {
dialogVisible.value = true
dialogTitle.value = type === 'create' ? '新增代理商' : '编辑代理商'
formType.value = type
resetForm()
//
if (type === 'update' && id) {
formLoading.value = true
try {
const res = await getAgentDetail(id)
if (res.code === 20001) {
formData.value = {
...res.data,
agentId: res.data.id
}
} else {
message.error(res.msg || '获取代理商详情失败')
dialogVisible.value = false
}
} catch (error) {
console.error('获取代理商详情失败:', error)
message.error('获取代理商详情失败')
dialogVisible.value = false
} finally {
formLoading.value = false
}
}
}
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
if (!formRef.value) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
let res
if (formType.value === 'create') {
res = await addAgent(formData.value as AddAgentData)
} else {
res = await updateAgent(formData.value as UpdateAgentData)
}
if (res.code === 20001) {
message.success(formType.value === 'create' ? '新增成功' : '修改成功')
dialogVisible.value = false
//
emit('success')
} else {
message.error(res.msg || '操作失败')
}
} catch (error) {
console.error('操作失败:', error)
message.error('操作失败')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
name: '',
loginname: '',
password: '',
contact: '',
address: '',
agentId: ''
}
formRef.value?.resetFields()
}
defineExpose({ open }) // open
</script>

161
web/src/views/interphone/agent/index.vue

@ -0,0 +1,161 @@
<template>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="120px"
>
<el-form-item label="代理商名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入代理商名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button type="primary" plain @click="openForm('create')">
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
row-key="id"
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
>
<el-table-column label="代理商ID" align="center" prop="id" min-width="120px" />
<el-table-column label="代理商名称" align="center" prop="name" min-width="150px" />
<el-table-column label="登录账号" align="center" prop="loginname" min-width="120px" />
<el-table-column label="联系人" align="center" prop="contact" min-width="100px" />
<el-table-column label="地址" align="center" prop="address" min-width="150px" />
<el-table-column label="创建时间" align="center" prop="createTime" min-width="160px">
<template #default="scope">
{{ scope.row.createTime || '-' }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" min-width="240px" fixed="right">
<template #default="scope">
<el-button link type="primary" @click="handleDetail(scope.row.id)">
详情
</el-button>
<el-button link type="primary" @click="openForm('update', scope.row.id)">
编辑
</el-button>
<el-button link type="success" @click="openBalance(scope.row.id, 'add')">
充值
</el-button>
<el-button link type="warning" @click="openBalance(scope.row.id, 'recovery')">
收回
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<AgentForm ref="formRef" @success="getList" />
<!-- 详情弹窗 -->
<AgentDetail ref="detailRef" />
<!-- 点卡充值/收回弹窗 -->
<AgentBalanceDialog ref="balanceRef" @success="getList" />
</template>
<script setup lang="ts">
import { getAgentList, type AgentListParams, type Agent } from '@/api/interphone/agent'
import AgentForm from './AgentForm.vue'
import AgentDetail from './AgentDetail.vue'
import AgentBalanceDialog from './AgentBalanceDialog.vue'
/** 代理商列表 */
defineOptions({ name: 'InterphoneAgent' })
const message = useMessage() //
const loading = ref(true) //
const list = ref<Agent[]>([]) //
const total = ref(0) //
const queryParams = reactive<AgentListParams>({
pageNo: 1,
pageSize: 10,
name: undefined
})
const queryFormRef = ref() //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const res = await getAgentList(queryParams)
console.log(res)
if (res.code === 20001) {
list.value = res.data?.data || []
total.value = res.data?.recordsFiltered || 0
} else {
message.error(res.msg || '获取代理商列表失败')
}
} catch (error) {
console.error('获取代理商列表失败:', error)
message.error('获取代理商列表失败')
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: 'create' | 'update', id?: string) => {
formRef.value.open(type, id)
}
/** 查看详情 */
const detailRef = ref()
const handleDetail = (id: string) => {
detailRef.value.open(id)
}
/** 点卡充值/收回 */
const balanceRef = ref()
const openBalance = (id: string, type: 'add' | 'recovery') => {
balanceRef.value.open(id, type)
}
/** 初始化 **/
onMounted(() => {
getList()
})
</script>

179
web/src/views/interphone/group/GroupForm.vue

@ -0,0 +1,179 @@
<template>
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="120px"
v-loading="formLoading"
>
<el-form-item label="所属机构" prop="orgid">
<el-select
v-model="formData.orgid"
placeholder="请选择所属机构"
filterable
class="!w-full"
:disabled="formType === 'update'"
>
<el-option
v-for="org in orgList"
:key="org.id"
:label="org.name"
:value="org.id"
/>
</el-select>
</el-form-item>
<el-form-item label="群组名称" prop="cgName">
<el-input v-model="formData.cgName" placeholder="请输入群组名称" />
</el-form-item>
<el-form-item label="发言时长限制" prop="cg_speech_limit_second">
<el-input-number
v-model="formData.cg_speech_limit_second"
:min="0"
:max="3600"
placeholder="请输入发言时长限制(秒)"
class="!w-full"
/>
<span class="ml-10px text-gray-500"></span>
</el-form-item>
<el-form-item label="备注" prop="remarks">
<el-input
v-model="formData.remarks"
type="textarea"
:rows="3"
placeholder="请输入备注"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm" :loading="formLoading">确定</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import {
getGroupDetail,
addGroup,
updateGroup,
type AddGroupData,
type UpdateGroupData
} from '@/api/interphone/group'
import { getOrgList, type Org } from '@/api/interphone/org'
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) //
const formType = ref<'create' | 'update'>('create') //
const orgList = ref<Org[]>([]) //
const formData = ref<any>({
orgid: '',
cgName: '',
cg_speech_limit_second: 60,
remarks: ''
})
const formRules = {
orgid: [{ required: true, message: '请选择所属机构', trigger: 'change' }],
cgName: [{ required: true, message: '请输入群组名称', trigger: 'blur' }]
}
const formRef = ref() // Ref
/** 获取机构列表 */
const getOrgOptions = async () => {
try {
const res = await getOrgList({ pageNo: 1, pageSize: 1000 })
if (res.code === 20001) {
orgList.value = res.data?.data || []
}
} catch (error) {
console.error('获取机构列表失败:', error)
}
}
/** 打开弹窗 */
const open = async (type: 'create' | 'update', id?: string) => {
dialogVisible.value = true
dialogTitle.value = type === 'create' ? '新增群组' : '编辑群组'
formType.value = type
resetForm()
//
await getOrgOptions()
//
if (type === 'update' && id) {
formLoading.value = true
try {
const res = await getGroupDetail(id)
if (res.code === 20001) {
formData.value = {
id: res.data.id,
orgid: res.data.orgId,
cgName: res.data.name,
cg_speech_limit_second: res.data.cg_speech_limit_second || 60,
remarks: res.data.remarks || ''
}
} else {
message.error(res.msg || '获取群组详情失败')
dialogVisible.value = false
}
} catch (error) {
console.error('获取群组详情失败:', error)
message.error('获取群组详情失败')
dialogVisible.value = false
} finally {
formLoading.value = false
}
}
}
/** 提交表单 */
const emit = defineEmits(['success'])
const submitForm = async () => {
//
if (!formRef.value) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
let res
if (formType.value === 'create') {
res = await addGroup(formData.value as AddGroupData)
} else {
res = await updateGroup(formData.value as UpdateGroupData)
}
if (res.code === 20001) {
message.success(formType.value === 'create' ? '新增成功' : '修改成功')
dialogVisible.value = false
emit('success')
} else {
message.error(res.msg || '操作失败')
}
} catch (error) {
console.error('操作失败:', error)
message.error('操作失败')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
orgid: '',
cgName: '',
cg_speech_limit_second: 60,
remarks: ''
}
formRef.value?.resetFields()
}
defineExpose({ open })
</script>

166
web/src/views/interphone/group/index.vue

@ -0,0 +1,166 @@
<template>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="100px"
>
<el-form-item label="群组名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入群组名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="所属机构" prop="orgname">
<el-input
v-model="queryParams.orgname"
placeholder="请输入所属机构"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button type="primary" plain @click="openForm('create')">
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
row-key="id"
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
>
<el-table-column label="群组名称" align="center" prop="name" min-width="150px" />
<el-table-column label="所属机构" align="center" prop="orgname" min-width="150px" />
<el-table-column label="群组类型" align="center" prop="type" min-width="100px" />
<el-table-column label="发言时长限制(秒)" align="center" prop="cg_speech_limit_second" min-width="140px">
<template #default="scope">
{{ scope.row.cg_speech_limit_second ?? '-' }}
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remarks" min-width="200px">
<template #default="scope">
{{ scope.row.remarks || '-' }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" min-width="150px" fixed="right">
<template #default="scope">
<el-button link type="primary" @click="openForm('update', scope.row.id)">
编辑
</el-button>
<el-button link type="danger" @click="handleDelete(scope.row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<GroupForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts">
import { getGroupList, deleteGroup, type GroupListParams, type Group } from '@/api/interphone/group'
import GroupForm from './GroupForm.vue'
/** 群组管理 */
defineOptions({ name: 'InterphoneGroup' })
const message = useMessage() //
const loading = ref(true) //
const list = ref<Group[]>([]) //
const total = ref(0) //
const queryParams = reactive<GroupListParams>({
pageNo: 1,
pageSize: 10,
name: undefined,
orgname: undefined
})
const queryFormRef = ref() //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const res = await getGroupList(queryParams)
if (res.code === 20001) {
list.value = res.data || []
total.value = res.count || 0
} else {
message.error(res.msg || '获取群组列表失败')
}
} catch (error) {
console.error('获取群组列表失败:', error)
message.error('获取群组列表失败')
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: 'create' | 'update', id?: string) => {
formRef.value.open(type, id)
}
/** 删除按钮操作 */
const handleDelete = async (id: string) => {
try {
await message.delConfirm('确定要删除该群组吗?')
const res = await deleteGroup({ id })
if (res.code === 20001) {
message.success('删除成功')
await getList()
} else {
message.error(res.msg || '删除失败')
}
} catch (error) {
if (error !== 'cancel') {
console.error('删除群组失败:', error)
message.error('删除失败')
}
}
}
/** 初始化 **/
onMounted(() => {
getList()
})
</script>

167
web/src/views/interphone/org/OrgForm.vue

@ -0,0 +1,167 @@
<template>
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
:disabled="formType === 'detail'"
>
<el-form-item label="单位名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入单位名称" />
</el-form-item>
<el-form-item label="登录账号" prop="loginname" v-if="formType === 'create'">
<el-input v-model="formData.loginname" placeholder="请输入登录账号" />
</el-form-item>
<el-form-item label="密码" prop="password" v-if="formType === 'create'">
<el-input v-model="formData.password" type="password" placeholder="请输入密码" show-password />
</el-form-item>
<el-form-item label="联系人" prop="contact">
<el-input v-model="formData.contact" placeholder="请输入联系人" />
</el-form-item>
<el-form-item label="联系电话" prop="phone">
<el-input v-model="formData.phone" placeholder="请输入联系电话" />
</el-form-item>
<el-form-item label="地址" prop="address">
<el-input v-model="formData.address" placeholder="请输入地址" />
</el-form-item>
<el-form-item label="是否默认" prop="isDefault">
<el-select v-model="formData.isDefault" placeholder="请选择是否默认" class="!w-full">
<el-option label="是" value="1" />
<el-option label="否" value="0" />
</el-select>
</el-form-item>
<el-form-item label="默认名称" prop="defaultName" v-if="formData.isDefault === '1'">
<el-input v-model="formData.defaultName" placeholder="请输入默认名称" />
</el-form-item>
</el-form>
<template #footer v-if="formType !== 'detail'">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm" :loading="formLoading">确定</el-button>
</template>
<template #footer v-else>
<el-button @click="dialogVisible = false">关闭</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import {
getOrgDetail,
addOrg,
updateOrg,
type Org,
type AddOrgData,
type UpdateOrgData
} from '@/api/interphone/org'
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) // 12
const formType = ref<'create' | 'update' | 'detail'>('create') // create - update - detail -
const formData = ref<any>({
id: undefined,
name: '',
loginname: '',
password: '',
contact: '',
phone: '',
address: '',
isDefault: '0',
defaultName: ''
})
const formRules = {
name: [{ required: true, message: '请输入单位名称', trigger: 'blur' }],
loginname: [{ required: true, message: '请输入登录账号', trigger: 'blur' }],
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
}
const formRef = ref() // Ref
/** 打开弹窗 */
const open = async (type: 'create' | 'update' | 'detail', id?: string) => {
dialogVisible.value = true
dialogTitle.value = type === 'create' ? '新增单位' : type === 'update' ? '编辑单位' : '单位详情'
formType.value = type
resetForm()
//
if (id) {
formLoading.value = true
try {
const res = await getOrgDetail(id)
if (res.code === 0) {
formData.value = { ...res.data }
} else {
message.error(res.msg || '获取单位详情失败')
dialogVisible.value = false
}
} catch (error) {
console.error('获取单位详情失败:', error)
message.error('获取单位详情失败')
dialogVisible.value = false
} finally {
formLoading.value = false
}
}
}
/** 提交表单 */
const emit = defineEmits(['success']) // success
const submitForm = async () => {
//
if (!formRef.value) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
let res
if (formType.value === 'create') {
res = await addOrg(formData.value as AddOrgData)
} else {
res = await updateOrg({
id: formData.value.id,
corgName: formData.value.name,
contact: formData.value.contact,
address: formData.value.address
} as UpdateOrgData)
}
if (res.code === 0) {
message.success(formType.value === 'create' ? '新增成功' : '修改成功')
dialogVisible.value = false
//
emit('success')
} else {
message.error(res.msg || '操作失败')
}
} catch (error) {
console.error('操作失败:', error)
message.error('操作失败')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
id: undefined,
name: '',
loginname: '',
password: '',
contact: '',
phone: '',
address: '',
isDefault: '0',
defaultName: ''
}
formRef.value?.resetFields()
}
defineExpose({ open }) // open
</script>

160
web/src/views/interphone/org/index.vue

@ -0,0 +1,160 @@
<template>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="80px"
>
<el-form-item label="单位名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入单位名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
<el-button type="primary" plain @click="openForm('create')">
<Icon icon="ep:plus" class="mr-5px" /> 新增
</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
row-key="id"
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
>
<el-table-column label="单位ID" align="center" prop="id" min-width="120px" />
<el-table-column label="单位名称" align="center" prop="name" min-width="150px" />
<el-table-column label="登录账号" align="center" prop="loginname" min-width="120px" />
<el-table-column label="联系人" align="center" prop="contact" min-width="100px" />
<el-table-column label="联系电话" align="center" prop="phone" min-width="120px" />
<el-table-column label="地址" align="center" prop="address" min-width="150px" />
<el-table-column label="创建时间" align="center" prop="createTime" min-width="160px">
<template #default="scope">
{{ scope.row.createTime || '-' }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" min-width="200px" fixed="right">
<template #default="scope">
<el-button link type="primary" @click="handleDetail(scope.row.id)">
详情
</el-button>
<el-button link type="primary" @click="openForm('update', scope.row.id)">
编辑
</el-button>
<el-button link type="danger" @click="handleDelete(scope.row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗添加/修改 -->
<OrgForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts">
import { getOrgList, deleteOrg, type OrgListParams, type Org } from '@/api/interphone/org'
import OrgForm from './OrgForm.vue'
/** 单位管理列表 */
defineOptions({ name: 'InterphoneOrg' })
const message = useMessage() //
const loading = ref(true) //
const list = ref<Org[]>([]) //
const total = ref(0) //
const queryParams = reactive<OrgListParams>({
pageNo: 1,
pageSize: 10,
name: undefined
})
const queryFormRef = ref() //
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const res = await getOrgList(queryParams)
if (res.code === 20001) {
list.value = res.data || []
total.value = res.count || 0
} else {
message.error(res.msg || '获取单位列表失败')
}
} catch (error) {
console.error('获取单位列表失败:', error)
message.error('获取单位列表失败')
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: string) => {
formRef.value.open(type, id)
}
/** 删除按钮操作 */
const handleDelete = async (id: string) => {
try {
//
await message.delConfirm()
//
const res = await deleteOrg({ id })
if (res.code === 20001) {
message.success('删除成功')
//
await getList()
} else {
message.error(res.msg || '删除失败')
}
} catch {}
}
/** 查看详情 */
const handleDetail = (id: string) => {
openForm('detail', id)
}
/** 初始化 **/
onMounted(() => {
getList()
})
</script>

209
web/src/views/interphone/terminal/TerminalForm.vue

@ -0,0 +1,209 @@
<template>
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="700px">
<el-form
ref="formRef"
:model="formData"
:rules="formRules"
label-width="100px"
v-loading="formLoading"
>
<el-form-item label="用户名称" prop="userName">
<el-input v-model="formData.userName" placeholder="请输入用户名称" />
</el-form-item>
<el-form-item label="所属机构" prop="orgid">
<el-select
v-model="formData.orgid"
placeholder="请选择所属机构"
filterable
class="!w-full"
>
<el-option
v-for="org in orgList"
:key="org.id"
:label="org.name"
:value="org.id"
/>
</el-select>
</el-form-item>
<el-form-item label="手机号" prop="userMobile">
<el-input v-model="formData.userMobile" placeholder="请输入手机号" />
</el-form-item>
<el-form-item label="账号状态" prop="enable">
<el-radio-group v-model="formData.enable">
<el-radio label="1">启用</el-radio>
<el-radio label="0">禁用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="语音状态" prop="userAudioStatus">
<el-radio-group v-model="formData.userAudioStatus">
<el-radio label="1">开启</el-radio>
<el-radio label="0">关闭</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="允许通话" prop="allowcall">
<el-radio-group v-model="formData.allowcall">
<el-radio label="1">允许</el-radio>
<el-radio label="0">禁止</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="GPS开关" prop="gpsSwitch">
<el-radio-group v-model="formData.gpsSwitch">
<el-radio label="1">开启</el-radio>
<el-radio label="0">关闭</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="用户类型" prop="user_type">
<el-select v-model="formData.user_type" placeholder="请选择用户类型" class="!w-full">
<el-option label="普通用户" value="normal" />
<el-option label="管理员" value="admin" />
</el-select>
</el-form-item>
<el-form-item label="备注" prop="beizhu">
<el-input
v-model="formData.beizhu"
type="textarea"
:rows="3"
placeholder="请输入备注"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm" :loading="formLoading">确定</el-button>
</template>
</el-dialog>
</template>
<script setup lang="ts">
import {
getTerminalDetail,
updateTerminalUser,
type UpdateTerminalUserData
} from '@/api/interphone/terminal'
import { getOrgList, type Org } from '@/api/interphone/org'
const message = useMessage() //
const dialogVisible = ref(false) //
const dialogTitle = ref('') //
const formLoading = ref(false) //
const orgList = ref<Org[]>([]) //
const formData = ref<any>({
userId: '',
userName: '',
orgid: '',
userMobile: '',
enable: '1',
userAudioStatus: '1',
allowcall: '1',
gpsSwitch: '1',
user_type: 'normal',
beizhu: ''
})
const formRules = {
userName: [{ required: true, message: '请输入用户名称', trigger: 'blur' }],
orgid: [{ required: true, message: '请选择所属机构', trigger: 'change' }]
}
const formRef = ref() // Ref
/** 获取机构列表 */
const getOrgOptions = async () => {
try {
const res = await getOrgList({ pageNo: 1, pageSize: 1000 })
if (res.code === 20001) {
orgList.value = res.data?.data || []
}
} catch (error) {
console.error('获取机构列表失败:', error)
}
}
/** 打开弹窗 */
const open = async (type: 'create' | 'update', id?: string) => {
dialogVisible.value = true
dialogTitle.value = type === 'create' ? '新增终端用户' : '编辑终端用户'
resetForm()
//
await getOrgOptions()
//
if (type === 'update' && id) {
formLoading.value = true
try {
const res = await getTerminalDetail(id)
if (res.code === 20001) {
formData.value = {
userId: res.data.id,
userName: res.data.userName || res.data.name,
orgid: res.data.orgId || res.data.orgid,
userMobile: res.data.userMobile || '',
enable: res.data.enable || '1',
userAudioStatus: res.data.userAudioStatus || '1',
allowcall: res.data.allowcall || '1',
gpsSwitch: res.data.gpsSwitch || '1',
user_type: res.data.user_type || 'normal',
beizhu: res.data.beizhu || ''
}
} else {
message.error(res.msg || '获取终端用户详情失败')
dialogVisible.value = false
}
} catch (error) {
console.error('获取终端用户详情失败:', error)
message.error('获取终端用户详情失败')
dialogVisible.value = false
} finally {
formLoading.value = false
}
}
}
/** 提交表单 */
const emit = defineEmits(['success'])
const submitForm = async () => {
//
if (!formRef.value) return
const valid = await formRef.value.validate()
if (!valid) return
//
formLoading.value = true
try {
const res = await updateTerminalUser(formData.value as UpdateTerminalUserData)
if (res.code === 20001) {
message.success('修改成功')
dialogVisible.value = false
emit('success')
} else {
message.error(res.msg || '操作失败')
}
} catch (error) {
console.error('操作失败:', error)
message.error('操作失败')
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
userId: '',
userName: '',
orgid: '',
userMobile: '',
enable: '1',
userAudioStatus: '1',
allowcall: '1',
gpsSwitch: '1',
user_type: 'normal',
beizhu: ''
}
formRef.value?.resetFields()
}
defineExpose({ open })
</script>

226
web/src/views/interphone/terminal/index.vue

@ -0,0 +1,226 @@
<template>
<ContentWrap>
<!-- 搜索工作栏 -->
<el-form
class="-mb-15px"
:model="queryParams"
ref="queryFormRef"
:inline="true"
label-width="100px"
>
<el-form-item label="用户名称" prop="name">
<el-input
v-model="queryParams.name"
placeholder="请输入用户名称"
clearable
@keyup.enter="handleQuery"
class="!w-240px"
/>
</el-form-item>
<el-form-item label="所属机构" prop="org_id">
<el-select
v-model="queryParams.org_id"
placeholder="请选择所属机构"
clearable
filterable
class="!w-240px"
>
<el-option
v-for="org in orgList"
:key="org.id"
:label="org.name"
:value="org.id"
/>
</el-select>
</el-form-item>
<el-form-item label="用户状态" prop="userStatus">
<el-select
v-model="queryParams.userStatus"
placeholder="请选择用户状态"
clearable
class="!w-240px"
>
<el-option label="在线" value="online" />
<el-option label="离线" value="offline" />
</el-select>
</el-form-item>
<el-form-item>
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
</el-form-item>
</el-form>
</ContentWrap>
<!-- 列表 -->
<ContentWrap>
<el-table
row-key="id"
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
>
<el-table-column label="用户名称" align="center" prop="name" min-width="120px" />
<el-table-column label="登录账号" align="center" prop="account" min-width="120px" />
<el-table-column label="所属机构" align="center" prop="orgName" min-width="150px">
<template #default="scope">
{{ scope.row.orgName || '-' }}
</template>
</el-table-column>
<el-table-column label="所属群组" align="center" prop="groupName" min-width="150px">
<template #default="scope">
{{ scope.row.groupName || '-' }}
</template>
</el-table-column>
<el-table-column label="IMEI" align="center" prop="imei" min-width="140px">
<template #default="scope">
{{ scope.row.imei || '-' }}
</template>
</el-table-column>
<el-table-column label="手机号" align="center" prop="userMobile" min-width="120px">
<template #default="scope">
{{ scope.row.userMobile || '-' }}
</template>
</el-table-column>
<el-table-column label="用户状态" align="center" prop="userStatus" min-width="100px">
<template #default="scope">
<el-tag v-if="scope.row.userStatus === 'online'" type="success">在线</el-tag>
<el-tag v-else type="info">离线</el-tag>
</template>
</el-table-column>
<el-table-column label="账号状态" align="center" prop="enable" min-width="100px">
<template #default="scope">
<el-tag v-if="scope.row.enable === '1'" type="success">启用</el-tag>
<el-tag v-else type="danger">禁用</el-tag>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="beizhu" min-width="150px">
<template #default="scope">
{{ scope.row.beizhu || '-' }}
</template>
</el-table-column>
<el-table-column label="操作" align="center" min-width="150px" fixed="right">
<template #default="scope">
<el-button link type="primary" @click="openForm('update', scope.row.id)">
编辑
</el-button>
<el-button link type="danger" @click="handleDelete(scope.row.id)">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination
:total="total"
v-model:page="queryParams.pageNo"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</ContentWrap>
<!-- 表单弹窗修改 -->
<TerminalForm ref="formRef" @success="getList" />
</template>
<script setup lang="ts">
import { getTerminalList, deleteTerminalUser, type TerminalListParams, type TerminalUser } from '@/api/interphone/terminal'
import { getOrgList, type Org } from '@/api/interphone/org'
import TerminalForm from './TerminalForm.vue'
/** 终端用户管理 */
defineOptions({ name: 'InterphoneTerminal' })
const message = useMessage() //
const loading = ref(true) //
const list = ref<TerminalUser[]>([]) //
const total = ref(0) //
const orgList = ref<Org[]>([]) //
const queryParams = reactive<TerminalListParams>({
pageNo: 1,
pageSize: 10,
name: undefined,
org_id: undefined,
userStatus: undefined
})
const queryFormRef = ref() //
/** 获取机构列表 */
const getOrgOptions = async () => {
try {
const res = await getOrgList({ pageNo: 1, pageSize: 1000 })
if (res.code === 20001) {
orgList.value = res.data?.data || []
}
} catch (error) {
console.error('获取机构列表失败:', error)
}
}
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
const res = await getTerminalList(queryParams)
console.log(res);
if (res.code === 20001) {
list.value = res.data?.data || []
total.value = res.data?.recordsFiltered || 0
} else {
message.error(res.msg || '获取终端用户列表失败')
}
} catch (error) {
console.error('获取终端用户列表失败:', error)
message.error('获取终端用户列表失败')
} finally {
loading.value = false
}
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.pageNo = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value.resetFields()
handleQuery()
}
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: 'create' | 'update', id?: string) => {
formRef.value.open(type, id)
}
/** 删除按钮操作 */
const handleDelete = async (id: string) => {
try {
await message.delConfirm('确定要删除该终端用户吗?')
const res = await deleteTerminalUser({ userlds: [id] })
if (res.code === 20001) {
message.success('删除成功')
await getList()
} else {
message.error(res.msg || '删除失败')
}
} catch (error) {
if (error !== 'cancel') {
console.error('删除终端用户失败:', error)
message.error('删除失败')
}
}
}
/** 初始化 **/
onMounted(async () => {
await getOrgOptions()
getList()
})
</script>
Loading…
Cancel
Save