feat: 更新和原型图一致
parent
6602e58d19
commit
1496a8b5b9
|
@ -7,5 +7,6 @@ NODE_ENV = 'development'
|
||||||
|
|
||||||
# 本地环境接口地址
|
# 本地环境接口地址
|
||||||
# 如果没有跨域问题,直接在这里配置即可
|
# 如果没有跨域问题,直接在这里配置即可
|
||||||
VITE_APP_BASE_API = 'http://192.168.1.116:8080'
|
# VITE_APP_BASE_API = 'http://192.168.1.116:8080'
|
||||||
|
VITE_APP_BASE_API = 'http://121.41.36.72:8080'
|
||||||
# VITE_APP_BASE_API = 'https://3lp9319797lh.vicp.fun'
|
# VITE_APP_BASE_API = 'https://3lp9319797lh.vicp.fun'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { PageRowsResult, PageRowsType } from '@/types';
|
import { PageRowsResult } from '@/types';
|
||||||
import { ApiManageType, StatisticsType } from '@/types/help';
|
import { ApiManagePageType, ApiManageType, StatisticsType } from '@/types/help';
|
||||||
import http from '@/utils/request';
|
import http from '@/utils/request';
|
||||||
|
|
||||||
// api接口
|
// api接口
|
||||||
|
@ -9,6 +9,7 @@ const api = {
|
||||||
apiPage: '/cargo/api/page', // 分页列表
|
apiPage: '/cargo/api/page', // 分页列表
|
||||||
apiSave: '/cargo/api/save', // 保存
|
apiSave: '/cargo/api/save', // 保存
|
||||||
statistics: '/cargo/statistics/', // 首页数据统计
|
statistics: '/cargo/statistics/', // 首页数据统计
|
||||||
|
adImage: '/cargo/adver/image', // 广告图
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,10 +32,10 @@ export function postApiGetAPI(data: { id: number | string }) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页列表
|
* 分页列表
|
||||||
* @param {PageRowsType} data 查询条件
|
* @param {ApiManagePageType} data 查询条件
|
||||||
* @return 返回请求分页列表接口的结果
|
* @return 返回请求分页列表接口的结果
|
||||||
*/
|
*/
|
||||||
export function postApiPageAPI(data: Partial<PageRowsType>) {
|
export function postApiPageAPI(data: Partial<ApiManagePageType>) {
|
||||||
return http.post<PageRowsResult<ApiManageType>>(api.apiPage, data);
|
return http.post<PageRowsResult<ApiManageType>>(api.apiPage, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,3 +55,11 @@ export function postApiSaveAPI(data: Partial<ApiManageType>) {
|
||||||
export function getStatisticsAPI() {
|
export function getStatisticsAPI() {
|
||||||
return http.get<StatisticsType>(api.statistics);
|
return http.get<StatisticsType>(api.statistics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 广告图
|
||||||
|
* @return 返回接口的结果
|
||||||
|
*/
|
||||||
|
export function getAdImageAPI() {
|
||||||
|
return http.get<string>(api.adImage);
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { PageRowsResult } from '@/types';
|
import { PageRowsResult } from '@/types';
|
||||||
import { BoatInfoPageType, BoatInfoType } from '@/types/boatInfo';
|
import { BoatInfoPageType, BoatInfoType, vinSearchType } from '@/types/boatInfo';
|
||||||
import http from '@/utils/request';
|
import http from '@/utils/request';
|
||||||
|
|
||||||
// api接口
|
// api接口
|
||||||
|
@ -10,7 +10,10 @@ const api = {
|
||||||
sailScheduleSave: '/cargo/sail_schedule/save', // 保存
|
sailScheduleSave: '/cargo/sail_schedule/save', // 保存
|
||||||
sailScheduleTmpExport: '/cargo/sail_schedule/tmp/export', // 船期模板下载
|
sailScheduleTmpExport: '/cargo/sail_schedule/tmp/export', // 船期模板下载
|
||||||
sailScheduleImport: '/cargo/sail_schedule/import', // 导入
|
sailScheduleImport: '/cargo/sail_schedule/import', // 导入
|
||||||
historyList: '/cargo/sail_schedule/history/page', // 历史数据
|
sailScheduleExport: '/cargo/sail_schedule/export', // 船期导出
|
||||||
|
publishHistoryList: '/cargo/sail_schedule/history/publish/page', // 我发布的历史数据
|
||||||
|
receiveHistoryList: '/cargo/sail_schedule/history/receive/page', // 我接受的历史数据
|
||||||
|
vinSearch: '/cargo/sail_schedule/vin/query', // 车架号查询
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,10 +76,39 @@ export function getSailScheduleImportAPI(data: { file: File }) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 历史数据
|
* 船期导出
|
||||||
* @param {BoatInfoPageType} data 分页信息
|
* @param {BoatInfoPageType} data 分页信息
|
||||||
* @return 返回请求分页列表接口的结果
|
* @return 返回请求分页列表接口的结果
|
||||||
*/
|
*/
|
||||||
export function getHistoryListAPI(data: Partial<BoatInfoPageType>) {
|
export function getSailScheduleExportAPI(data: Partial<BoatInfoPageType>) {
|
||||||
return http.post<PageRowsResult<BoatInfoType>>(api.historyList, data);
|
return http.get<ArrayBuffer>(api.sailScheduleExport, data, {
|
||||||
|
responseType: 'arraybuffer',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 我发布的历史数据
|
||||||
|
* @param {BoatInfoPageType} data 分页信息
|
||||||
|
* @return 返回请求分页列表接口的结果
|
||||||
|
*/
|
||||||
|
export function getPublishHistoryListAPI(data: Partial<BoatInfoPageType>) {
|
||||||
|
return http.post<PageRowsResult<BoatInfoType>>(api.publishHistoryList, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 我接受的历史数据
|
||||||
|
* @param {BoatInfoPageType} data 分页信息
|
||||||
|
* @return 返回请求分页列表接口的结果
|
||||||
|
*/
|
||||||
|
export function getReceiveHistoryListAPI(data: Partial<BoatInfoPageType>) {
|
||||||
|
return http.post<PageRowsResult<BoatInfoType>>(api.receiveHistoryList, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车架号查询
|
||||||
|
* @param {BoatInfoPageType} data 分页信息
|
||||||
|
* @return 返回请求分页列表接口的结果
|
||||||
|
*/
|
||||||
|
export function getVinSearchAPI(data: { vin: string }) {
|
||||||
|
return http.get<vinSearchType[]>(api.vinSearch, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,8 @@ const api = {
|
||||||
employeeGet: '/cargo/employee/get', // 获取
|
employeeGet: '/cargo/employee/get', // 获取
|
||||||
employeeList: '/cargo/employee/list', // 字典列表
|
employeeList: '/cargo/employee/list', // 字典列表
|
||||||
employeePage: '/cargo/employee/page', // 分页列表
|
employeePage: '/cargo/employee/page', // 分页列表
|
||||||
employeeSave: '/cargo/enterprise/employee/add', // 保存
|
employeeAdd: '/cargo/enterprise/employee/add', // 保存
|
||||||
|
employeeSave: '/cargo/employee/save', // 编辑
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -72,6 +73,15 @@ export function postEmployeeListAPI(data: dictionaryType) {
|
||||||
* @param {EmployeeType} data 员工信息
|
* @param {EmployeeType} data 员工信息
|
||||||
* @return 返回请求保存接口的结果
|
* @return 返回请求保存接口的结果
|
||||||
*/
|
*/
|
||||||
|
export function postEmployeeAddAPI(data: Partial<EmployeeType>) {
|
||||||
|
return http.post<string>(api.employeeAdd, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编辑
|
||||||
|
* @param {EmployeeType} data 员工信息
|
||||||
|
* @return 返回请求保存接口的结果
|
||||||
|
*/
|
||||||
export function postEmployeeSaveAPI(data: Partial<EmployeeType>) {
|
export function postEmployeeSaveAPI(data: Partial<EmployeeType>) {
|
||||||
return http.post<string>(api.employeeSave, data);
|
return http.post<string>(api.employeeSave, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { PageRowsResult, PageRowsType } from '@/types';
|
import { PageRowsResult, PageRowsType } from '@/types';
|
||||||
import { HelpType } from '@/types/help';
|
import { agreeTextType, HelpType } from '@/types/help';
|
||||||
import http from '@/utils/request';
|
import http from '@/utils/request';
|
||||||
|
|
||||||
// api接口
|
// api接口
|
||||||
|
@ -8,6 +8,10 @@ const api = {
|
||||||
helpGet: '/cargo/help/get', // 获取
|
helpGet: '/cargo/help/get', // 获取
|
||||||
helpPage: '/cargo/help/page', // 分页列表
|
helpPage: '/cargo/help/page', // 分页列表
|
||||||
helpSave: '/cargo/help/save', // 保存
|
helpSave: '/cargo/help/save', // 保存
|
||||||
|
textAgree: '/cargo/text/agree', // 同意协议
|
||||||
|
textGet: '/cargo/text/get', // 获取协议
|
||||||
|
textSave: '/cargo/text/save', // 保存
|
||||||
|
textIsAgree: '/cargo/text/sign', // 是否同意
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,3 +49,36 @@ export function postHelpPageAPI(data: Partial<PageRowsType>) {
|
||||||
export function postHelpSaveAPI(data: Partial<HelpType>) {
|
export function postHelpSaveAPI(data: Partial<HelpType>) {
|
||||||
return http.post<string>(api.helpSave, data);
|
return http.post<string>(api.helpSave, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同意协议
|
||||||
|
* @return 返回请求保存接口的结果
|
||||||
|
*/
|
||||||
|
export function postTextAgreeAPI() {
|
||||||
|
return http.post<string>(api.textAgree);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取协议
|
||||||
|
* @return 返回请求保存接口的结果
|
||||||
|
*/
|
||||||
|
export function postTextGetAPI(data: { textType: string }) {
|
||||||
|
return http.get<agreeTextType>(api.textGet, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存协议
|
||||||
|
* @param {HelpType} data 参数
|
||||||
|
* @return 返回请求保存接口的结果
|
||||||
|
*/
|
||||||
|
export function postTextSaveAPI(data: Partial<agreeTextType>) {
|
||||||
|
return http.post<string>(api.textSave, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否同意
|
||||||
|
* @return 返回请求保存接口的结果
|
||||||
|
*/
|
||||||
|
export function postTextIsAgreeAPI() {
|
||||||
|
return http.post<boolean>(api.textIsAgree);
|
||||||
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ const api = {
|
||||||
manifestSave: '/cargo/manifest/save', // 保存
|
manifestSave: '/cargo/manifest/save', // 保存
|
||||||
manifestImport: '/cargo/manifest/import', // 舱单导入
|
manifestImport: '/cargo/manifest/import', // 舱单导入
|
||||||
manifestExport: '/cargo/manifest/tmp/export', // 下载模版
|
manifestExport: '/cargo/manifest/tmp/export', // 下载模版
|
||||||
|
manifestFileExport: '/cargo/manifest/export', // 舱单导出
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -70,3 +71,13 @@ export function getManifestTmpExportAPI() {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 舱单导出
|
||||||
|
* @return 返回请求下载接口的结果
|
||||||
|
*/
|
||||||
|
export function getManifestFileExportAPI(data: Partial<ManifestPageType>) {
|
||||||
|
return http.get<ArrayBuffer>(api.manifestFileExport, data, {
|
||||||
|
responseType: 'arraybuffer',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -21,5 +21,5 @@ export function getAppListAPI() {
|
||||||
* @return 返回请求获取系统操作权限树接口的结果
|
* @return 返回请求获取系统操作权限树接口的结果
|
||||||
*/
|
*/
|
||||||
export function getMenuTreeAPI(data: menuParamsType) {
|
export function getMenuTreeAPI(data: menuParamsType) {
|
||||||
return http.post<menuType[]>(api.menuTree, data);
|
return http.postParams<menuType[]>(api.menuTree, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,14 @@
|
||||||
import { dictionaryListType, dictionaryType, PageRowsResult } from '@/types';
|
import { rolePremType } from '@/types/role';
|
||||||
import { getRoleListType, rolePremType, roleType } from '@/types/role';
|
|
||||||
import http from '@/utils/request';
|
import http from '@/utils/request';
|
||||||
|
|
||||||
// api接口
|
// api接口
|
||||||
const api = {
|
const api = {
|
||||||
roleSave: '/admin/role/save', // 角色保存
|
rolePremSave: '/admin/user/perm/save', // 添加角色操作权限
|
||||||
rolePremSave: '/admin/role/perm/save', // 添加角色操作权限
|
roleMenuList: '/admin/user/perm/list', // 用户菜单列表
|
||||||
rolePage: '/admin/role/page', // 角色分页列表
|
|
||||||
roleList: '/admin/role/list', // 角色字典列表
|
|
||||||
roleGet: '/admin/role/get', // 角色详情
|
|
||||||
roleDelete: '/admin/role/delete', // 角色删除
|
|
||||||
roleMenuList: '/admin/role/perm/list', // 角色菜单列表
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色保存
|
* 用户添加操作权限
|
||||||
* @param {roleType} data 角色信息
|
|
||||||
* @return 返回请求角色保存接口的结果
|
|
||||||
*/
|
|
||||||
export function postRoleSaveAPI(data: roleType) {
|
|
||||||
return http.post<string>(api.roleSave, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 角色操作权限
|
|
||||||
* @param {rolePremType} data 角色权限
|
* @param {rolePremType} data 角色权限
|
||||||
* @return 返回请求角色操作权限接口的结果
|
* @return 返回请求角色操作权限接口的结果
|
||||||
*/
|
*/
|
||||||
|
@ -32,46 +17,10 @@ export function postRolePremSaveAPI(data: rolePremType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色分页列表
|
* 用户操作权限菜单列表
|
||||||
* @param {getUserListType} data 分页信息
|
|
||||||
* @return 返回请求角色分页列表接口的结果
|
|
||||||
*/
|
|
||||||
export function postRolePageAPI(data: Partial<getRoleListType>) {
|
|
||||||
return http.post<PageRowsResult<roleType>>(api.rolePage, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 角色字典列表
|
|
||||||
* @param {dictionaryType} data 字典信息
|
|
||||||
* @return 返回请求角色字典列表接口的结果
|
|
||||||
*/
|
|
||||||
export function getRoleListAPI(data: dictionaryType) {
|
|
||||||
return http.postParams<dictionaryListType[]>(api.roleList, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 角色详情
|
|
||||||
* @param {string|number} data 角色id
|
|
||||||
* @return 返回请求角色详情接口的结果
|
|
||||||
*/
|
|
||||||
export function getRoleGetAPI(data: { id: number | string }) {
|
|
||||||
return http.postParams<roleType>(api.roleGet, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 角色删除
|
|
||||||
* @param {number} data 角色id
|
|
||||||
* @return 返回请求角色删除接口的结果
|
|
||||||
*/
|
|
||||||
export function getRoleDeleteAPI(data: number[]) {
|
|
||||||
return http.post<string>(api.roleDelete, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 角色菜单列表
|
|
||||||
* @param {string|number} data 角色id
|
* @param {string|number} data 角色id
|
||||||
* @return 返回请求角色菜单列表接口的结果
|
* @return 返回请求角色菜单列表接口的结果
|
||||||
*/
|
*/
|
||||||
export function getRoleMenuListAPI(data: { roleId: number | string }) {
|
export function getUserRoleMenuListAPI(data: { userId: number | string }) {
|
||||||
return http.postParams<string[]>(api.roleMenuList, data);
|
return http.postParams<string[]>(api.roleMenuList, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +1,11 @@
|
||||||
import { dictionaryListType, dictionaryType, PageRowsResult } from '@/types';
|
import { loginDataType, userInfoRepType, userPasswordType, userType } from '@/types/user';
|
||||||
import { roleType } from '@/types/role';
|
|
||||||
import {
|
|
||||||
getUserListType,
|
|
||||||
loginDataType,
|
|
||||||
userInfoRepType,
|
|
||||||
userPasswordType,
|
|
||||||
userRoleType,
|
|
||||||
userType,
|
|
||||||
} from '@/types/user';
|
|
||||||
import http from '@/utils/request';
|
import http from '@/utils/request';
|
||||||
|
|
||||||
// api接口
|
// api接口
|
||||||
const api = {
|
const api = {
|
||||||
login: '/admin/user/login', // 用户登录接口
|
login: '/admin/user/login', // 用户登录接口
|
||||||
userSave: '/admin/user/save', // 用户保存
|
|
||||||
userPassword: '/admin/user/password', // 用户修改密码
|
userPassword: '/admin/user/password', // 用户修改密码
|
||||||
userPage: '/admin/user/page', // 用户分页列表
|
|
||||||
userList: '/admin/user/list', // 用户字典列表
|
|
||||||
userGet: '/admin/user/get', // 用户详情
|
userGet: '/admin/user/get', // 用户详情
|
||||||
userDelete: '/admin/user/delete', // 用户删除
|
|
||||||
userRole: '/admin/user/role/add', // 用户添加角色
|
|
||||||
userRoleList: '/admin/user/role/list', // 用户角色列表
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,15 +21,6 @@ export function postLoginAPI(data: loginDataType) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户保存
|
|
||||||
* @param {userType} data 用户信息
|
|
||||||
* @return 返回请求保存接口的结果
|
|
||||||
*/
|
|
||||||
export function postUserSaveAPI(data: userType) {
|
|
||||||
return http.post<string>(api.userSave, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户修改密码
|
* 用户修改密码
|
||||||
* @param {userPasswordType} data 用户修改密码信息
|
* @param {userPasswordType} data 用户修改密码信息
|
||||||
|
@ -54,24 +30,6 @@ export function postUserPasswordAPI(data: userPasswordType) {
|
||||||
return http.post<string>(api.userPassword, data);
|
return http.post<string>(api.userPassword, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户分页列表
|
|
||||||
* @param {getUserListType} data 分页信息
|
|
||||||
* @return 返回请求分页列表接口的结果
|
|
||||||
*/
|
|
||||||
export function postUserPageAPI(data: Partial<getUserListType>) {
|
|
||||||
return http.post<PageRowsResult<userType>>(api.userPage, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户字典列表
|
|
||||||
* @param {dictionaryType} data 字典信息
|
|
||||||
* @return 返回请求用户字典列表接口的结果
|
|
||||||
*/
|
|
||||||
export function getUserListAPI(data: dictionaryType) {
|
|
||||||
return http.postParams<dictionaryListType[]>(api.userList, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户详情
|
* 用户详情
|
||||||
* @param {string|number} data 用户id
|
* @param {string|number} data 用户id
|
||||||
|
@ -80,30 +38,3 @@ export function getUserListAPI(data: dictionaryType) {
|
||||||
export function getUserGetAPI(data: { id: number | string }) {
|
export function getUserGetAPI(data: { id: number | string }) {
|
||||||
return http.postParams<userType>(api.userGet, data);
|
return http.postParams<userType>(api.userGet, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户删除
|
|
||||||
* @param {number} data 用户id
|
|
||||||
* @return 返回请求用户删除接口的结果
|
|
||||||
*/
|
|
||||||
export function getUserDeleteAPI(data: number[]) {
|
|
||||||
return http.post<string>(api.userDelete, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户添加角色
|
|
||||||
* @param {userRoleType} data 用户角色
|
|
||||||
* @return 返回请求用户添加角色接口的结果
|
|
||||||
*/
|
|
||||||
export function postUserRoleAPI(data: userRoleType) {
|
|
||||||
return http.post<string>(api.userRole, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户角色列表
|
|
||||||
* @param {string|number} data 用户id
|
|
||||||
* @return 返回请求用户角色列表接口的结果
|
|
||||||
*/
|
|
||||||
export function getUserRoleListAPI(data: { userId: number | string }) {
|
|
||||||
return http.postParams<roleType[]>(api.userRoleList, data);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { dictionaryListType, dictionaryType, PageRowsResult } from '@/types';
|
import { dictionaryListType, dictionaryType, PageRowsResult } from '@/types';
|
||||||
import { LoadWharfPageType, LoadWharfType } from '@/types/boatInfo';
|
import { LoadInfoType, LoadWharfPageType, LoadWharfType } from '@/types/boatInfo';
|
||||||
import http from '@/utils/request';
|
import http from '@/utils/request';
|
||||||
|
|
||||||
// api接口
|
// api接口
|
||||||
|
@ -9,6 +9,8 @@ const api = {
|
||||||
wharfList: '/cargo/wharf/list', // 字典列表
|
wharfList: '/cargo/wharf/list', // 字典列表
|
||||||
wharfPage: '/cargo/wharf/page', // 分页列表
|
wharfPage: '/cargo/wharf/page', // 分页列表
|
||||||
wharfSave: '/cargo/wharf/save', // 保存
|
wharfSave: '/cargo/wharf/save', // 保存
|
||||||
|
wharfInfo: '/cargo/wharf/get/info', // 获取绑定的码头信息
|
||||||
|
wharfPhoto: '/cargo/wharf/image/', // 获取绑定的码头图片
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -55,3 +57,25 @@ export function postWharfPageAPI(data: Partial<LoadWharfPageType>) {
|
||||||
export function postWharfSaveAPI(data: Partial<LoadWharfType>) {
|
export function postWharfSaveAPI(data: Partial<LoadWharfType>) {
|
||||||
return http.post<string>(api.wharfSave, data);
|
return http.post<string>(api.wharfSave, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取绑定的码头信息
|
||||||
|
* @return 返回请求保存接口的结果
|
||||||
|
*/
|
||||||
|
export function postWharfInfoAPI() {
|
||||||
|
return http.get<LoadInfoType>(api.wharfInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取绑定的码头图片
|
||||||
|
* @return 返回请求保存接口的结果
|
||||||
|
*/
|
||||||
|
export function getWharfPhotoAPI(id: string | number) {
|
||||||
|
return http.get<ArrayBuffer>(
|
||||||
|
`${api.wharfPhoto}/${id}`,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
responseType: 'arraybuffer',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="29px" xmlns="http://www.w3.org/2000/svg">
|
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="29px" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g transform="matrix(1 0 0 1 -84 -186 )">
|
<g transform="matrix(1 0 0 1 -84 -186 )">
|
||||||
<path d="M 31.8064516129032 16.1945266272189 C 32.1290322580645 15.7655325443787 31.9139784946237 15.0147928994083 31.2688172043011 14.6930473372781 L 26.9677419354839 12.8698224852071 L 26.9677419354839 7.40014792899408 C 26.9677419354839 6.86390532544379 26.6451612903226 6.43491124260355 26.2150537634409 6.22041420118343 L 18.4731182795699 3.21745562130178 L 18.4731182795699 2.46671597633136 C 18.4731182795699 1.07248520710059 17.3978494623656 0 16 0 C 14.6021505376344 0 13.5268817204301 1.07248520710059 13.5268817204301 2.46671597633136 L 13.5268817204301 3.21745562130178 L 5.67741935483871 6.32766272189349 C 5.13978494623656 6.54215976331361 4.9247311827957 6.97115384615385 4.9247311827957 7.40014792899408 L 4.9247311827957 12.8698224852071 L 0.731182795698925 14.6930473372781 C 0.0860215053763442 15.0147928994083 -0.129032258064516 15.7655325443787 0.301075268817205 16.301775147929 L 6.75268817204301 26.5976331360947 C 6.86021505376344 26.8121301775148 7.0752688172043 26.9193786982249 7.29032258064516 27.0266272189349 C 8.47311827956989 27.241124260355 9.44086021505376 27.7773668639053 10.3010752688172 28.6353550295858 L 10.4086021505376 28.7426035502959 C 10.7311827956989 29.064349112426 11.3763440860215 29.064349112426 11.6989247311828 28.7426035502959 L 11.8064516129032 28.6353550295858 C 12.8817204301075 27.5628698224852 14.3870967741935 26.9193786982248 16 26.9193786982248 C 17.6129032258065 26.9193786982248 19.1182795698925 27.5628698224852 20.1935483870968 28.6353550295858 C 20.5161290322581 28.957100591716 21.1612903225806 28.957100591716 21.4838709677419 28.6353550295858 C 22.3440860215054 27.7773668639053 23.5268817204301 27.133875739645 24.7096774193548 26.9193786982248 C 24.9247311827957 26.9193786982248 25.1397849462366 26.7048816568047 25.3548387096774 26.4903846153846 L 31.8064516129032 16.1945266272189 Z M 24.494623655914 11.7973372781065 L 16.8602150537634 8.47263313609468 C 16.3225806451613 8.25813609467456 15.6774193548387 8.25813609467456 15.1397849462366 8.47263313609468 L 7.29032258064516 11.7973372781065 L 7.29032258064516 8.25813609467456 L 16 4.93343195266272 L 24.494623655914 8.25813609467456 L 24.494623655914 11.7973372781065 Z " fill-rule="nonzero" fill="#aaaaaa" stroke="none" transform="matrix(1 0 0 1 84 186 )" />
|
<path d="M 31.8064516129032 16.1945266272189 C 32.1290322580645 15.7655325443787 31.9139784946237 15.0147928994083 31.2688172043011 14.6930473372781 L 26.9677419354839 12.8698224852071 L 26.9677419354839 7.40014792899408 C 26.9677419354839 6.86390532544379 26.6451612903226 6.43491124260355 26.2150537634409 6.22041420118343 L 18.4731182795699 3.21745562130178 L 18.4731182795699 2.46671597633136 C 18.4731182795699 1.07248520710059 17.3978494623656 0 16 0 C 14.6021505376344 0 13.5268817204301 1.07248520710059 13.5268817204301 2.46671597633136 L 13.5268817204301 3.21745562130178 L 5.67741935483871 6.32766272189349 C 5.13978494623656 6.54215976331361 4.9247311827957 6.97115384615385 4.9247311827957 7.40014792899408 L 4.9247311827957 12.8698224852071 L 0.731182795698925 14.6930473372781 C 0.0860215053763442 15.0147928994083 -0.129032258064516 15.7655325443787 0.301075268817205 16.301775147929 L 6.75268817204301 26.5976331360947 C 6.86021505376344 26.8121301775148 7.0752688172043 26.9193786982249 7.29032258064516 27.0266272189349 C 8.47311827956989 27.241124260355 9.44086021505376 27.7773668639053 10.3010752688172 28.6353550295858 L 10.4086021505376 28.7426035502959 C 10.7311827956989 29.064349112426 11.3763440860215 29.064349112426 11.6989247311828 28.7426035502959 L 11.8064516129032 28.6353550295858 C 12.8817204301075 27.5628698224852 14.3870967741935 26.9193786982248 16 26.9193786982248 C 17.6129032258065 26.9193786982248 19.1182795698925 27.5628698224852 20.1935483870968 28.6353550295858 C 20.5161290322581 28.957100591716 21.1612903225806 28.957100591716 21.4838709677419 28.6353550295858 C 22.3440860215054 27.7773668639053 23.5268817204301 27.133875739645 24.7096774193548 26.9193786982248 C 24.9247311827957 26.9193786982248 25.1397849462366 26.7048816568047 25.3548387096774 26.4903846153846 L 31.8064516129032 16.1945266272189 Z M 24.494623655914 11.7973372781065 L 16.8602150537634 8.47263313609468 C 16.3225806451613 8.25813609467456 15.6774193548387 8.25813609467456 15.1397849462366 8.47263313609468 L 7.29032258064516 11.7973372781065 L 7.29032258064516 8.25813609467456 L 16 4.93343195266272 L 24.494623655914 8.25813609467456 L 24.494623655914 11.7973372781065 Z " fill-rule="nonzero" stroke="none" transform="matrix(1 0 0 1 84 186 )" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="32px" xmlns="http://www.w3.org/2000/svg">
|
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="32px" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g transform="matrix(1 0 0 1 -84 -593 )">
|
<g transform="matrix(1 0 0 1 -84 -593 )">
|
||||||
<path d="M 32 21.3333333333333 C 32 27.2 27.7333333333333 32 22.4 32 C 17.0666666666667 32 12.8 27.2 12.8 21.3333333333333 C 12.8 15.4666666666667 17.0666666666667 10.6666666666667 22.4 10.6666666666667 C 27.7333333333333 10.6666666666667 32 15.4666666666667 32 21.3333333333333 Z M 27.2 19.5555555555556 L 24 19.5555555555556 L 24 16 C 24 15.1111111111111 23.2888888888889 14.2222222222222 22.4 14.2222222222222 C 21.5111111111111 14.2222222222222 20.8 14.9333333333333 20.8 16 L 20.8 21.3333333333333 C 20.8 22.2222222222222 21.5111111111111 23.1111111111111 22.4 23.1111111111111 L 27.2 23.1111111111111 C 28.0888888888889 23.1111111111111 28.8 22.4 28.8 21.3333333333333 C 28.8 20.2666666666667 28.0888888888889 19.5555555555556 27.2 19.5555555555556 Z M 0 2.66666666666667 C 0 1.24444444444444 1.06666666666667 0 2.31111111111111 0 L 29.5111111111111 0 C 30.9333333333333 0 32 1.24444444444444 32 2.66666666666667 C 32 4.08888888888889 30.9333333333333 5.33333333333333 29.6888888888889 5.33333333333333 L 2.31111111111111 5.33333333333333 C 1.06666666666667 5.33333333333333 0 4.08888888888889 0 2.66666666666667 Z M 0 11.5555555555556 C 0 10.1333333333333 1.06666666666667 8.88888888888889 2.31111111111111 8.88888888888889 L 10.3111111111111 8.88888888888889 C 11.7333333333333 8.88888888888889 12.6222222222222 10.1333333333333 12.6222222222222 11.5555555555556 C 12.6222222222222 12.9777777777778 11.7333333333333 14.2222222222222 10.4888888888889 14.2222222222222 L 2.31111111111111 14.2222222222222 C 1.06666666666667 14.2222222222222 0 12.9777777777778 0 11.5555555555556 Z M 0 20.4444444444444 C 0 19.0222222222222 1.06666666666667 17.7777777777778 2.31111111111111 17.7777777777778 L 7.11111111111111 17.7777777777778 C 8.53333333333333 17.7777777777778 9.42222222222222 19.0222222222222 9.42222222222222 20.4444444444444 C 9.6 21.8666666666667 8.53333333333333 23.1111111111111 7.11111111111111 23.1111111111111 L 2.31111111111111 23.1111111111111 C 1.06666666666667 23.1111111111111 0 21.8666666666667 0 20.4444444444444 Z M 0 29.3333333333333 C 0 27.9111111111111 1.06666666666667 26.6666666666667 2.31111111111111 26.6666666666667 L 3.91111111111111 26.6666666666667 C 5.33333333333333 26.6666666666667 6.22222222222222 27.9111111111111 6.22222222222222 29.3333333333333 C 6.22222222222222 30.7555555555555 5.33333333333333 32 4.08888888888889 32 L 2.31111111111111 32 C 1.06666666666667 32 0 30.7555555555555 0 29.3333333333333 Z " fill-rule="nonzero" fill="#aaaaaa" stroke="none" transform="matrix(1 0 0 1 84 593 )" />
|
<path d="M 32 21.3333333333333 C 32 27.2 27.7333333333333 32 22.4 32 C 17.0666666666667 32 12.8 27.2 12.8 21.3333333333333 C 12.8 15.4666666666667 17.0666666666667 10.6666666666667 22.4 10.6666666666667 C 27.7333333333333 10.6666666666667 32 15.4666666666667 32 21.3333333333333 Z M 27.2 19.5555555555556 L 24 19.5555555555556 L 24 16 C 24 15.1111111111111 23.2888888888889 14.2222222222222 22.4 14.2222222222222 C 21.5111111111111 14.2222222222222 20.8 14.9333333333333 20.8 16 L 20.8 21.3333333333333 C 20.8 22.2222222222222 21.5111111111111 23.1111111111111 22.4 23.1111111111111 L 27.2 23.1111111111111 C 28.0888888888889 23.1111111111111 28.8 22.4 28.8 21.3333333333333 C 28.8 20.2666666666667 28.0888888888889 19.5555555555556 27.2 19.5555555555556 Z M 0 2.66666666666667 C 0 1.24444444444444 1.06666666666667 0 2.31111111111111 0 L 29.5111111111111 0 C 30.9333333333333 0 32 1.24444444444444 32 2.66666666666667 C 32 4.08888888888889 30.9333333333333 5.33333333333333 29.6888888888889 5.33333333333333 L 2.31111111111111 5.33333333333333 C 1.06666666666667 5.33333333333333 0 4.08888888888889 0 2.66666666666667 Z M 0 11.5555555555556 C 0 10.1333333333333 1.06666666666667 8.88888888888889 2.31111111111111 8.88888888888889 L 10.3111111111111 8.88888888888889 C 11.7333333333333 8.88888888888889 12.6222222222222 10.1333333333333 12.6222222222222 11.5555555555556 C 12.6222222222222 12.9777777777778 11.7333333333333 14.2222222222222 10.4888888888889 14.2222222222222 L 2.31111111111111 14.2222222222222 C 1.06666666666667 14.2222222222222 0 12.9777777777778 0 11.5555555555556 Z M 0 20.4444444444444 C 0 19.0222222222222 1.06666666666667 17.7777777777778 2.31111111111111 17.7777777777778 L 7.11111111111111 17.7777777777778 C 8.53333333333333 17.7777777777778 9.42222222222222 19.0222222222222 9.42222222222222 20.4444444444444 C 9.6 21.8666666666667 8.53333333333333 23.1111111111111 7.11111111111111 23.1111111111111 L 2.31111111111111 23.1111111111111 C 1.06666666666667 23.1111111111111 0 21.8666666666667 0 20.4444444444444 Z M 0 29.3333333333333 C 0 27.9111111111111 1.06666666666667 26.6666666666667 2.31111111111111 26.6666666666667 L 3.91111111111111 26.6666666666667 C 5.33333333333333 26.6666666666667 6.22222222222222 27.9111111111111 6.22222222222222 29.3333333333333 C 6.22222222222222 30.7555555555555 5.33333333333333 32 4.08888888888889 32 L 2.31111111111111 32 C 1.06666666666667 32 0 30.7555555555555 0 29.3333333333333 Z " fill-rule="nonzero" stroke="none" transform="matrix(1 0 0 1 84 593 )" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="29px" xmlns="http://www.w3.org/2000/svg">
|
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="29px" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g transform="matrix(1 0 0 1 -84 -394 )">
|
<g transform="matrix(1 0 0 1 -84 -394 )">
|
||||||
<path d="M 31.8318401748088 4.05227163775821 C 32.0982363040425 2.9064139719341 31.8318401748088 1.82791880937854 31.0327142188232 1.0190632354223 L 30.899547370064 0.884275037043493 C 30.0338067738411 0.142813562276649 28.8351178398627 -0.126794430401814 27.769626970501 0.277633356576309 L 1.66483533635087 10.5231162294082 C 0.732542531606056 10.8601499171969 0.133198064616825 11.7363995903425 0.0665834243795847 12.7474690577878 C 0 13.7585385252332 0.466146402372405 14.7022138934891 1.33188699859529 15.1740357796566 L 6.85915405025753 18.4768837705918 C 7.19213360387077 18.6790976640809 7.59169658186359 18.5442778697812 7.79147807086 18.2072441819925 C 7.99125955985641 17.8702420901246 7.85806149523958 17.4658143031465 7.525113157484 17.2636004096575 L 1.9978148899641 14.0281781138325 C 1.59825191197128 13.7585385252332 1.33188699859529 13.354110738255 1.39847042297487 12.8822888520875 C 1.46505384735446 12.41046696592 1.73144997658811 12.0060391789419 2.19759637896051 11.8038252854528 L 28.3023880131107 1.55831081670008 C 28.7019509911035 1.42349102240042 29.1015139690963 1.42349102240042 29.4344623068519 1.55831081670008 L 10.1888559388169 18.5442778697812 C 9.5229280474481 19.1509195502484 9.12336506945528 20.0271692233941 9.12336506945528 20.97084459165 L 9.12336506945528 28.1831506580668 C 9.12336506945528 28.5875784450449 9.38972998283128 28.8571864377234 9.7892929608241 28.8571864377234 C 10.1888559388169 28.8571864377234 10.4552208521929 28.5875784450449 10.4552208521929 28.1831506580668 L 10.4552208521929 20.97084459165 C 10.4552208521929 20.4315970103722 10.6550023411893 19.8923810250153 11.1211799594194 19.5553473372265 L 30.4333697518339 2.43456048984573 C 30.6331512408303 2.83898827682385 30.6331512408303 3.24341606380197 30.5665678164508 3.64784385078009 L 25.7052286561573 22.4537359452628 C 25.4388325269237 23.3974113135187 24.7729046355549 24.2062668874749 23.9071952551896 24.5433005752637 C 23.0414858748244 24.8803342630524 21.9759637896051 24.8803026671315 21.1102544092399 24.3410866817746 L 14.6506321211175 20.6338109038612 C 14.3176837833619 20.4315970103722 13.9181208053691 20.5664168046718 13.7183393163727 20.9034504924606 C 13.5185578273763 21.2404525843284 13.6517246761355 21.6448803713065 13.9847042297487 21.8470942647956 L 20.4442953020134 25.6217641418984 C 21.1102544092399 26.0261919288765 21.9093803652255 26.2284058223656 22.6418916809739 26.2284058223656 C 23.2412361479632 26.2284058223656 23.7739971905728 26.0935860280659 24.373341657562 25.8913721345768 C 25.6386140159201 25.3521561492199 26.6375214609021 24.2736609866643 26.9705010145154 22.8581637322409 L 31.8318401748088 4.05227163775821 Z " fill-rule="nonzero" fill="#aaaaaa" stroke="none" transform="matrix(1 0 0 1 84 394 )" />
|
<path d="M 31.8318401748088 4.05227163775821 C 32.0982363040425 2.9064139719341 31.8318401748088 1.82791880937854 31.0327142188232 1.0190632354223 L 30.899547370064 0.884275037043493 C 30.0338067738411 0.142813562276649 28.8351178398627 -0.126794430401814 27.769626970501 0.277633356576309 L 1.66483533635087 10.5231162294082 C 0.732542531606056 10.8601499171969 0.133198064616825 11.7363995903425 0.0665834243795847 12.7474690577878 C 0 13.7585385252332 0.466146402372405 14.7022138934891 1.33188699859529 15.1740357796566 L 6.85915405025753 18.4768837705918 C 7.19213360387077 18.6790976640809 7.59169658186359 18.5442778697812 7.79147807086 18.2072441819925 C 7.99125955985641 17.8702420901246 7.85806149523958 17.4658143031465 7.525113157484 17.2636004096575 L 1.9978148899641 14.0281781138325 C 1.59825191197128 13.7585385252332 1.33188699859529 13.354110738255 1.39847042297487 12.8822888520875 C 1.46505384735446 12.41046696592 1.73144997658811 12.0060391789419 2.19759637896051 11.8038252854528 L 28.3023880131107 1.55831081670008 C 28.7019509911035 1.42349102240042 29.1015139690963 1.42349102240042 29.4344623068519 1.55831081670008 L 10.1888559388169 18.5442778697812 C 9.5229280474481 19.1509195502484 9.12336506945528 20.0271692233941 9.12336506945528 20.97084459165 L 9.12336506945528 28.1831506580668 C 9.12336506945528 28.5875784450449 9.38972998283128 28.8571864377234 9.7892929608241 28.8571864377234 C 10.1888559388169 28.8571864377234 10.4552208521929 28.5875784450449 10.4552208521929 28.1831506580668 L 10.4552208521929 20.97084459165 C 10.4552208521929 20.4315970103722 10.6550023411893 19.8923810250153 11.1211799594194 19.5553473372265 L 30.4333697518339 2.43456048984573 C 30.6331512408303 2.83898827682385 30.6331512408303 3.24341606380197 30.5665678164508 3.64784385078009 L 25.7052286561573 22.4537359452628 C 25.4388325269237 23.3974113135187 24.7729046355549 24.2062668874749 23.9071952551896 24.5433005752637 C 23.0414858748244 24.8803342630524 21.9759637896051 24.8803026671315 21.1102544092399 24.3410866817746 L 14.6506321211175 20.6338109038612 C 14.3176837833619 20.4315970103722 13.9181208053691 20.5664168046718 13.7183393163727 20.9034504924606 C 13.5185578273763 21.2404525843284 13.6517246761355 21.6448803713065 13.9847042297487 21.8470942647956 L 20.4442953020134 25.6217641418984 C 21.1102544092399 26.0261919288765 21.9093803652255 26.2284058223656 22.6418916809739 26.2284058223656 C 23.2412361479632 26.2284058223656 23.7739971905728 26.0935860280659 24.373341657562 25.8913721345768 C 25.6386140159201 25.3521561492199 26.6375214609021 24.2736609866643 26.9705010145154 22.8581637322409 L 31.8318401748088 4.05227163775821 Z " fill-rule="nonzero" stroke="none" transform="matrix(1 0 0 1 84 394 )" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="36px" xmlns="http://www.w3.org/2000/svg">
|
<svg version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="32px" height="36px" xmlns="http://www.w3.org/2000/svg">
|
||||||
<g transform="matrix(1 0 0 1 -84 -488 )">
|
<g transform="matrix(1 0 0 1 -84 -488 )">
|
||||||
<path d="M 18.6666666545139 13.4556212879068 L 23.999999984375 13.4556212879068 L 23.999999984375 8.13017750092455 C 23.999999984375 7.63998393215635 24.3979690984866 7.24260352949335 24.8888888796296 7.24260352949335 C 25.3798086607727 7.24260352949335 25.7777777748843 7.63998393215635 25.7777777748843 8.13017750092455 L 25.7777777748843 13.4556212879068 L 31.1111111047454 13.4556212879068 C 31.6020308858885 13.4556212879068 32 13.8530016905698 32 14.343195259338 C 32 14.8333888281062 31.6020308858885 15.2307692307692 31.1111111047454 15.2307692307692 L 25.7777777748843 15.2307692307692 L 25.7777777748843 20.5562130177515 C 25.7777777748843 21.0464065865197 25.3798086607727 21.4437869891827 24.8888888796296 21.4437869891827 C 24.3979690984866 21.4437869891827 23.999999984375 21.0464065865197 23.999999984375 20.5562130177515 L 23.999999984375 15.2307692307692 L 18.6666666545139 15.2307692307692 C 18.1757468733708 15.2307692307692 17.7777777592593 14.8333888281062 17.7777777592593 14.343195259338 C 17.7777777592593 13.8530016905698 18.1757468733708 13.4556212879068 18.6666666545139 13.4556212879068 Z M 30 20.6840236686391 L 30.2222221886574 20.6831361085429 C 30.2222221886574 20.1929425397747 30.620191302769 19.7955621371117 31.1111110839121 19.7955621371117 C 31.6020308650551 19.7955621371117 31.9999999791667 20.1929425397747 31.9999999791667 20.6831361085429 L 32 33.2662721754808 C 31.9995564818193 34.7365396105881 30.8057791101131 35.928192063087 29.3333334351962 35.928192063087 C 28.8188541791035 35.928192063087 28.3153585793775 35.779587327387 27.8835555235133 35.5002958441198 L 16.5048888642546 28.1378698086169 C 16.2109336845382 27.9478214882398 15.8326218362668 27.9478214882398 15.5386666565504 28.1378698086169 L 4.11377778898842 35.5082840098003 C 3.68254972175569 35.7864761256624 3.1800650159474 35.9344576611834 2.66666655930324 35.9344576611834 C 1.19420033215083 35.9344576611834 0.000414442319860577 34.7427731863621 0 33.2724852209689 L 0 6.35502959966716 C 0 2.92367461115139 2.78578377079869 0.142011820451183 6.22222220428241 0.142011820451183 L 25.7777777748843 0.142011820451183 C 29.214216208368 0.142011820451183 31.9999999791667 2.92367461115139 31.9999999791667 6.35502955806213 L 31.9999999791667 8.18343193879438 C 31.9999999791667 8.67362550756258 31.6020308650551 9.07100591022559 31.1111110839121 9.07100591022559 C 30.620191302769 9.07100591022559 30.2222221886574 8.67362550756259 30.2222221886574 8.18343193879438 L 30.2222221886574 6.35502959966716 C 30.2222221886574 3.90406178356279 28.2323766528219 1.91715978629143 25.7777777748843 2 L 6.22222220428241 2 C 3.76762332634482 1.91715978629143 1.77777779050926 3.90406178356279 2 6.35502959966716 L 2 33.2724852209689 C 1.77777776933179 33.2725643174599 1.77777775874305 33.2726434139586 1.77777775874305 33.2727225104524 C 1.77777775874305 33.7629160677317 2.17574686352721 34.1602964610811 2.66666663316435 34.1602964610811 C 2.83791950301204 34.1602964610811 3.00552670215961 34.1109001074683 3.14933333128299 34.0180473511464 L 14.5742221988449 26.6467455482618 C 15.4564039377868 26.0777934671316 16.5908684453466 26.0788359085129 17.471999988625 26.6494082701553 L 28.8497777728843 34.0118343056583 C 28.9937759684371 34.1050539462454 29.1617203167725 34.1546583128729 29.3333336863881 34.1546583128729 C 29.8242534560252 34.1546583128729 30.2222225608094 33.7572779195235 30.2222225608094 33.2670843622442 C 30.2222225608094 33.2668136332811 30.2222224367587 33.2665429043305 30 33.2662721754808 L 30 20.6840236686391 Z " fill-rule="nonzero" fill="#aaaaaa" stroke="none" transform="matrix(1 0 0 1 84 488 )" />
|
<path d="M 18.6666666545139 13.4556212879068 L 23.999999984375 13.4556212879068 L 23.999999984375 8.13017750092455 C 23.999999984375 7.63998393215635 24.3979690984866 7.24260352949335 24.8888888796296 7.24260352949335 C 25.3798086607727 7.24260352949335 25.7777777748843 7.63998393215635 25.7777777748843 8.13017750092455 L 25.7777777748843 13.4556212879068 L 31.1111111047454 13.4556212879068 C 31.6020308858885 13.4556212879068 32 13.8530016905698 32 14.343195259338 C 32 14.8333888281062 31.6020308858885 15.2307692307692 31.1111111047454 15.2307692307692 L 25.7777777748843 15.2307692307692 L 25.7777777748843 20.5562130177515 C 25.7777777748843 21.0464065865197 25.3798086607727 21.4437869891827 24.8888888796296 21.4437869891827 C 24.3979690984866 21.4437869891827 23.999999984375 21.0464065865197 23.999999984375 20.5562130177515 L 23.999999984375 15.2307692307692 L 18.6666666545139 15.2307692307692 C 18.1757468733708 15.2307692307692 17.7777777592593 14.8333888281062 17.7777777592593 14.343195259338 C 17.7777777592593 13.8530016905698 18.1757468733708 13.4556212879068 18.6666666545139 13.4556212879068 Z M 30 20.6840236686391 L 30.2222221886574 20.6831361085429 C 30.2222221886574 20.1929425397747 30.620191302769 19.7955621371117 31.1111110839121 19.7955621371117 C 31.6020308650551 19.7955621371117 31.9999999791667 20.1929425397747 31.9999999791667 20.6831361085429 L 32 33.2662721754808 C 31.9995564818193 34.7365396105881 30.8057791101131 35.928192063087 29.3333334351962 35.928192063087 C 28.8188541791035 35.928192063087 28.3153585793775 35.779587327387 27.8835555235133 35.5002958441198 L 16.5048888642546 28.1378698086169 C 16.2109336845382 27.9478214882398 15.8326218362668 27.9478214882398 15.5386666565504 28.1378698086169 L 4.11377778898842 35.5082840098003 C 3.68254972175569 35.7864761256624 3.1800650159474 35.9344576611834 2.66666655930324 35.9344576611834 C 1.19420033215083 35.9344576611834 0.000414442319860577 34.7427731863621 0 33.2724852209689 L 0 6.35502959966716 C 0 2.92367461115139 2.78578377079869 0.142011820451183 6.22222220428241 0.142011820451183 L 25.7777777748843 0.142011820451183 C 29.214216208368 0.142011820451183 31.9999999791667 2.92367461115139 31.9999999791667 6.35502955806213 L 31.9999999791667 8.18343193879438 C 31.9999999791667 8.67362550756258 31.6020308650551 9.07100591022559 31.1111110839121 9.07100591022559 C 30.620191302769 9.07100591022559 30.2222221886574 8.67362550756259 30.2222221886574 8.18343193879438 L 30.2222221886574 6.35502959966716 C 30.2222221886574 3.90406178356279 28.2323766528219 1.91715978629143 25.7777777748843 2 L 6.22222220428241 2 C 3.76762332634482 1.91715978629143 1.77777779050926 3.90406178356279 2 6.35502959966716 L 2 33.2724852209689 C 1.77777776933179 33.2725643174599 1.77777775874305 33.2726434139586 1.77777775874305 33.2727225104524 C 1.77777775874305 33.7629160677317 2.17574686352721 34.1602964610811 2.66666663316435 34.1602964610811 C 2.83791950301204 34.1602964610811 3.00552670215961 34.1109001074683 3.14933333128299 34.0180473511464 L 14.5742221988449 26.6467455482618 C 15.4564039377868 26.0777934671316 16.5908684453466 26.0788359085129 17.471999988625 26.6494082701553 L 28.8497777728843 34.0118343056583 C 28.9937759684371 34.1050539462454 29.1617203167725 34.1546583128729 29.3333336863881 34.1546583128729 C 29.8242534560252 34.1546583128729 30.2222225608094 33.7572779195235 30.2222225608094 33.2670843622442 C 30.2222225608094 33.2668136332811 30.2222224367587 33.2665429043305 30 33.2662721754808 L 30 20.6840236686391 Z " fill-rule="nonzero" stroke="none" transform="matrix(1 0 0 1 84 488 )" />
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 216 KiB |
Binary file not shown.
After Width: | Height: | Size: 83 KiB |
|
@ -31,4 +31,9 @@ interface PaginationProps {
|
||||||
defineProps<PaginationProps>();
|
defineProps<PaginationProps>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss">
|
||||||
|
.el-pagination__total,
|
||||||
|
.el-pagination__jump {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="header-left">
|
<div class="header-left">
|
||||||
<img class="logo" src="@/assets/images/logo.png" />
|
<img class="logo" src="@/assets/images/logo.png" />
|
||||||
<!-- <div class="left-title">
|
<div class="left-title">
|
||||||
<div class="title">船货信息智慧共享服务平台</div>
|
<div class="title">船货信息智慧共享服务平台</div>
|
||||||
<div class="text">Intelligent sharing service platform for ship and cargo information</div>
|
<div class="text">Intelligent sharing service platform for ship and cargo information</div>
|
||||||
</div> -->
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
<div
|
<div
|
||||||
|
@ -54,7 +54,7 @@ const menuList = ref<menuListType[]>([
|
||||||
icon: 'API',
|
icon: 'API',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/enterprise/employee',
|
path: '/setting',
|
||||||
title: '设置',
|
title: '设置',
|
||||||
icon: 'Setting',
|
icon: 'Setting',
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,6 +16,6 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background-color: var(--el-bg-color-page);
|
background-color: #555;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
<template>
|
|
||||||
<template v-for="subItem in menuList" :key="subItem.path">
|
|
||||||
<el-sub-menu v-if="subItem.children && subItem.children.length > 0" :index="subItem.path">
|
|
||||||
<template #title>
|
|
||||||
<el-icon v-if="subItem.meta?.native">
|
|
||||||
<component :is="subItem.meta?.icon"></component>
|
|
||||||
</el-icon>
|
|
||||||
<svg-icon :icon="subItem.meta?.icon" className="side-icon" v-else></svg-icon>
|
|
||||||
<span>{{ subItem.meta?.title }}</span>
|
|
||||||
</template>
|
|
||||||
<!-- 有children递归本次组件 -->
|
|
||||||
<SubMenu :menuList="subItem.children" />
|
|
||||||
</el-sub-menu>
|
|
||||||
|
|
||||||
<el-menu-item v-else :index="subItem.path">
|
|
||||||
<el-icon v-if="subItem.meta?.native">
|
|
||||||
<component :is="subItem.meta?.icon"></component>
|
|
||||||
</el-icon>
|
|
||||||
<svg-icon :icon="subItem.meta?.icon" className="side-icon" v-else></svg-icon>
|
|
||||||
<template #title>
|
|
||||||
<span>{{ subItem.meta?.title }}</span>
|
|
||||||
</template>
|
|
||||||
</el-menu-item>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { RouteRecordRaw } from 'vue-router';
|
|
||||||
|
|
||||||
// 获取父组件传递的值
|
|
||||||
defineProps({
|
|
||||||
menuList: {
|
|
||||||
type: Array<RouteRecordRaw>,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.side-icon {
|
|
||||||
margin-right: 10px;
|
|
||||||
font-size: 18px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,23 +1,62 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
<img class="side-logo" src="@/assets/images/logo.png" />
|
<img class="side-logo" src="@/assets/images/logo.png" />
|
||||||
<el-scrollbar>
|
<div
|
||||||
<el-menu :default-active="activeMenu" background-color="#333" text-color="#fff" router>
|
class="side-item"
|
||||||
<SubMenu :menuList="menuList"></SubMenu>
|
v-for="item in menuList"
|
||||||
</el-menu>
|
:key="item.path"
|
||||||
</el-scrollbar>
|
:class="{ 'side-item-active': activeMenu === item.path }"
|
||||||
|
@click="onClickMenu(item)"
|
||||||
|
>
|
||||||
|
<svg-icon :icon="item.icon" className="side-icon"></svg-icon>
|
||||||
|
<span>{{ item.title }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue';
|
import { computed, onMounted, ref } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { filterRoutes, generateMenus } from '@/utils/routers';
|
import { getAdImageAPI } from '@/api/ApiManage';
|
||||||
import SubMenu from './components/SubMenu.vue';
|
|
||||||
|
|
||||||
// 获取路由携带的参数和路径
|
// 获取路由携带的参数和路径
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
|
interface menuListType {
|
||||||
|
path: string;
|
||||||
|
title: string;
|
||||||
|
icon: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 侧边导航菜单
|
||||||
|
const menuList = ref<menuListType[]>([
|
||||||
|
{
|
||||||
|
path: '/boat',
|
||||||
|
title: '船舶信息',
|
||||||
|
icon: 'BoatInfo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/manifest',
|
||||||
|
title: '舱单信息',
|
||||||
|
icon: 'ManifestInfo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/send',
|
||||||
|
title: '发布信息',
|
||||||
|
icon: 'SendInfo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/subscribe',
|
||||||
|
title: '订阅信息',
|
||||||
|
icon: 'SubscribeInfo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/history',
|
||||||
|
title: '历史数据',
|
||||||
|
icon: 'History',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
// 默认激活菜单
|
// 默认激活菜单
|
||||||
const activeMenu = computed(() => {
|
const activeMenu = computed(() => {
|
||||||
const { path } = route;
|
const { path } = route;
|
||||||
|
@ -27,10 +66,19 @@ const activeMenu = computed(() => {
|
||||||
// 获取路由实例
|
// 获取路由实例
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
// 筛选符合条件的路由
|
// 切换菜单
|
||||||
const menuList = computed(() => {
|
const onClickMenu = (item: menuListType) => {
|
||||||
const fRoutes = filterRoutes(router.getRoutes());
|
router.push(item.path);
|
||||||
return generateMenus(fRoutes);
|
};
|
||||||
|
|
||||||
|
// 获取广告图
|
||||||
|
const getAdImage = async () => {
|
||||||
|
const { data } = await getAdImageAPI();
|
||||||
|
console.log(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await getAdImage();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -41,6 +89,8 @@ const menuList = computed(() => {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -50,5 +100,30 @@ const menuList = computed(() => {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 170px;
|
height: 170px;
|
||||||
}
|
}
|
||||||
|
.side-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #d7d7d7;
|
||||||
|
background-color: #333;
|
||||||
|
border-bottom: 1px solid #555c64;
|
||||||
|
.side-icon {
|
||||||
|
margin-bottom: 6px;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.side-item-active {
|
||||||
|
color: #ff0;
|
||||||
|
background-color: #555;
|
||||||
|
}
|
||||||
|
.side-item:hover {
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
background-color: #000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -43,5 +43,8 @@ import Sidebar from './Sidebar/index.vue';
|
||||||
color: #fff;
|
color: #fff;
|
||||||
background-color: #9c000c;
|
background-color: #9c000c;
|
||||||
}
|
}
|
||||||
|
.el-main {
|
||||||
|
background-color: #555;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,24 +1,11 @@
|
||||||
import { App } from 'vue';
|
import { App } from 'vue';
|
||||||
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
|
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
|
||||||
import Layout from '@/layouts/index.vue';
|
import Layout from '@/layouts/index.vue';
|
||||||
import boatRoutes from './modules/boat';
|
|
||||||
import enterpriseRoutes from './modules/enterprise';
|
|
||||||
import historyRoutes from './modules/history';
|
|
||||||
import manifestRoutes from './modules/manifest';
|
|
||||||
import sendRoutes from './modules/send';
|
|
||||||
import subscriptionRoutes from './modules/subscription';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 异步路由组件
|
* 异步路由组件
|
||||||
*/
|
*/
|
||||||
export const asyncRoutes = [
|
export const asyncRoutes = [];
|
||||||
...boatRoutes,
|
|
||||||
...manifestRoutes,
|
|
||||||
...enterpriseRoutes,
|
|
||||||
...sendRoutes,
|
|
||||||
...subscriptionRoutes,
|
|
||||||
...historyRoutes,
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 公共路由
|
* 公共路由
|
||||||
|
@ -68,19 +55,61 @@ export const constantRoutes: Array<RouteRecordRaw> = [
|
||||||
path: '/notice',
|
path: '/notice',
|
||||||
name: 'Notice',
|
name: 'Notice',
|
||||||
component: () => import('@/views/Notice/index.vue'),
|
component: () => import('@/views/Notice/index.vue'),
|
||||||
meta: { title: '公告', roles: ['test2'] },
|
meta: { title: '公告' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/api',
|
path: '/api',
|
||||||
name: 'Api',
|
name: 'Api',
|
||||||
component: () => import('@/views/ApiManage/index.vue'),
|
component: () => import('@/views/ApiManage/index.vue'),
|
||||||
meta: { title: 'API', roles: ['test2'] },
|
meta: { title: 'API' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/setting',
|
||||||
|
name: 'Setting',
|
||||||
|
component: () => import('@/views/Setting/index.vue'),
|
||||||
|
meta: { title: '设置' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/help',
|
path: '/help',
|
||||||
name: 'HelpCenter',
|
name: 'HelpCenter',
|
||||||
component: () => import('@/views/Help/index.vue'),
|
component: () => import('@/views/Help/index.vue'),
|
||||||
meta: { title: '帮助', roles: ['test2'] },
|
meta: { title: '帮助' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/boat',
|
||||||
|
name: 'BoatInfo',
|
||||||
|
component: () => import('@/views/Boat/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '船舶信息',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/manifest',
|
||||||
|
name: 'Manifest',
|
||||||
|
component: () => import('@/views/Manifest/index.vue'),
|
||||||
|
meta: { title: '舱单信息' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/send',
|
||||||
|
name: 'sendInfo',
|
||||||
|
component: () => import('@/views/Send/index.vue'),
|
||||||
|
meta: { title: '发布信息' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/subscribe',
|
||||||
|
name: 'Subscribe',
|
||||||
|
component: () => import('@/views/Subscription/index.vue'),
|
||||||
|
meta: { title: '订阅信息' },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/history',
|
||||||
|
name: 'History',
|
||||||
|
component: () => import('@/views/History/index.vue'),
|
||||||
|
meta: {
|
||||||
|
title: '历史数据',
|
||||||
|
icon: 'History',
|
||||||
|
native: false,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
import { RouteRecordRaw } from 'vue-router';
|
|
||||||
import Layout from '@/layouts/index.vue';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 船期信息路由
|
|
||||||
*/
|
|
||||||
const boatRoutes: Array<RouteRecordRaw> = [
|
|
||||||
{
|
|
||||||
path: '/boat',
|
|
||||||
component: Layout,
|
|
||||||
redirect: '/boat/info',
|
|
||||||
name: 'Boat',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/boat/info',
|
|
||||||
name: 'BoatInfo',
|
|
||||||
component: () => import('@/views/Boat/Infos/index.vue'),
|
|
||||||
meta: {
|
|
||||||
title: '船期管理',
|
|
||||||
icon: 'BoatInfo',
|
|
||||||
native: false,
|
|
||||||
roles: ['test2'],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default boatRoutes;
|
|
|
@ -1,41 +0,0 @@
|
||||||
import { RouteRecordRaw } from 'vue-router';
|
|
||||||
import Layout from '@/layouts/index.vue';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 企业管理路由
|
|
||||||
*/
|
|
||||||
const enterpriseRoutes: Array<RouteRecordRaw> = [
|
|
||||||
{
|
|
||||||
path: '/enterprise',
|
|
||||||
component: Layout,
|
|
||||||
redirect: '/enterprise/manage',
|
|
||||||
name: 'Enterprise',
|
|
||||||
// meta: {
|
|
||||||
// title: '企业中心',
|
|
||||||
// icon: 'Setting',
|
|
||||||
// roles: ['test2'], // 测试权限
|
|
||||||
// },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/enterprise/manage',
|
|
||||||
name: 'CompanyManage',
|
|
||||||
component: () => import('@/views/Enterprise/Manage/index.vue'),
|
|
||||||
// meta: { title: '企业管理', icon: 'Menu', roles: ['test2'] },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/enterprise/employee',
|
|
||||||
name: 'EmployeeManage',
|
|
||||||
component: () => import('@/views/Enterprise/Employee/index.vue'),
|
|
||||||
// meta: { title: '员工管理', icon: 'Menu', roles: ['test2'] },
|
|
||||||
},
|
|
||||||
// {
|
|
||||||
// path: '/enterprise/register',
|
|
||||||
// name: 'CompanyRegister',
|
|
||||||
// component: () => import('@/views/Enterprise/Company/index.vue'),
|
|
||||||
// meta: { title: '企业注册', icon: 'Menu', roles: ['test2'] },
|
|
||||||
// },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default enterpriseRoutes;
|
|
|
@ -1,24 +0,0 @@
|
||||||
import { RouteRecordRaw } from 'vue-router';
|
|
||||||
import Layout from '@/layouts/index.vue';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 帮助信息路由
|
|
||||||
*/
|
|
||||||
const helpRoutes: Array<RouteRecordRaw> = [
|
|
||||||
{
|
|
||||||
path: '/help',
|
|
||||||
component: Layout,
|
|
||||||
redirect: '/help/center',
|
|
||||||
name: 'help',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/help/center',
|
|
||||||
name: 'HelpCenter',
|
|
||||||
component: () => import('@/views/Help/index.vue'),
|
|
||||||
meta: { title: '帮助信息', icon: 'Menu', roles: ['test2'] },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default helpRoutes;
|
|
|
@ -1,32 +0,0 @@
|
||||||
import { RouteRecordRaw } from 'vue-router';
|
|
||||||
import Layout from '@/layouts/index.vue';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 历史数据路由
|
|
||||||
*/
|
|
||||||
const historyRoutes: Array<RouteRecordRaw> = [
|
|
||||||
{
|
|
||||||
path: '/history',
|
|
||||||
component: Layout,
|
|
||||||
redirect: '/history/mine',
|
|
||||||
// meta: {
|
|
||||||
// title: '历史数据',
|
|
||||||
// icon: 'History',
|
|
||||||
// native: false,
|
|
||||||
// },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/history/mine',
|
|
||||||
name: 'Mine',
|
|
||||||
component: () => import('@/views/History/index.vue'),
|
|
||||||
meta: {
|
|
||||||
title: '历史数据',
|
|
||||||
icon: 'History',
|
|
||||||
native: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default historyRoutes;
|
|
|
@ -1,35 +0,0 @@
|
||||||
import { RouteRecordRaw } from 'vue-router';
|
|
||||||
import Layout from '@/layouts/index.vue';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 舱单路由
|
|
||||||
*/
|
|
||||||
const manifestRoutes: Array<RouteRecordRaw> = [
|
|
||||||
{
|
|
||||||
path: '/manifest',
|
|
||||||
component: Layout,
|
|
||||||
redirect: '/manifest/manage',
|
|
||||||
name: 'Manifest',
|
|
||||||
// meta: {
|
|
||||||
// title: '舱单管理',
|
|
||||||
// icon: 'Setting',
|
|
||||||
// roles: ['test2'], // 测试权限
|
|
||||||
// },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/manifest/manage',
|
|
||||||
name: 'ManifestManage',
|
|
||||||
component: () => import('@/views/Manifest/Manage/index.vue'),
|
|
||||||
meta: { title: '舱单信息', icon: 'ManifestInfo', native: false },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/manifest/detail',
|
|
||||||
name: 'ManifestDetail',
|
|
||||||
component: () => import('@/views/Manifest/Detail/index.vue'),
|
|
||||||
// meta: { title: '舱单明细', icon: 'Menu', roles: ['test2'] },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default manifestRoutes;
|
|
|
@ -1,31 +0,0 @@
|
||||||
import { RouteRecordRaw } from 'vue-router';
|
|
||||||
import Layout from '@/layouts/index.vue';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 订阅信息路由
|
|
||||||
*/
|
|
||||||
const subscriptionRoutes: Array<RouteRecordRaw> = [
|
|
||||||
{
|
|
||||||
path: '/subscribe',
|
|
||||||
component: Layout,
|
|
||||||
redirect: '/subscribe/manage',
|
|
||||||
name: 'Subscribe',
|
|
||||||
meta: { title: '订阅管理', icon: 'SubscribeInfo', native: false },
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/subscribe/publish',
|
|
||||||
name: 'SubscribePublish',
|
|
||||||
component: () => import('@/views/Subscription/Publish/index.vue'),
|
|
||||||
meta: { title: '我的订阅', icon: 'Menu', native: true, roles: ['test2'] },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/subscribe/receive',
|
|
||||||
name: 'SubscribeReceive',
|
|
||||||
component: () => import('@/views/Subscription/Receive/index.vue'),
|
|
||||||
meta: { title: '收到订阅', icon: 'Menu', native: true, roles: ['test2'] },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default subscriptionRoutes;
|
|
|
@ -1,35 +0,0 @@
|
||||||
import { RouteRecordRaw } from 'vue-router';
|
|
||||||
import Layout from '@/layouts/index.vue';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 系统设置路由
|
|
||||||
*/
|
|
||||||
const systemRoutes: Array<RouteRecordRaw> = [
|
|
||||||
{
|
|
||||||
path: '/system',
|
|
||||||
component: Layout,
|
|
||||||
redirect: '/system/user',
|
|
||||||
name: 'System',
|
|
||||||
meta: {
|
|
||||||
title: '系统管理',
|
|
||||||
icon: 'Setting',
|
|
||||||
roles: ['test2'], // 测试权限
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
path: '/system/user',
|
|
||||||
name: 'User',
|
|
||||||
component: () => import('@/views/System/Users/index.vue'),
|
|
||||||
meta: { title: '用户管理', icon: 'Menu', roles: ['test2'] },
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: '/system/role',
|
|
||||||
name: 'Roles',
|
|
||||||
component: () => import('@/views/System/Roles/index.vue'),
|
|
||||||
meta: { title: '角色管理', icon: 'Menu', roles: ['test2'] },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
export default systemRoutes;
|
|
|
@ -1,8 +1,24 @@
|
||||||
.el-table__header th {
|
.el-table__header th {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #252525;
|
color: #fff;
|
||||||
background: #fafafa;
|
background: #005478;
|
||||||
}
|
}
|
||||||
.el-table .el-table__header th {
|
.el-table .el-table__header th {
|
||||||
background: var(--el-fill-color-light) !important;
|
background: #005478 !important;
|
||||||
|
}
|
||||||
|
.el-table,
|
||||||
|
.el-table__expanded-cell {
|
||||||
|
background-color: #555;
|
||||||
|
}
|
||||||
|
.el-table tr {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #555;
|
||||||
|
}
|
||||||
|
.el-table__body tr.hover-row > td.el-table__cell {
|
||||||
|
color: #000;
|
||||||
|
background-color: #ffc;
|
||||||
|
}
|
||||||
|
.el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell {
|
||||||
|
color: #000;
|
||||||
|
background-color: #ffc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,12 +45,3 @@ body {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
|
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
|
||||||
}
|
}
|
||||||
.card {
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding: 20px;
|
|
||||||
overflow-x: hidden;
|
|
||||||
background-color: var(--el-bg-color);
|
|
||||||
border: 1px solid var(--el-border-color-light);
|
|
||||||
border-radius: 6px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
}
|
|
||||||
|
|
|
@ -16,6 +16,8 @@ export interface EmployeeType {
|
||||||
nickname: string;
|
nickname: string;
|
||||||
username: string;
|
username: string;
|
||||||
phone: string;
|
phone: string;
|
||||||
|
dept: string;
|
||||||
|
job: string;
|
||||||
wharfId: number;
|
wharfId: number;
|
||||||
userId: number;
|
userId: number;
|
||||||
password: string;
|
password: string;
|
||||||
|
|
|
@ -25,6 +25,7 @@ export interface BoatInfoType {
|
||||||
shipStatus: string;
|
shipStatus: string;
|
||||||
tradeType: string;
|
tradeType: string;
|
||||||
loadPortId: number | string;
|
loadPortId: number | string;
|
||||||
|
loadPort: PortType;
|
||||||
dischargePortId: number | string;
|
dischargePortId: number | string;
|
||||||
ship: ShipType;
|
ship: ShipType;
|
||||||
route: BoatRouteType;
|
route: BoatRouteType;
|
||||||
|
@ -80,6 +81,31 @@ export interface LoadWharfType {
|
||||||
port: PortType;
|
port: PortType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 码头简介类型
|
||||||
|
*/
|
||||||
|
export interface LoadInfoType {
|
||||||
|
id: number;
|
||||||
|
createBy: number;
|
||||||
|
createDate: string;
|
||||||
|
updateBy: number;
|
||||||
|
updateDate: string;
|
||||||
|
version: number;
|
||||||
|
name: string;
|
||||||
|
portId: number;
|
||||||
|
address: string;
|
||||||
|
longitude: number;
|
||||||
|
latitude: number;
|
||||||
|
berthageNum: number;
|
||||||
|
transitCapacity: number;
|
||||||
|
storageCapacity: number;
|
||||||
|
handlingCapacity: number;
|
||||||
|
photo: string;
|
||||||
|
intro: string;
|
||||||
|
status: string;
|
||||||
|
port: PortType;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 码头分页列表类型
|
* 码头分页列表类型
|
||||||
*/
|
*/
|
||||||
|
@ -268,3 +294,18 @@ export interface ProvinceCityType {
|
||||||
code: string;
|
code: string;
|
||||||
status: string;
|
status: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车架号查询结果类型
|
||||||
|
*/
|
||||||
|
export interface vinSearchType {
|
||||||
|
id: number;
|
||||||
|
createBy: number;
|
||||||
|
createDate: string;
|
||||||
|
updateBy: number;
|
||||||
|
updateDate: string;
|
||||||
|
version: number;
|
||||||
|
scheduleId: number;
|
||||||
|
shipStatus: string;
|
||||||
|
schedule: BoatInfoType;
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { PageRowsType } from '.';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 帮助中心类型
|
* 帮助中心类型
|
||||||
*/
|
*/
|
||||||
|
@ -31,6 +33,13 @@ export interface ApiManageType {
|
||||||
resp: string;
|
resp: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api接口分页类型
|
||||||
|
*/
|
||||||
|
export interface ApiManagePageType extends PageRowsType {
|
||||||
|
apiType: '基础数据' | '信息发布' | '信息订阅' | '信息查询';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 首页数据统计接口
|
* 首页数据统计接口
|
||||||
*/
|
*/
|
||||||
|
@ -60,3 +69,17 @@ export interface OutImportVoyages {
|
||||||
fields: any[];
|
fields: any[];
|
||||||
datas: any[];
|
datas: any[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 协议类型
|
||||||
|
*/
|
||||||
|
export interface agreeTextType {
|
||||||
|
id: number;
|
||||||
|
createBy: number;
|
||||||
|
createDate: string;
|
||||||
|
updateBy: number;
|
||||||
|
updateDate: string;
|
||||||
|
version: number;
|
||||||
|
content: string;
|
||||||
|
textType: string;
|
||||||
|
}
|
||||||
|
|
|
@ -21,8 +21,8 @@ export interface roleType {
|
||||||
* 添加角色操作权限
|
* 添加角色操作权限
|
||||||
*/
|
*/
|
||||||
export interface rolePremType {
|
export interface rolePremType {
|
||||||
roleId: number;
|
userId: number | string;
|
||||||
perms: any[];
|
perms: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -51,6 +51,6 @@ export const checkStatus = (status: number, message?: string | Array<string>): v
|
||||||
if (message) {
|
if (message) {
|
||||||
errMsg = typeof message === 'string' ? message : message[0];
|
errMsg = typeof message === 'string' ? message : message[0];
|
||||||
}
|
}
|
||||||
ElMessage.error('请求失败!');
|
ElMessage.error(errMsg || '请求失败!');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,119 +1,82 @@
|
||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog v-model="dialogVisible" title="查看接口" width="80%" @close="onCloseDialog">
|
||||||
v-model="dialogVisible"
|
<div class="content">
|
||||||
:title="`${dialogProps.title}码头`"
|
<div class="item">
|
||||||
width="80%"
|
<div class="title">接口名称:</div>
|
||||||
@close="onCloseDialog"
|
<div class="text">{{ dialogProps?.name }}</div>
|
||||||
>
|
</div>
|
||||||
<el-form
|
<div class="item">
|
||||||
ref="ruleFormRef"
|
<div class="title">接口地址:</div>
|
||||||
label-width="auto"
|
<div class="text">{{ dialogProps?.url }}</div>
|
||||||
:rules="formRules"
|
</div>
|
||||||
:disabled="dialogProps.isView"
|
<div class="item">
|
||||||
:model="dialogProps.row"
|
<div class="title">接口功能:</div>
|
||||||
:hide-required-asterisk="dialogProps.isView"
|
<div class="text">{{ dialogProps?.remark }}</div>
|
||||||
>
|
</div>
|
||||||
<el-form-item label="名称" prop="name">
|
<div class="item">
|
||||||
<el-input v-model="dialogProps.row!.name" placeholder="请输入名称" />
|
<div class="title">接口参数:</div>
|
||||||
</el-form-item>
|
<div class="text">{{ dialogProps?.req }}</div>
|
||||||
|
</div>
|
||||||
<!-- 接口地址 -->
|
<div class="item">
|
||||||
<el-form-item label="接口地址" prop="url">
|
<div class="title">接口返回:</div>
|
||||||
<el-input v-model="dialogProps.row!.url" placeholder="请输入接口地址" />
|
<div class="text">{{ dialogProps?.resp }}</div>
|
||||||
</el-form-item>
|
</div>
|
||||||
|
</div>
|
||||||
<!-- 功能描述 -->
|
|
||||||
<el-form-item label="功能描述" prop="remark">
|
|
||||||
<el-input v-model="dialogProps.row!.remark" placeholder="请输入功能描述" />
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<!-- 接口参数 -->
|
|
||||||
<el-form-item label="接口参数" prop="req">
|
|
||||||
<el-input v-model="dialogProps.row!.req" placeholder="请输入接口参数" />
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<!-- 接口返回 -->
|
|
||||||
<el-form-item label="接口返回" prop="resp">
|
|
||||||
<el-input v-model="dialogProps.row!.resp" placeholder="请输入接口返回" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
<el-button @click="dialogVisible = false">取消</el-button>
|
||||||
<el-button v-show="!dialogProps.isView" type="primary" @click="onClickConfirm(ruleFormRef)">
|
|
||||||
确认
|
|
||||||
</el-button>
|
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ElMessage, FormInstance, FormRules } from 'element-plus';
|
import {} from 'element-plus';
|
||||||
import { reactive, ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
import { postApiGetAPI } from '@/api/ApiManage';
|
||||||
import { ApiManageType } from '@/types/help';
|
import { ApiManageType } from '@/types/help';
|
||||||
|
|
||||||
interface DialogPropsType {
|
|
||||||
title: string;
|
|
||||||
isView: boolean;
|
|
||||||
row: Partial<ApiManageType>;
|
|
||||||
api?: (params: any) => Promise<any>;
|
|
||||||
getTableList?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 是否显示dialog
|
// 是否显示dialog
|
||||||
const dialogVisible = ref(false);
|
const dialogVisible = ref(false);
|
||||||
|
|
||||||
// 父组件传递的值
|
// 父组件传递的值
|
||||||
const dialogProps = ref<DialogPropsType>({
|
const dialogProps = ref<ApiManageType>();
|
||||||
isView: false,
|
|
||||||
title: '',
|
// 获取接口详情
|
||||||
row: {},
|
const getApiManageData = async (id: string | number) => {
|
||||||
});
|
const { data } = await postApiGetAPI({ id });
|
||||||
|
dialogProps.value = data;
|
||||||
|
};
|
||||||
|
|
||||||
// 显示dialog,新增/编辑订阅
|
// 显示dialog,新增/编辑订阅
|
||||||
const isShowDialog = (params: DialogPropsType) => {
|
const isShowDialog = async (params: ApiManageType) => {
|
||||||
dialogProps.value = params;
|
params.id && (await getApiManageData(params.id));
|
||||||
dialogVisible.value = true;
|
dialogVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 向父组件暴露该方法
|
// 向父组件暴露该方法
|
||||||
defineExpose({ isShowDialog });
|
defineExpose({ isShowDialog });
|
||||||
|
|
||||||
const formRules = reactive<FormRules>({
|
|
||||||
name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
|
|
||||||
url: [{ required: true, message: '请输入接口地址', trigger: 'blur' }],
|
|
||||||
remark: [{ required: true, message: '请输入功能描述', trigger: 'blur' }],
|
|
||||||
req: [{ required: true, message: '请输入接口参数', trigger: 'blur' }],
|
|
||||||
resp: [{ required: true, message: '请输入接口返回', trigger: 'blur' }],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 表单节点
|
|
||||||
const ruleFormRef = ref<FormInstance>();
|
|
||||||
|
|
||||||
// dialog 关闭事件
|
// dialog 关闭事件
|
||||||
const onCloseDialog = () => {
|
const onCloseDialog = () => {
|
||||||
// 重置表单
|
dialogVisible.value = false;
|
||||||
ruleFormRef.value?.resetFields();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 新增/编辑
|
|
||||||
const onClickConfirm = (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
formEl.validate(async (valid) => {
|
|
||||||
if (!valid) return;
|
|
||||||
try {
|
|
||||||
await dialogProps.value.api!(dialogProps.value.row);
|
|
||||||
ElMessage({
|
|
||||||
message: `${dialogProps.value.title}成功`,
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
dialogProps.value.getTableList!();
|
|
||||||
} finally {
|
|
||||||
dialogVisible.value = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped>
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 27px;
|
||||||
|
.title {
|
||||||
|
font-weight: 700;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -1,22 +1,30 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="table">
|
<div class="table">
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="footer-util">滚装船货信息平台API开放接口文档</div>
|
<div class="footer-util">
|
||||||
|
<div class="title">滚装船货信息平台API开放接口文档</div>
|
||||||
|
<div class="api-btn">
|
||||||
|
<div
|
||||||
|
class="btn"
|
||||||
|
:class="{ 'btn-active': currentApiType === item }"
|
||||||
|
v-for="item in apiTypeList"
|
||||||
|
:key="item"
|
||||||
|
@click="onClickChangeApiType(item)"
|
||||||
|
>
|
||||||
|
{{ item }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
<div class="footer-table">
|
<div class="footer-table">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="tableLoading"
|
v-loading="tableLoading"
|
||||||
:data="tableState.tableData"
|
:data="tableState.tableData"
|
||||||
border
|
border
|
||||||
stripe
|
|
||||||
style="width: 100%; height: 100%"
|
style="width: 100%; height: 100%"
|
||||||
>
|
>
|
||||||
<el-table-column prop="name" label="名称" align="center" width="180" />
|
<el-table-column prop="name" label="名称" align="center" width="180" />
|
||||||
<el-table-column prop="url" label="接口地址" align="center" width="150" />
|
<el-table-column prop="remark" label="功能描述" align="center" />
|
||||||
<el-table-column prop="remark" label="功能描述" align="center" width="200" />
|
|
||||||
<el-table-column prop="req" label="接口参数" align="center" width="150" />
|
|
||||||
<el-table-column prop="resp" label="接口返回" align="center" width="150" />
|
|
||||||
<el-table-column prop="createDate" label="创建时间" align="center" width="180" />
|
|
||||||
<el-table-column prop="operator" label="操作" width="200px" align="center" fixed="right">
|
<el-table-column prop="operator" label="操作" width="200px" align="center" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
|
@ -24,7 +32,7 @@
|
||||||
size="small"
|
size="small"
|
||||||
icon="View"
|
icon="View"
|
||||||
link
|
link
|
||||||
@click="onClickOpenDialog('查看', scope.row)"
|
@click="onClickOpenDialog(scope.row)"
|
||||||
>
|
>
|
||||||
查看
|
查看
|
||||||
</el-button>
|
</el-button>
|
||||||
|
@ -47,18 +55,38 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { postApiPageAPI, postApiSaveAPI } from '@/api/ApiManage';
|
import { postApiPageAPI } from '@/api/ApiManage';
|
||||||
import Pagination from '@/components/Pagination/Pagination.vue';
|
import Pagination from '@/components/Pagination/Pagination.vue';
|
||||||
import { useTable } from '@/hooks/useTable';
|
import { useTable } from '@/hooks/useTable';
|
||||||
import { ApiManageType } from '@/types/help';
|
import { ApiManageType } from '@/types/help';
|
||||||
import ApiDialog from './ApiDialog.vue';
|
import ApiDialog from './ApiDialog.vue';
|
||||||
|
|
||||||
|
type apiInterface = '基础数据' | '信息发布' | '信息订阅' | '信息查询';
|
||||||
|
|
||||||
|
// api类型列表
|
||||||
|
const apiTypeList = ref<apiInterface[]>(['基础数据', '信息发布', '信息订阅', '信息查询']);
|
||||||
|
const currentApiType = ref<apiInterface>('基础数据');
|
||||||
|
const onClickChangeApiType = async (item: apiInterface) => {
|
||||||
|
if (item === currentApiType.value) return;
|
||||||
|
|
||||||
|
currentApiType.value = item;
|
||||||
|
// 添加查询参数
|
||||||
|
tableState.value.searchParam = {
|
||||||
|
apiType: item,
|
||||||
|
};
|
||||||
|
await searchTable();
|
||||||
|
};
|
||||||
|
|
||||||
// 获取列表表格数据
|
// 获取列表表格数据
|
||||||
const { getTableList, tableState, tableChangeCurrent, tableChangeSize } = useTable({
|
const { getTableList, tableState, searchTable, tableChangeCurrent, tableChangeSize } = useTable({
|
||||||
api: postApiPageAPI,
|
api: postApiPageAPI,
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
tableState.value.searchInitParam = {
|
||||||
|
apiType: currentApiType.value,
|
||||||
|
};
|
||||||
|
|
||||||
await getTableList();
|
await getTableList();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -66,15 +94,8 @@ const tableLoading = ref(false);
|
||||||
|
|
||||||
// 新增/编辑企业
|
// 新增/编辑企业
|
||||||
const apiDialogRef = ref<InstanceType<typeof ApiDialog> | null>(null);
|
const apiDialogRef = ref<InstanceType<typeof ApiDialog> | null>(null);
|
||||||
const onClickOpenDialog = (title: string, row: Partial<ApiManageType> = {}) => {
|
const onClickOpenDialog = (row: ApiManageType) => {
|
||||||
const params = {
|
apiDialogRef.value?.isShowDialog(row);
|
||||||
title,
|
|
||||||
isView: title === '查看',
|
|
||||||
row: { ...row },
|
|
||||||
api: postApiSaveAPI,
|
|
||||||
getTableList,
|
|
||||||
};
|
|
||||||
apiDialogRef.value?.isShowDialog(params);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变每页显示条目个数
|
// 改变每页显示条目个数
|
||||||
|
@ -99,7 +120,6 @@ const handleCurrentChange = async (val: number) => {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 16px 16px 0;
|
padding: 16px 16px 0;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
||||||
}
|
}
|
||||||
|
@ -111,17 +131,43 @@ const handleCurrentChange = async (val: number) => {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
||||||
.footer-util {
|
.footer-util {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: space-between;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
font-size: 30px;
|
color: #fff;
|
||||||
font-weight: 700;
|
.title {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.api-btn {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
.btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 150px;
|
||||||
|
height: 50px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #d7d7d7;
|
||||||
|
background-color: rgb(51 51 51 / 100%);
|
||||||
|
border-radius: 75px;
|
||||||
|
box-shadow: 5px 5px 5px rgb(0 0 0 / 34.9%);
|
||||||
|
}
|
||||||
|
.btn-active {
|
||||||
|
color: #000;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.footer-table {
|
.footer-table {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="Manage">
|
|
||||||
<BoatTable />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import BoatTable from './components/BoatTable.vue';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.manage {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -18,6 +18,9 @@
|
||||||
<el-button icon="Refresh" @click="onClickResetForm(tableFormRef)">重置</el-button>
|
<el-button icon="Refresh" @click="onClickResetForm(tableFormRef)">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
<div>
|
||||||
|
<el-button type="success" @click="onClickExport">船期导出</el-button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
|
@ -26,7 +29,6 @@
|
||||||
v-loading="tableLoading"
|
v-loading="tableLoading"
|
||||||
:data="tableState.tableData"
|
:data="tableState.tableData"
|
||||||
border
|
border
|
||||||
stripe
|
|
||||||
style="width: 100%; height: 100%"
|
style="width: 100%; height: 100%"
|
||||||
>
|
>
|
||||||
<el-table-column prop="enterprise.name" label="企业" align="center" width="150" />
|
<el-table-column prop="enterprise.name" label="企业" align="center" width="150" />
|
||||||
|
@ -61,7 +63,7 @@
|
||||||
<el-table-column prop="loadPort.name" label="装货港口" align="center" width="150" />
|
<el-table-column prop="loadPort.name" label="装货港口" align="center" width="150" />
|
||||||
<el-table-column prop="dischargePort.name" label="卸货港口" align="center" width="150" />
|
<el-table-column prop="dischargePort.name" label="卸货港口" align="center" width="150" />
|
||||||
<el-table-column prop="createDate" label="创建时间" align="center" width="180" />
|
<el-table-column prop="createDate" label="创建时间" align="center" width="180" />
|
||||||
<!-- <el-table-column prop="operator" label="操作" width="200px" align="center" fixed="right">
|
<el-table-column prop="operator" label="操作" width="200px" align="center" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
|
@ -73,7 +75,7 @@
|
||||||
查看
|
查看
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column> -->
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</div>
|
</div>
|
||||||
<!-- 分页 -->
|
<!-- 分页 -->
|
||||||
|
@ -90,9 +92,13 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { FormInstance } from 'element-plus';
|
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { getSailSchedulePageAPI } from '@/api/Boat/info';
|
import {
|
||||||
|
getSailScheduleExportAPI,
|
||||||
|
getSailScheduleGetAPI,
|
||||||
|
getSailSchedulePageAPI,
|
||||||
|
} from '@/api/Boat/info';
|
||||||
import { postShipListAPI } from '@/api/Ship';
|
import { postShipListAPI } from '@/api/Ship';
|
||||||
import Pagination from '@/components/Pagination/Pagination.vue';
|
import Pagination from '@/components/Pagination/Pagination.vue';
|
||||||
import RemoteSelect from '@/components/RemoteSelect/index.vue';
|
import RemoteSelect from '@/components/RemoteSelect/index.vue';
|
||||||
|
@ -151,11 +157,55 @@ const onClickResetForm = async (formEl: FormInstance | undefined) => {
|
||||||
formEl.resetFields();
|
formEl.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onClickExport = () => {
|
||||||
|
ElMessageBox.confirm(`你确定要导出船期信息吗?`, '温馨提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
draggable: true,
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
try {
|
||||||
|
let params: any = {
|
||||||
|
rows: tableState.value.pageAble.rows,
|
||||||
|
page: tableState.value.pageAble.page,
|
||||||
|
};
|
||||||
|
if (searchTableForm.shipId) {
|
||||||
|
params.shipId = searchTableForm.shipId;
|
||||||
|
}
|
||||||
|
if (searchTableForm.voyage) {
|
||||||
|
params.voyage = searchTableForm.voyage;
|
||||||
|
}
|
||||||
|
const { data } = await getSailScheduleExportAPI(params);
|
||||||
|
const blob = new Blob([data], {
|
||||||
|
type: 'application/vnd.ms-excel;charset=utf-8',
|
||||||
|
});
|
||||||
|
const downloadUrl = URL.createObjectURL(blob);
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = downloadUrl;
|
||||||
|
link.download = '船期信息.xlsx';
|
||||||
|
link.click();
|
||||||
|
ElMessage({
|
||||||
|
message: '导出成功',
|
||||||
|
type: 'success',
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage({
|
||||||
|
message: '导出失败',
|
||||||
|
type: 'error',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
console.log('用户点击了取消');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// 查看详情
|
// 查看详情
|
||||||
// const onClickOpenDetail = async (row: BoatInfoType) => {
|
const onClickOpenDetail = async (row: BoatInfoType) => {
|
||||||
// const { data } = await getSailScheduleGetAPI({ id: row.id });
|
const { data } = await getSailScheduleGetAPI({ id: row.id });
|
||||||
// console.log('🚀 ~ file: BoatTable.vue:146 ~ onClickOpenDetail ~ data:', data);
|
console.log('🚀 ~ file: BoatTable.vue:146 ~ onClickOpenDetail ~ data:', data);
|
||||||
// };
|
};
|
||||||
|
|
||||||
// 改变每页显示条目个数
|
// 改变每页显示条目个数
|
||||||
const handleSizeChange = async (val: number) => {
|
const handleSizeChange = async (val: number) => {
|
||||||
|
@ -177,11 +227,8 @@ const handleCurrentChange = async (val: number) => {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 16px 16px 0;
|
justify-content: space-between;
|
||||||
margin-bottom: 16px;
|
padding: 0 16px;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
}
|
}
|
||||||
.footer {
|
.footer {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -191,9 +238,6 @@ const handleCurrentChange = async (val: number) => {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
.footer-util {
|
.footer-util {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
|
@ -0,0 +1,92 @@
|
||||||
|
<template>
|
||||||
|
<div class="table">
|
||||||
|
<div class="header">
|
||||||
|
<div class="title">{{ currentSubscribeNav }}</div>
|
||||||
|
<div class="api-btn">
|
||||||
|
<div
|
||||||
|
class="btn"
|
||||||
|
:class="{ 'btn-active': currentSubscribeNav === item }"
|
||||||
|
v-for="item in subscribeNavList"
|
||||||
|
:key="item"
|
||||||
|
@click="onClickChangeSubscribeType(item)"
|
||||||
|
>
|
||||||
|
{{ item }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<BoatTable v-if="currentSubscribeNav === '船期信息'" />
|
||||||
|
<!-- <ManifestDetailTable v-if="currentSubscribeNav === '船图查询'" /> -->
|
||||||
|
<!-- <ReceiveTable v-if="currentSubscribeNav === '船位跟踪'" /> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
// import ManifestDetailTable from './components/ManifestDetailTable.vue';
|
||||||
|
import BoatTable from './components/BoatTable.vue';
|
||||||
|
|
||||||
|
// 订阅导航列表
|
||||||
|
const subscribeNavList = ref(['船期信息', '船图查询', '船位跟踪']);
|
||||||
|
const currentSubscribeNav = ref('船期信息');
|
||||||
|
const onClickChangeSubscribeType = async (item: string) => {
|
||||||
|
if (item === currentSubscribeNav.value) return;
|
||||||
|
currentSubscribeNav.value = item;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.table {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.header {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 16px 16px 0;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #fff;
|
||||||
|
.title {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.api-btn {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
.btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 150px;
|
||||||
|
height: 50px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #d7d7d7;
|
||||||
|
background-color: rgb(51 51 51 / 100%);
|
||||||
|
border-radius: 75px;
|
||||||
|
box-shadow: 5px 5px 5px rgb(0 0 0 / 34.9%);
|
||||||
|
}
|
||||||
|
.btn-active {
|
||||||
|
color: #000;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 1;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,19 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="manage">
|
|
||||||
<CompanyRegister :isShowBackBtn="false" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import CompanyRegister from '@/views/Login/register.vue';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.manage {
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 25px;
|
|
||||||
background-color: #fff;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,18 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="manage">
|
|
||||||
<EmployeeTable />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import EmployeeTable from './components/EmployeeTable.vue';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.manage {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,239 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-dialog
|
|
||||||
v-model="dialogVisible"
|
|
||||||
:title="`${dialogProps.title}企业`"
|
|
||||||
width="80%"
|
|
||||||
@close="onCloseDialog"
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="ruleFormRef"
|
|
||||||
label-width="auto"
|
|
||||||
:rules="formRules"
|
|
||||||
:disabled="dialogProps.isView"
|
|
||||||
:model="dialogProps.row"
|
|
||||||
:hide-required-asterisk="dialogProps.isView"
|
|
||||||
>
|
|
||||||
<el-row>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="企业类型" prop="enterpriseType" required>
|
|
||||||
<el-select
|
|
||||||
v-model="dialogProps.row!.enterpriseType"
|
|
||||||
placeholder="请选择企业类型"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in companyTypeList"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="港口" prop="portId" required>
|
|
||||||
<RemoteSelect
|
|
||||||
v-model:value="dialogProps.row!.portId"
|
|
||||||
placeholder="请选择港口"
|
|
||||||
:api="postPortListAPI"
|
|
||||||
:disabled="dialogProps.isView"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="企业全称" prop="name">
|
|
||||||
<el-input v-model="dialogProps.row!.name" placeholder="请输入企业全称" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="企业统一社会信用代码" prop="code">
|
|
||||||
<el-input v-model="dialogProps.row!.code" placeholder="请输入企业统一社会信用代码" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="合同编号" prop="contractNo">
|
|
||||||
<el-input v-model="dialogProps.row!.contractNo" placeholder="请输入合同编号" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="法定代表人" prop="legalPerson">
|
|
||||||
<el-input v-model="dialogProps.row!.legalPerson" placeholder="请输入法定代表人" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="地址" prop="address">
|
|
||||||
<el-input v-model="dialogProps.row!.address" placeholder="请输入企业地址" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="企业状态">
|
|
||||||
<el-tag v-if="dialogProps.row!.enterpriseStatus === '正常'" type="success">
|
|
||||||
{{ dialogProps.row!.enterpriseStatus }}
|
|
||||||
</el-tag>
|
|
||||||
<el-tag v-else-if="dialogProps.row!.enterpriseStatus === '待审核'" type="danger">
|
|
||||||
{{ dialogProps.row!.enterpriseStatus }}
|
|
||||||
</el-tag>
|
|
||||||
<el-tag v-else-if="dialogProps.row!.enterpriseStatus === '已注册'" type="primary">
|
|
||||||
{{ dialogProps.row!.enterpriseStatus }}
|
|
||||||
</el-tag>
|
|
||||||
<el-tag v-else type="info">{{ dialogProps.row!.enterpriseStatus }}</el-tag>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="营业执照" prop="licensePhoto">
|
|
||||||
<UploadImg
|
|
||||||
v-model:imageID="dialogProps.row!.licensePhoto"
|
|
||||||
width="135px"
|
|
||||||
height="135px"
|
|
||||||
:file-size="3"
|
|
||||||
:fileNo="dialogProps.row!.code"
|
|
||||||
:companyID="dialogProps.row!.id"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="联系人" prop="linkman">
|
|
||||||
<el-input v-model="dialogProps.row!.linkman" placeholder="请输入联系人姓名" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="手机号" prop="phone">
|
|
||||||
<el-input v-model="dialogProps.row!.phone" placeholder="请填写手机号码" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="身份证" prop="idPhoto">
|
|
||||||
<UploadImg
|
|
||||||
v-model:imageID="dialogProps.row!.idPhoto"
|
|
||||||
width="135px"
|
|
||||||
height="135px"
|
|
||||||
:file-size="3"
|
|
||||||
:imgType="1"
|
|
||||||
:fileNo="dialogProps.row!.phone"
|
|
||||||
:companyID="dialogProps.row!.id"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</el-form>
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
|
||||||
<el-button
|
|
||||||
v-if="dialogProps.row!.enterpriseStatus === '待审核'"
|
|
||||||
type="success"
|
|
||||||
@click="onClickRegPass(dialogProps.row.id!)"
|
|
||||||
>审核通过</el-button
|
|
||||||
>
|
|
||||||
<el-button v-show="!dialogProps.isView" type="primary" @click="onClickConfirm(ruleFormRef)"
|
|
||||||
>确认</el-button
|
|
||||||
>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ElMessage, ElMessageBox, FormInstance, FormRules } from 'element-plus';
|
|
||||||
import { reactive, ref } from 'vue';
|
|
||||||
import { postEnterpriseRegPassAPI } from '@/api/Enterprise/company';
|
|
||||||
import { postPortListAPI } from '@/api/Port';
|
|
||||||
import RemoteSelect from '@/components/RemoteSelect/index.vue';
|
|
||||||
import UploadImg from '@/components/Upload/img.vue';
|
|
||||||
import { EnterpriseType } from '@/types/boatInfo';
|
|
||||||
|
|
||||||
interface DialogPropsType {
|
|
||||||
title: string;
|
|
||||||
isView: boolean;
|
|
||||||
row: Partial<EnterpriseType>;
|
|
||||||
api?: (params: any) => Promise<any>;
|
|
||||||
getTableList?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 企业列表
|
|
||||||
const companyTypeList = [
|
|
||||||
{
|
|
||||||
value: '港口码头',
|
|
||||||
label: '港口码头',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '船公司',
|
|
||||||
label: '船公司',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '货主',
|
|
||||||
label: '货主',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '船代',
|
|
||||||
label: '船代',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '货贷',
|
|
||||||
label: '货贷',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// 是否显示dialog
|
|
||||||
const dialogVisible = ref(false);
|
|
||||||
|
|
||||||
// 父组件传递的值
|
|
||||||
const dialogProps = ref<DialogPropsType>({
|
|
||||||
isView: false,
|
|
||||||
title: '',
|
|
||||||
row: {},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 显示dialog,新增/编辑订阅
|
|
||||||
const isShowDialog = (params: DialogPropsType) => {
|
|
||||||
dialogProps.value = params;
|
|
||||||
dialogVisible.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 向父组件暴露该方法
|
|
||||||
defineExpose({ isShowDialog });
|
|
||||||
|
|
||||||
// 校验规则
|
|
||||||
const formRules = reactive<FormRules>({
|
|
||||||
name: [{ required: true, message: '请输入企业全称', trigger: 'blur' }],
|
|
||||||
code: [{ required: true, message: '请输入企业统一社会信用代码', trigger: 'blur' }],
|
|
||||||
address: [{ required: true, message: '请输入企业地址', trigger: 'blur' }],
|
|
||||||
legalPerson: [{ required: true, message: '请输入法定代表人', trigger: 'blur' }],
|
|
||||||
contractNo: [{ required: true, message: '请输入合同编号', trigger: 'blur' }],
|
|
||||||
linkman: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
|
|
||||||
phone: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
|
|
||||||
portId: [{ required: true, message: '请选择港口', trigger: 'blur' }],
|
|
||||||
licensePhoto: [{ required: true, message: '请上传营业执照', trigger: 'blur' }],
|
|
||||||
idPhoto: [{ required: true, message: '请上传身份证照片', trigger: 'blur' }],
|
|
||||||
enterpriseType: [{ required: true, message: '请选择企业类型', trigger: 'blur' }],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 表单节点
|
|
||||||
const ruleFormRef = ref<FormInstance>();
|
|
||||||
|
|
||||||
// dialog 关闭事件
|
|
||||||
const onCloseDialog = () => {
|
|
||||||
// 重置表单
|
|
||||||
ruleFormRef.value?.resetFields();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 审核通过
|
|
||||||
const onClickRegPass = (id: number) => {
|
|
||||||
ElMessageBox.confirm('确定审核通过吗?', '温馨提示', {
|
|
||||||
confirmButtonText: '确认',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
type: 'info',
|
|
||||||
}).then(async () => {
|
|
||||||
try {
|
|
||||||
await postEnterpriseRegPassAPI([id]);
|
|
||||||
ElMessage({
|
|
||||||
type: 'success',
|
|
||||||
message: '审核通过',
|
|
||||||
});
|
|
||||||
dialogProps.value.getTableList!();
|
|
||||||
} finally {
|
|
||||||
dialogVisible.value = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 新增/编辑用户
|
|
||||||
const onClickConfirm = (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
formEl.validate(async (valid) => {
|
|
||||||
if (!valid) return;
|
|
||||||
try {
|
|
||||||
await dialogProps.value.api!(dialogProps.value.row);
|
|
||||||
ElMessage({
|
|
||||||
message: `${dialogProps.value.title}成功`,
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
dialogProps.value.getTableList!();
|
|
||||||
} finally {
|
|
||||||
dialogVisible.value = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
|
@ -1,300 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="table">
|
|
||||||
<div class="header">
|
|
||||||
<el-form :inline="true" :model="searchTableForm" ref="tableFormRef">
|
|
||||||
<el-form-item prop="enterpriseStatus">
|
|
||||||
<el-select
|
|
||||||
v-model="searchTableForm.enterpriseStatus"
|
|
||||||
placeholder="请选择状态"
|
|
||||||
style="width: 120px"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in companyTypeList"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item prop="key">
|
|
||||||
<el-input v-model="searchTableForm.key" placeholder="单位名称或税号" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="Search" @click="onClickSearch">查询</el-button>
|
|
||||||
<el-button icon="Refresh" @click="onClickResetForm(tableFormRef)">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
<div class="footer">
|
|
||||||
<!-- <div class="footer-util">
|
|
||||||
<el-button type="primary" icon="Plus" @click="onClickOpenDrawer('新增')">
|
|
||||||
新增订阅
|
|
||||||
</el-button>
|
|
||||||
</div> -->
|
|
||||||
<!-- 表格 -->
|
|
||||||
<div class="footer-table">
|
|
||||||
<el-table
|
|
||||||
v-loading="tableLoading"
|
|
||||||
:data="tableState.tableData"
|
|
||||||
border
|
|
||||||
stripe
|
|
||||||
style="width: 100%; height: 100%"
|
|
||||||
>
|
|
||||||
<el-table-column prop="name" label="企业全称" align="center" width="180" />
|
|
||||||
<el-table-column prop="legalPerson" label="法定代表人" align="center" width="100" />
|
|
||||||
<el-table-column prop="code" label="企业统一社会信用代码" align="center" width="200" />
|
|
||||||
<el-table-column prop="address" label="地址" align="center" width="180" />
|
|
||||||
<el-table-column prop="enterpriseType" label="企业类型" align="center" width="180" />
|
|
||||||
<el-table-column prop="enterpriseStatus" label="企业状态" align="center" width="120">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-tag v-if="scope.row.enterpriseStatus === '正常'" type="success">
|
|
||||||
{{ scope.row.enterpriseStatus }}
|
|
||||||
</el-tag>
|
|
||||||
<el-tag v-else-if="scope.row.enterpriseStatus === '待审核'" type="danger">
|
|
||||||
{{ scope.row.enterpriseStatus }}
|
|
||||||
</el-tag>
|
|
||||||
<el-tag v-else-if="scope.row.enterpriseStatus === '已注册'" type="primary">
|
|
||||||
{{ scope.row.enterpriseStatus }}
|
|
||||||
</el-tag>
|
|
||||||
<el-tag v-else type="info">{{ scope.row.enterpriseStatus }}</el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="linkman" label="联系人" align="center" width="120" />
|
|
||||||
<el-table-column prop="phone" label="手机号" align="center" width="120" />
|
|
||||||
<el-table-column prop="createDate" label="创建时间" align="center" width="180" />
|
|
||||||
<el-table-column prop="operator" label="操作" width="200px" align="center" fixed="right">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="View"
|
|
||||||
link
|
|
||||||
@click="onClickOpenDialog('查看', scope.row)"
|
|
||||||
>
|
|
||||||
查看
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="Edit"
|
|
||||||
link
|
|
||||||
@click="onClickOpenDialog('编辑', scope.row)"
|
|
||||||
>
|
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="success"
|
|
||||||
size="small"
|
|
||||||
icon="User"
|
|
||||||
link
|
|
||||||
@click="onClickOpenEmployee(scope.row)"
|
|
||||||
>
|
|
||||||
员工
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
size="small"
|
|
||||||
icon="Delete"
|
|
||||||
link
|
|
||||||
@click="onClickDel(scope.row)"
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
<!-- 分页 -->
|
|
||||||
<div class="footer-pagination">
|
|
||||||
<Pagination
|
|
||||||
:pageAble="tableState.pageAble"
|
|
||||||
:handle-size-change="handleSizeChange"
|
|
||||||
:handle-current-change="handleCurrentChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<CompanyDialog ref="companyDialogRef" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
|
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
|
||||||
import { useRouter } from 'vue-router';
|
|
||||||
import {
|
|
||||||
postEnterpriseDeleteAPI,
|
|
||||||
postEnterprisePageAPI,
|
|
||||||
postEnterpriseSaveAPI,
|
|
||||||
} from '@/api/Enterprise/company';
|
|
||||||
import Pagination from '@/components/Pagination/Pagination.vue';
|
|
||||||
import { useTable } from '@/hooks/useTable';
|
|
||||||
import { EnterpriseType } from '@/types/boatInfo';
|
|
||||||
import CompanyDialog from './CompanyDialog.vue';
|
|
||||||
|
|
||||||
// 获取列表表格数据
|
|
||||||
const { getTableList, tableState, searchTable, resetTable, tableChangeCurrent, tableChangeSize } =
|
|
||||||
useTable({
|
|
||||||
api: postEnterprisePageAPI,
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
await getTableList();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 查询条件
|
|
||||||
const searchTableForm = reactive({
|
|
||||||
key: '',
|
|
||||||
enterpriseStatus: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 企业状态
|
|
||||||
const companyTypeList = [
|
|
||||||
{
|
|
||||||
value: '待审核',
|
|
||||||
label: '待审核',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '正常',
|
|
||||||
label: '正常',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '已关闭',
|
|
||||||
label: '已关闭',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '已注册',
|
|
||||||
label: '已注册',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// 表格是否加载
|
|
||||||
const tableLoading = ref(false);
|
|
||||||
|
|
||||||
// 查询表单节点
|
|
||||||
const tableFormRef = ref<FormInstance>();
|
|
||||||
|
|
||||||
// 查询
|
|
||||||
const onClickSearch = async () => {
|
|
||||||
tableLoading.value = true;
|
|
||||||
|
|
||||||
// 添加查询参数
|
|
||||||
tableState.value.searchParam = searchTableForm;
|
|
||||||
|
|
||||||
// 查询表格
|
|
||||||
await searchTable();
|
|
||||||
tableLoading.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 重置
|
|
||||||
const onClickResetForm = async (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
await resetTable();
|
|
||||||
formEl.resetFields();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 新增/编辑企业
|
|
||||||
const companyDialogRef = ref<InstanceType<typeof CompanyDialog> | null>(null);
|
|
||||||
const onClickOpenDialog = (title: string, row: Partial<EnterpriseType> = {}) => {
|
|
||||||
const params = {
|
|
||||||
title,
|
|
||||||
isView: title === '查看',
|
|
||||||
row: { ...row },
|
|
||||||
api: postEnterpriseSaveAPI,
|
|
||||||
getTableList,
|
|
||||||
};
|
|
||||||
companyDialogRef.value?.isShowDialog(params);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 路由
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
// 员工
|
|
||||||
const onClickOpenEmployee = (row: EnterpriseType) => {
|
|
||||||
router.push({
|
|
||||||
path: '/enterprise/employee',
|
|
||||||
query: {
|
|
||||||
enterpriseId: row.id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 删除
|
|
||||||
const onClickDel = (row: EnterpriseType) => {
|
|
||||||
ElMessageBox.confirm(`你确定要删除企业 ${row.name} 吗?`, '温馨提示', {
|
|
||||||
confirmButtonText: '确定',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
type: 'warning',
|
|
||||||
draggable: true,
|
|
||||||
})
|
|
||||||
.then(async () => {
|
|
||||||
await postEnterpriseDeleteAPI([row.id]);
|
|
||||||
// 更新表格
|
|
||||||
await getTableList();
|
|
||||||
ElMessage({
|
|
||||||
message: '删除成功',
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
console.log('用户点击了取消');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 改变每页显示条目个数
|
|
||||||
const handleSizeChange = async (val: number) => {
|
|
||||||
await tableChangeSize(val);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 当前页数改变
|
|
||||||
const handleCurrentChange = async (val: number) => {
|
|
||||||
await tableChangeCurrent(val);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.table {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
padding: 16px 16px 0;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
}
|
|
||||||
.footer {
|
|
||||||
position: relative;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 16px;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
.footer-util {
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
justify-content: flex-end;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
.footer-table {
|
|
||||||
position: relative;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.footer-pagination {
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
justify-content: flex-end;
|
|
||||||
width: 100%;
|
|
||||||
padding-top: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,18 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="manage">
|
|
||||||
<CompanyTable />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import CompanyTable from './components/CompanyTable.vue';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.manage {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
<template>
|
||||||
|
<div class="agree">
|
||||||
|
<div class="agree-content">
|
||||||
|
<div class="title">{{ agreeText?.textType }}</div>
|
||||||
|
<div class="content" v-html="agreeText?.content"></div>
|
||||||
|
</div>
|
||||||
|
<div class="agree-btn" v-if="textType === 'AGREEMENT' && !isAgree">
|
||||||
|
<el-checkbox v-model="checked" size="large">
|
||||||
|
<div class="btn-text">我已经完整阅读,并同意用户协议</div>
|
||||||
|
</el-checkbox>
|
||||||
|
|
||||||
|
<el-button type="primary" @click="onClickAgree">同意,并不再提示</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { onMounted, ref } from 'vue';
|
||||||
|
import { postTextAgreeAPI, postTextGetAPI, postTextIsAgreeAPI } from '@/api/Help';
|
||||||
|
import { agreeTextType } from '@/types/help';
|
||||||
|
|
||||||
|
interface propsType {
|
||||||
|
textType: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<propsType>(), {
|
||||||
|
textType: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 协议规则内容
|
||||||
|
const agreeText = ref<agreeTextType>();
|
||||||
|
|
||||||
|
// 判断用户是否同意了协议
|
||||||
|
const isAgree = ref(false);
|
||||||
|
const checked = ref(false);
|
||||||
|
|
||||||
|
// 获取协议规则
|
||||||
|
const getAgreeText = async () => {
|
||||||
|
const { data } = await postTextGetAPI({ textType: props.textType });
|
||||||
|
agreeText.value = data;
|
||||||
|
// 判断是用户协议还是共享规则
|
||||||
|
if (props.textType === 'AGREEMENT') {
|
||||||
|
// 判断用户是否同意了协议
|
||||||
|
const { data: isAgreeData } = await postTextIsAgreeAPI();
|
||||||
|
isAgree.value = isAgreeData;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 同意协议
|
||||||
|
const onClickAgree = async () => {
|
||||||
|
if (checked.value) {
|
||||||
|
await postTextAgreeAPI();
|
||||||
|
isAgree.value = true;
|
||||||
|
} else {
|
||||||
|
ElMessage({
|
||||||
|
type: 'info',
|
||||||
|
message: '请勾选同意用户协议',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await getAgreeText();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.agree {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.agree-content {
|
||||||
|
flex: 1;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
.title {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 50px;
|
||||||
|
color: #333;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 50px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.agree-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
.btn-text {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,116 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-dialog
|
|
||||||
v-model="dialogVisible"
|
|
||||||
:title="`${dialogProps.title}`"
|
|
||||||
width="80%"
|
|
||||||
@close="onCloseDialog"
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="ruleFormRef"
|
|
||||||
label-width="auto"
|
|
||||||
:rules="formRules"
|
|
||||||
:disabled="dialogProps.isView"
|
|
||||||
:model="dialogProps.row"
|
|
||||||
:hide-required-asterisk="dialogProps.isView"
|
|
||||||
>
|
|
||||||
<el-form-item label="序号" prop="serial">
|
|
||||||
<el-input v-model="dialogProps.row!.serial" placeholder="请输入序号" type="number" />
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<!-- 名称 -->
|
|
||||||
<el-form-item label="名称" prop="name">
|
|
||||||
<el-input v-model="dialogProps.row!.name" placeholder="请输入名称" />
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<!-- 备注 -->
|
|
||||||
<el-form-item label="备注" prop="remark">
|
|
||||||
<el-input v-model="dialogProps.row!.remark" placeholder="请输入备注" type="textarea" />
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<!-- 类型 -->
|
|
||||||
<el-form-item label="类型" prop="type">
|
|
||||||
<el-select v-model="dialogProps.row!.type" placeholder="请选择类型">
|
|
||||||
<el-option label="主题" value="主题" />
|
|
||||||
<el-option label="问题" value="问题" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-button @click="dialogVisible = false">取消</el-button>
|
|
||||||
<el-button v-show="!dialogProps.isView" type="primary" @click="onClickConfirm(ruleFormRef)">
|
|
||||||
确认
|
|
||||||
</el-button>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ElMessage, FormInstance, FormRules } from 'element-plus';
|
|
||||||
import { reactive, ref } from 'vue';
|
|
||||||
import { HelpType } from '@/types/help';
|
|
||||||
|
|
||||||
interface DialogPropsType {
|
|
||||||
title: string;
|
|
||||||
isView: boolean;
|
|
||||||
row: Partial<HelpType>;
|
|
||||||
api?: (params: any) => Promise<any>;
|
|
||||||
getTableList?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 是否显示dialog
|
|
||||||
const dialogVisible = ref(false);
|
|
||||||
|
|
||||||
// 父组件传递的值
|
|
||||||
const dialogProps = ref<DialogPropsType>({
|
|
||||||
isView: false,
|
|
||||||
title: '',
|
|
||||||
row: {},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 显示dialog,新增/编辑订阅
|
|
||||||
const isShowDialog = (params: DialogPropsType) => {
|
|
||||||
dialogProps.value = params;
|
|
||||||
dialogVisible.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 向父组件暴露该方法
|
|
||||||
defineExpose({ isShowDialog });
|
|
||||||
|
|
||||||
const formRules = reactive<FormRules>({
|
|
||||||
serial: [{ required: true, message: '请输入序号', trigger: 'blur' }],
|
|
||||||
name: [{ required: true, message: '请输入名称', trigger: 'blur' }],
|
|
||||||
remark: [{ required: true, message: '请输入备注', trigger: 'blur' }],
|
|
||||||
type: [{ required: true, message: '请选择类型', trigger: 'change' }],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 表单节点
|
|
||||||
const ruleFormRef = ref<FormInstance>();
|
|
||||||
|
|
||||||
// dialog 关闭事件
|
|
||||||
const onCloseDialog = () => {
|
|
||||||
// 重置表单
|
|
||||||
ruleFormRef.value?.resetFields();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 新增/编辑
|
|
||||||
const onClickConfirm = (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
formEl.validate(async (valid) => {
|
|
||||||
if (!valid) return;
|
|
||||||
try {
|
|
||||||
await dialogProps.value.api!(dialogProps.value.row);
|
|
||||||
ElMessage({
|
|
||||||
message: `${dialogProps.value.title}成功`,
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
dialogProps.value.getTableList!();
|
|
||||||
} finally {
|
|
||||||
dialogVisible.value = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
|
@ -1,135 +1,141 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="table">
|
<div class="notify">
|
||||||
<div class="footer">
|
<div class="list">
|
||||||
<!-- 表格 -->
|
<ul
|
||||||
<div class="footer-table">
|
class="list-wrap"
|
||||||
<el-table
|
v-infinite-scroll="helpListLoad"
|
||||||
v-loading="tableLoading"
|
:infinite-scroll-disabled="disabled"
|
||||||
:data="tableState.tableData"
|
:infinite-scroll-distance="100"
|
||||||
border
|
>
|
||||||
stripe
|
<li
|
||||||
style="width: 100%; height: 100%"
|
v-for="item in helpDocsList"
|
||||||
|
:key="item.id"
|
||||||
|
class="list-item"
|
||||||
|
@click="onClickOpenDialog(item)"
|
||||||
>
|
>
|
||||||
<el-table-column prop="serial" label="序号" align="center" width="80" />
|
<div class="item-icon"></div>
|
||||||
<el-table-column prop="name" label="名称" align="center" width="180" />
|
<div class="item-title">{{ item.name }}</div>
|
||||||
<el-table-column prop="remark" label="备注" align="center" width="200" />
|
<div class="item-date">{{ item.createDate }}</div>
|
||||||
<el-table-column prop="type" label="状态" align="center" width="120" />
|
</li>
|
||||||
<el-table-column prop="createDate" label="创建时间" align="center" width="180" />
|
</ul>
|
||||||
<el-table-column prop="operator" label="操作" width="200px" align="center" fixed="right">
|
|
||||||
<template #default="scope">
|
<div class="content">
|
||||||
<el-button
|
<div class="title">{{ helpDocsData?.name }}</div>
|
||||||
type="primary"
|
<div class="wrap" v-html="helpDocsData?.remark"></div>
|
||||||
size="small"
|
|
||||||
icon="View"
|
|
||||||
link
|
|
||||||
@click="onClickOpenDialog('查看', scope.row)"
|
|
||||||
>
|
|
||||||
查看
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
<!-- 分页 -->
|
|
||||||
<div class="footer-pagination">
|
|
||||||
<Pagination
|
|
||||||
:pageAble="tableState.pageAble"
|
|
||||||
:handle-size-change="handleSizeChange"
|
|
||||||
:handle-current-change="handleCurrentChange"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<HelpDialog ref="helpDialogRef" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { postHelpPageAPI, postHelpSaveAPI } from '@/api/Help';
|
import { postHelpGetAPI, postHelpPageAPI } from '@/api/Help';
|
||||||
import Pagination from '@/components/Pagination/Pagination.vue';
|
|
||||||
import { useTable } from '@/hooks/useTable';
|
|
||||||
import { HelpType } from '@/types/help';
|
import { HelpType } from '@/types/help';
|
||||||
import HelpDialog from './HelpDialog.vue';
|
|
||||||
|
const helpDocsList = ref<HelpType[]>([]);
|
||||||
|
const helpDocsData = ref<HelpType>();
|
||||||
|
|
||||||
|
// 分页参数-当前页数
|
||||||
|
const currentPage = ref(1);
|
||||||
|
|
||||||
|
// 加载更多状态
|
||||||
|
const loadMoreState = ref('loading');
|
||||||
|
const disabled = computed(() => loadMoreState.value === 'finished');
|
||||||
|
|
||||||
// 获取列表表格数据
|
// 获取列表表格数据
|
||||||
const { getTableList, tableState, tableChangeCurrent, tableChangeSize } = useTable({
|
const getHelpDocsList = async () => {
|
||||||
api: postHelpPageAPI,
|
const { data } = await postHelpPageAPI({
|
||||||
});
|
page: currentPage.value,
|
||||||
|
rows: 10,
|
||||||
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
helpDocsList.value = [...helpDocsList.value, ...data.records];
|
||||||
await getTableList();
|
currentPage.value++;
|
||||||
});
|
// 检查是否到达最后一页或当前数据不足一页
|
||||||
|
if (currentPage.value >= Number(data.pages) || data.records.length < 10) {
|
||||||
// 表格是否加载
|
loadMoreState.value = 'finished';
|
||||||
const tableLoading = ref(false);
|
} else {
|
||||||
|
loadMoreState.value = 'loading';
|
||||||
// 新增/编辑企业
|
}
|
||||||
const helpDialogRef = ref<InstanceType<typeof HelpDialog> | null>(null);
|
|
||||||
const onClickOpenDialog = (title: string, row: Partial<HelpType> = {}) => {
|
|
||||||
const params = {
|
|
||||||
title,
|
|
||||||
isView: title === '查看',
|
|
||||||
row: { ...row },
|
|
||||||
api: postHelpSaveAPI,
|
|
||||||
getTableList,
|
|
||||||
};
|
|
||||||
helpDialogRef.value?.isShowDialog(params);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 改变每页显示条目个数
|
const helpListLoad = async () => {
|
||||||
const handleSizeChange = async (val: number) => {
|
await getHelpDocsList();
|
||||||
await tableChangeSize(val);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 当前页数改变
|
const onClickOpenDialog = async (row: HelpType) => {
|
||||||
const handleCurrentChange = async (val: number) => {
|
const { data } = await postHelpGetAPI({ id: row.id });
|
||||||
await tableChangeCurrent(val);
|
helpDocsData.value = data;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.table {
|
.notify {
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
.header {
|
height: 100%;
|
||||||
display: flex;
|
overflow-x: hidden;
|
||||||
padding: 16px 16px 0;
|
color: #fff;
|
||||||
margin-bottom: 16px;
|
.list {
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
}
|
|
||||||
.footer {
|
|
||||||
position: relative;
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
justify-content: space-between;
|
||||||
flex-direction: column;
|
width: 100%;
|
||||||
padding: 16px;
|
height: 100%;
|
||||||
overflow: hidden;
|
.list-wrap {
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
.footer-util {
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
justify-content: flex-end;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
.footer-table {
|
|
||||||
position: relative;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.footer-pagination {
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
width: 30%;
|
||||||
flex-shrink: 0;
|
height: 500px;
|
||||||
justify-content: flex-end;
|
overflow: auto;
|
||||||
width: 100%;
|
.list-item {
|
||||||
padding-top: 20px;
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 0;
|
||||||
|
overflow: hidden;
|
||||||
|
.item-icon {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.item-title {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 16px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.item-date {
|
||||||
|
margin-left: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
margin-left: 20px;
|
||||||
|
font-size: 21px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #333;
|
||||||
|
background-color: #fff;
|
||||||
|
.title {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 16px;
|
||||||
|
font-size: 23px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.wrap {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 70px);
|
||||||
|
padding: 0 16px 20px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,92 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="manage">
|
<div class="table">
|
||||||
<HelpTable />
|
<div class="header">
|
||||||
|
<div class="title">帮助信息</div>
|
||||||
|
<div class="api-btn">
|
||||||
|
<div
|
||||||
|
class="btn"
|
||||||
|
:class="{ 'btn-active': currentNav === item }"
|
||||||
|
v-for="item in helpDocsList"
|
||||||
|
:key="item"
|
||||||
|
@click="onClickChangeNav(item)"
|
||||||
|
>
|
||||||
|
{{ item }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<HelpTable v-if="currentNav === '分类主题'" />
|
||||||
|
<AgreeText v-if="currentNav === '用户协议'" textType="AGREEMENT" />
|
||||||
|
<AgreeText v-if="currentNav === '共享规则'" textType="RULE" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import AgreeText from './components/AgreeText.vue';
|
||||||
import HelpTable from './components/HelpTable.vue';
|
import HelpTable from './components/HelpTable.vue';
|
||||||
|
|
||||||
|
// 帮助文档列表
|
||||||
|
const helpDocsList = ref(['分类主题', '用户协议', '共享规则']);
|
||||||
|
const currentNav = ref('分类主题');
|
||||||
|
const onClickChangeNav = (item: string) => {
|
||||||
|
if (item === currentNav.value) return;
|
||||||
|
currentNav.value = item;
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.manage {
|
.table {
|
||||||
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
.header {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 16px 16px 0;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #fff;
|
||||||
|
.title {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.api-btn {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
.btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 150px;
|
||||||
|
height: 50px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #d7d7d7;
|
||||||
|
background-color: rgb(51 51 51 / 100%);
|
||||||
|
border-radius: 75px;
|
||||||
|
box-shadow: 5px 5px 5px rgb(0 0 0 / 34.9%);
|
||||||
|
}
|
||||||
|
.btn-active {
|
||||||
|
color: #000;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 1;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="table">
|
<div class="table">
|
||||||
<div class="header">
|
<!-- <div class="header">
|
||||||
<el-form :inline="true" :model="searchTableForm" ref="tableFormRef">
|
<el-form :inline="true" :model="searchTableForm" ref="tableFormRef">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<RemoteSelect
|
<RemoteSelect
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
<el-button icon="Refresh" @click="onClickResetForm(tableFormRef)">重置</el-button>
|
<el-button icon="Refresh" @click="onClickResetForm(tableFormRef)">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div> -->
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
<div class="footer-table">
|
<div class="footer-table">
|
||||||
|
@ -26,7 +26,6 @@
|
||||||
v-loading="tableLoading"
|
v-loading="tableLoading"
|
||||||
:data="tableState.tableData"
|
:data="tableState.tableData"
|
||||||
border
|
border
|
||||||
stripe
|
|
||||||
style="width: 100%; height: 100%"
|
style="width: 100%; height: 100%"
|
||||||
>
|
>
|
||||||
<el-table-column prop="enterprise.name" label="企业" align="center" width="150" />
|
<el-table-column prop="enterprise.name" label="企业" align="center" width="150" />
|
||||||
|
@ -76,55 +75,23 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { FormInstance } from 'element-plus';
|
import { onMounted, ref } from 'vue';
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { getPublishHistoryListAPI } from '@/api/Boat/info';
|
||||||
import { getHistoryListAPI } from '@/api/Boat/info';
|
|
||||||
import { postShipListAPI } from '@/api/Ship';
|
|
||||||
import Pagination from '@/components/Pagination/Pagination.vue';
|
import Pagination from '@/components/Pagination/Pagination.vue';
|
||||||
import RemoteSelect from '@/components/RemoteSelect/index.vue';
|
|
||||||
import { useTable } from '@/hooks/useTable';
|
import { useTable } from '@/hooks/useTable';
|
||||||
|
|
||||||
// 获取用户列表表格数据
|
// 获取用户列表表格数据
|
||||||
const { getTableList, tableState, searchTable, resetTable, tableChangeCurrent, tableChangeSize } =
|
const { getTableList, tableState, tableChangeCurrent, tableChangeSize } = useTable({
|
||||||
useTable({
|
api: getPublishHistoryListAPI,
|
||||||
api: getHistoryListAPI,
|
});
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await getTableList();
|
await getTableList();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 查询条件
|
|
||||||
const searchTableForm = reactive({
|
|
||||||
shipId: '',
|
|
||||||
voyage: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 表格是否加载
|
// 表格是否加载
|
||||||
const tableLoading = ref(false);
|
const tableLoading = ref(false);
|
||||||
|
|
||||||
// 查询表单节点
|
|
||||||
const tableFormRef = ref<FormInstance>();
|
|
||||||
|
|
||||||
// 查询
|
|
||||||
const onClickSearch = async () => {
|
|
||||||
tableLoading.value = true;
|
|
||||||
|
|
||||||
// 添加查询参数
|
|
||||||
tableState.value.searchParam = searchTableForm;
|
|
||||||
|
|
||||||
// 查询表格
|
|
||||||
await searchTable();
|
|
||||||
tableLoading.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 重置
|
|
||||||
const onClickResetForm = async (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
await resetTable();
|
|
||||||
formEl.resetFields();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 改变每页显示条目个数
|
// 改变每页显示条目个数
|
||||||
const handleSizeChange = async (val: number) => {
|
const handleSizeChange = async (val: number) => {
|
||||||
await tableChangeSize(val);
|
await tableChangeSize(val);
|
||||||
|
@ -147,9 +114,7 @@ const handleCurrentChange = async (val: number) => {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 16px 16px 0;
|
padding: 16px 16px 0;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
}
|
}
|
||||||
.footer {
|
.footer {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -159,9 +124,7 @@ const handleCurrentChange = async (val: number) => {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
.footer-util {
|
.footer-util {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
|
@ -0,0 +1,148 @@
|
||||||
|
<template>
|
||||||
|
<div class="table">
|
||||||
|
<!-- <div class="header">
|
||||||
|
<el-form :inline="true" :model="searchTableForm" ref="tableFormRef">
|
||||||
|
<el-form-item>
|
||||||
|
<RemoteSelect
|
||||||
|
v-model:value="searchTableForm.shipId"
|
||||||
|
placeholder="请选择船舶"
|
||||||
|
style="width: 120px"
|
||||||
|
:api="postShipListAPI"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-input v-model="searchTableForm.voyage" placeholder="请输入航次" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="Search" @click="onClickSearch">查询</el-button>
|
||||||
|
<el-button icon="Refresh" @click="onClickResetForm(tableFormRef)">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</div> -->
|
||||||
|
<div class="footer">
|
||||||
|
<!-- 表格 -->
|
||||||
|
<div class="footer-table">
|
||||||
|
<el-table
|
||||||
|
v-loading="tableLoading"
|
||||||
|
:data="tableState.tableData"
|
||||||
|
border
|
||||||
|
style="width: 100%; height: 100%"
|
||||||
|
>
|
||||||
|
<el-table-column prop="enterprise.name" label="企业" align="center" width="150" />
|
||||||
|
<el-table-column prop="ship.name" label="船舶" align="center" width="150" />
|
||||||
|
<el-table-column prop="voyage" label="航次" align="center" width="180" />
|
||||||
|
<el-table-column prop="shipRoute.name" label="航线" align="center" width="150" />
|
||||||
|
<el-table-column prop="loadWharf.name" label="装货码头" align="center" width="150" />
|
||||||
|
<el-table-column prop="dischargeWharf.name" label="卸货码头" align="center" width="150" />
|
||||||
|
<el-table-column prop="carNumPlan" label="计划商品车数量" align="center" width="180" />
|
||||||
|
<el-table-column prop="spareNumPlan" label="计划件杂货数量" align="center" width="180" />
|
||||||
|
<el-table-column prop="carNumActual" label="实际商品车数量" align="center" width="180" />
|
||||||
|
<el-table-column
|
||||||
|
prop="spareNumActual"
|
||||||
|
label="实际件杂货数量"
|
||||||
|
align="center"
|
||||||
|
width="180"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
prop="departureDatePlan"
|
||||||
|
label="计划离泊时间"
|
||||||
|
align="center"
|
||||||
|
width="200"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
prop="departureDateActual"
|
||||||
|
label="实际离泊时间"
|
||||||
|
align="center"
|
||||||
|
width="200"
|
||||||
|
/>
|
||||||
|
<el-table-column prop="shipStatus" label="船舶状态" align="center" width="150" />
|
||||||
|
<el-table-column prop="tradeType" label="贸易类型" align="center" width="150" />
|
||||||
|
<el-table-column prop="loadPort.name" label="装货港口" align="center" width="150" />
|
||||||
|
<el-table-column prop="dischargePort.name" label="卸货港口" align="center" width="150" />
|
||||||
|
<el-table-column prop="createDate" label="创建时间" align="center" width="180" />
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<div class="footer-pagination">
|
||||||
|
<Pagination
|
||||||
|
:pageAble="tableState.pageAble"
|
||||||
|
:handle-size-change="handleSizeChange"
|
||||||
|
:handle-current-change="handleCurrentChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, ref } from 'vue';
|
||||||
|
import { getReceiveHistoryListAPI } from '@/api/Boat/info';
|
||||||
|
import Pagination from '@/components/Pagination/Pagination.vue';
|
||||||
|
import { useTable } from '@/hooks/useTable';
|
||||||
|
|
||||||
|
// 获取用户列表表格数据
|
||||||
|
const { getTableList, tableState, tableChangeCurrent, tableChangeSize } = useTable({
|
||||||
|
api: getReceiveHistoryListAPI,
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await getTableList();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 表格是否加载
|
||||||
|
const tableLoading = ref(false);
|
||||||
|
|
||||||
|
// 改变每页显示条目个数
|
||||||
|
const handleSizeChange = async (val: number) => {
|
||||||
|
await tableChangeSize(val);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 当前页数改变
|
||||||
|
const handleCurrentChange = async (val: number) => {
|
||||||
|
await tableChangeCurrent(val);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.table {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
padding: 16px 16px 0;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 16px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 4px;
|
||||||
|
.footer-util {
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
.footer-table {
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.footer-pagination {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
justify-content: flex-end;
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,18 +1,91 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="manage">
|
<div class="table">
|
||||||
<HistoryTable />
|
<div class="header">
|
||||||
|
<div class="title">历史船货信息</div>
|
||||||
|
<div class="api-btn">
|
||||||
|
<div
|
||||||
|
class="btn"
|
||||||
|
:class="{ 'btn-active': currentHistoryNav === item }"
|
||||||
|
v-for="item in historyNavList"
|
||||||
|
:key="item"
|
||||||
|
@click="onClickChangeHistoryNav(item)"
|
||||||
|
>
|
||||||
|
{{ item }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<PublishTable v-if="currentHistoryNav === '我发布的'" />
|
||||||
|
<ReceiveTable v-if="currentHistoryNav === '我收到的'" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import HistoryTable from './components/HistoryTable.vue';
|
import { ref } from 'vue';
|
||||||
|
import PublishTable from './components/PublishTable.vue';
|
||||||
|
import ReceiveTable from './components/ReceiveTable.vue';
|
||||||
|
|
||||||
|
// 历史导航列表
|
||||||
|
const historyNavList = ref(['我发布的', '我收到的']);
|
||||||
|
const currentHistoryNav = ref('我发布的');
|
||||||
|
const onClickChangeHistoryNav = (item: string) => {
|
||||||
|
if (currentHistoryNav.value === item) return;
|
||||||
|
currentHistoryNav.value = item;
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.manage {
|
.table {
|
||||||
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
.header {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 16px 16px 0;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #fff;
|
||||||
|
.title {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.api-btn {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
.btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 150px;
|
||||||
|
height: 50px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #d7d7d7;
|
||||||
|
background-color: rgb(51 51 51 / 100%);
|
||||||
|
border-radius: 75px;
|
||||||
|
box-shadow: 5px 5px 5px rgb(0 0 0 / 34.9%);
|
||||||
|
}
|
||||||
|
.btn-active {
|
||||||
|
color: #000;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 1;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="card-title">{{ title }}</div>
|
<div class="card-title">{{ title }}</div>
|
||||||
<div class="card-text number">{{ number }}</div>
|
<div class="card-text">{{ number }}</div>
|
||||||
<div class="card-text">
|
|
||||||
<div>{{ totalTitle }}</div>
|
|
||||||
<div>{{ totalNumber }}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -13,38 +9,36 @@
|
||||||
defineProps<{
|
defineProps<{
|
||||||
title: string;
|
title: string;
|
||||||
number: number;
|
number: number;
|
||||||
totalTitle: string;
|
|
||||||
totalNumber: number;
|
|
||||||
}>();
|
}>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.card {
|
.card {
|
||||||
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-bottom: 20px;
|
height: 88px;
|
||||||
color: #020817;
|
margin: 20px 0;
|
||||||
background-color: #fff;
|
font-size: 32px;
|
||||||
border: 1px solid #e4e4e7;
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
border: 5px solid #d7d7d7;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
.card-title {
|
.card-title {
|
||||||
box-sizing: border-box;
|
position: absolute;
|
||||||
width: 100%;
|
top: -14px; /* 使标题悬浮在边框上方 */
|
||||||
padding: 10px;
|
left: 20px; /* 根据需要调整水平位置 */
|
||||||
font-size: 18px;
|
padding: 0 8px; /* 增加一点内边距 */
|
||||||
font-weight: 500;
|
font-size: 15px;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #555;
|
||||||
}
|
}
|
||||||
.card-text {
|
.card-text {
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 40px;
|
height: 100%;
|
||||||
padding: 0 10px 10px;
|
color: #80ffff;
|
||||||
}
|
|
||||||
.number {
|
|
||||||
font-size: 24px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -22,9 +22,6 @@ defineProps({
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.chart {
|
.chart {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 400px;
|
height: 200px;
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #e4e4e7;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,94 +1,151 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="home">
|
<div class="home">
|
||||||
<!-- <div class="home-search">
|
<div class="home-search">
|
||||||
<el-form :inline="true" :model="searchTableForm" ref="searchTableFormRef">
|
<el-form :inline="true" :model="searchTableForm" ref="searchTableFormRef">
|
||||||
<el-form-item label="车架号" prop="name">
|
<el-form-item
|
||||||
<el-input v-model="searchTableForm.name" placeholder="请输入车架号" />
|
prop="vin"
|
||||||
|
:rules="[{ required: true, message: '请输入车架号', trigger: 'blur' }]"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
<div class="search-label">车架号</div>
|
||||||
|
</template>
|
||||||
|
<el-input v-model="searchTableForm.vin" placeholder="请输入车架号" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="Search">查询</el-button>
|
<el-button type="primary" icon="Search" @click="onClickSearch(searchTableFormRef)"
|
||||||
|
>查询</el-button
|
||||||
|
>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div> -->
|
|
||||||
<div class="home-header">
|
|
||||||
<el-row :gutter="20">
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="2">
|
|
||||||
<Card
|
|
||||||
title="年度船舶艘次"
|
|
||||||
:number="tableData.yearVoyages"
|
|
||||||
totalTitle="累计船舶艘次"
|
|
||||||
:totalNumber="tableData.totalVoyages"
|
|
||||||
></Card>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="2">
|
|
||||||
<Card
|
|
||||||
title="本港年度艘次"
|
|
||||||
:number="tableData.yearPortVoyages"
|
|
||||||
totalTitle="本港船舶艘次"
|
|
||||||
:totalNumber="tableData.totalPortVoyages"
|
|
||||||
></Card>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="2">
|
|
||||||
<Card
|
|
||||||
title="年度货物数量"
|
|
||||||
:number="tableData.yearCargos"
|
|
||||||
totalTitle="累计货物数量"
|
|
||||||
:totalNumber="tableData.totalCargos"
|
|
||||||
></Card>
|
|
||||||
</el-col>
|
|
||||||
<el-col :xs="24" :sm="12" :md="8" :lg="6" :xl="2">
|
|
||||||
<Card
|
|
||||||
title="本港年度货物"
|
|
||||||
:number="tableData.yearPortCargos"
|
|
||||||
totalTitle="本港货物累计"
|
|
||||||
:totalNumber="tableData.totalPortCargos"
|
|
||||||
></Card>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="home-content">
|
<template v-if="!isShowVinDialog">
|
||||||
<el-row :gutter="32">
|
<div class="home-header">
|
||||||
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="4" class="charts">
|
<el-row :gutter="20">
|
||||||
<HomeChart :option="outImportVoyages" />
|
<el-col :xs="24" :sm="12" :md="6" :lg="3" :xl="3">
|
||||||
</el-col>
|
<Card title="累计船舶艘次" :number="tableData.totalVoyages"></Card>
|
||||||
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="4" class="charts">
|
</el-col>
|
||||||
<HomeChart :option="outExportVoyages" />
|
<el-col :xs="24" :sm="12" :md="6" :lg="3" :xl="3">
|
||||||
</el-col>
|
<Card title="年度船舶艘次" :number="tableData.yearVoyages"></Card>
|
||||||
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="4" class="charts">
|
</el-col>
|
||||||
<HomeChart :option="inTotalVoyages" />
|
<el-col :xs="24" :sm="12" :md="6" :lg="3" :xl="3">
|
||||||
</el-col>
|
<Card title="本港船舶艘次" :number="tableData.totalPortVoyages"></Card>
|
||||||
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="4" class="charts">
|
</el-col>
|
||||||
<HomeChart :option="inYearVoyages" />
|
<el-col :xs="24" :sm="12" :md="6" :lg="3" :xl="3">
|
||||||
</el-col>
|
<Card title="本港年度艘次" :number="tableData.yearPortVoyages"></Card>
|
||||||
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="4" class="charts">
|
</el-col>
|
||||||
<HomeChart :option="outImportCargos" />
|
<el-col :xs="24" :sm="12" :md="6" :lg="3" :xl="3">
|
||||||
</el-col>
|
<Card title="累计货物数量" :number="tableData.totalCargos"></Card>
|
||||||
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="4" class="charts">
|
</el-col>
|
||||||
<HomeChart :option="outExportCargos" />
|
<el-col :xs="24" :sm="12" :md="6" :lg="3" :xl="3">
|
||||||
</el-col>
|
<Card title="年度货物数量" :number="tableData.yearCargos"></Card>
|
||||||
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="4" class="charts">
|
</el-col>
|
||||||
<HomeChart :option="inTotalCargos" />
|
<el-col :xs="24" :sm="12" :md="6" :lg="3" :xl="3">
|
||||||
</el-col>
|
<Card title="本港货物累计" :number="tableData.totalPortCargos"></Card>
|
||||||
<el-col :xs="24" :sm="24" :md="8" :lg="8" :xl="4" class="charts">
|
</el-col>
|
||||||
<HomeChart :option="inYearCargos" />
|
<el-col :xs="24" :sm="12" :md="6" :lg="3" :xl="3">
|
||||||
</el-col>
|
<Card title="本港年度货物" :number="tableData.yearPortCargos"></Card>
|
||||||
</el-row>
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
<div class="home-content">
|
||||||
|
<el-row :gutter="32">
|
||||||
|
<el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="4" class="charts">
|
||||||
|
<HomeChart :option="outImportVoyages" />
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="4" class="charts">
|
||||||
|
<HomeChart :option="outExportVoyages" />
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="4" class="charts">
|
||||||
|
<HomeChart :option="inTotalVoyages" />
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="4" class="charts">
|
||||||
|
<HomeChart :option="inYearVoyages" />
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="4" class="charts">
|
||||||
|
<HomeChart :option="outImportCargos" />
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="4" class="charts">
|
||||||
|
<HomeChart :option="outExportCargos" />
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="4" class="charts">
|
||||||
|
<HomeChart :option="inTotalCargos" />
|
||||||
|
</el-col>
|
||||||
|
<el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="4" class="charts">
|
||||||
|
<HomeChart :option="inYearCargos" />
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</div>
|
||||||
|
<div class="home-footer">
|
||||||
|
<div class="notice">最新公告:{{ noticeData?.title }}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="home-vin" v-else>
|
||||||
|
<div class="vin-title">
|
||||||
|
<div class="text">{{ searchTableForm.vin }}</div>
|
||||||
|
的航运物流跟踪
|
||||||
|
</div>
|
||||||
|
<div class="vin-table" v-for="(item, index) in vinData" :key="index">
|
||||||
|
<div>{{ item.schedule.createDate }}</div>
|
||||||
|
<div>{{ item.schedule.loadPort.name }}</div>
|
||||||
|
<div>{{ item.shipStatus }}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { ElMessage, FormInstance } from 'element-plus';
|
||||||
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { getStatisticsAPI } from '@/api/ApiManage';
|
import { getStatisticsAPI } from '@/api/ApiManage';
|
||||||
|
import { getVinSearchAPI } from '@/api/Boat/info';
|
||||||
|
import { noticePageAPI } from '@/api/Notice';
|
||||||
|
import { vinSearchType } from '@/types/boatInfo';
|
||||||
import { OutImportVoyages } from '@/types/help';
|
import { OutImportVoyages } from '@/types/help';
|
||||||
|
import { NoticeType } from '@/types/notice';
|
||||||
import Card from './components/Card.vue';
|
import Card from './components/Card.vue';
|
||||||
import HomeChart from './components/HomeChart.vue';
|
import HomeChart from './components/HomeChart.vue';
|
||||||
|
|
||||||
// 查询条件
|
// 查询条件
|
||||||
// const searchTableForm = reactive({
|
const searchTableFormRef = ref();
|
||||||
// name: '',
|
const searchTableForm = reactive({
|
||||||
// });
|
vin: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
const vinData = ref<vinSearchType[]>([]);
|
||||||
|
const isShowVinDialog = ref(false);
|
||||||
|
|
||||||
|
// 车架号查询
|
||||||
|
const onClickSearch = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) return;
|
||||||
|
const { data } = await getVinSearchAPI({ vin: searchTableForm.vin });
|
||||||
|
if (data.length > 0) {
|
||||||
|
vinData.value = data;
|
||||||
|
isShowVinDialog.value = true;
|
||||||
|
} else {
|
||||||
|
ElMessage({
|
||||||
|
type: 'warning',
|
||||||
|
message: '未查询到数据',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const noticeData = ref<NoticeType>();
|
||||||
|
|
||||||
|
// 获取公告
|
||||||
|
const getNoticeList = async () => {
|
||||||
|
const { data } = await noticePageAPI({
|
||||||
|
page: 1,
|
||||||
|
rows: 10,
|
||||||
|
});
|
||||||
|
if (data.records.length > 0) {
|
||||||
|
noticeData.value = data.records[0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 首页数据
|
// 首页数据
|
||||||
const tableData = ref({
|
const tableData = ref({
|
||||||
|
@ -107,6 +164,9 @@ const outImportVoyages = ref({
|
||||||
title: {
|
title: {
|
||||||
text: '外贸进口艘次',
|
text: '外贸进口艘次',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
bottom: '2%',
|
bottom: '2%',
|
||||||
|
@ -143,6 +203,9 @@ const outExportVoyages = ref({
|
||||||
title: {
|
title: {
|
||||||
text: '外贸出口艘次',
|
text: '外贸出口艘次',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
bottom: '2%',
|
bottom: '2%',
|
||||||
|
@ -174,11 +237,14 @@ const outExportVoyages = ref({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 外贸累计艘次
|
// 内贸累计艘次
|
||||||
const inTotalVoyages = ref({
|
const inTotalVoyages = ref({
|
||||||
title: {
|
title: {
|
||||||
text: '外贸累计艘次',
|
text: '内贸累计艘次',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
bottom: '2%',
|
bottom: '2%',
|
||||||
|
@ -210,11 +276,14 @@ const inTotalVoyages = ref({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// 外贸年度艘次
|
// 内贸年度艘次
|
||||||
const inYearVoyages = ref({
|
const inYearVoyages = ref({
|
||||||
title: {
|
title: {
|
||||||
text: '外贸年度艘次',
|
text: '内贸年度艘次',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
bottom: '2%',
|
bottom: '2%',
|
||||||
|
@ -251,6 +320,9 @@ const outImportCargos = ref({
|
||||||
title: {
|
title: {
|
||||||
text: '外贸进口货物',
|
text: '外贸进口货物',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
bottom: '2%',
|
bottom: '2%',
|
||||||
|
@ -287,6 +359,9 @@ const outExportCargos = ref({
|
||||||
title: {
|
title: {
|
||||||
text: '外贸出口货物',
|
text: '外贸出口货物',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
bottom: '2%',
|
bottom: '2%',
|
||||||
|
@ -323,6 +398,9 @@ const inTotalCargos = ref({
|
||||||
title: {
|
title: {
|
||||||
text: '内贸累计货物',
|
text: '内贸累计货物',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
bottom: '2%',
|
bottom: '2%',
|
||||||
|
@ -359,6 +437,9 @@ const inYearCargos = ref({
|
||||||
title: {
|
title: {
|
||||||
text: '内贸年度货物',
|
text: '内贸年度货物',
|
||||||
left: 'center',
|
left: 'center',
|
||||||
|
textStyle: {
|
||||||
|
color: '#fff',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
bottom: '2%',
|
bottom: '2%',
|
||||||
|
@ -419,6 +500,7 @@ const handlePieData = (data: OutImportVoyages) => {
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await getHomeStatistics();
|
await getHomeStatistics();
|
||||||
|
await getNoticeList();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -428,11 +510,15 @@ onMounted(async () => {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
.home-search {
|
.home-search {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
padding: 16px 16px 0;
|
padding: 16px 16px 0;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
||||||
|
.search-label {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.home-header {
|
.home-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -444,5 +530,63 @@ onMounted(async () => {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.home-footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
.notice {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 60%;
|
||||||
|
height: 40px;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #aaa;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
background-color: rgb(68 68 68 / 100%);
|
||||||
|
border-radius: 36px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.home-vin {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 70px);
|
||||||
|
.vin-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 600px;
|
||||||
|
height: 60px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #fff;
|
||||||
|
background-color: rgb(127 127 127 / 100%);
|
||||||
|
border-radius: 38px;
|
||||||
|
.text {
|
||||||
|
margin-right: 6px;
|
||||||
|
font-size: 32px;
|
||||||
|
font-style: italic;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.vin-table {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 80%;
|
||||||
|
height: 50px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #fff;
|
||||||
|
background-color: rgb(255 255 255 / 0%);
|
||||||
|
border-bottom: 1px solid rgb(215 215 215 / 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,73 +1,189 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="login-container">
|
<div class="login">
|
||||||
<!-- 暗黑模式切换 开始 -->
|
<div class="login-header">
|
||||||
<SwitchDark></SwitchDark>
|
<img class="logo" src="@/assets/images/logo.png" />
|
||||||
<!-- 暗黑模式切换 结束 -->
|
<div class="left-title">
|
||||||
|
<div class="title">船货信息智慧共享服务平台</div>
|
||||||
<!-- 登录 -->
|
<div class="text">Intelligent sharing service platform for ship and cargo information</div>
|
||||||
<div class="login-box">
|
|
||||||
<div class="login-welcome" v-if="currentPage === 0">
|
|
||||||
<img src="../../assets/images/welcome.png" alt="welcome" />
|
|
||||||
</div>
|
</div>
|
||||||
<div class="login-form" v-if="currentPage === 0">
|
</div>
|
||||||
<div class="login-logo">
|
<div class="login-content">
|
||||||
<img class="logo-icon" src="../../assets/images/logo.png" alt="logo" />
|
<div class="login-box" v-if="currentPage === 0">
|
||||||
<span class="logo-text">船货信息智慧共享服务平台</span>
|
<div class="login-welcome">
|
||||||
</div>
|
<div class="pc">
|
||||||
<!-- 登录功能 开始 -->
|
<div class="logo-title">滚装码头专业版</div>
|
||||||
<el-form ref="loginFormRef" :model="loginForm" :rules="loginRules">
|
<img src="@/assets/images/login-pc.png" />
|
||||||
<!-- 用户名 开始 -->
|
|
||||||
<el-form-item prop="username">
|
|
||||||
<el-input
|
|
||||||
placeholder="请输入用户名"
|
|
||||||
autocomplete="on"
|
|
||||||
style="position: relative"
|
|
||||||
v-model="loginForm.username"
|
|
||||||
type="text"
|
|
||||||
>
|
|
||||||
<template #prefix>
|
|
||||||
<svg-icon icon="user" />
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 用户名 结束 -->
|
|
||||||
|
|
||||||
<!-- 密码 开始 -->
|
|
||||||
<el-form-item prop="password">
|
|
||||||
<el-input
|
|
||||||
placeholder="请输入密码"
|
|
||||||
autocomplete="on"
|
|
||||||
v-model="loginForm.password"
|
|
||||||
show-password
|
|
||||||
>
|
|
||||||
<template #prefix>
|
|
||||||
<svg-icon icon="password" />
|
|
||||||
</template>
|
|
||||||
</el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<!-- 密码 结束 -->
|
|
||||||
|
|
||||||
<div class="login-btn">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
style="width: 100%; height: 100%"
|
|
||||||
:loading="loading"
|
|
||||||
@click="onClickSubmit(loginFormRef)"
|
|
||||||
>
|
|
||||||
登录
|
|
||||||
</el-button>
|
|
||||||
|
|
||||||
<el-button style="width: 100%; height: 100%" @click="onClickChangePage(1)">
|
|
||||||
企业入驻
|
|
||||||
</el-button>
|
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
<div class="mini">
|
||||||
<!-- 登录功能 结束 -->
|
<div class="logo-title">Mini APP</div>
|
||||||
|
<img src="@/assets/images/login.png" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="login-form">
|
||||||
|
<el-form ref="loginFormRef" :model="loginForm" :rules="loginRules">
|
||||||
|
<div class="form-title">
|
||||||
|
<div class="form-title-left">欢迎使用</div>
|
||||||
|
<div class="form-title-right" @click="onClickChangePage(1)">企业入驻</div>
|
||||||
|
</div>
|
||||||
|
<el-form-item prop="username">
|
||||||
|
<el-input
|
||||||
|
placeholder="请输入登录账号(手机账号)"
|
||||||
|
autocomplete="on"
|
||||||
|
style="position: relative"
|
||||||
|
v-model="loginForm.username"
|
||||||
|
type="text"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<svg-icon icon="user" />
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item prop="password">
|
||||||
|
<el-input
|
||||||
|
placeholder="请输入密码"
|
||||||
|
autocomplete="on"
|
||||||
|
v-model="loginForm.password"
|
||||||
|
show-password
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<svg-icon icon="password" />
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<div class="login-btn">
|
||||||
|
<el-button
|
||||||
|
type="success"
|
||||||
|
style="width: 100%; height: 100%"
|
||||||
|
:loading="loading"
|
||||||
|
@click="onClickSubmit(loginFormRef)"
|
||||||
|
>
|
||||||
|
登录
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 企业入驻 -->
|
<div class="register" v-if="currentPage === 1">
|
||||||
<div class="login-form1" v-if="currentPage === 1">
|
<div class="register-header">入驻企业登记信息</div>
|
||||||
<CompanyRegister @go-to-login="onClickChangePage(0)" />
|
<div class="register-box">
|
||||||
|
<div class="register-welcome">
|
||||||
|
<div class="pc">
|
||||||
|
<div class="logo-title">滚装码头专业版</div>
|
||||||
|
<img src="@/assets/images/login-pc.png" />
|
||||||
|
</div>
|
||||||
|
<div class="mini">
|
||||||
|
<div class="logo-title">Mini APP</div>
|
||||||
|
<img src="@/assets/images/login.png" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<el-form ref="registerFormRef" :rules="formRules" :model="ruleForm" class="register-form">
|
||||||
|
<div class="form-left">
|
||||||
|
<div class="form-wrap">
|
||||||
|
<div class="form-title">基本信息</div>
|
||||||
|
<el-row :gutter="30">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item prop="enterpriseType">
|
||||||
|
<el-select
|
||||||
|
v-model="ruleForm.enterpriseType"
|
||||||
|
placeholder="请选择企业类型"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in companyTypeList"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.label"
|
||||||
|
:value="item.value"
|
||||||
|
></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item prop="portId">
|
||||||
|
<RemoteSelect
|
||||||
|
v-model:value="ruleForm.portId"
|
||||||
|
placeholder="请选择港口"
|
||||||
|
:api="postPortListAPI"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-form-item prop="name">
|
||||||
|
<el-input v-model="ruleForm.name" placeholder="请输入企业全称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-row :gutter="30">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item prop="code">
|
||||||
|
<el-input v-model="ruleForm.code" placeholder="请输入企业统一社会信用代码" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item prop="legalPerson">
|
||||||
|
<el-input v-model="ruleForm.legalPerson" placeholder="请输入法定代表人" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<el-form-item prop="contractNo">
|
||||||
|
<el-input v-model="ruleForm.contractNo" placeholder="请输入合同编号" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item prop="address">
|
||||||
|
<el-input v-model="ruleForm.address" placeholder="请输入企业地址" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="licensePhoto">
|
||||||
|
<el-input v-model="ruleForm.licensePhoto" disabled placeholder="请上传营业执照">
|
||||||
|
<template #append>
|
||||||
|
<UploadImg v-model:imageID="ruleForm.licensePhoto" :file-no="ruleForm.code" />
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
<div class="form-submit">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
:loading="submitLoading"
|
||||||
|
@click="onClickSubmitRegister(registerFormRef)"
|
||||||
|
>
|
||||||
|
提交
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-right">
|
||||||
|
<div class="form-title">联系人 / 管理员</div>
|
||||||
|
<el-form-item prop="linkman">
|
||||||
|
<el-input v-model="ruleForm.linkman" placeholder="请输入联系人姓名" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="phone">
|
||||||
|
<el-input v-model="ruleForm.phone" placeholder="请填写登录账号(手机号码)" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="idPhoto">
|
||||||
|
<el-input v-model="ruleForm.idPhoto" disabled placeholder="请上传身份证照片">
|
||||||
|
<template #append>
|
||||||
|
<UploadImg
|
||||||
|
v-model:imageID="ruleForm.idPhoto"
|
||||||
|
:img-type="1"
|
||||||
|
:file-no="ruleForm.phone"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="password">
|
||||||
|
<el-input v-model="ruleForm.password" placeholder="请输入登录密码" show-password />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item prop="confirmPassword">
|
||||||
|
<el-input
|
||||||
|
v-model="ruleForm.confirmPassword"
|
||||||
|
placeholder="请再次输入密码"
|
||||||
|
show-password
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -75,13 +191,16 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { FormInstance, FormRules } from 'element-plus';
|
import type { FormInstance, FormRules } from 'element-plus';
|
||||||
import { ElNotification } from 'element-plus';
|
import { ElMessage, ElNotification } from 'element-plus';
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import SwitchDark from '@/components/SwitchDark/index.vue';
|
import { postEnterpriseRegAPI } from '@/api/Enterprise/company';
|
||||||
|
import { postPortListAPI } from '@/api/Port';
|
||||||
|
import RemoteSelect from '@/components/RemoteSelect/index.vue';
|
||||||
import { useUserStore } from '@/store/modules/user';
|
import { useUserStore } from '@/store/modules/user';
|
||||||
import { getTimeStateStr } from '@/utils';
|
import { getTimeStateStr } from '@/utils';
|
||||||
import CompanyRegister from './register.vue';
|
import { validPhone } from '@/utils/validate';
|
||||||
|
import UploadImg from './components/Upload.vue';
|
||||||
|
|
||||||
// 当前页
|
// 当前页
|
||||||
const currentPage = ref(0);
|
const currentPage = ref(0);
|
||||||
|
@ -96,14 +215,8 @@ const loginFormRef = ref<FormInstance>();
|
||||||
|
|
||||||
// 校验规则
|
// 校验规则
|
||||||
const loginRules = reactive<FormRules>({
|
const loginRules = reactive<FormRules>({
|
||||||
username: [
|
username: [{ required: true, message: '请填写登录账号', trigger: 'blur' }],
|
||||||
{ required: true, message: '请输入用户名', trigger: 'blur' },
|
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
|
||||||
{ min: 4, message: '用户名长度不能小于4位', trigger: 'blur' },
|
|
||||||
],
|
|
||||||
password: [
|
|
||||||
{ required: true, message: '请输入密码', trigger: 'blur' },
|
|
||||||
{ min: 4, max: 16, message: '密码长度不符合规范,密码长度 4 - 16 位', trigger: 'blur' },
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 用户账户密码
|
// 用户账户密码
|
||||||
|
@ -143,90 +256,352 @@ const onClickSubmit = (formEl: FormInstance | undefined) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 企业列表
|
||||||
|
const companyTypeList = [
|
||||||
|
{
|
||||||
|
value: '港口码头',
|
||||||
|
label: '港口码头',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '船公司',
|
||||||
|
label: '船公司',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '货主',
|
||||||
|
label: '货主',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '船代',
|
||||||
|
label: '船代',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: '货贷',
|
||||||
|
label: '货贷',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
// 表单
|
||||||
|
const ruleForm = reactive({
|
||||||
|
name: '',
|
||||||
|
code: '',
|
||||||
|
address: '',
|
||||||
|
legalPerson: '',
|
||||||
|
contractNo: '',
|
||||||
|
linkman: '',
|
||||||
|
phone: '',
|
||||||
|
password: '',
|
||||||
|
confirmPassword: '',
|
||||||
|
portId: '',
|
||||||
|
licensePhoto: '',
|
||||||
|
idPhoto: '',
|
||||||
|
enterpriseType: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
// 表单校验
|
||||||
|
const registerFormRef = ref<FormInstance>();
|
||||||
|
|
||||||
|
const validatePass2 = (_: any, value: any, callback: any) => {
|
||||||
|
if (value === '') {
|
||||||
|
callback(new Error('请再次输入密码'));
|
||||||
|
} else if (value !== ruleForm.password) {
|
||||||
|
callback(new Error('两次密码不一致!'));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const checkPhone = (_: any, value: string, callback: any) => {
|
||||||
|
if (!validPhone(value)) {
|
||||||
|
// 返回一个错误提示
|
||||||
|
callback(new Error('请输入正确的手机号码'));
|
||||||
|
} else {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 校验规则
|
||||||
|
const formRules = reactive<FormRules>({
|
||||||
|
name: [{ required: true, message: '请输入企业全称', trigger: 'blur' }],
|
||||||
|
code: [{ required: true, message: '请输入企业统一社会信用代码', trigger: 'blur' }],
|
||||||
|
address: [{ required: true, message: '请输入企业地址', trigger: 'blur' }],
|
||||||
|
legalPerson: [{ required: true, message: '请输入法定代表人', trigger: 'blur' }],
|
||||||
|
contractNo: [{ required: true, message: '请输入合同编号', trigger: 'blur' }],
|
||||||
|
linkman: [{ required: true, message: '请输入联系人', trigger: 'blur' }],
|
||||||
|
phone: [
|
||||||
|
{ required: true, message: '请输入手机号', trigger: 'blur' },
|
||||||
|
{ validator: checkPhone, trigger: 'blur' },
|
||||||
|
],
|
||||||
|
portId: [{ required: true, message: '请选择港口', trigger: 'blur' }],
|
||||||
|
licensePhoto: [{ required: true, message: '请上传营业执照', trigger: 'blur' }],
|
||||||
|
idPhoto: [{ required: true, message: '请上传身份证照片', trigger: 'blur' }],
|
||||||
|
enterpriseType: [{ required: true, message: '请选择企业类型', trigger: 'blur' }],
|
||||||
|
password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
|
||||||
|
confirmPassword: [{ required: true, validator: validatePass2, trigger: 'blur' }],
|
||||||
|
});
|
||||||
|
|
||||||
|
// 按钮加载状态
|
||||||
|
const submitLoading = ref(false);
|
||||||
|
|
||||||
|
// 企业入驻
|
||||||
|
const onClickSubmitRegister = (formEl: FormInstance | undefined) => {
|
||||||
|
// 进行表单校验
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.validate(async (valid) => {
|
||||||
|
if (!valid) return;
|
||||||
|
try {
|
||||||
|
submitLoading.value = true; // 按钮进入加载状态
|
||||||
|
// 通过验证
|
||||||
|
await postEnterpriseRegAPI(ruleForm);
|
||||||
|
|
||||||
|
ElMessage({
|
||||||
|
message: '企业注册成功',
|
||||||
|
type: 'success',
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
submitLoading.value = false; // 关闭按钮加载状态
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.login-container {
|
.login {
|
||||||
position: relative;
|
width: 100%;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
min-width: 550px;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
min-height: 500px;
|
background: linear-gradient(180deg, rgb(51 51 51 / 100%) 0%, rgb(242 242 242 / 100%) 100%);
|
||||||
background-image: url('@/assets/images/login_bg.svg');
|
.login-header {
|
||||||
background-position: 50%;
|
|
||||||
background-size: 100% 100%;
|
|
||||||
background-size: cover;
|
|
||||||
.dark {
|
|
||||||
position: absolute;
|
|
||||||
top: 5%;
|
|
||||||
right: 3.2%;
|
|
||||||
}
|
|
||||||
.login-box {
|
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-around;
|
width: 100%;
|
||||||
width: 96%;
|
height: 70px;
|
||||||
height: 94%;
|
padding: 0 20px;
|
||||||
padding: 0 4% 0 20px;
|
background-color: rgb(156 0 12 / 100%);
|
||||||
overflow: hidden;
|
.logo {
|
||||||
border-radius: 10px;
|
width: 80px;
|
||||||
.login-welcome {
|
height: 50px;
|
||||||
width: 750px;
|
margin-right: 16px;
|
||||||
img {
|
}
|
||||||
width: 100%;
|
.left-title {
|
||||||
height: 100%;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
color: #fff;
|
||||||
|
.title {
|
||||||
|
font-size: 24px;
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.text {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 400;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.login-form {
|
}
|
||||||
|
.login-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 70px);
|
||||||
|
.login-box {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 40px 45px 25px;
|
display: flex;
|
||||||
border-radius: 10px;
|
align-items: center;
|
||||||
.login-logo {
|
justify-content: space-around;
|
||||||
|
width: 96%;
|
||||||
|
height: 94%;
|
||||||
|
.login-welcome {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
.pc {
|
||||||
justify-content: center;
|
display: flex;
|
||||||
margin-bottom: 40px;
|
flex-direction: column;
|
||||||
.logo-icon {
|
align-items: center;
|
||||||
width: 70px;
|
justify-content: center;
|
||||||
|
.logo-title {
|
||||||
|
font-size: 32px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
width: 500px;
|
||||||
|
height: 400px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.logo-text {
|
.mini {
|
||||||
padding-left: 25px;
|
display: flex;
|
||||||
font-size: 48px;
|
flex-direction: column;
|
||||||
font-weight: bold;
|
align-items: center;
|
||||||
white-space: nowrap;
|
justify-content: flex-end;
|
||||||
|
height: 445px;
|
||||||
|
margin-left: 10px;
|
||||||
|
.logo-title {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 32px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
width: 160px;
|
||||||
|
height: 330px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
:deep(.el-form-item) {
|
.login-form {
|
||||||
color: #454545;
|
box-sizing: border-box;
|
||||||
background: rgb(0 0 0 / 10%);
|
width: 400px;
|
||||||
border: 1px solid rgb(255 255 255 / 10%);
|
padding: 60px 45px;
|
||||||
border-radius: 5px;
|
background-color: #fff;
|
||||||
|
border-radius: 7px;
|
||||||
|
box-shadow: 0 0 13px rgb(0 0 0 / 34.9%);
|
||||||
|
.form-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
.form-title-left {
|
||||||
|
font-size: 38px;
|
||||||
|
}
|
||||||
|
.form-title-right {
|
||||||
|
font-size: 20px;
|
||||||
|
color: #027db4;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.form-title-right:hover {
|
||||||
|
color: rgb(217 0 27);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:deep(.el-form-item) {
|
||||||
|
color: #454545;
|
||||||
|
background: rgb(0 0 0 / 10%);
|
||||||
|
border: 1px solid rgb(255 255 255 / 10%);
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
:deep(input) {
|
||||||
|
height: 47px;
|
||||||
|
padding: 12px 5px 12px 15px;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
.login-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
height: 47px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
:deep(input) {
|
}
|
||||||
height: 47px;
|
.register {
|
||||||
padding: 12px 5px 12px 15px;
|
box-sizing: border-box;
|
||||||
border: 0;
|
width: 96%;
|
||||||
border-radius: 0;
|
height: 94%;
|
||||||
box-shadow: none;
|
background-color: #fff;
|
||||||
|
.register-header {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
padding: 40px 0;
|
||||||
|
font-size: 39px;
|
||||||
|
font-weight: 700;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
.login-btn {
|
.register-box {
|
||||||
|
box-sizing: border-box;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 47px;
|
padding: 0 20px;
|
||||||
margin: 20px 0;
|
.register-welcome {
|
||||||
|
display: flex;
|
||||||
|
.pc {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
.logo-title {
|
||||||
|
font-size: 32px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
width: 320px;
|
||||||
|
height: 256px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mini {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
height: 445px;
|
||||||
|
margin-left: 10px;
|
||||||
|
.logo-title {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 32px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
width: 100px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.register-form {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 40px;
|
||||||
|
.form-left {
|
||||||
|
width: 49%;
|
||||||
|
.form-wrap {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px 30px;
|
||||||
|
border: 1px dashed #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
.form-title {
|
||||||
|
position: absolute;
|
||||||
|
top: -14px; /* 使标题悬浮在边框上方 */
|
||||||
|
left: 20px; /* 根据需要调整水平位置 */
|
||||||
|
padding: 0 8px; /* 增加一点内边距 */
|
||||||
|
font-size: 18px;
|
||||||
|
color: #333;
|
||||||
|
background: #fff; /* 设置背景覆盖边框 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.form-submit {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.form-right {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 49%;
|
||||||
|
padding: 20px 30px;
|
||||||
|
border: 1px dashed #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
.form-title {
|
||||||
|
position: absolute;
|
||||||
|
top: -14px; /* 使标题悬浮在边框上方 */
|
||||||
|
left: 20px; /* 根据需要调整水平位置 */
|
||||||
|
padding: 0 8px; /* 增加一点内边距 */
|
||||||
|
font-size: 18px;
|
||||||
|
color: #333;
|
||||||
|
background: #fff; /* 设置背景覆盖边框 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.login-form1 {
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 70%;
|
|
||||||
padding: 40px 45px 25px;
|
|
||||||
border-radius: 10px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="manage">
|
|
||||||
<ManifestDetailTable />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import ManifestDetailTable from './components/ManifestDetailTable.vue';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.manage {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,18 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="manage">
|
|
||||||
<ManifestTable />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import ManifestTable from './components/ManifestTable.vue';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.manage {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -3,7 +3,11 @@
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<el-form :inline="true" :model="searchTableForm" ref="tableFormRef">
|
<el-form :inline="true" :model="searchTableForm" ref="tableFormRef">
|
||||||
<el-form-item prop="name">
|
<el-form-item prop="name">
|
||||||
<el-input v-model="searchTableForm.billNo" placeholder="请输入提单号" />
|
<el-input
|
||||||
|
v-model="searchTableForm.billNo"
|
||||||
|
placeholder="请输入提单号"
|
||||||
|
style="width: 120px"
|
||||||
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="Search" @click="onClickSearch">查询</el-button>
|
<el-button type="primary" icon="Search" @click="onClickSearch">查询</el-button>
|
||||||
|
@ -12,14 +16,12 @@
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="footer-util">舱单明细</div>
|
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
<div class="footer-table">
|
<div class="footer-table">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="tableLoading"
|
v-loading="tableLoading"
|
||||||
:data="tableState.tableData"
|
:data="tableState.tableData"
|
||||||
border
|
border
|
||||||
stripe
|
|
||||||
style="width: 100%; height: 100%"
|
style="width: 100%; height: 100%"
|
||||||
>
|
>
|
||||||
<el-table-column prop="manifest.name" label="舱单" align="center" width="150" />
|
<el-table-column prop="manifest.name" label="舱单" align="center" width="150" />
|
||||||
|
@ -56,24 +58,32 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { FormInstance } from 'element-plus';
|
import { FormInstance } from 'element-plus';
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
|
||||||
import { getManifestDetailPageAPI } from '@/api/Manifest/detail';
|
import { getManifestDetailPageAPI } from '@/api/Manifest/detail';
|
||||||
import Pagination from '@/components/Pagination/Pagination.vue';
|
import Pagination from '@/components/Pagination/Pagination.vue';
|
||||||
import { useTable } from '@/hooks/useTable';
|
import { useTable } from '@/hooks/useTable';
|
||||||
|
|
||||||
// 路由参数
|
// 接受父组件参数
|
||||||
const route = useRoute();
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
manifestId: string;
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
manifestId: '',
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
// 获取列表表格数据
|
// 获取列表表格数据
|
||||||
const { getTableList, tableState, searchTable, resetTable, tableChangeCurrent, tableChangeSize } =
|
const { getTableList, tableState, searchTable, resetTable, tableChangeCurrent, tableChangeSize } =
|
||||||
useTable({
|
useTable({
|
||||||
api: getManifestDetailPageAPI,
|
api: getManifestDetailPageAPI,
|
||||||
initParam: {
|
|
||||||
manifestId: [route.query.manifestId as string],
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
|
if (props.manifestId) {
|
||||||
|
tableState.value.searchInitParam = {
|
||||||
|
manifestId: [props.manifestId],
|
||||||
|
};
|
||||||
|
}
|
||||||
await getTableList();
|
await getTableList();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -107,28 +117,6 @@ const onClickResetForm = async (formEl: FormInstance | undefined) => {
|
||||||
formEl.resetFields();
|
formEl.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除
|
|
||||||
// const onClickDel = (row: EmployeeType) => {
|
|
||||||
// ElMessageBox.confirm(`你确定要删除员工 ${row.name} 吗?`, '温馨提示', {
|
|
||||||
// confirmButtonText: '确定',
|
|
||||||
// cancelButtonText: '取消',
|
|
||||||
// type: 'warning',
|
|
||||||
// draggable: true,
|
|
||||||
// })
|
|
||||||
// .then(async () => {
|
|
||||||
// await postEmployeeDeleteAPI([row.id]);
|
|
||||||
// // 更新表格
|
|
||||||
// await getTableList();
|
|
||||||
// ElMessage({
|
|
||||||
// message: '删除成功',
|
|
||||||
// type: 'success',
|
|
||||||
// });
|
|
||||||
// })
|
|
||||||
// .catch(() => {
|
|
||||||
// console.log('用户点击了取消');
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
|
|
||||||
// 改变每页显示条目个数
|
// 改变每页显示条目个数
|
||||||
const handleSizeChange = async (val: number) => {
|
const handleSizeChange = async (val: number) => {
|
||||||
await tableChangeSize(val);
|
await tableChangeSize(val);
|
||||||
|
@ -149,11 +137,8 @@ const handleCurrentChange = async (val: number) => {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 16px 16px 0;
|
justify-content: space-between;
|
||||||
margin-bottom: 16px;
|
padding: 0 16px;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
}
|
}
|
||||||
.footer {
|
.footer {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -163,9 +148,6 @@ const handleCurrentChange = async (val: number) => {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
.footer-util {
|
.footer-util {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
|
@ -5,33 +5,19 @@
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<RemoteSelect
|
<RemoteSelect
|
||||||
v-model:value="searchTableForm.shipId"
|
v-model:value="searchTableForm.shipId"
|
||||||
placeholder="请选择船舶"
|
placeholder="请选择船名"
|
||||||
:api="postShipListAPI"
|
:api="postShipListAPI"
|
||||||
style="width: 120px"
|
style="width: 120px"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
|
||||||
<el-input v-model="searchTableForm.voyage" placeholder="请输入航次" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-select
|
|
||||||
v-model="searchTableForm.goodsStatus"
|
|
||||||
placeholder="货物状态"
|
|
||||||
style="width: 120px"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in goodsStatusList"
|
|
||||||
:key="item.value"
|
|
||||||
:label="item.label"
|
|
||||||
:value="item.value"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="Search" @click="onClickSearch">查询</el-button>
|
<el-button type="primary" icon="Search" @click="onClickSearch">查询</el-button>
|
||||||
<el-button icon="Refresh" @click="onClickResetForm(tableFormRef)">重置</el-button>
|
<el-button icon="Refresh" @click="onClickResetForm(tableFormRef)">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
<div>
|
||||||
|
<el-button type="success" @click="onClickExport">舱单导出</el-button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
|
@ -40,7 +26,6 @@
|
||||||
v-loading="tableLoading"
|
v-loading="tableLoading"
|
||||||
:data="tableState.tableData"
|
:data="tableState.tableData"
|
||||||
border
|
border
|
||||||
stripe
|
|
||||||
style="width: 100%; height: 100%"
|
style="width: 100%; height: 100%"
|
||||||
>
|
>
|
||||||
<el-table-column prop="schedule.name" label="船期" align="center" width="120" />
|
<el-table-column prop="schedule.name" label="船期" align="center" width="120" />
|
||||||
|
@ -87,10 +72,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { FormInstance } from 'element-plus';
|
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { getManifestFileExportAPI, getManifestPageAPI } from '@/api/Manifest';
|
||||||
import { getManifestPageAPI } from '@/api/Manifest';
|
|
||||||
import { postShipListAPI } from '@/api/Ship';
|
import { postShipListAPI } from '@/api/Ship';
|
||||||
import Pagination from '@/components/Pagination/Pagination.vue';
|
import Pagination from '@/components/Pagination/Pagination.vue';
|
||||||
import RemoteSelect from '@/components/RemoteSelect/index.vue';
|
import RemoteSelect from '@/components/RemoteSelect/index.vue';
|
||||||
|
@ -107,25 +91,6 @@ onMounted(async () => {
|
||||||
await getTableList();
|
await getTableList();
|
||||||
});
|
});
|
||||||
|
|
||||||
const goodsStatusList = [
|
|
||||||
{
|
|
||||||
value: '有计划',
|
|
||||||
label: '有计划',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '已靠港',
|
|
||||||
label: '已靠港',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '作业中',
|
|
||||||
label: '作业中',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: '已离港',
|
|
||||||
label: '已离港',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
// 查询条件
|
// 查询条件
|
||||||
const searchTableForm = reactive({
|
const searchTableForm = reactive({
|
||||||
scheduleId: '',
|
scheduleId: '',
|
||||||
|
@ -161,41 +126,55 @@ const onClickResetForm = async (formEl: FormInstance | undefined) => {
|
||||||
formEl.resetFields();
|
formEl.resetFields();
|
||||||
};
|
};
|
||||||
|
|
||||||
// 路由
|
// 导出舱单
|
||||||
const router = useRouter();
|
const onClickExport = () => {
|
||||||
|
ElMessageBox.confirm(`你确定要导出舱单信息吗?`, '温馨提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning',
|
||||||
|
draggable: true,
|
||||||
|
})
|
||||||
|
.then(async () => {
|
||||||
|
try {
|
||||||
|
let params: any = {
|
||||||
|
rows: tableState.value.pageAble.rows,
|
||||||
|
page: tableState.value.pageAble.page,
|
||||||
|
};
|
||||||
|
if (searchTableForm.shipId) {
|
||||||
|
params.shipId = searchTableForm.shipId;
|
||||||
|
}
|
||||||
|
const { data } = await getManifestFileExportAPI(params);
|
||||||
|
const blob = new Blob([data], {
|
||||||
|
type: 'application/vnd.ms-excel;charset=utf-8',
|
||||||
|
});
|
||||||
|
const downloadUrl = URL.createObjectURL(blob);
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = downloadUrl;
|
||||||
|
link.download = '舱单信息.xlsx';
|
||||||
|
link.click();
|
||||||
|
ElMessage({
|
||||||
|
message: '导出成功',
|
||||||
|
type: 'success',
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage({
|
||||||
|
message: '导出失败',
|
||||||
|
type: 'error',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
console.log('用户点击了取消');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const emits = defineEmits(['ManifestID']);
|
||||||
|
|
||||||
// 查看明细
|
// 查看明细
|
||||||
const onClickOpenDetail = (row: ManifestType) => {
|
const onClickOpenDetail = (row: ManifestType) => {
|
||||||
router.push({
|
emits('ManifestID', row);
|
||||||
path: '/Manifest/detail',
|
|
||||||
query: {
|
|
||||||
manifestId: row.id,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 删除
|
|
||||||
// const onClickDel = (row: ManifestType) => {
|
|
||||||
// ElMessageBox.confirm(`你确定要删除舱单吗?`, '温馨提示', {
|
|
||||||
// confirmButtonText: '确定',
|
|
||||||
// cancelButtonText: '取消',
|
|
||||||
// type: 'warning',
|
|
||||||
// draggable: true,
|
|
||||||
// })
|
|
||||||
// .then(async () => {
|
|
||||||
// await postManifestDeleteAPI([row.id]);
|
|
||||||
// // 更新表格
|
|
||||||
// await getTableList();
|
|
||||||
// ElMessage({
|
|
||||||
// message: '删除成功',
|
|
||||||
// type: 'success',
|
|
||||||
// });
|
|
||||||
// })
|
|
||||||
// .catch(() => {
|
|
||||||
// console.log('用户点击了取消');
|
|
||||||
// });
|
|
||||||
// };
|
|
||||||
|
|
||||||
// 改变每页显示条目个数
|
// 改变每页显示条目个数
|
||||||
const handleSizeChange = async (val: number) => {
|
const handleSizeChange = async (val: number) => {
|
||||||
await tableChangeSize(val);
|
await tableChangeSize(val);
|
||||||
|
@ -216,11 +195,8 @@ const handleCurrentChange = async (val: number) => {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 16px 16px 0;
|
justify-content: space-between;
|
||||||
margin-bottom: 16px;
|
padding: 0 16px;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
}
|
}
|
||||||
.footer {
|
.footer {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -230,9 +206,6 @@ const handleCurrentChange = async (val: number) => {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
.footer-util {
|
.footer-util {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
|
@ -0,0 +1,103 @@
|
||||||
|
<template>
|
||||||
|
<div class="table">
|
||||||
|
<div class="header">
|
||||||
|
<div class="title">{{ currentSubscribeNav }}</div>
|
||||||
|
<div class="api-btn">
|
||||||
|
<div
|
||||||
|
class="btn"
|
||||||
|
:class="{ 'btn-active': currentSubscribeNav === item }"
|
||||||
|
v-for="item in subscribeNavList"
|
||||||
|
:key="item"
|
||||||
|
@click="onClickChangeSubscribeType(item)"
|
||||||
|
>
|
||||||
|
{{ item }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<ManifestTable v-if="currentSubscribeNav === '舱单信息'" @ManifestID="onClickOpenDetail" />
|
||||||
|
<ManifestDetailTable :manifestId="manifestID" v-if="currentSubscribeNav === '提单明细'" />
|
||||||
|
<!-- <ReceiveTable v-if="currentSubscribeNav === '积载图'" /> -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { ManifestType } from '@/types/manifest';
|
||||||
|
import ManifestDetailTable from './components/ManifestDetailTable.vue';
|
||||||
|
import ManifestTable from './components/ManifestTable.vue';
|
||||||
|
|
||||||
|
const manifestID = ref();
|
||||||
|
|
||||||
|
// 订阅导航列表
|
||||||
|
const subscribeNavList = ref(['舱单信息', '提单明细', '积载图']);
|
||||||
|
const currentSubscribeNav = ref('舱单信息');
|
||||||
|
const onClickChangeSubscribeType = async (item: string) => {
|
||||||
|
if (item === currentSubscribeNav.value) return;
|
||||||
|
currentSubscribeNav.value = item;
|
||||||
|
if (item === '提单明细') {
|
||||||
|
manifestID.value = '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onClickOpenDetail = (row: ManifestType) => {
|
||||||
|
manifestID.value = row.id;
|
||||||
|
currentSubscribeNav.value = '提单明细';
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.table {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.header {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 16px 16px 0;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #fff;
|
||||||
|
.title {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.api-btn {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
.btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 150px;
|
||||||
|
height: 50px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #d7d7d7;
|
||||||
|
background-color: rgb(51 51 51 / 100%);
|
||||||
|
border-radius: 75px;
|
||||||
|
box-shadow: 5px 5px 5px rgb(0 0 0 / 34.9%);
|
||||||
|
}
|
||||||
|
.btn-active {
|
||||||
|
color: #000;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 1;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="notify">
|
<div class="notify">
|
||||||
|
<div class="title">平台公告</div>
|
||||||
<div class="list">
|
<div class="list">
|
||||||
<div class="list-title">平台公告</div>
|
|
||||||
<ul
|
<ul
|
||||||
class="list-wrap"
|
class="list-wrap"
|
||||||
v-infinite-scroll="noticeListLoad"
|
v-infinite-scroll="noticeListLoad"
|
||||||
|
@ -14,17 +14,21 @@
|
||||||
class="list-item"
|
class="list-item"
|
||||||
@click="onClickOpenDialog(item)"
|
@click="onClickOpenDialog(item)"
|
||||||
>
|
>
|
||||||
|
<div class="item-icon"></div>
|
||||||
<div class="item-title">{{ item.title }}</div>
|
<div class="item-title">{{ item.title }}</div>
|
||||||
<div class="item-date">{{ item.createDate }}</div>
|
<div class="item-date">{{ item.createDate }}</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
|
||||||
<el-dialog v-model="isShowNotice" width="70%" top="50px">
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
|
<div class="border1"></div>
|
||||||
|
<div class="border2"></div>
|
||||||
|
<div class="border3"></div>
|
||||||
|
<div class="border4"></div>
|
||||||
<div class="title">{{ noticeViewData?.title }}</div>
|
<div class="title">{{ noticeViewData?.title }}</div>
|
||||||
<div class="wrap" v-html="noticeViewData?.content"></div>
|
<div class="wrap" v-html="noticeViewData?.content"></div>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -79,28 +83,26 @@ const onClickOpenDialog = async (row: NoticeType) => {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
color: #fff;
|
||||||
|
.title {
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
font-size: 30px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
.list {
|
.list {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: calc(100% - 100px);
|
||||||
padding: 20px;
|
|
||||||
color: #303133;
|
|
||||||
background-color: #fff;
|
|
||||||
border: 1px solid #e4ede7;
|
|
||||||
border-radius: 4px;
|
|
||||||
.list-title {
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
font-size: 30px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
.list-wrap {
|
.list-wrap {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 100%;
|
width: 30%;
|
||||||
height: calc(100% - 50px);
|
height: 500px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
.list-item {
|
.list-item {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@ -109,7 +111,13 @@ const onClickOpenDialog = async (row: NoticeType) => {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-bottom: 1px dashed #e4e4e7;
|
.item-icon {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
margin-right: 10px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
.item-title {
|
.item-title {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -123,21 +131,63 @@ const onClickOpenDialog = async (row: NoticeType) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
.content {
|
||||||
.content {
|
position: relative;
|
||||||
width: 100%;
|
box-sizing: border-box;
|
||||||
height: 100%;
|
flex: 1;
|
||||||
.title {
|
height: 100%;
|
||||||
display: flex;
|
margin-left: 20px;
|
||||||
justify-content: center;
|
font-size: 21px;
|
||||||
padding: 16px;
|
font-style: normal;
|
||||||
font-size: 23px;
|
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
color: var(--el-text-color-regular);
|
background-color: #333;
|
||||||
}
|
border: 5px solid #fff;
|
||||||
.wrap {
|
border-radius: 9px;
|
||||||
width: 100%;
|
.title {
|
||||||
height: calc(100% - 70px);
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 16px;
|
||||||
|
font-size: 23px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.wrap {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 70px);
|
||||||
|
padding: 0 16px 20px;
|
||||||
|
}
|
||||||
|
.border1 {
|
||||||
|
position: absolute;
|
||||||
|
top: -5px;
|
||||||
|
left: 10%;
|
||||||
|
width: 80%;
|
||||||
|
height: 5px;
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
|
.border2 {
|
||||||
|
position: absolute;
|
||||||
|
top: 10%;
|
||||||
|
left: -5px;
|
||||||
|
width: 5px;
|
||||||
|
height: 80%;
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
|
.border3 {
|
||||||
|
position: absolute;
|
||||||
|
top: 10%;
|
||||||
|
left: 100%;
|
||||||
|
width: 5px;
|
||||||
|
height: 80%;
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
|
.border4 {
|
||||||
|
position: absolute;
|
||||||
|
top: 100%;
|
||||||
|
left: 10%;
|
||||||
|
width: 80%;
|
||||||
|
height: 5px;
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
<template>
|
||||||
|
<div class="send">
|
||||||
|
<el-steps class="header" :active="currentActive" finish-status="success">
|
||||||
|
<el-step title="发布船期信息" />
|
||||||
|
<el-step title="发布舱单信息" />
|
||||||
|
<el-step title="提交舱单明细" />
|
||||||
|
</el-steps>
|
||||||
|
<div class="content">
|
||||||
|
<div class="content-left">
|
||||||
|
<div class="left-icon">{{ currentActive }}</div>
|
||||||
|
<div class="left-title">{{ currentTitle[currentActive - 1] }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-right">
|
||||||
|
<BoatInfoSend @updateBoatID="onUpdateBoatID" v-if="currentActive === 1" />
|
||||||
|
<ManifestSend
|
||||||
|
:scheduleId="manifestProps?.scheduleId"
|
||||||
|
:voyage="manifestProps?.voyage"
|
||||||
|
:loadPortId="manifestProps?.loadPortId"
|
||||||
|
:dischargePortId="manifestProps?.dischargePortId"
|
||||||
|
@updateBoatID="onUpdateManifest"
|
||||||
|
v-if="currentActive === 2"
|
||||||
|
/>
|
||||||
|
<ManifestDetailSend
|
||||||
|
:manifestId="manifestDetailProps?.manifestId"
|
||||||
|
:billNo="manifestDetailProps?.billNo"
|
||||||
|
:brandId="manifestDetailProps?.brandId"
|
||||||
|
:model="manifestDetailProps?.model"
|
||||||
|
v-if="currentActive === 3"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import BoatInfoSend from './BoatInfoSend.vue';
|
||||||
|
import ManifestDetailSend from './ManifestDetailSend.vue';
|
||||||
|
import ManifestSend from './ManifestSend.vue';
|
||||||
|
|
||||||
|
// 当前选中的步骤
|
||||||
|
const currentActive = ref(1);
|
||||||
|
const currentTitle = ref(['发布船期信息', '发布舱单信息', '提交舱单明细']);
|
||||||
|
|
||||||
|
interface manifestPropsType {
|
||||||
|
scheduleId: string;
|
||||||
|
voyage: string;
|
||||||
|
loadPortId: number | string;
|
||||||
|
dischargePortId: string | number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const manifestProps = ref<manifestPropsType>();
|
||||||
|
// 发布船期信息
|
||||||
|
const onUpdateBoatID = (params: manifestPropsType) => {
|
||||||
|
manifestProps.value = params;
|
||||||
|
currentActive.value = 2;
|
||||||
|
};
|
||||||
|
|
||||||
|
interface manifestDetailPropsType {
|
||||||
|
manifestId: string | number;
|
||||||
|
billNo?: string;
|
||||||
|
brandId?: string;
|
||||||
|
model?: string;
|
||||||
|
}
|
||||||
|
const manifestDetailProps = ref<manifestDetailPropsType>();
|
||||||
|
const onUpdateManifest = (params: manifestDetailPropsType) => {
|
||||||
|
manifestDetailProps.value = params;
|
||||||
|
currentActive.value = 3;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.send {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.header {
|
||||||
|
width: 100%;
|
||||||
|
height: 70px;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 70px);
|
||||||
|
.content-left {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 30%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 40px 0 0 20px;
|
||||||
|
background-color: #027db4;
|
||||||
|
.left-icon {
|
||||||
|
width: 64px;
|
||||||
|
height: 64px;
|
||||||
|
margin-right: 10px;
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 64px;
|
||||||
|
color: #d9001b;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
.left-title {
|
||||||
|
height: 64px;
|
||||||
|
font-size: 32px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 64px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content-right {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 70%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,176 @@
|
||||||
|
<template>
|
||||||
|
<div class="table">
|
||||||
|
<div class="footer">
|
||||||
|
<div class="footer-util">
|
||||||
|
<div class="title">我最近发布的信息</div>
|
||||||
|
<el-button type="primary" icon="Plus" @click="onClickSendInfo"> 新增发布 </el-button>
|
||||||
|
</div>
|
||||||
|
<!-- 表格 -->
|
||||||
|
<div class="footer-table">
|
||||||
|
<el-table
|
||||||
|
v-loading="tableLoading"
|
||||||
|
:data="tableState.tableData"
|
||||||
|
border
|
||||||
|
style="width: 100%; height: 100%"
|
||||||
|
>
|
||||||
|
<el-table-column prop="enterprise.name" label="企业" align="center" width="150" />
|
||||||
|
<el-table-column prop="ship.name" label="船舶" align="center" width="150" />
|
||||||
|
<el-table-column prop="voyage" label="航次" align="center" width="180" />
|
||||||
|
<el-table-column prop="shipRoute.name" label="航线" align="center" width="150" />
|
||||||
|
<el-table-column prop="loadWharf.name" label="装货码头" align="center" width="150" />
|
||||||
|
<el-table-column prop="dischargeWharf.name" label="卸货码头" align="center" width="150" />
|
||||||
|
<el-table-column prop="carNumPlan" label="计划商品车数量" align="center" width="180" />
|
||||||
|
<el-table-column prop="spareNumPlan" label="计划件杂货数量" align="center" width="180" />
|
||||||
|
<el-table-column prop="carNumActual" label="实际商品车数量" align="center" width="180" />
|
||||||
|
<el-table-column
|
||||||
|
prop="spareNumActual"
|
||||||
|
label="实际件杂货数量"
|
||||||
|
align="center"
|
||||||
|
width="180"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
prop="departureDatePlan"
|
||||||
|
label="计划离泊时间"
|
||||||
|
align="center"
|
||||||
|
width="200"
|
||||||
|
/>
|
||||||
|
<el-table-column
|
||||||
|
prop="departureDateActual"
|
||||||
|
label="实际离泊时间"
|
||||||
|
align="center"
|
||||||
|
width="200"
|
||||||
|
/>
|
||||||
|
<el-table-column prop="tradeType" label="贸易类型" align="center" width="150" />
|
||||||
|
<el-table-column prop="loadPort.name" label="装货港口" align="center" width="150" />
|
||||||
|
<el-table-column prop="dischargePort.name" label="卸货港口" align="center" width="150" />
|
||||||
|
<el-table-column prop="shipStatus" label="当前状态" align="center" width="150" />
|
||||||
|
<el-table-column prop="createDate" label="创建时间" align="center" width="180" />
|
||||||
|
<el-table-column prop="operator" label="操作" width="200px" align="center" fixed="right">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
icon="View"
|
||||||
|
link
|
||||||
|
@click="onClickOpenDetail(scope.row)"
|
||||||
|
>
|
||||||
|
查看
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<div class="footer-pagination">
|
||||||
|
<Pagination
|
||||||
|
:pageAble="tableState.pageAble"
|
||||||
|
:handle-size-change="handleSizeChange"
|
||||||
|
:handle-current-change="handleCurrentChange"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { onMounted, ref } from 'vue';
|
||||||
|
import { getSailScheduleGetAPI, getSailSchedulePageAPI } from '@/api/Boat/info';
|
||||||
|
import Pagination from '@/components/Pagination/Pagination.vue';
|
||||||
|
import { useTable } from '@/hooks/useTable';
|
||||||
|
import { PageRowsResult } from '@/types';
|
||||||
|
import { BoatInfoType } from '@/types/boatInfo';
|
||||||
|
|
||||||
|
const handleTableData = (data: PageRowsResult<BoatInfoType>) => {
|
||||||
|
const { records } = data;
|
||||||
|
for (const item of records) {
|
||||||
|
item.departureDatePlan = dayjs(item.departureDatePlan).format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
item.departureDateActual = dayjs(item.departureDateActual).format('YYYY-MM-DD HH:mm:ss');
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取用户列表表格数据
|
||||||
|
const { getTableList, tableState, tableChangeCurrent, tableChangeSize } = useTable({
|
||||||
|
api: getSailSchedulePageAPI,
|
||||||
|
dataCallBack: handleTableData,
|
||||||
|
});
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await getTableList();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 表格是否加载
|
||||||
|
const tableLoading = ref(false);
|
||||||
|
|
||||||
|
const emits = defineEmits(['sendInfo']);
|
||||||
|
|
||||||
|
// 新增发布
|
||||||
|
const onClickSendInfo = () => {
|
||||||
|
emits('sendInfo');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 查看详情
|
||||||
|
const onClickOpenDetail = async (row: BoatInfoType) => {
|
||||||
|
const { data } = await getSailScheduleGetAPI({ id: row.id });
|
||||||
|
console.log('🚀 ~ file: BoatTable.vue:146 ~ onClickOpenDetail ~ data:', data);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 改变每页显示条目个数
|
||||||
|
const handleSizeChange = async (val: number) => {
|
||||||
|
await tableChangeSize(val);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 当前页数改变
|
||||||
|
const handleCurrentChange = async (val: number) => {
|
||||||
|
await tableChangeCurrent(val);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.table {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
.header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 16px;
|
||||||
|
overflow: hidden;
|
||||||
|
.footer-util {
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
.title {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #80ffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.footer-table {
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.footer-pagination {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
justify-content: flex-end;
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,84 +1,80 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="send">
|
<div class="table">
|
||||||
<el-steps class="header" :active="currentActive" finish-status="success">
|
<div class="header">
|
||||||
<el-step title="发布船期信息" />
|
<div class="title">发布船货信息</div>
|
||||||
<el-step title="发布舱单信息" />
|
</div>
|
||||||
<el-step title="提交舱单明细" />
|
|
||||||
</el-steps>
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<BoatInfoSend @updateBoatID="onUpdateBoatID" v-if="currentActive === 1" />
|
<SendTable v-if="currentSubscribeNav === '船货信息'" @sendInfo="onClickSendInfo" />
|
||||||
<ManifestSend
|
<Send v-if="currentSubscribeNav === '发布信息'" />
|
||||||
:scheduleId="manifestProps?.scheduleId"
|
|
||||||
:voyage="manifestProps?.voyage"
|
|
||||||
:loadPortId="manifestProps?.loadPortId"
|
|
||||||
:dischargePortId="manifestProps?.dischargePortId"
|
|
||||||
@updateBoatID="onUpdateManifest"
|
|
||||||
v-if="currentActive === 2"
|
|
||||||
/>
|
|
||||||
<ManifestDetailSend
|
|
||||||
:manifestId="manifestDetailProps?.manifestId"
|
|
||||||
:billNo="manifestDetailProps?.billNo"
|
|
||||||
:brandId="manifestDetailProps?.brandId"
|
|
||||||
:model="manifestDetailProps?.model"
|
|
||||||
v-if="currentActive === 3"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
import BoatInfoSend from './components/BoatInfoSend.vue';
|
import Send from './components/Send.vue';
|
||||||
import ManifestDetailSend from './components/ManifestDetailSend.vue';
|
import SendTable from './components/SendTable.vue';
|
||||||
import ManifestSend from './components/ManifestSend.vue';
|
|
||||||
|
|
||||||
// 当前选中的步骤
|
// 订阅导航列表
|
||||||
const currentActive = ref(1);
|
const currentSubscribeNav = ref('船货信息');
|
||||||
|
|
||||||
interface manifestPropsType {
|
// 新增发布
|
||||||
scheduleId: string;
|
const onClickSendInfo = () => {
|
||||||
voyage: string;
|
currentSubscribeNav.value = '发布信息';
|
||||||
loadPortId: number | string;
|
|
||||||
dischargePortId: string | number;
|
|
||||||
}
|
|
||||||
|
|
||||||
const manifestProps = ref<manifestPropsType>();
|
|
||||||
// 发布船期信息
|
|
||||||
const onUpdateBoatID = (params: manifestPropsType) => {
|
|
||||||
manifestProps.value = params;
|
|
||||||
currentActive.value = 2;
|
|
||||||
};
|
|
||||||
|
|
||||||
interface manifestDetailPropsType {
|
|
||||||
manifestId: string | number;
|
|
||||||
billNo?: string;
|
|
||||||
brandId?: string;
|
|
||||||
model?: string;
|
|
||||||
}
|
|
||||||
const manifestDetailProps = ref<manifestDetailPropsType>();
|
|
||||||
const onUpdateManifest = (params: manifestDetailPropsType) => {
|
|
||||||
manifestDetailProps.value = params;
|
|
||||||
currentActive.value = 3;
|
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.send {
|
.table {
|
||||||
box-sizing: border-box;
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 16px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
.header {
|
.header {
|
||||||
width: 100%;
|
box-sizing: border-box;
|
||||||
height: 70px;
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 16px 16px 0;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #fff;
|
||||||
|
.title {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.api-btn {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
.btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 150px;
|
||||||
|
height: 50px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #d7d7d7;
|
||||||
|
background-color: rgb(51 51 51 / 100%);
|
||||||
|
border-radius: 75px;
|
||||||
|
box-shadow: 5px 5px 5px rgb(0 0 0 / 34.9%);
|
||||||
|
}
|
||||||
|
.btn-active {
|
||||||
|
color: #000;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.content {
|
.content {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 100%;
|
flex: 1;
|
||||||
height: calc(100% - 70px);
|
padding: 16px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -21,34 +21,26 @@
|
||||||
:disabled="dialogProps.isView"
|
:disabled="dialogProps.isView"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<!-- <el-form-item label="码头">
|
<el-form-item label="码头" prop="wharfId" required>
|
||||||
<el-select
|
<RemoteSelect
|
||||||
v-model="dialogProps.row!.wharfId"
|
v-model:value="dialogProps.row!.wharfId"
|
||||||
placeholder="请选择港口"
|
placeholder="请选择码头"
|
||||||
style="width: 100%"
|
:api="postWharfListAPI"
|
||||||
clearable
|
:disabled="dialogProps.isView"
|
||||||
filterable
|
/>
|
||||||
remote
|
</el-form-item>
|
||||||
reserve-keyword
|
|
||||||
remote-show-suffix
|
|
||||||
:remote-method="onRemoteWharf"
|
|
||||||
:loading="wharfLoading"
|
|
||||||
:disabled="dialogProps.isView"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in wharfList"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.text"
|
|
||||||
:value="item.id"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item> -->
|
|
||||||
<el-form-item label="姓名" prop="name">
|
<el-form-item label="姓名" prop="name">
|
||||||
<el-input v-model="dialogProps.row!.name" placeholder="请输入姓名" />
|
<el-input v-model="dialogProps.row!.name" placeholder="请输入姓名" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="昵称">
|
<el-form-item label="昵称">
|
||||||
<el-input v-model="dialogProps.row!.nickname" placeholder="请输入昵称" />
|
<el-input v-model="dialogProps.row!.nickname" placeholder="请输入昵称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="部门" prop="dept">
|
||||||
|
<el-input v-model="dialogProps.row!.dept" placeholder="请输入部门" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="职位" prop="job">
|
||||||
|
<el-input v-model="dialogProps.row!.job" placeholder="请输入职位" />
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="用户名" prop="username">
|
<el-form-item label="用户名" prop="username">
|
||||||
<el-input v-model="dialogProps.row!.username" placeholder="请输入用户名" />
|
<el-input v-model="dialogProps.row!.username" placeholder="请输入用户名" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
@ -74,6 +66,7 @@
|
||||||
import { ElMessage, FormInstance, FormRules } from 'element-plus';
|
import { ElMessage, FormInstance, FormRules } from 'element-plus';
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { postEnterpriseListAPI } from '@/api/Enterprise/company';
|
import { postEnterpriseListAPI } from '@/api/Enterprise/company';
|
||||||
|
import { postWharfListAPI } from '@/api/Wharf';
|
||||||
import RemoteSelect from '@/components/RemoteSelect/index.vue';
|
import RemoteSelect from '@/components/RemoteSelect/index.vue';
|
||||||
import { EmployeeType } from '@/types/Enterprise';
|
import { EmployeeType } from '@/types/Enterprise';
|
||||||
|
|
||||||
|
@ -109,7 +102,9 @@ const formRules = reactive<FormRules>({
|
||||||
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||||||
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
username: [{ required: true, message: '请输入用户名', trigger: 'blur' }],
|
||||||
enterpriseId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
|
enterpriseId: [{ required: true, message: '请选择企业', trigger: 'blur' }],
|
||||||
// password: [{ required: true, message: '请输入密码', trigger: 'blur' }],
|
wharfId: [{ required: true, message: '请选择码头', trigger: 'blur' }],
|
||||||
|
job: [{ required: true, message: '请输入职位', trigger: 'blur' }],
|
||||||
|
dept: [{ required: true, message: '请输入部门', trigger: 'blur' }],
|
||||||
phone: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
|
phone: [{ required: true, message: '请输入联系电话', trigger: 'blur' }],
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,237 @@
|
||||||
|
<template>
|
||||||
|
<div class="notify">
|
||||||
|
<div class="list">
|
||||||
|
<div class="list-left">
|
||||||
|
<div class="left-title">在册用户:</div>
|
||||||
|
<div
|
||||||
|
class="list-wrap"
|
||||||
|
v-infinite-scroll="employeeListLoad"
|
||||||
|
:infinite-scroll-disabled="disabled"
|
||||||
|
:infinite-scroll-distance="100"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-for="item in employeeList"
|
||||||
|
:key="item.id"
|
||||||
|
class="list-item"
|
||||||
|
:class="{ 'list-item-active': currentUser.userId === item.id }"
|
||||||
|
@click="onClickOpenDialog(item)"
|
||||||
|
>
|
||||||
|
<div class="item-title">{{ item.name }}</div>
|
||||||
|
<div class="item-date">{{ item.dept }}/{{ item.job }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="list-right">
|
||||||
|
<div class="right-title">操作权限</div>
|
||||||
|
<div class="content">
|
||||||
|
<div class="content-title" v-if="currentUser.name">{{ currentUser.name }}的操作权限</div>
|
||||||
|
<el-checkbox-group v-model="currentUser.perms">
|
||||||
|
<div class="content-checkbox">
|
||||||
|
<div class="checkbox-title">查看船货信息:</div>
|
||||||
|
<div class="checkbox">
|
||||||
|
<el-checkbox label="船期信息" value="/sail_schedule/page" />
|
||||||
|
<el-checkbox label="舱单信息" value="/manifest/page" />
|
||||||
|
<el-checkbox label="舱单明细" value="/manifest/detail/page" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-checkbox">
|
||||||
|
<div class="checkbox-title">发布船货信息:</div>
|
||||||
|
<div class="checkbox">
|
||||||
|
<el-checkbox label="发布船货信息" value="sail_schedule/save" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-checkbox">
|
||||||
|
<div class="checkbox-title">订阅船货信息:</div>
|
||||||
|
<div class="checkbox">
|
||||||
|
<el-checkbox label="我的订阅" value="/subscribe/publish/page" />
|
||||||
|
<el-checkbox label="收到订阅" value="/subscribe/receive/page" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-checkbox-group>
|
||||||
|
|
||||||
|
<div class="content-btn">
|
||||||
|
<el-button type="primary" @click="onClickSubmit"> 提交保存 </el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
import { computed, ref } from 'vue';
|
||||||
|
import { postEmployeePageAPI } from '@/api/Enterprise/employee';
|
||||||
|
import { getUserRoleMenuListAPI, postRolePremSaveAPI } from '@/api/System/role';
|
||||||
|
import { EmployeeType } from '@/types/Enterprise';
|
||||||
|
|
||||||
|
// 用户列表
|
||||||
|
const employeeList = ref<EmployeeType[]>([]);
|
||||||
|
|
||||||
|
// 分页参数-当前页数
|
||||||
|
const currentPage = ref(1);
|
||||||
|
|
||||||
|
// 加载更多状态
|
||||||
|
const loadMoreState = ref('loading');
|
||||||
|
const disabled = computed(() => loadMoreState.value === 'finished');
|
||||||
|
|
||||||
|
// 获取用户列表
|
||||||
|
const getEmployeeList = async () => {
|
||||||
|
const { data } = await postEmployeePageAPI({
|
||||||
|
page: currentPage.value,
|
||||||
|
rows: 10,
|
||||||
|
});
|
||||||
|
|
||||||
|
employeeList.value = [...employeeList.value, ...data.records];
|
||||||
|
currentPage.value++;
|
||||||
|
// 检查是否到达最后一页或当前数据不足一页
|
||||||
|
if (currentPage.value >= Number(data.pages) || data.records.length < 10) {
|
||||||
|
loadMoreState.value = 'finished';
|
||||||
|
} else {
|
||||||
|
loadMoreState.value = 'loading';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 当前选中的用户
|
||||||
|
const currentUser = ref<{
|
||||||
|
name: string;
|
||||||
|
userId: number | string;
|
||||||
|
perms: string[];
|
||||||
|
}>({
|
||||||
|
name: '',
|
||||||
|
userId: '',
|
||||||
|
perms: [],
|
||||||
|
});
|
||||||
|
|
||||||
|
// 获取用户权限
|
||||||
|
const onClickOpenDialog = async (row: EmployeeType) => {
|
||||||
|
const { data } = await getUserRoleMenuListAPI({ userId: row.id });
|
||||||
|
currentUser.value.name = row.name;
|
||||||
|
currentUser.value.userId = row.id;
|
||||||
|
currentUser.value.perms = data;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 保存用户权限
|
||||||
|
const onClickSubmit = async () => {
|
||||||
|
// 判断是否选中了用户
|
||||||
|
if (currentUser.value.userId) {
|
||||||
|
await postRolePremSaveAPI({
|
||||||
|
userId: currentUser.value.userId,
|
||||||
|
perms: currentUser.value.perms,
|
||||||
|
});
|
||||||
|
ElMessage({
|
||||||
|
message: '保存成功',
|
||||||
|
type: 'success',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ElMessage({
|
||||||
|
message: '请选择用户',
|
||||||
|
type: 'warning',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const employeeListLoad = async () => {
|
||||||
|
await getEmployeeList();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.notify {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
color: #fff;
|
||||||
|
.list {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.list-left {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 30%;
|
||||||
|
.left-title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
.list-wrap {
|
||||||
|
height: 500px;
|
||||||
|
overflow: auto;
|
||||||
|
.list-item {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
padding: 0 6px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-bottom: 1px solid #fff;
|
||||||
|
.item-title {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
font-size: 16px;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.item-date {
|
||||||
|
margin-left: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.list-item:hover {
|
||||||
|
color: #333;
|
||||||
|
background-color: #ffffc9;
|
||||||
|
}
|
||||||
|
.list-item-active {
|
||||||
|
color: #333;
|
||||||
|
background-color: #ffffc9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.list-right {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
margin-left: 20px;
|
||||||
|
.right-title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
height: 400px;
|
||||||
|
padding: 40px;
|
||||||
|
color: #333;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 6px;
|
||||||
|
.content-title {
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
.content-checkbox {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
.checkbox-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
.checkbox {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -2,51 +2,32 @@
|
||||||
<div class="table">
|
<div class="table">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<el-form :inline="true" :model="searchTableForm" ref="tableFormRef">
|
<el-form :inline="true" :model="searchTableForm" ref="tableFormRef">
|
||||||
<!-- <el-form-item prop="enterpriseId">
|
|
||||||
<RemoteSelect
|
|
||||||
v-model:value="searchTableForm.enterpriseId"
|
|
||||||
placeholder="请选择企业"
|
|
||||||
style="width: 120px"
|
|
||||||
:api="postEnterpriseListAPI"
|
|
||||||
/>
|
|
||||||
</el-form-item> -->
|
|
||||||
<el-form-item prop="wharfId">
|
|
||||||
<RemoteSelect
|
|
||||||
v-model:value="searchTableForm.wharfId"
|
|
||||||
placeholder="请选择码头"
|
|
||||||
:api="postWharfListAPI"
|
|
||||||
style="width: 120px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item prop="name">
|
<el-form-item prop="name">
|
||||||
<el-input v-model="searchTableForm.name" placeholder="姓名" />
|
<el-input v-model="searchTableForm.name" placeholder="姓名" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item prop="username">
|
|
||||||
<el-input v-model="searchTableForm.username" placeholder="用户名" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" icon="Search" @click="onClickSearch">查询</el-button>
|
<el-button type="primary" icon="Search" @click="onClickSearch">查询</el-button>
|
||||||
<el-button icon="Refresh" @click="onClickResetForm(tableFormRef)">重置</el-button>
|
<el-button icon="Refresh" @click="onClickResetForm(tableFormRef)">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
<div>
|
||||||
<div class="footer">
|
|
||||||
<div class="footer-util">
|
|
||||||
<el-button type="primary" icon="Plus" @click="onClickOpenDialog('新增')">
|
<el-button type="primary" icon="Plus" @click="onClickOpenDialog('新增')">
|
||||||
新增员工
|
新增员工
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
<div class="footer-table">
|
<div class="footer-table">
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="tableLoading"
|
v-loading="tableLoading"
|
||||||
:data="tableState.tableData"
|
:data="tableState.tableData"
|
||||||
border
|
border
|
||||||
stripe
|
|
||||||
style="width: 100%; height: 100%"
|
style="width: 100%; height: 100%"
|
||||||
>
|
>
|
||||||
<el-table-column prop="name" label="姓名" align="center" width="180" />
|
<el-table-column prop="name" label="姓名" align="center" width="180" />
|
||||||
<el-table-column prop="enterprise.name" label="企业名称" align="center" width="100" />
|
<el-table-column prop="dept" label="部门" align="center" width="180" />
|
||||||
|
<el-table-column prop="job" label="职位" align="center" width="180" />
|
||||||
<el-table-column prop="nickname" label="昵称" align="center" width="180" />
|
<el-table-column prop="nickname" label="昵称" align="center" width="180" />
|
||||||
<el-table-column prop="username" label="用户名" align="center" width="180" />
|
<el-table-column prop="username" label="用户名" align="center" width="180" />
|
||||||
<el-table-column prop="wharf.name" label="码头" align="center" width="180" />
|
<el-table-column prop="wharf.name" label="码头" align="center" width="180" />
|
||||||
|
@ -71,7 +52,7 @@
|
||||||
>
|
>
|
||||||
查看
|
查看
|
||||||
</el-button>
|
</el-button>
|
||||||
<!-- <el-button
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
size="small"
|
size="small"
|
||||||
icon="Edit"
|
icon="Edit"
|
||||||
|
@ -79,7 +60,7 @@
|
||||||
@click="onClickOpenDialog('编辑', scope.row)"
|
@click="onClickOpenDialog('编辑', scope.row)"
|
||||||
>
|
>
|
||||||
编辑
|
编辑
|
||||||
</el-button> -->
|
</el-button>
|
||||||
<el-button
|
<el-button
|
||||||
type="danger"
|
type="danger"
|
||||||
size="small"
|
size="small"
|
||||||
|
@ -110,13 +91,12 @@
|
||||||
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
|
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import {
|
import {
|
||||||
|
postEmployeeAddAPI,
|
||||||
postEmployeeDeleteAPI,
|
postEmployeeDeleteAPI,
|
||||||
postEmployeePageAPI,
|
postEmployeePageAPI,
|
||||||
postEmployeeSaveAPI,
|
postEmployeeSaveAPI,
|
||||||
} from '@/api/Enterprise/employee';
|
} from '@/api/Enterprise/employee';
|
||||||
import { postWharfListAPI } from '@/api/Wharf';
|
|
||||||
import Pagination from '@/components/Pagination/Pagination.vue';
|
import Pagination from '@/components/Pagination/Pagination.vue';
|
||||||
import RemoteSelect from '@/components/RemoteSelect/index.vue';
|
|
||||||
import { useTable } from '@/hooks/useTable';
|
import { useTable } from '@/hooks/useTable';
|
||||||
import { EmployeeType } from '@/types/Enterprise';
|
import { EmployeeType } from '@/types/Enterprise';
|
||||||
import EmployeeDialog from './EmployeeDialog.vue';
|
import EmployeeDialog from './EmployeeDialog.vue';
|
||||||
|
@ -133,10 +113,7 @@ onMounted(async () => {
|
||||||
|
|
||||||
// 查询条件
|
// 查询条件
|
||||||
const searchTableForm = reactive({
|
const searchTableForm = reactive({
|
||||||
// enterpriseId: route.query.enterpriseId as string,
|
|
||||||
name: '',
|
name: '',
|
||||||
username: '',
|
|
||||||
wharfId: '',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 表格是否加载
|
// 表格是否加载
|
||||||
|
@ -171,8 +148,8 @@ const onClickOpenDialog = (title: string, row: Partial<EmployeeType> = {}) => {
|
||||||
const params = {
|
const params = {
|
||||||
title,
|
title,
|
||||||
isView: title === '查看',
|
isView: title === '查看',
|
||||||
row: { ...row },
|
row: title === '新增' ? { password: '123456', ...row } : { ...row },
|
||||||
api: postEmployeeSaveAPI,
|
api: title === '新增' ? postEmployeeAddAPI : postEmployeeSaveAPI,
|
||||||
getTableList,
|
getTableList,
|
||||||
};
|
};
|
||||||
employeeDialogRef.value?.isShowDialog(params);
|
employeeDialogRef.value?.isShowDialog(params);
|
||||||
|
@ -220,11 +197,8 @@ const handleCurrentChange = async (val: number) => {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 16px 16px 0;
|
justify-content: space-between;
|
||||||
margin-bottom: 16px;
|
padding: 0 16px;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
}
|
}
|
||||||
.footer {
|
.footer {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -234,15 +208,6 @@ const handleCurrentChange = async (val: number) => {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
.footer-util {
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
justify-content: flex-end;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
.footer-table {
|
.footer-table {
|
||||||
position: relative;
|
position: relative;
|
||||||
flex: 1;
|
flex: 1;
|
|
@ -0,0 +1,93 @@
|
||||||
|
<template>
|
||||||
|
<div class="notify">
|
||||||
|
<div class="list">
|
||||||
|
<div class="list-wrap">
|
||||||
|
<div class="title">{{ wharfInfo?.name }}</div>
|
||||||
|
<div class="list-item">地理位置:{{ wharfInfo?.address }}</div>
|
||||||
|
<div class="list-item">通过能力:{{ wharfInfo?.transitCapacity }}</div>
|
||||||
|
<div class="list-item">泊位数量:{{ wharfInfo?.berthageNum }}</div>
|
||||||
|
<div class="list-item">堆存能力:{{ wharfInfo?.storageCapacity }}</div>
|
||||||
|
<div class="list-item">接卸能力:{{ wharfInfo?.handlingCapacity }}</div>
|
||||||
|
<div class="list-item">简介:{{ wharfInfo?.intro }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<img class="wharfInfo" :src="wharfPhoto" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { onMounted, ref } from 'vue';
|
||||||
|
import { getWharfPhotoAPI, postWharfInfoAPI } from '@/api/Wharf';
|
||||||
|
import { LoadInfoType } from '@/types/boatInfo';
|
||||||
|
|
||||||
|
// 码头信息
|
||||||
|
const wharfInfo = ref<LoadInfoType>();
|
||||||
|
const wharfPhoto = ref('');
|
||||||
|
|
||||||
|
// 获取绑定的码头信息
|
||||||
|
const getWharfInfo = async () => {
|
||||||
|
const { data } = await postWharfInfoAPI();
|
||||||
|
wharfInfo.value = data;
|
||||||
|
// 获取码头图片
|
||||||
|
const { data: photo } = await getWharfPhotoAPI(data.portId);
|
||||||
|
|
||||||
|
const arrayBufferToBase64 = (buffer: ArrayBuffer): string => {
|
||||||
|
let binary = '';
|
||||||
|
const bytes = new Uint8Array(buffer);
|
||||||
|
const len = bytes.byteLength;
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
binary += String.fromCharCode(bytes[i]);
|
||||||
|
}
|
||||||
|
return btoa(binary);
|
||||||
|
};
|
||||||
|
|
||||||
|
const base64String = arrayBufferToBase64(photo);
|
||||||
|
wharfPhoto.value = `data:image/png;base64,${base64String}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await getWharfInfo();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.notify {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
color: #fff;
|
||||||
|
.list {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.list-wrap {
|
||||||
|
width: 50%;
|
||||||
|
height: 100%;
|
||||||
|
.title {
|
||||||
|
font-size: 26px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
.list-item {
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 1;
|
||||||
|
height: 100%;
|
||||||
|
margin-left: 20px;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: calc(100% - 40px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,93 @@
|
||||||
|
<template>
|
||||||
|
<div class="table">
|
||||||
|
<div class="header">
|
||||||
|
<div class="title">用户设置</div>
|
||||||
|
<div class="api-btn">
|
||||||
|
<div
|
||||||
|
class="btn"
|
||||||
|
:class="{ 'btn-active': currentNav === item }"
|
||||||
|
v-for="item in helpDocsList"
|
||||||
|
:key="item"
|
||||||
|
@click="onClickChangeNav(item)"
|
||||||
|
>
|
||||||
|
{{ item }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<Wharf v-if="currentNav === '码头信息'" />
|
||||||
|
<EmployeeTable v-if="currentNav === '用户管理'" />
|
||||||
|
<employeeRole v-if="currentNav === '权限管理'" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import employeeRole from './components/EmployeeRole.vue';
|
||||||
|
import EmployeeTable from './components/EmployeeTable.vue';
|
||||||
|
import Wharf from './components/Wharf.vue';
|
||||||
|
|
||||||
|
// 帮助文档列表
|
||||||
|
const helpDocsList = ref(['码头信息', '用户管理', '权限管理']);
|
||||||
|
const currentNav = ref('码头信息');
|
||||||
|
const onClickChangeNav = (item: string) => {
|
||||||
|
if (item === currentNav.value) return;
|
||||||
|
currentNav.value = item;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.table {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.header {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 16px 16px 0;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #fff;
|
||||||
|
.title {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.api-btn {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
.btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 150px;
|
||||||
|
height: 50px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #d7d7d7;
|
||||||
|
background-color: rgb(51 51 51 / 100%);
|
||||||
|
border-radius: 75px;
|
||||||
|
box-shadow: 5px 5px 5px rgb(0 0 0 / 34.9%);
|
||||||
|
}
|
||||||
|
.btn-active {
|
||||||
|
color: #000;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 1;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,18 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="manage">
|
|
||||||
<PublishTable />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import PublishTable from './components/PublishTable.vue';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.manage {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,18 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="manage">
|
|
||||||
<ReceiveTable />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import ReceiveTable from './components/ReceiveTable.vue';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.manage {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -83,10 +83,10 @@
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="订阅状态" prop="subStatus">
|
<el-form-item label="订阅状态" prop="subStatus">
|
||||||
<el-select v-model="dialogProps.row!.subStatus" placeholder="请选择订阅状态">
|
<el-select v-model="dialogProps.row!.subStatus" placeholder="请选择订阅状态">
|
||||||
<el-option label="待接受" value="待接受" />
|
<el-option label="待接受" value="NO_ACCEPTED" />
|
||||||
<el-option label="已关闭" value="已关闭" />
|
<el-option label="已关闭" value="CLOSED" />
|
||||||
<el-option label="订阅中" value="订阅中" />
|
<el-option label="订阅中" value="SUBSCRIBE" />
|
||||||
<el-option label="已取消" value="已取消" />
|
<el-option label="已取消" value="CANCELLED" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="table">
|
<div class="table">
|
||||||
<div class="header">
|
<!-- <div class="header">
|
||||||
<el-form :inline="true" :model="searchTableForm" ref="tableFormRef">
|
<el-form :inline="true" :model="searchTableForm" ref="tableFormRef">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<RemoteSelect
|
<RemoteSelect
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
<el-button icon="Refresh" @click="onClickResetForm(tableFormRef)">重置</el-button>
|
<el-button icon="Refresh" @click="onClickResetForm(tableFormRef)">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div> -->
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<div class="footer-util">
|
<div class="footer-util">
|
||||||
<el-button type="primary" icon="Plus" @click="onClickOpenDialog('新增')">
|
<el-button type="primary" icon="Plus" @click="onClickOpenDialog('新增')">
|
||||||
|
@ -44,7 +44,6 @@
|
||||||
v-loading="tableLoading"
|
v-loading="tableLoading"
|
||||||
:data="tableState.tableData"
|
:data="tableState.tableData"
|
||||||
border
|
border
|
||||||
stripe
|
|
||||||
style="width: 100%; height: 100%"
|
style="width: 100%; height: 100%"
|
||||||
>
|
>
|
||||||
<el-table-column prop="enterprise.name" label="订阅企业" align="center" width="150" />
|
<el-table-column prop="enterprise.name" label="订阅企业" align="center" width="150" />
|
||||||
|
@ -127,10 +126,10 @@
|
||||||
prop="status"
|
prop="status"
|
||||||
>
|
>
|
||||||
<el-select v-model="statusForm.status" placeholder="请选择订阅状态">
|
<el-select v-model="statusForm.status" placeholder="请选择订阅状态">
|
||||||
<el-option label="待接受" value="待接受" />
|
<el-option label="待接受" value="NO_ACCEPTED" />
|
||||||
<el-option label="已关闭" value="已关闭" />
|
<el-option label="已关闭" value="CLOSED" />
|
||||||
<el-option label="订阅中" value="订阅中" />
|
<el-option label="订阅中" value="SUBSCRIBE" />
|
||||||
<el-option label="已取消" value="已取消" />
|
<el-option label="已取消" value="CANCELLED" />
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
@ -148,17 +147,13 @@
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
|
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { postEnterpriseListAPI } from '@/api/Enterprise/company';
|
|
||||||
import { postPortListAPI } from '@/api/Port';
|
|
||||||
import {
|
import {
|
||||||
editStatusAPI,
|
editStatusAPI,
|
||||||
publishPageAPI,
|
publishPageAPI,
|
||||||
subscriptionDeleteAPI,
|
subscriptionDeleteAPI,
|
||||||
subscriptionSaveAPI,
|
subscriptionSaveAPI,
|
||||||
} from '@/api/Subscription';
|
} from '@/api/Subscription';
|
||||||
import { postWharfListAPI } from '@/api/Wharf';
|
|
||||||
import Pagination from '@/components/Pagination/Pagination.vue';
|
import Pagination from '@/components/Pagination/Pagination.vue';
|
||||||
import RemoteSelect from '@/components/RemoteSelect/index.vue';
|
|
||||||
import { useTable } from '@/hooks/useTable';
|
import { useTable } from '@/hooks/useTable';
|
||||||
import { PageRowsResult } from '@/types';
|
import { PageRowsResult } from '@/types';
|
||||||
import { SubscriptionType } from '@/types/subscription';
|
import { SubscriptionType } from '@/types/subscription';
|
||||||
|
@ -175,48 +170,25 @@ const handleTableData = (data: PageRowsResult<SubscriptionType>) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 获取列表表格数据
|
// 获取列表表格数据
|
||||||
const { getTableList, tableState, searchTable, resetTable, tableChangeCurrent, tableChangeSize } =
|
const { getTableList, tableState, tableChangeCurrent, tableChangeSize } = useTable({
|
||||||
useTable({
|
api: publishPageAPI,
|
||||||
api: publishPageAPI,
|
dataCallBack: handleTableData,
|
||||||
dataCallBack: handleTableData,
|
});
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await getTableList();
|
await getTableList();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 查询条件
|
// 查询条件
|
||||||
const searchTableForm = reactive({
|
// const searchTableForm = reactive({
|
||||||
enterpriseId: '',
|
// enterpriseId: '',
|
||||||
portId: '',
|
// portId: '',
|
||||||
wharfId: '',
|
// wharfId: '',
|
||||||
});
|
// });
|
||||||
|
|
||||||
// 表格是否加载
|
// 表格是否加载
|
||||||
const tableLoading = ref(false);
|
const tableLoading = ref(false);
|
||||||
|
|
||||||
// 查询表单节点
|
|
||||||
const tableFormRef = ref<FormInstance>();
|
|
||||||
|
|
||||||
// 查询
|
|
||||||
const onClickSearch = async () => {
|
|
||||||
tableLoading.value = true;
|
|
||||||
|
|
||||||
// 添加查询参数
|
|
||||||
tableState.value.searchParam = searchTableForm;
|
|
||||||
|
|
||||||
// 查询表格
|
|
||||||
await searchTable();
|
|
||||||
tableLoading.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 重置
|
|
||||||
const onClickResetForm = async (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
await resetTable();
|
|
||||||
formEl.resetFields();
|
|
||||||
};
|
|
||||||
|
|
||||||
const publishDialogRef = ref<InstanceType<typeof PublishDialog> | null>(null);
|
const publishDialogRef = ref<InstanceType<typeof PublishDialog> | null>(null);
|
||||||
const onClickOpenDialog = (title: string, row: Partial<SubscriptionType> = {}) => {
|
const onClickOpenDialog = (title: string, row: Partial<SubscriptionType> = {}) => {
|
||||||
const params = {
|
const params = {
|
||||||
|
@ -302,9 +274,7 @@ const handleCurrentChange = async (val: number) => {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 16px 16px 0;
|
padding: 16px 16px 0;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
}
|
}
|
||||||
.footer {
|
.footer {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -314,9 +284,7 @@ const handleCurrentChange = async (val: number) => {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
.footer-util {
|
.footer-util {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="table">
|
<div class="table">
|
||||||
<div class="header">
|
<!-- <div class="header">
|
||||||
<el-form :inline="true" :model="searchTableForm" ref="tableFormRef">
|
<el-form :inline="true" :model="searchTableForm" ref="tableFormRef">
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<RemoteSelect
|
<RemoteSelect
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
<el-button icon="Refresh" @click="onClickResetForm(tableFormRef)">重置</el-button>
|
<el-button icon="Refresh" @click="onClickResetForm(tableFormRef)">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div> -->
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
<!-- 表格 -->
|
<!-- 表格 -->
|
||||||
<div class="footer-table">
|
<div class="footer-table">
|
||||||
|
@ -75,14 +75,9 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { FormInstance } from 'element-plus';
|
import { onMounted, ref } from 'vue';
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
|
||||||
import { postEnterpriseListAPI } from '@/api/Enterprise/company';
|
|
||||||
import { postPortListAPI } from '@/api/Port';
|
|
||||||
import { receivePageAPI } from '@/api/Subscription';
|
import { receivePageAPI } from '@/api/Subscription';
|
||||||
import { postWharfListAPI } from '@/api/Wharf';
|
|
||||||
import Pagination from '@/components/Pagination/Pagination.vue';
|
import Pagination from '@/components/Pagination/Pagination.vue';
|
||||||
import RemoteSelect from '@/components/RemoteSelect/index.vue';
|
|
||||||
import { useTable } from '@/hooks/useTable';
|
import { useTable } from '@/hooks/useTable';
|
||||||
import { PageRowsResult } from '@/types';
|
import { PageRowsResult } from '@/types';
|
||||||
import { SubscriptionType } from '@/types/subscription';
|
import { SubscriptionType } from '@/types/subscription';
|
||||||
|
@ -98,48 +93,20 @@ const handleTableData = (data: PageRowsResult<SubscriptionType>) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
// 获取列表表格数据
|
// 获取列表表格数据
|
||||||
const { getTableList, tableState, searchTable, resetTable, tableChangeCurrent, tableChangeSize } =
|
const { getTableList, tableState, tableChangeCurrent, tableChangeSize } = useTable({
|
||||||
useTable({
|
api: receivePageAPI,
|
||||||
api: receivePageAPI,
|
dataCallBack: handleTableData,
|
||||||
dataCallBack: handleTableData,
|
});
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await getTableList();
|
await getTableList();
|
||||||
});
|
});
|
||||||
|
|
||||||
// 查询条件
|
// 查询条件
|
||||||
const searchTableForm = reactive({
|
|
||||||
enterpriseId: '',
|
|
||||||
portId: '',
|
|
||||||
wharfId: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 表格是否加载
|
// 表格是否加载
|
||||||
const tableLoading = ref(false);
|
const tableLoading = ref(false);
|
||||||
|
|
||||||
// 查询表单节点
|
|
||||||
const tableFormRef = ref<FormInstance>();
|
|
||||||
|
|
||||||
// 查询
|
|
||||||
const onClickSearch = async () => {
|
|
||||||
tableLoading.value = true;
|
|
||||||
|
|
||||||
// 添加查询参数
|
|
||||||
tableState.value.searchParam = searchTableForm;
|
|
||||||
|
|
||||||
// 查询表格
|
|
||||||
await searchTable();
|
|
||||||
tableLoading.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 重置
|
|
||||||
const onClickResetForm = async (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
await resetTable();
|
|
||||||
formEl.resetFields();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 改变每页显示条目个数
|
// 改变每页显示条目个数
|
||||||
const handleSizeChange = async (val: number) => {
|
const handleSizeChange = async (val: number) => {
|
||||||
await tableChangeSize(val);
|
await tableChangeSize(val);
|
||||||
|
@ -162,9 +129,7 @@ const handleCurrentChange = async (val: number) => {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: 16px 16px 0;
|
padding: 16px 16px 0;
|
||||||
margin-bottom: 16px;
|
margin-bottom: 16px;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
}
|
}
|
||||||
.footer {
|
.footer {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -174,9 +139,7 @@ const handleCurrentChange = async (val: number) => {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
.footer-util {
|
.footer-util {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
|
@ -0,0 +1,91 @@
|
||||||
|
<template>
|
||||||
|
<div class="table">
|
||||||
|
<div class="header">
|
||||||
|
<div class="title">{{ currentSubscribeNav }}清单</div>
|
||||||
|
<div class="api-btn">
|
||||||
|
<div
|
||||||
|
class="btn"
|
||||||
|
:class="{ 'btn-active': currentSubscribeNav === item }"
|
||||||
|
v-for="item in subscribeNavList"
|
||||||
|
:key="item"
|
||||||
|
@click="onClickChangeSubscribeType(item)"
|
||||||
|
>
|
||||||
|
{{ item }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<PublishTable v-if="currentSubscribeNav === '我的订阅'" />
|
||||||
|
<ReceiveTable v-if="currentSubscribeNav === '收到订阅'" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import PublishTable from './components/PublishTable.vue';
|
||||||
|
import ReceiveTable from './components/ReceiveTable.vue';
|
||||||
|
|
||||||
|
// 订阅导航列表
|
||||||
|
const subscribeNavList = ref(['我的订阅', '收到订阅']);
|
||||||
|
const currentSubscribeNav = ref('我的订阅');
|
||||||
|
const onClickChangeSubscribeType = async (item: string) => {
|
||||||
|
if (item === currentSubscribeNav.value) return;
|
||||||
|
currentSubscribeNav.value = item;
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.table {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.header {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
flex-shrink: 0;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 16px 16px 0;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
color: #fff;
|
||||||
|
.title {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
.api-btn {
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
.btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 150px;
|
||||||
|
height: 50px;
|
||||||
|
margin-left: 10px;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #d7d7d7;
|
||||||
|
background-color: rgb(51 51 51 / 100%);
|
||||||
|
border-radius: 75px;
|
||||||
|
box-shadow: 5px 5px 5px rgb(0 0 0 / 34.9%);
|
||||||
|
}
|
||||||
|
.btn-active {
|
||||||
|
color: #000;
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 1;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,100 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-drawer
|
|
||||||
v-model="drawerVisible"
|
|
||||||
:title="`${drawerProps.title}角色`"
|
|
||||||
size="450px"
|
|
||||||
:destroy-on-close="true"
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="roleFormRef"
|
|
||||||
label-width="100px"
|
|
||||||
label-suffix=" :"
|
|
||||||
:disabled="drawerProps.isView"
|
|
||||||
:model="drawerProps.row"
|
|
||||||
:hide-required-asterisk="drawerProps.isView"
|
|
||||||
:rules="roleDrawerRules"
|
|
||||||
>
|
|
||||||
<el-form-item label="角色名称" prop="name" required>
|
|
||||||
<el-input v-model="drawerProps.row!.name" placeholder="请输入角色名称" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="角色标识" prop="code" required>
|
|
||||||
<el-input v-model="drawerProps.row!.code" placeholder="请输入角色标识,标识唯一" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="角色类型" prop="type" required>
|
|
||||||
<el-select v-model="drawerProps.row!.type" placeholder="请选择角色类型" style="width: 100%">
|
|
||||||
<el-option label="系统管理员" value="系统管理员" />
|
|
||||||
<el-option label="普通角色" value="普通角色" />
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="角色描述">
|
|
||||||
<el-input v-model="drawerProps.row!.remark" type="textarea" placeholder="请输入角色描述" />
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-button @click="drawerVisible = false">取消</el-button>
|
|
||||||
<el-button type="primary" @click="onClickConfirm(roleFormRef)">确定</el-button>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-drawer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { FormInstance, FormRules } from 'element-plus';
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
import { reactive, ref } from 'vue';
|
|
||||||
import { roleType } from '@/types/role';
|
|
||||||
|
|
||||||
interface DrawerPropsType {
|
|
||||||
title: string;
|
|
||||||
isView: boolean;
|
|
||||||
row: Partial<roleType>;
|
|
||||||
api?: (params: any) => Promise<any>;
|
|
||||||
getTableList?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 是否显示drawer
|
|
||||||
const drawerVisible = ref(false);
|
|
||||||
|
|
||||||
// 父组件传递的值
|
|
||||||
const drawerProps = ref<DrawerPropsType>({
|
|
||||||
isView: false,
|
|
||||||
title: '',
|
|
||||||
row: {},
|
|
||||||
});
|
|
||||||
|
|
||||||
const isShowDrawer = async (item: DrawerPropsType) => {
|
|
||||||
drawerProps.value = item;
|
|
||||||
drawerVisible.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 向父组件暴露该方法
|
|
||||||
defineExpose({ isShowDrawer });
|
|
||||||
|
|
||||||
// 表单节点
|
|
||||||
const roleFormRef = ref<FormInstance>();
|
|
||||||
|
|
||||||
// 校验规则
|
|
||||||
const roleDrawerRules = reactive<FormRules>({
|
|
||||||
name: [{ required: true, message: '请输入角色名称', trigger: 'blur' }],
|
|
||||||
code: [{ required: true, message: '请输入角色标识', trigger: 'blur' }],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 新增/编辑角色
|
|
||||||
const onClickConfirm = (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
formEl.validate(async (valid) => {
|
|
||||||
if (!valid) return;
|
|
||||||
try {
|
|
||||||
// 新增角色
|
|
||||||
await drawerProps.value.api!(drawerProps.value.row);
|
|
||||||
ElMessage({ message: `${drawerProps.value.title}成功`, type: 'success' });
|
|
||||||
drawerProps.value.getTableList!();
|
|
||||||
} finally {
|
|
||||||
drawerVisible.value = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
|
@ -1,88 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="roleMenuTree">
|
|
||||||
<div class="title">
|
|
||||||
<span>角色名称</span>
|
|
||||||
<el-input v-model="row!" style="flex: 1" disabled />
|
|
||||||
</div>
|
|
||||||
<el-scrollbar max-height="100%">
|
|
||||||
<el-tree
|
|
||||||
ref="roleMenuTreeRef"
|
|
||||||
:data="menuTreeData"
|
|
||||||
:props="defaultMenuProps"
|
|
||||||
:default-expanded-keys="menuData"
|
|
||||||
show-checkbox
|
|
||||||
highlight-current
|
|
||||||
node-key="url"
|
|
||||||
@check-change="onCheckTreeChange"
|
|
||||||
/>
|
|
||||||
</el-scrollbar>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ElTree } from 'element-plus';
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { menuType } from '@/types/menu';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 父组件传递值类型
|
|
||||||
*/
|
|
||||||
interface MenuTreePropsType {
|
|
||||||
row: string;
|
|
||||||
menuTreeData: menuType[];
|
|
||||||
menuData: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
// 接受父组件参数
|
|
||||||
withDefaults(defineProps<MenuTreePropsType>(), {
|
|
||||||
row: '',
|
|
||||||
menuTreeData: () => [],
|
|
||||||
menuData: () => [],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 菜单节点默认配置
|
|
||||||
const defaultMenuProps = {
|
|
||||||
children: 'children',
|
|
||||||
label: 'name',
|
|
||||||
};
|
|
||||||
|
|
||||||
// 菜单权限节点
|
|
||||||
const roleMenuTreeRef = ref<InstanceType<typeof ElTree>>();
|
|
||||||
|
|
||||||
// 监听用户菜单数据-获取并设置用户菜单数据
|
|
||||||
// watch(
|
|
||||||
// () => props.menuData,
|
|
||||||
// () => {
|
|
||||||
// // 在父组件渲染完成后,等待下一个 DOM 更新周期
|
|
||||||
// // nextTick(() => {
|
|
||||||
// // // 在回调函数中处理数据变化的逻辑
|
|
||||||
// // roleMenuTreeRef.value?.setCheckedKeys(props.menuData, true);
|
|
||||||
// // });
|
|
||||||
// },
|
|
||||||
// { immediate: true }
|
|
||||||
// );
|
|
||||||
|
|
||||||
// 选中菜单
|
|
||||||
const emit = defineEmits(['updateMenuData']);
|
|
||||||
|
|
||||||
const onCheckTreeChange = () => {
|
|
||||||
emit('updateMenuData', roleMenuTreeRef.value?.getCheckedKeys());
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.roleMenuTree {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
.title {
|
|
||||||
display: flex;
|
|
||||||
gap: 16px;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
.el-scrollbar {
|
|
||||||
border: var(--zb-border-light);
|
|
||||||
border-radius: var(--el-input-border-radius, var(--el-border-radius-base));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,319 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="role-table">
|
|
||||||
<div class="header">
|
|
||||||
<el-form :inline="true" :model="roleTableForm" ref="roleTableFormRef">
|
|
||||||
<el-form-item label="角色名" prop="name">
|
|
||||||
<el-input v-model="roleTableForm.name" placeholder="请输入角色名称" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="Search" @click="onClickSearch">查询</el-button>
|
|
||||||
<el-button icon="Refresh" @click="onClickResetForm(roleTableFormRef)">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
<div class="footer">
|
|
||||||
<div class="footer-util">
|
|
||||||
<el-button type="primary" icon="Plus" @click="onClickOpenDrawer('新增')">
|
|
||||||
新增角色
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
<!-- 表格 -->
|
|
||||||
<div class="footer-table">
|
|
||||||
<el-table
|
|
||||||
v-loading="tableLoading"
|
|
||||||
:data="tableState.tableData"
|
|
||||||
border
|
|
||||||
stripe
|
|
||||||
style="width: 100%; height: 100%"
|
|
||||||
>
|
|
||||||
<el-table-column prop="name" label="角色名称" align="center" width="100" />
|
|
||||||
<el-table-column
|
|
||||||
prop="type"
|
|
||||||
:show-overflow-tooltip="true"
|
|
||||||
width="180"
|
|
||||||
label="角色类型"
|
|
||||||
align="center"
|
|
||||||
/>
|
|
||||||
<el-table-column prop="code" label="角色标识" align="center" width="180" />
|
|
||||||
<el-table-column prop="dstatus" label="状态" align="center" width="100" />
|
|
||||||
<el-table-column prop="remark" label="备注" align="center" width="180" />
|
|
||||||
<el-table-column prop="createDate" label="创建时间" align="center" width="180" />
|
|
||||||
<el-table-column prop="operator" label="操作" width="200px" align="center" fixed="right">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="Setting"
|
|
||||||
link
|
|
||||||
@click="onClickOpenMenuDrawer(scope.row)"
|
|
||||||
>
|
|
||||||
设置权限
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="Edit"
|
|
||||||
link
|
|
||||||
@click="onClickOpenDrawer('编辑', scope.row)"
|
|
||||||
>
|
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
size="small"
|
|
||||||
icon="Delete"
|
|
||||||
link
|
|
||||||
@click="onClickDel(scope.row)"
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
<!-- 分页 -->
|
|
||||||
<div class="footer-pagination">
|
|
||||||
<Pagination
|
|
||||||
:pageAble="tableState.pageAble"
|
|
||||||
:handle-size-change="handleSizeChange"
|
|
||||||
:handle-current-change="handleCurrentChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<RoleDrawer ref="roleDrawerRef" />
|
|
||||||
|
|
||||||
<el-drawer v-model="menuDrawer" :with-header="false" size="40%" title="角色配置">
|
|
||||||
<el-tabs type="border-card">
|
|
||||||
<el-tab-pane v-for="item in menuList" :key="item.name" :label="item.name">
|
|
||||||
<RoleMenuTree
|
|
||||||
:row="roleName"
|
|
||||||
:menu-tree-data="item.list"
|
|
||||||
:menuData="menuData"
|
|
||||||
@update-menu-data="onUpdateMenuData"
|
|
||||||
/>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
<template #footer>
|
|
||||||
<div style="flex: auto">
|
|
||||||
<el-button @click="menuDrawer = false">取消</el-button>
|
|
||||||
<el-button type="primary" @click="onClickConfirmRoleMenu">确认</el-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-drawer>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
|
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
|
||||||
import { getAppListAPI, getMenuTreeAPI } from '@/api/System/menu';
|
|
||||||
import {
|
|
||||||
getRoleDeleteAPI,
|
|
||||||
getRoleMenuListAPI,
|
|
||||||
postRolePageAPI,
|
|
||||||
postRolePremSaveAPI,
|
|
||||||
postRoleSaveAPI,
|
|
||||||
} from '@/api/System/role';
|
|
||||||
import Pagination from '@/components/Pagination/Pagination.vue';
|
|
||||||
import { useTable } from '@/hooks/useTable';
|
|
||||||
import { menuType } from '@/types/menu';
|
|
||||||
import { rolePremType, roleType } from '@/types/role';
|
|
||||||
import RoleDrawer from './RoleDrawer.vue';
|
|
||||||
import RoleMenuTree from './RoleMenuTree.vue';
|
|
||||||
|
|
||||||
// 获取角色列表表格数据
|
|
||||||
const { getTableList, tableState, searchTable, resetTable, tableChangeCurrent, tableChangeSize } =
|
|
||||||
useTable({
|
|
||||||
api: postRolePageAPI,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 全部菜单列表
|
|
||||||
const menuList = ref<
|
|
||||||
{
|
|
||||||
name: string;
|
|
||||||
list: menuType[];
|
|
||||||
}[]
|
|
||||||
>([]);
|
|
||||||
|
|
||||||
// 获取全部菜单信息
|
|
||||||
const getMenuList = async () => {
|
|
||||||
try {
|
|
||||||
const { data } = await getAppListAPI();
|
|
||||||
if (data.length > 0) {
|
|
||||||
for (const item of data) {
|
|
||||||
const { data: list } = await getMenuTreeAPI({ appName: item });
|
|
||||||
menuList.value.push({ name: item, list });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
await getTableList();
|
|
||||||
await getMenuList();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 查询条件
|
|
||||||
const roleTableForm = reactive({
|
|
||||||
name: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 查询表单节点
|
|
||||||
const roleTableFormRef = ref<FormInstance>();
|
|
||||||
|
|
||||||
// 表格是否加载
|
|
||||||
const tableLoading = ref(false);
|
|
||||||
|
|
||||||
// 查询
|
|
||||||
const onClickSearch = async () => {
|
|
||||||
tableLoading.value = true;
|
|
||||||
|
|
||||||
// 添加查询参数
|
|
||||||
tableState.value.searchParam = roleTableForm;
|
|
||||||
|
|
||||||
// 查询表格
|
|
||||||
await searchTable();
|
|
||||||
tableLoading.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 重置
|
|
||||||
const onClickResetForm = async (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
await resetTable();
|
|
||||||
formEl.resetFields();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 新增/编辑角色
|
|
||||||
const roleDrawerRef = ref<InstanceType<typeof RoleDrawer> | null>(null);
|
|
||||||
const onClickOpenDrawer = (title: string, row: Partial<roleType> = {}) => {
|
|
||||||
const params = {
|
|
||||||
title,
|
|
||||||
isView: title === '查看',
|
|
||||||
row: { ...row },
|
|
||||||
api: postRoleSaveAPI,
|
|
||||||
getTableList: getTableList,
|
|
||||||
};
|
|
||||||
roleDrawerRef.value?.isShowDrawer(params);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 设置权限
|
|
||||||
const menuDrawer = ref(false);
|
|
||||||
|
|
||||||
// 菜单权限表单
|
|
||||||
const roleName = ref('');
|
|
||||||
const activeRow = ref<rolePremType>({
|
|
||||||
roleId: 0,
|
|
||||||
perms: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 用户菜单列表
|
|
||||||
const menuData = ref<string[]>([]);
|
|
||||||
|
|
||||||
// 获取用户菜单列表
|
|
||||||
const getUserMenuList = async (roleId: number) => {
|
|
||||||
const { data } = await getRoleMenuListAPI({ roleId });
|
|
||||||
menuData.value = data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 打开设置权限
|
|
||||||
const onClickOpenMenuDrawer = async (row: roleType) => {
|
|
||||||
roleName.value = row.name;
|
|
||||||
row.id && (await getUserMenuList(row.id));
|
|
||||||
menuDrawer.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const onUpdateMenuData = (data: string[]) => {
|
|
||||||
activeRow.value.perms = data;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 确认角色权限
|
|
||||||
const onClickConfirmRoleMenu = async () => {
|
|
||||||
await postRolePremSaveAPI(activeRow.value);
|
|
||||||
menuDrawer.value = false;
|
|
||||||
ElMessage({
|
|
||||||
message: '设置权限成功',
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
};
|
|
||||||
// 删除角色
|
|
||||||
const onClickDel = (row: roleType) => {
|
|
||||||
ElMessageBox.confirm(`确定要删除角色 ${row.name} 吗?`, '温馨提示', {
|
|
||||||
confirmButtonText: '确定',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
type: 'warning',
|
|
||||||
draggable: true,
|
|
||||||
})
|
|
||||||
.then(async () => {
|
|
||||||
await getRoleDeleteAPI([row.id]);
|
|
||||||
// 更新表格
|
|
||||||
await getTableList();
|
|
||||||
ElMessage({
|
|
||||||
message: '删除角色成功',
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
console.log('用户点击了取消');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 改变每页显示条目个数
|
|
||||||
const handleSizeChange = async (val: number) => {
|
|
||||||
await tableChangeSize(val);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 当前页数改变
|
|
||||||
const handleCurrentChange = async (val: number) => {
|
|
||||||
await tableChangeCurrent(val);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.role-table {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
padding: 16px 16px 0;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
}
|
|
||||||
.footer {
|
|
||||||
position: relative;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 16px;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
.footer-util {
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
justify-content: flex-end;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
.footer-table {
|
|
||||||
position: relative;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.footer-pagination {
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
justify-content: flex-end;
|
|
||||||
width: 100%;
|
|
||||||
padding-top: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,18 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="roleManage">
|
|
||||||
<RoleTable />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import RoleTable from './components/RoleTable.vue';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.roleManage {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,144 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-drawer
|
|
||||||
v-model="drawerVisible"
|
|
||||||
:destroy-on-close="true"
|
|
||||||
size="450px"
|
|
||||||
:title="`${drawerProps.title}用户`"
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="ruleFormRef"
|
|
||||||
label-width="100px"
|
|
||||||
label-suffix=" :"
|
|
||||||
:rules="userDrawerRules"
|
|
||||||
:disabled="drawerProps.isView"
|
|
||||||
:model="drawerProps.row"
|
|
||||||
:hide-required-asterisk="drawerProps.isView"
|
|
||||||
>
|
|
||||||
<!-- <el-form-item label="用户头像" prop="avatar">
|
|
||||||
<UploadImg
|
|
||||||
v-model:image-url="drawerProps.row!.avatar"
|
|
||||||
width="135px"
|
|
||||||
height="135px"
|
|
||||||
:file-size="3"
|
|
||||||
>
|
|
||||||
<template #empty>
|
|
||||||
<el-icon><Avatar /></el-icon>
|
|
||||||
<span>请上传头像</span>
|
|
||||||
</template>
|
|
||||||
<template #tip> 头像大小不能超过 3M </template>
|
|
||||||
</UploadImg>
|
|
||||||
</el-form-item> -->
|
|
||||||
|
|
||||||
<el-form-item label="用户姓名" prop="name">
|
|
||||||
<el-input v-model="drawerProps.row!.name" placeholder="请填写用户姓名" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="账号" prop="username">
|
|
||||||
<el-input v-model="drawerProps.row!.username" placeholder="请填写账号" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="手机号" prop="phone">
|
|
||||||
<el-input v-model="drawerProps.row!.phone" placeholder="请填写手机号" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="邮箱">
|
|
||||||
<el-input v-model="drawerProps.row!.email" placeholder="请填写邮箱" clearable></el-input>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<template #footer>
|
|
||||||
<el-button @click="drawerVisible = false">取消</el-button>
|
|
||||||
<el-button v-show="!drawerProps.isView" type="primary" @click="onClickConfirm(ruleFormRef)"
|
|
||||||
>确定</el-button
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
</el-drawer>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import type { FormInstance, FormRules } from 'element-plus';
|
|
||||||
import { ElMessage } from 'element-plus';
|
|
||||||
import { reactive, ref } from 'vue';
|
|
||||||
import { userType } from '@/types/user';
|
|
||||||
import { validPhone } from '@/utils/validate';
|
|
||||||
|
|
||||||
interface DrawerPropsType {
|
|
||||||
title: string;
|
|
||||||
isView: boolean;
|
|
||||||
row: Partial<userType>;
|
|
||||||
api?: (params: any) => Promise<any>;
|
|
||||||
getTableList?: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 是否显示drawer
|
|
||||||
const drawerVisible = ref(false);
|
|
||||||
|
|
||||||
// 父组件传递的值
|
|
||||||
const drawerProps = ref<DrawerPropsType>({
|
|
||||||
isView: false,
|
|
||||||
title: '',
|
|
||||||
row: {},
|
|
||||||
});
|
|
||||||
|
|
||||||
// 显示drawer,新增/编辑用户
|
|
||||||
const isShowDrawer = (item: DrawerPropsType) => {
|
|
||||||
drawerProps.value = item;
|
|
||||||
drawerVisible.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 向父组件暴露该方法
|
|
||||||
defineExpose({ isShowDrawer });
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 手机号校验规则
|
|
||||||
* @param {any} rule 校验规则
|
|
||||||
* @param {string} value 手机号
|
|
||||||
* @param {any} callback 回调函数
|
|
||||||
* @return 是否通过校验
|
|
||||||
*/
|
|
||||||
const checkPhone = (rule: any, value: string, callback: any) => {
|
|
||||||
if (!validPhone(value)) {
|
|
||||||
// 返回一个错误提示
|
|
||||||
callback(new Error('请输入正确的手机号码'));
|
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 校验规则
|
|
||||||
const userDrawerRules = reactive<FormRules>({
|
|
||||||
username: [
|
|
||||||
{ required: true, message: '请输入账号', trigger: 'blur' },
|
|
||||||
{ min: 4, message: '账号长度不能小于4位', trigger: 'blur' },
|
|
||||||
],
|
|
||||||
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
|
||||||
phone: [
|
|
||||||
{ required: true, message: '请输入手机号', trigger: 'blur' },
|
|
||||||
{ validator: checkPhone, trigger: 'blur' },
|
|
||||||
],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 表单节点
|
|
||||||
const ruleFormRef = ref<FormInstance>();
|
|
||||||
|
|
||||||
// 新增/编辑用户
|
|
||||||
const onClickConfirm = (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
formEl.validate(async (valid) => {
|
|
||||||
if (!valid) return;
|
|
||||||
try {
|
|
||||||
// 用户新增/编辑不需要密码
|
|
||||||
const row = { ...drawerProps.value.row };
|
|
||||||
if (row.password !== undefined) {
|
|
||||||
delete row.password;
|
|
||||||
}
|
|
||||||
await drawerProps.value.api!(row);
|
|
||||||
ElMessage({
|
|
||||||
message: `${drawerProps.value.title}成功`,
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
drawerProps.value.getTableList!();
|
|
||||||
} finally {
|
|
||||||
drawerVisible.value = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
|
|
@ -1,125 +0,0 @@
|
||||||
<template>
|
|
||||||
<el-dialog v-model="userRoleDialog" title="关联角色" width="50%" @close="onCloseDialog">
|
|
||||||
<el-form ref="userRoleFormRef" :model="userRoleForm" :rules="userRoleRules" label-width="100px">
|
|
||||||
<el-form-item label="用户名" required>
|
|
||||||
<el-input v-model="userRoleForm.username" disabled placeholder="请输入用户名" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="用户角色" prop="roleIds" required>
|
|
||||||
<el-select
|
|
||||||
v-model="userRoleForm.roleIds"
|
|
||||||
multiple
|
|
||||||
collapse-tags
|
|
||||||
collapse-tags-tooltip
|
|
||||||
:max-collapse-tags="3"
|
|
||||||
placeholder="请选择角色"
|
|
||||||
style="width: 100%"
|
|
||||||
>
|
|
||||||
<el-option
|
|
||||||
v-for="item in roleList"
|
|
||||||
:key="item.id"
|
|
||||||
:label="item.text"
|
|
||||||
:value="item.id"
|
|
||||||
></el-option>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
<template #footer>
|
|
||||||
<span class="dialog-footer">
|
|
||||||
<el-button @click="userRoleDialog = false">取消</el-button>
|
|
||||||
<el-button type="primary" @click="onClickConfirm(userRoleFormRef)">确定</el-button>
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ElMessage, FormInstance, FormRules } from 'element-plus';
|
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
|
||||||
import { getRoleListAPI } from '@/api/System/role';
|
|
||||||
import { getUserRoleListAPI, postUserRoleAPI } from '@/api/System/user';
|
|
||||||
import { dictionaryListType } from '@/types';
|
|
||||||
import { userType } from '@/types/user';
|
|
||||||
|
|
||||||
// 表单类型
|
|
||||||
type userRoleFormType = {
|
|
||||||
username: string;
|
|
||||||
userId: number | string;
|
|
||||||
roleIds: number[];
|
|
||||||
};
|
|
||||||
|
|
||||||
// 角色列表
|
|
||||||
const roleList = ref<dictionaryListType[]>([]);
|
|
||||||
|
|
||||||
// 获取角色列表
|
|
||||||
const getRoleList = async () => {
|
|
||||||
const { data } = await getRoleListAPI({});
|
|
||||||
roleList.value = data;
|
|
||||||
};
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
await getRoleList();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 是否显示dialog
|
|
||||||
const userRoleDialog = ref(false);
|
|
||||||
|
|
||||||
// 获取用户角色列表
|
|
||||||
const getUserRoleList = async (userId: string | number) => {
|
|
||||||
const { data } = await getUserRoleListAPI({ userId });
|
|
||||||
userRoleForm.roleIds = data.map((item) => item.id);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 显示dialog,新增/编辑用户
|
|
||||||
const isShowDialog = async (item: userType) => {
|
|
||||||
if (item) {
|
|
||||||
userRoleForm.userId = item.id;
|
|
||||||
userRoleForm.username = item.username;
|
|
||||||
item.id && (await getUserRoleList(item.id));
|
|
||||||
}
|
|
||||||
userRoleDialog.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 向父组件暴露该方法
|
|
||||||
defineExpose({ isShowDialog });
|
|
||||||
|
|
||||||
// 新增/编辑用户表单
|
|
||||||
const userRoleForm = reactive<userRoleFormType>({
|
|
||||||
username: '', // 用户名
|
|
||||||
userId: '',
|
|
||||||
roleIds: [], // 角色列表
|
|
||||||
});
|
|
||||||
|
|
||||||
// 表单节点
|
|
||||||
const userRoleFormRef = ref<FormInstance>();
|
|
||||||
|
|
||||||
// dialog 关闭事件
|
|
||||||
const onCloseDialog = () => {
|
|
||||||
// 重置表单
|
|
||||||
userRoleFormRef.value?.resetFields();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 校验规则
|
|
||||||
const userRoleRules = reactive<FormRules>({
|
|
||||||
roleIds: [{ required: true, message: '请选择用户角色', trigger: 'change' }],
|
|
||||||
});
|
|
||||||
|
|
||||||
// 分配角色
|
|
||||||
const onClickConfirm = (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
formEl.validate(async (valid) => {
|
|
||||||
if (!valid) return;
|
|
||||||
try {
|
|
||||||
// 分配角色
|
|
||||||
await postUserRoleAPI(userRoleForm);
|
|
||||||
ElMessage({
|
|
||||||
message: '设置用户角色成功',
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
} finally {
|
|
||||||
userRoleDialog.value = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped></style>
|
|
|
@ -1,245 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="user-table">
|
|
||||||
<div class="header">
|
|
||||||
<el-form :inline="true" :model="userTableForm" ref="userTableFormRef">
|
|
||||||
<el-form-item label="账号" prop="username">
|
|
||||||
<el-input v-model="userTableForm.username" placeholder="请输入账号" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="Search" @click="onClickSearch">查询</el-button>
|
|
||||||
<el-button icon="Refresh" @click="onClickResetForm(userTableFormRef)">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
</div>
|
|
||||||
<div class="footer">
|
|
||||||
<div class="footer-util">
|
|
||||||
<el-button type="primary" icon="Plus" @click="onClickOpenDrawer('新增')">
|
|
||||||
新增用户
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
<!-- 表格 -->
|
|
||||||
<div class="footer-table">
|
|
||||||
<el-table
|
|
||||||
v-loading="tableLoading"
|
|
||||||
:data="tableState.tableData"
|
|
||||||
border
|
|
||||||
stripe
|
|
||||||
style="width: 100%; height: 100%"
|
|
||||||
>
|
|
||||||
<el-table-column prop="username" label="账号" align="center" width="180" />
|
|
||||||
<el-table-column prop="name" label="姓名" align="center" />
|
|
||||||
<el-table-column prop="roleList" label="关联角色" align="center" width="120">
|
|
||||||
<template #default="scope">
|
|
||||||
<div style="display: flex; flex-wrap: wrap">
|
|
||||||
<el-tag
|
|
||||||
v-for="item in scope.row.roleList"
|
|
||||||
:key="item.id"
|
|
||||||
effect="dark"
|
|
||||||
disable-transitions
|
|
||||||
style="margin-right: 6px; margin-bottom: 6px"
|
|
||||||
>
|
|
||||||
{{ item.roleName }}
|
|
||||||
</el-tag>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column prop="phone" label="手机号" align="center" width="120" />
|
|
||||||
<el-table-column prop="email" label="邮箱" align="center" width="120" />
|
|
||||||
<el-table-column prop="dstatus" label="用户状态" align="center" width="100" />
|
|
||||||
<el-table-column prop="createDate" label="创建时间" align="center" width="180" />
|
|
||||||
<el-table-column prop="operator" label="操作" width="200px" align="center" fixed="right">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="User"
|
|
||||||
link
|
|
||||||
@click="onClickOpenUserRole(scope.row)"
|
|
||||||
>
|
|
||||||
角色
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
size="small"
|
|
||||||
icon="Edit"
|
|
||||||
link
|
|
||||||
@click="onClickOpenDrawer('编辑', scope.row)"
|
|
||||||
>
|
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
<el-button
|
|
||||||
type="danger"
|
|
||||||
size="small"
|
|
||||||
icon="Delete"
|
|
||||||
link
|
|
||||||
@click="onClickDel(scope.row)"
|
|
||||||
>
|
|
||||||
删除
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
<!-- 分页 -->
|
|
||||||
<div class="footer-pagination">
|
|
||||||
<Pagination
|
|
||||||
:pageAble="tableState.pageAble"
|
|
||||||
:handle-size-change="handleSizeChange"
|
|
||||||
:handle-current-change="handleCurrentChange"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<UserDrawer ref="userDrawerRef" />
|
|
||||||
<UserRoleDialog ref="userRoleDialogRef" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ElMessage, ElMessageBox, FormInstance } from 'element-plus';
|
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
|
||||||
import { getUserDeleteAPI, postUserPageAPI, postUserSaveAPI } from '@/api/System/user';
|
|
||||||
import Pagination from '@/components/Pagination/Pagination.vue';
|
|
||||||
import { useTable } from '@/hooks/useTable';
|
|
||||||
import { userType } from '@/types/user';
|
|
||||||
import UserDrawer from './UserDrawer.vue';
|
|
||||||
import UserRoleDialog from './UserRoleDialog.vue';
|
|
||||||
|
|
||||||
// 获取用户列表表格数据
|
|
||||||
const { getTableList, tableState, searchTable, resetTable, tableChangeCurrent, tableChangeSize } =
|
|
||||||
useTable({
|
|
||||||
api: postUserPageAPI,
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
await getTableList();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 查询条件
|
|
||||||
const userTableForm = reactive({
|
|
||||||
username: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
// 表格是否加载
|
|
||||||
const tableLoading = ref(false);
|
|
||||||
|
|
||||||
// 查询表单节点
|
|
||||||
const userTableFormRef = ref<FormInstance>();
|
|
||||||
|
|
||||||
// 查询
|
|
||||||
const onClickSearch = async () => {
|
|
||||||
tableLoading.value = true;
|
|
||||||
|
|
||||||
// 添加查询参数
|
|
||||||
tableState.value.searchParam = userTableForm;
|
|
||||||
|
|
||||||
// 查询表格
|
|
||||||
await searchTable();
|
|
||||||
tableLoading.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 重置
|
|
||||||
const onClickResetForm = async (formEl: FormInstance | undefined) => {
|
|
||||||
if (!formEl) return;
|
|
||||||
await resetTable();
|
|
||||||
formEl.resetFields();
|
|
||||||
};
|
|
||||||
|
|
||||||
// 设置用户角色
|
|
||||||
const userRoleDialogRef = ref<InstanceType<typeof UserRoleDialog> | null>(null);
|
|
||||||
const onClickOpenUserRole = (row: userType) => {
|
|
||||||
userRoleDialogRef.value?.isShowDialog(row);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 新增/编辑/查看用户 drawer 节点
|
|
||||||
const userDrawerRef = ref<InstanceType<typeof UserDrawer> | null>(null);
|
|
||||||
const onClickOpenDrawer = (title: string, row: Partial<userType> = {}) => {
|
|
||||||
const params = {
|
|
||||||
title,
|
|
||||||
isView: title === '查看',
|
|
||||||
row: { ...row },
|
|
||||||
api: postUserSaveAPI,
|
|
||||||
getTableList: getTableList,
|
|
||||||
};
|
|
||||||
userDrawerRef.value?.isShowDrawer(params);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 删除
|
|
||||||
const onClickDel = (row: userType) => {
|
|
||||||
ElMessageBox.confirm(`你确定要删除用户 ${row.name} 吗?`, '温馨提示', {
|
|
||||||
confirmButtonText: '确定',
|
|
||||||
cancelButtonText: '取消',
|
|
||||||
type: 'warning',
|
|
||||||
draggable: true,
|
|
||||||
})
|
|
||||||
.then(async () => {
|
|
||||||
await getUserDeleteAPI([row.id]);
|
|
||||||
// 更新表格
|
|
||||||
await getTableList();
|
|
||||||
ElMessage({
|
|
||||||
message: '删除用户成功',
|
|
||||||
type: 'success',
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
console.log('用户点击了取消');
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 改变每页显示条目个数
|
|
||||||
const handleSizeChange = async (val: number) => {
|
|
||||||
await tableChangeSize(val);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 当前页数改变
|
|
||||||
const handleCurrentChange = async (val: number) => {
|
|
||||||
await tableChangeCurrent(val);
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.user-table {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
padding: 16px 16px 0;
|
|
||||||
margin-bottom: 16px;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
}
|
|
||||||
.footer {
|
|
||||||
position: relative;
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
flex: 1;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 16px;
|
|
||||||
overflow: hidden;
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
|
||||||
.footer-util {
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
justify-content: flex-end;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
}
|
|
||||||
.footer-table {
|
|
||||||
position: relative;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
.footer-pagination {
|
|
||||||
box-sizing: border-box;
|
|
||||||
display: flex;
|
|
||||||
flex-shrink: 0;
|
|
||||||
justify-content: flex-end;
|
|
||||||
width: 100%;
|
|
||||||
padding-top: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,18 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="userManage">
|
|
||||||
<UserTable />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import UserTable from './components/UserTable.vue';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.userManage {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
Loading…
Reference in New Issue