@ -0,0 +1,18 @@
|
||||
/node_modules
|
||||
/.env.local
|
||||
/.umirc.local.ts
|
||||
/config/config.local.ts
|
||||
/src/.umi
|
||||
/src/.umi-production
|
||||
/src/.umi-test
|
||||
/dist
|
||||
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
yarn.lock
|
||||
package-lock.json
|
||||
|
||||
.DS_Store
|
||||
**/.DS_Store
|
||||
.DS_Store?
|
||||
@ -0,0 +1,2 @@
|
||||
registry=https://registry.npmmirror.com/
|
||||
package-lock=false
|
||||
@ -0,0 +1,50 @@
|
||||
import defaultSettings from './config/defaultSettings'
|
||||
import proxy from './config/proxy'
|
||||
import routes from './config/routes'
|
||||
import { defineConfig } from '@umijs/max'
|
||||
|
||||
const { REACT_APP_ENV } = process.env
|
||||
|
||||
export default defineConfig({
|
||||
title: defaultSettings.title,
|
||||
theme: {
|
||||
'primary-color': defaultSettings.primaryColor
|
||||
},
|
||||
model: {},
|
||||
antd: {
|
||||
},
|
||||
request: {},
|
||||
initialState: {
|
||||
loading: '@/components/Loading'
|
||||
},
|
||||
dva: {},
|
||||
// layout: {},
|
||||
mfsu: { strategy: 'normal' },
|
||||
locale: {
|
||||
default: 'zh-CN',
|
||||
antd: true,
|
||||
baseNavigator: false
|
||||
},
|
||||
fastRefresh: true,
|
||||
history: {
|
||||
type: 'browser'
|
||||
},
|
||||
hash: false,
|
||||
// publicPath: "./", //本地静态化 for android
|
||||
publicPath: "/", //部署到服务端需要 publicPath: "/",或者 publicPath: "/xxxxx/",
|
||||
manifest: {
|
||||
basePath: "/", //本地静态化 for android 部署到服务端需要 publicPath: "/",或者 publicPath: "/xxxxx/",
|
||||
},
|
||||
routes: routes,
|
||||
proxy: proxy[REACT_APP_ENV || 'dev'],
|
||||
codeSplitting: {
|
||||
jsStrategy: 'granularChunks'
|
||||
},
|
||||
chainWebpack(config, { webpack }) {
|
||||
config.plugin('code-inspector-plugin').use(require('code-inspector-plugin').codeInspectorPlugin, [
|
||||
{
|
||||
bundler: 'webpack',
|
||||
},
|
||||
]);
|
||||
},
|
||||
})
|
||||
@ -0,0 +1,8 @@
|
||||
export default {
|
||||
primaryColor: '#2969ff',
|
||||
menu: {
|
||||
locale: true,
|
||||
},
|
||||
title: 'AI文档审阅系统',
|
||||
iconfontUrl: '//at.alicdn.com/t/font_2163129_p3ldyoksz3s.js'
|
||||
}
|
||||
@ -0,0 +1,665 @@
|
||||
export default [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/topnavbar00/home',
|
||||
},
|
||||
{
|
||||
name: 'login',
|
||||
path: '/login',
|
||||
component: './login/Login'
|
||||
},
|
||||
{
|
||||
name: 'topnavbar',
|
||||
icon: 'table',
|
||||
path: '/topnavbar00',
|
||||
component: './topnavbar/TopNavBar',
|
||||
routes: [
|
||||
{
|
||||
path: '/topnavbar00/home',
|
||||
name: 'home',
|
||||
component: './home/HomeList'
|
||||
},
|
||||
// 多维统计
|
||||
{
|
||||
path: '/topnavbar00/multidstatistics',
|
||||
name: 'multidstatistics',
|
||||
component: './nav_system_content/SystemContentList',
|
||||
routes: [
|
||||
{
|
||||
path: '/topnavbar00/multidstatistics/staffstatistics',
|
||||
// icon: 'bank',
|
||||
name: 'staffstatistics',
|
||||
component: './multi-d-statistics/multiDStatistics',
|
||||
},
|
||||
],
|
||||
},
|
||||
// 人员管理
|
||||
{
|
||||
path: '/topnavbar00/staffmanage',
|
||||
name: 'staffmanage',
|
||||
component: './nav_system_content/SystemContentList',
|
||||
routes: [
|
||||
{
|
||||
path: '/topnavbar00/staffmanage/staffinfo',
|
||||
// icon: 'bank',
|
||||
name: 'staffinfo',
|
||||
component: './staffmanage_staffinfo/StaffInfo',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/staffmanage/staffresume',
|
||||
// icon: 'bank',
|
||||
name: 'staffresume',
|
||||
component: './staffmanage_staffresume/StaffResume',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/staffmanage/staffadjust',
|
||||
// icon: 'bank',
|
||||
name: 'staffadjust',
|
||||
component: './staffmanage_staffadjust/StaffAdjust',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/staffmanage/staffresume',
|
||||
// icon: 'bank',
|
||||
name: 'staffresume',
|
||||
component: './staffmanage_staffresume/StaffResume',
|
||||
},
|
||||
],
|
||||
},
|
||||
// 组织管理
|
||||
{
|
||||
path: '/topnavbar00/organmanage',
|
||||
name: 'organmanage',
|
||||
component: './nav_system_content/SystemContentList',
|
||||
routes: [
|
||||
{
|
||||
path: '/topnavbar00/organmanage/organchart',
|
||||
// icon: 'bank',
|
||||
name: 'organchart',
|
||||
component: './organmanage_organchart/OrganChart',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/organmanage/deptmaintain',
|
||||
// icon: 'bank',
|
||||
name: 'deptmaintain',
|
||||
component: './organmanage_deptmaintain/DeptMaintain',
|
||||
},
|
||||
],
|
||||
},
|
||||
// 考勤管理
|
||||
{
|
||||
path: '/topnavbar00/attendancemanage',
|
||||
name: 'attendancemanage',
|
||||
component: './nav_system_content/SystemContentList',
|
||||
routes: [
|
||||
{
|
||||
path: '/topnavbar00/attendancemanage/attendancedata',
|
||||
// icon: 'bank',
|
||||
name: 'attendancedata',
|
||||
component: './attendancemanage_attendancedata/attendancemanageAttendancedata',
|
||||
},
|
||||
],
|
||||
},
|
||||
// 绩效管理
|
||||
{
|
||||
path: '/topnavbar00/performancemanage',
|
||||
name: 'performancemanage',
|
||||
component: './nav_system_content/SystemContentList',
|
||||
routes: [
|
||||
{
|
||||
path: '/topnavbar00/performancemanage/performancelist',
|
||||
// icon: 'bank',
|
||||
name: 'performancelist',
|
||||
component: './performancemanage_performancelist/PerformanceList',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/performancemanage/performanceruleset',
|
||||
// icon: 'bank',
|
||||
name: 'performanceruleset',
|
||||
component: './performancemanage_performanceruleset/PerformanceRuleset',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/performancemanage/performanceassess',
|
||||
// icon: 'bank',
|
||||
name: 'performanceassess',
|
||||
component: './performancemanage_performanceassess/PerformanceAssess',
|
||||
},
|
||||
],
|
||||
},
|
||||
// 薪酬管理
|
||||
{
|
||||
path: '/topnavbar00/salarymanage',
|
||||
name: 'salarymanage',
|
||||
component: './nav_system_content/SystemContentList',
|
||||
routes: [
|
||||
{
|
||||
path: '/topnavbar00/salarymanage/salarydata',
|
||||
// icon: 'bank',
|
||||
name: 'salarydata',
|
||||
component: './salarymanage_salarydata/SalaryData',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/salarymanage/salaryruleset',
|
||||
// icon: 'bank',
|
||||
name: 'salaryruleset',
|
||||
component: './salarymanage_salaryruleset/SalaryRuleset',
|
||||
},
|
||||
],
|
||||
},
|
||||
//效率管理
|
||||
{
|
||||
path: '/topnavbar00/hrefficiency',
|
||||
name: 'hrefficiency',
|
||||
component: './nav_system_content/SystemContentList',
|
||||
routes: [
|
||||
{
|
||||
path: '/topnavbar00/hrefficiency/timesheet',
|
||||
// icon: 'bank',
|
||||
name: 'timesheet',
|
||||
component: './hrefficiency_timesheet/TimeSheetList',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/hrefficiency/documentUpdate',
|
||||
// icon: 'bank',
|
||||
name: 'documentUpdate',
|
||||
component: './documentUpdate/TimeSheetList',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/hrefficiency/agentSetting',
|
||||
// icon: 'bank',
|
||||
name: 'agentSetting',
|
||||
component: './agentSetting/TimeSheetList',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/hrefficiency/backgroundManagement',
|
||||
// icon: 'bank',
|
||||
name: 'backgroundManagement',
|
||||
component: './backgroundManagement/TimeSheetList',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/hrefficiency/staffsheet',
|
||||
// icon: 'bank',
|
||||
name: 'staffsheet',
|
||||
component: './hrefficiency_staffsheet/StaffSheetList',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/hrefficiency/staffuph',
|
||||
// icon: 'bank',
|
||||
name: 'staffuph',
|
||||
component: './hrefficiency_staffuph/StaffUPHList',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/hrefficiency/deptuph',
|
||||
// icon: 'bank',
|
||||
name: 'deptuph',
|
||||
component: './hrefficiency_deptuph/DeptUPHList',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/hrefficiency/allstaffuph',
|
||||
// icon: 'bank',
|
||||
name: 'allstaffuph',
|
||||
component: './hrefficiency_allstaffuph/AllStaffUPHList',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/hrefficiency/workreport',
|
||||
// icon: 'bank',
|
||||
name: 'workreport',
|
||||
component: './hrefficiency_workreport/WorkReport',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/hrefficiency/dataSet',
|
||||
// icon: 'bank',
|
||||
name: 'dataSet',
|
||||
component: './dataSet/TimeSheetList',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/hrefficiency/systemMonitoring',
|
||||
// icon: 'bank',
|
||||
name: 'systemMonitoring',
|
||||
component: './systemMonitoring/TimeSheetList',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/hrefficiency/systemApplicationStatistics',
|
||||
// icon: 'bank',
|
||||
name: 'systemApplicationStatistics',
|
||||
component: './systemApplicationStatistics/TimeSheetList',
|
||||
},
|
||||
],
|
||||
},
|
||||
// 知识库管理
|
||||
{
|
||||
path: '/topnavbar00/knowledgebase',
|
||||
name: 'knowledgebase',
|
||||
component: './nav_system_content/SystemContentList',
|
||||
routes: [
|
||||
{
|
||||
path: '/topnavbar00/knowledgebase/qaknowledgebase',
|
||||
// icon: 'bank',
|
||||
name: 'qaknowledgebase',
|
||||
component: './knowledgebase_qaknowledgebase/QaKnowledgebase',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/knowledgebase/docknowledgebase',
|
||||
// icon: 'bank',
|
||||
name: 'docknowledgebase',
|
||||
component: './knowledgebase_docknowledgebase/DocKnowledgebase',
|
||||
},
|
||||
],
|
||||
},
|
||||
// 后台管理
|
||||
{
|
||||
path: '/topnavbar00/backendmanage',
|
||||
name: 'backendmanage',
|
||||
component: './nav_system_content/SystemContentList',
|
||||
routes: [
|
||||
{
|
||||
path: '/topnavbar00/backendmanage/datadict',
|
||||
// icon: 'bank',
|
||||
name: 'datadict',
|
||||
component: './backendmanage_datadict/DataDict',
|
||||
},
|
||||
{
|
||||
path: '/topnavbar00/backendmanage/configmanage',
|
||||
// icon: 'bank',
|
||||
name: 'configmanage',
|
||||
component: './backendmanage_configmanage/ConfigManage',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
// 异常页
|
||||
{
|
||||
name: 'exception',
|
||||
icon: 'warning',
|
||||
path: '/exception00',
|
||||
hideInMenu: true,
|
||||
routes: [
|
||||
// exception
|
||||
{
|
||||
path: '/exception00/403',
|
||||
name: 'not-permission',
|
||||
component: './exception/403'
|
||||
},
|
||||
{
|
||||
path: '/exception00/404',
|
||||
name: 'not-find',
|
||||
component: './exception/404'
|
||||
},
|
||||
{
|
||||
path: '/exception00/500',
|
||||
name: 'server-error',
|
||||
component: './exception/500'
|
||||
},
|
||||
{
|
||||
path: '/exception00/1403',
|
||||
name: 'not-license-permission',
|
||||
hideLayout: true,
|
||||
component: './exception/1403'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
// icon,
|
||||
hideInMenu: true,
|
||||
routes: [
|
||||
{
|
||||
// 网站通用图标
|
||||
routes: [
|
||||
{ icon: 'accountBook' },
|
||||
{ icon: 'aim' },
|
||||
{ icon: 'alert' },
|
||||
{ icon: 'apartment' },
|
||||
{ icon: 'api' },
|
||||
{ icon: 'appstoreAdd' },
|
||||
{ icon: 'appstore' },
|
||||
{ icon: 'audio' },
|
||||
{ icon: 'audioMuted' },
|
||||
{ icon: 'audit' },
|
||||
{ icon: 'bank' },
|
||||
{ icon: 'barcode' },
|
||||
{ icon: 'bars' },
|
||||
{ icon: 'bell' },
|
||||
{ icon: 'block' },
|
||||
{ icon: 'book' },
|
||||
{ icon: 'border' },
|
||||
{ icon: 'borderlessTable' },
|
||||
{ icon: 'branches' },
|
||||
{ icon: 'bug' },
|
||||
{ icon: 'build' },
|
||||
{ icon: 'bulb' },
|
||||
{ icon: 'calculator' },
|
||||
{ icon: 'calendar' },
|
||||
{ icon: 'camera' },
|
||||
{ icon: 'car' },
|
||||
{ icon: 'carryOut' },
|
||||
{ icon: 'ciCircle' },
|
||||
{ icon: 'ci' },
|
||||
{ icon: 'clear' },
|
||||
{ icon: 'cloudDownload' },
|
||||
{ icon: 'cloud' },
|
||||
{ icon: 'cloudServer' },
|
||||
{ icon: 'cloudSync' },
|
||||
{ icon: 'cloudUpload' },
|
||||
{ icon: 'cluster' },
|
||||
{ icon: 'code' },
|
||||
{ icon: 'coffee' },
|
||||
{ icon: 'comment' },
|
||||
{ icon: 'compass' },
|
||||
{ icon: 'compress' },
|
||||
{ icon: 'consoleSql' },
|
||||
{ icon: 'contacts' },
|
||||
{ icon: 'container' },
|
||||
{ icon: 'control' },
|
||||
{ icon: 'copyright' },
|
||||
{ icon: 'creditCard' },
|
||||
{ icon: 'crown' },
|
||||
{ icon: 'customerService' },
|
||||
{ icon: 'dashboard' },
|
||||
{ icon: 'database' },
|
||||
{ icon: 'deleteColumn' },
|
||||
{ icon: 'deleteRow' },
|
||||
{ icon: 'deliveredProcedure' },
|
||||
{ icon: 'deploymentUnit' },
|
||||
{ icon: 'desktop' },
|
||||
{ icon: 'dingtalk' },
|
||||
{ icon: 'disconnect' },
|
||||
{ icon: 'dislike' },
|
||||
{ icon: 'dollarCircle' },
|
||||
{ icon: 'dollar' },
|
||||
{ icon: 'download' },
|
||||
{ icon: 'ellipsis' },
|
||||
{ icon: 'environment' },
|
||||
{ icon: 'euroCircle' },
|
||||
{ icon: 'euro' },
|
||||
{ icon: 'exception' },
|
||||
{ icon: 'expandAlt' },
|
||||
{ icon: 'expand' },
|
||||
{ icon: 'experiment' },
|
||||
{ icon: 'export' },
|
||||
{ icon: 'eye' },
|
||||
{ icon: 'fieldBinary' },
|
||||
{ icon: 'fieldNumber' },
|
||||
{ icon: 'fieldString' },
|
||||
{ icon: 'fieldTime' },
|
||||
{ icon: 'fileAdd' },
|
||||
{ icon: 'fileDone' },
|
||||
{ icon: 'fileExcel' },
|
||||
{ icon: 'fileExclamation' },
|
||||
{ icon: 'file' },
|
||||
{ icon: 'fileGif' },
|
||||
{ icon: 'fileImage' },
|
||||
{ icon: 'fileJpg' },
|
||||
{ icon: 'fileMarkdown' },
|
||||
{ icon: 'filePdf' },
|
||||
{ icon: 'filePpt' },
|
||||
{ icon: 'fileProtect' },
|
||||
{ icon: 'fileSearch' },
|
||||
{ icon: 'fileSync' },
|
||||
{ icon: 'fileText' },
|
||||
{ icon: 'fileUnknown' },
|
||||
{ icon: 'fileWord' },
|
||||
{ icon: 'fileZip' },
|
||||
{ icon: 'filter' },
|
||||
{ icon: 'fire' },
|
||||
{ icon: 'flag' },
|
||||
{ icon: 'folderAdd' },
|
||||
{ icon: 'folder' },
|
||||
{ icon: 'folderView' },
|
||||
{ icon: 'fork' },
|
||||
{ icon: 'formatPainter' },
|
||||
{ icon: 'frown' },
|
||||
{ icon: 'function' },
|
||||
{ icon: 'fundProjectionScreen' },
|
||||
{ icon: 'fundView' },
|
||||
{ icon: 'funnelPlot' },
|
||||
{ icon: 'gateway' },
|
||||
{ icon: 'gif' },
|
||||
{ icon: 'gift' },
|
||||
{ icon: 'global' },
|
||||
{ icon: 'gold' },
|
||||
{ icon: 'group' },
|
||||
{ icon: 'hdd' },
|
||||
{ icon: 'heart' },
|
||||
{ icon: 'history' },
|
||||
{ icon: 'home' },
|
||||
{ icon: 'hourglass' },
|
||||
{ icon: 'idcard' },
|
||||
{ icon: 'import' },
|
||||
{ icon: 'inbox' },
|
||||
{ icon: 'insertRowAbove' },
|
||||
{ icon: 'insertRowBelow' },
|
||||
{ icon: 'insertRowLeft' },
|
||||
{ icon: 'insertRowRight' },
|
||||
{ icon: 'insurance' },
|
||||
{ icon: 'interaction' },
|
||||
{ icon: 'key' },
|
||||
{ icon: 'laptop' },
|
||||
{ icon: 'layout' },
|
||||
{ icon: 'like' },
|
||||
{ icon: 'line' },
|
||||
{ icon: 'link' },
|
||||
{ icon: 'loading3Quarters' },
|
||||
{ icon: 'loading' },
|
||||
{ icon: 'lock' },
|
||||
{ icon: 'macCommand' },
|
||||
{ icon: 'mail' },
|
||||
{ icon: 'man' },
|
||||
{ icon: 'medicineBox' },
|
||||
{ icon: 'meh' },
|
||||
{ icon: 'menu' },
|
||||
{ icon: 'mergeCells' },
|
||||
{ icon: 'message' },
|
||||
{ icon: 'mobile' },
|
||||
{ icon: 'moneyCollect' },
|
||||
{ icon: 'monitor' },
|
||||
{ icon: 'more' },
|
||||
{ icon: 'nodeCollapse' },
|
||||
{ icon: 'nodeExpand' },
|
||||
{ icon: 'nodeIndex' },
|
||||
{ icon: 'notification' },
|
||||
{ icon: 'number' },
|
||||
{ icon: 'oneToOne' },
|
||||
{ icon: 'partition' },
|
||||
{ icon: 'payCircle' },
|
||||
{ icon: 'percentage' },
|
||||
{ icon: 'phone' },
|
||||
{ icon: 'picture' },
|
||||
{ icon: 'playSquare' },
|
||||
{ icon: 'poundCircle' },
|
||||
{ icon: 'pound' },
|
||||
{ icon: 'poweroff' },
|
||||
{ icon: 'printer' },
|
||||
{ icon: 'profile' },
|
||||
{ icon: 'project' },
|
||||
{ icon: 'propertySafety' },
|
||||
{ icon: 'pullRequest' },
|
||||
{ icon: 'pushpin' },
|
||||
{ icon: 'qrcode' },
|
||||
{ icon: 'read' },
|
||||
{ icon: 'reconciliation' },
|
||||
{ icon: 'redEnvelope' },
|
||||
{ icon: 'reload' },
|
||||
{ icon: 'rest' },
|
||||
{ icon: 'robot' },
|
||||
{ icon: 'rocket' },
|
||||
{ icon: 'rotateLeft' },
|
||||
{ icon: 'rotateRight' },
|
||||
{ icon: 'safetyCertificate' },
|
||||
{ icon: 'safety' },
|
||||
{ icon: 'save' },
|
||||
{ icon: 'scan' },
|
||||
{ icon: 'schedule' },
|
||||
{ icon: 'search' },
|
||||
{ icon: 'securityScan' },
|
||||
{ icon: 'select' },
|
||||
{ icon: 'send' },
|
||||
{ icon: 'setting' },
|
||||
{ icon: 'shake' },
|
||||
{ icon: 'shareAlt' },
|
||||
{ icon: 'shop' },
|
||||
{ icon: 'shoppingCart' },
|
||||
{ icon: 'shopping' },
|
||||
{ icon: 'sisternode' },
|
||||
{ icon: 'skin' },
|
||||
{ icon: 'smile' },
|
||||
{ icon: 'solution' },
|
||||
{ icon: 'sound' },
|
||||
{ icon: 'splitCells' },
|
||||
{ icon: 'star' },
|
||||
{ icon: 'subnode' },
|
||||
{ icon: 'switcher' },
|
||||
{ icon: 'sync' },
|
||||
{ icon: 'table' },
|
||||
{ icon: 'tablet' },
|
||||
{ icon: 'tag' },
|
||||
{ icon: 'tags' },
|
||||
{ icon: 'team' },
|
||||
{ icon: 'thunderbolt' },
|
||||
{ icon: 'toTop' },
|
||||
{ icon: 'tool' },
|
||||
{ icon: 'trademarkCircle' },
|
||||
{ icon: 'trademark' },
|
||||
{ icon: 'transaction' },
|
||||
{ icon: 'translation' },
|
||||
{ icon: 'trophy' },
|
||||
{ icon: 'ungroup' },
|
||||
{ icon: 'unlock' },
|
||||
{ icon: 'upload' },
|
||||
{ icon: 'usb' },
|
||||
{ icon: 'userAdd' },
|
||||
{ icon: 'userDelete' },
|
||||
{ icon: 'user' },
|
||||
{ icon: 'userSwitch' },
|
||||
{ icon: 'usergroupAdd' },
|
||||
{ icon: 'usergroupDelete' },
|
||||
{ icon: 'verified' },
|
||||
{ icon: 'videoCameraAdd' },
|
||||
{ icon: 'videoCamera' },
|
||||
{ icon: 'wallet' },
|
||||
{ icon: 'whatsApp' },
|
||||
{ icon: 'wifi' },
|
||||
{ icon: 'woman' },
|
||||
]
|
||||
},
|
||||
{
|
||||
// 编辑类图标
|
||||
routes: [
|
||||
{ icon: 'edit' },
|
||||
{ icon: 'form' },
|
||||
{ icon: 'copy' },
|
||||
{ icon: 'scissor' },
|
||||
{ icon: 'delete' },
|
||||
{ icon: 'snippets' },
|
||||
{ icon: 'diff' },
|
||||
{ icon: 'highlight' },
|
||||
{ icon: 'alignCenter' },
|
||||
{ icon: 'alignLeft' },
|
||||
{ icon: 'alignRight' },
|
||||
{ icon: 'bgColors' },
|
||||
{ icon: 'bold' },
|
||||
{ icon: 'italic' },
|
||||
{ icon: 'underline' },
|
||||
{ icon: 'strikethrough' },
|
||||
{ icon: 'redo' },
|
||||
{ icon: 'undo' },
|
||||
{ icon: 'zoomIn' },
|
||||
{ icon: 'zoomOut' },
|
||||
{ icon: 'fontColors' },
|
||||
{ icon: 'fontSize' },
|
||||
{ icon: 'lineHeight' },
|
||||
{ icon: 'dash' },
|
||||
{ icon: 'smallDash' },
|
||||
{ icon: 'sortAscending' },
|
||||
{ icon: 'sortDescending' },
|
||||
{ icon: 'drag' },
|
||||
{ icon: 'orderedList' },
|
||||
{ icon: 'unorderedList' },
|
||||
{ icon: 'radiusSetting' },
|
||||
{ icon: 'columnWidth' },
|
||||
{ icon: 'columnHeight' },
|
||||
]
|
||||
},
|
||||
{
|
||||
// 数据类图标
|
||||
routes: [
|
||||
{ icon: 'areaChart' },
|
||||
{ icon: 'pieChart' },
|
||||
{ icon: 'barChart' },
|
||||
{ icon: 'dotChart' },
|
||||
{ icon: 'lineChart' },
|
||||
{ icon: 'radarChart' },
|
||||
{ icon: 'heatMap' },
|
||||
{ icon: 'fall' },
|
||||
{ icon: 'rise' },
|
||||
{ icon: 'stock' },
|
||||
{ icon: 'boxPlot' },
|
||||
{ icon: 'fund' },
|
||||
{ icon: 'sliders' },
|
||||
]
|
||||
},
|
||||
{
|
||||
// 品牌和标识
|
||||
routes: [
|
||||
{ icon: 'android' },
|
||||
{ icon: 'apple' },
|
||||
{ icon: 'windows' },
|
||||
{ icon: 'ie' },
|
||||
{ icon: 'chrome' },
|
||||
{ icon: 'github' },
|
||||
{ icon: 'aliwangwang' },
|
||||
{ icon: 'dingding' },
|
||||
{ icon: 'weiboSquare' },
|
||||
{ icon: 'weiboCircle' },
|
||||
{ icon: 'taobaoCircle' },
|
||||
{ icon: 'html5' },
|
||||
{ icon: 'weibo' },
|
||||
{ icon: 'twitter' },
|
||||
{ icon: 'wechat' },
|
||||
{ icon: 'youtube' },
|
||||
{ icon: 'alipayCircle' },
|
||||
{ icon: 'taobao' },
|
||||
{ icon: 'skype' },
|
||||
{ icon: 'qq' },
|
||||
{ icon: 'mediumWorkmark' },
|
||||
{ icon: 'gitlab' },
|
||||
{ icon: 'medium' },
|
||||
{ icon: 'linkedin' },
|
||||
{ icon: 'googlePlus' },
|
||||
{ icon: 'dropbox' },
|
||||
{ icon: 'facebook' },
|
||||
{ icon: 'codepen' },
|
||||
{ icon: 'codeSandbox' },
|
||||
{ icon: 'amazon' },
|
||||
{ icon: 'google' },
|
||||
{ icon: 'codepenCircle' },
|
||||
{ icon: 'alipay' },
|
||||
{ icon: 'antDesign' },
|
||||
{ icon: 'antCloud' },
|
||||
{ icon: 'aliyun' },
|
||||
{ icon: 'zhihu' },
|
||||
{ icon: 'slack' },
|
||||
{ icon: 'slackSquare' },
|
||||
{ icon: 'behance' },
|
||||
{ icon: 'behanceSquare' },
|
||||
{ icon: 'dribbble' },
|
||||
{ icon: 'dribbbleSquare' },
|
||||
{ icon: 'instagram' },
|
||||
{ icon: 'yuque' },
|
||||
{ icon: 'alibaba' },
|
||||
{ icon: 'yahoo' },
|
||||
{ icon: 'reddit' },
|
||||
{ icon: 'sketch' },
|
||||
]
|
||||
}
|
||||
|
||||
],
|
||||
},
|
||||
{
|
||||
component: './404',
|
||||
},
|
||||
|
||||
]
|
||||
@ -0,0 +1,17 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"],
|
||||
"@@/*": ["./src/.umi/*"],
|
||||
"umi": ["./node_module/umi"],
|
||||
"@umijs/max": ["./node_module/umi"],
|
||||
"@umijs/max/typings": ["./src/.umi/typings"],
|
||||
"ahooks": ["./node_module/ahooks"],
|
||||
"@ant-design/icons": ["./node_module/@ant-design/icons"],
|
||||
"dayjs": ["./node_module/dayjs"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "flx-lms-fe",
|
||||
"version": "1.0.0",
|
||||
"private": true,
|
||||
"author": "",
|
||||
"scripts": {
|
||||
"dev": "cross-env REACT_APP_ENV=dev max dev",
|
||||
"build": "cross-env REACT_APP_ENV=prod max build",
|
||||
"postinstall": "max setup",
|
||||
"setup": "max setup",
|
||||
"start": "cross-env REACT_APP_ENV=dev max dev",
|
||||
"start:no-mock": "cross-env MOCK=none REACT_APP_ENV=dev max dev"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^4.8.0",
|
||||
"@umijs/max": "^4.0.70",
|
||||
"antd": "5.6.0",
|
||||
"braft-editor": "^2.3.9",
|
||||
"braft-finder": "^0.0.21",
|
||||
"braft-utils": "^3.0.2",
|
||||
"echarts": "^4.9.0",
|
||||
"echarts-for-react": "^3.0.2",
|
||||
"moment": "^2.29.1",
|
||||
"qs": "^6.11.0",
|
||||
"react": "^18.2.0",
|
||||
"react-contexify": "^5.0.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-split-pane": "^0.1.92"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.0.0",
|
||||
"@types/react-dom": "^18.0.0",
|
||||
"code-inspector-plugin": "^1.2.3",
|
||||
"cross-env": "^7.0.3",
|
||||
"typescript": "^4.1.2"
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 77 KiB |
@ -0,0 +1,563 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>人力资源管理系统 - 多维统计</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.5.0/echarts.min.js"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Pacifico&display=swap" rel="stylesheet">
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#2D5CF6',
|
||||
secondary: '#F5F6FA'
|
||||
},
|
||||
borderRadius: {
|
||||
'none': '0px',
|
||||
'sm': '2px',
|
||||
DEFAULT: '4px',
|
||||
'md': '8px',
|
||||
'lg': '12px',
|
||||
'xl': '16px',
|
||||
'2xl': '20px',
|
||||
'3xl': '24px',
|
||||
'full': '9999px',
|
||||
'button': '4px'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
}
|
||||
.fa-icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="min-h-[1024px] bg-secondary font-sans">
|
||||
<!-- 顶部导航 -->
|
||||
<!-- <header class="w-full bg-primary text-white shadow-md">
|
||||
<div class="container mx-auto px-6 h-16 flex items-center justify-between">
|
||||
<div class="flex items-center space-x-8">
|
||||
<a href="#" class="text-2xl font-['Pacifico']">人力</a>
|
||||
<nav class="hidden md:flex space-x-6">
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">多维统计</a>
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">人员管理</a>
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">组织管理</a>
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">考勤管理</a>
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">绩效管理</a>
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">薪酬管理</a>
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">知识库</a>
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">后台管理</a>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<div class="relative">
|
||||
<input type="text" placeholder="搜索..." class="bg-white/20 text-sm px-4 py-2 rounded-button w-48 focus:outline-none focus:ring-2 focus:ring-white/50">
|
||||
<i class="fa-icon fa-solid fa-magnifying-glass absolute right-3 top-1/2 transform -translate-y-1/2 text-white/70"></i>
|
||||
</div>
|
||||
<button class="flex items-center space-x-1 bg-white/10 hover:bg-white/20 px-3 py-1 rounded-button transition">
|
||||
<i class="fa-icon fa-solid fa-robot"></i>
|
||||
<span class="text-sm">AI助手</span>
|
||||
</button>
|
||||
<div class="w-8 h-8 rounded-full bg-white/20 flex items-center justify-center cursor-pointer">
|
||||
<i class="fa-icon fa-solid fa-user"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header> -->
|
||||
|
||||
<!-- 主要内容 -->
|
||||
<main class="container mx-auto px-6 py-8">
|
||||
<!-- 数据卡片行 -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
|
||||
<div class="bg-white p-6 rounded-lg shadow-sm hover:shadow-md transition">
|
||||
<div class="flex justify-between items-start">
|
||||
<div>
|
||||
<p class="text-gray-500 text-sm">员工总数</p>
|
||||
<p class="text-3xl font-bold mt-2">1,248</p>
|
||||
</div>
|
||||
<div class="bg-green-100 text-green-800 px-2 py-1 rounded-button text-xs flex items-center">
|
||||
<i class="fa-icon fa-solid fa-arrow-up mr-1"></i>
|
||||
<span>5.2%</span>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-gray-500 text-xs mt-2">较上月增加 62 人</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white p-6 rounded-lg shadow-sm hover:shadow-md transition">
|
||||
<div>
|
||||
<p class="text-gray-500 text-sm">本月入职</p>
|
||||
<p class="text-3xl font-bold mt-2">87</p>
|
||||
</div>
|
||||
<p class="text-gray-500 text-xs mt-2">其中社招 52 人,校招 35 人</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white p-6 rounded-lg shadow-sm hover:shadow-md transition">
|
||||
<div>
|
||||
<p class="text-gray-500 text-sm">本月离职</p>
|
||||
<p class="text-3xl font-bold mt-2">25</p>
|
||||
</div>
|
||||
<p class="text-gray-500 text-xs mt-2">主动离职 18 人,被动离职 7 人</p>
|
||||
</div>
|
||||
|
||||
<div class="bg-white p-6 rounded-lg shadow-sm hover:shadow-md transition">
|
||||
<div>
|
||||
<p class="text-gray-500 text-sm">平均工龄</p>
|
||||
<p class="text-3xl font-bold mt-2">3.2</p>
|
||||
</div>
|
||||
<p class="text-gray-500 text-xs mt-2">年,较行业平均高 0.8 年</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图表行1 -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
|
||||
<div class="bg-white p-6 rounded-lg shadow-sm">
|
||||
<h3 class="text-lg font-semibold mb-4">部门人员分布</h3>
|
||||
<div class="chart-container" id="departmentChart"></div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white p-6 rounded-lg shadow-sm">
|
||||
<h3 class="text-lg font-semibold mb-4">职位分布</h3>
|
||||
<div class="chart-container" id="positionChart"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图表行2 -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
|
||||
<div class="bg-white p-6 rounded-lg shadow-sm">
|
||||
<h3 class="text-lg font-semibold mb-4">员工年龄分布</h3>
|
||||
<div class="chart-container" id="ageChart"></div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white p-6 rounded-lg shadow-sm">
|
||||
<h3 class="text-lg font-semibold mb-4">员工工龄分布</h3>
|
||||
<div class="chart-container" id="seniorityChart"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 图表行3 -->
|
||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
|
||||
<div class="bg-white p-6 rounded-lg shadow-sm">
|
||||
<h3 class="text-lg font-semibold mb-4">员工绩效分布</h3>
|
||||
<div class="chart-container" id="performanceChart"></div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white p-6 rounded-lg shadow-sm">
|
||||
<h3 class="text-lg font-semibold mb-4">招聘渠道分布</h3>
|
||||
<div class="chart-container" id="recruitmentChart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- 页脚 -->
|
||||
<footer class="w-full bg-gray-800 text-white py-8 mt-auto">
|
||||
<div class="container mx-auto px-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold mb-4">关于我们</h3>
|
||||
<p class="text-sm text-gray-400 mb-4">人力科技是一家专注于企业人力资源数字化解决方案的高科技公司,致力于为企业提供智能化的人力资源管理工具。</p>
|
||||
<div class="flex space-x-4">
|
||||
<a href="#" class="text-gray-400 hover:text-white transition"><i class="fa-icon fa-brands fa-weixin"></i></a>
|
||||
<a href="#" class="text-gray-400 hover:text-white transition"><i class="fa-icon fa-brands fa-weibo"></i></a>
|
||||
<a href="#" class="text-gray-400 hover:text-white transition"><i class="fa-icon fa-brands fa-linkedin"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold mb-4">快速链接</h3>
|
||||
<ul class="space-y-2">
|
||||
<li><a href="#" class="text-sm text-gray-400 hover:text-white transition">产品介绍</a></li>
|
||||
<li><a href="#" class="text-sm text-gray-400 hover:text-white transition">解决方案</a></li>
|
||||
<li><a href="#" class="text-sm text-gray-400 hover:text-white transition">客户案例</a></li>
|
||||
<li><a href="#" class="text-sm text-gray-400 hover:text-white transition">价格方案</a></li>
|
||||
<li><a href="#" class="text-sm text-gray-400 hover:text-white transition">帮助中心</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 class="text-lg font-semibold mb-4">联系我们</h3>
|
||||
<ul class="space-y-2 text-sm text-gray-400">
|
||||
<li class="flex items-start">
|
||||
<i class="fa-icon fa-solid fa-map-marker-alt mt-1 mr-2"></i>
|
||||
<span>北京市海淀区中关村软件园 12 号楼 3 层</span>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<i class="fa-icon fa-solid fa-phone mr-2"></i>
|
||||
<span>400-888-8888</span>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<i class="fa-icon fa-solid fa-envelope mr-2"></i>
|
||||
<span>contact@hrtech.com</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="border-t border-gray-700 mt-8 pt-6 text-center text-sm text-gray-400">
|
||||
<p>© 2023 人力科技 版权所有 | 京ICP备12345678号-1 | 京公网安备11010802023456号</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
// 部门分布图表
|
||||
const departmentChart = echarts.init(document.getElementById('departmentChart'));
|
||||
departmentChart.setOption({
|
||||
animation: false,
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
right: 10,
|
||||
top: 'center',
|
||||
data: ['技术部', '产品部', '市场部', '销售部', '人力资源', '财务部', '行政部']
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '部门分布',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderRadius: 4,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2
|
||||
},
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: '18',
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 320, name: '技术部' },
|
||||
{ value: 240, name: '产品部' },
|
||||
{ value: 149, name: '市场部' },
|
||||
{ value: 180, name: '销售部' },
|
||||
{ value: 98, name: '人力资源' },
|
||||
{ value: 56, name: '财务部' },
|
||||
{ value: 105, name: '行政部' }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// 职位分布图表
|
||||
const positionChart = echarts.init(document.getElementById('positionChart'));
|
||||
positionChart.setOption({
|
||||
animation: false,
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
right: 10,
|
||||
top: 'center',
|
||||
data: ['工程师', '产品经理', '设计师', '市场专员', '销售代表', 'HRBP', '财务专员', '行政专员']
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '职位分布',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderRadius: 4,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2
|
||||
},
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: '18',
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 280, name: '工程师' },
|
||||
{ value: 120, name: '产品经理' },
|
||||
{ value: 90, name: '设计师' },
|
||||
{ value: 80, name: '市场专员' },
|
||||
{ value: 150, name: '销售代表' },
|
||||
{ value: 60, name: 'HRBP' },
|
||||
{ value: 40, name: '财务专员' },
|
||||
{ value: 80, name: '行政专员' }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// 年龄分布图表
|
||||
const ageChart = echarts.init(document.getElementById('ageChart'));
|
||||
ageChart.setOption({
|
||||
animation: false,
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
data: ['20-25岁', '26-30岁', '31-35岁', '36-40岁', '41岁以上'],
|
||||
axisTick: {
|
||||
alignWithLabel: true
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '人数',
|
||||
type: 'bar',
|
||||
barWidth: '60%',
|
||||
itemStyle: {
|
||||
color: '#2D5CF6'
|
||||
},
|
||||
data: [120, 480, 360, 180, 108]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// 工龄分布图表
|
||||
const seniorityChart = echarts.init(document.getElementById('seniorityChart'));
|
||||
seniorityChart.setOption({
|
||||
animation: false,
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
right: 10,
|
||||
top: 'center',
|
||||
data: ['1年以内', '1-3年', '3-5年', '5-10年', '10年以上']
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '工龄分布',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderRadius: 4,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2
|
||||
},
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: '18',
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 280, name: '1年以内' },
|
||||
{ value: 420, name: '1-3年' },
|
||||
{ value: 300, name: '3-5年' },
|
||||
{ value: 180, name: '5-10年' },
|
||||
{ value: 68, name: '10年以上' }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// 绩效分布图表
|
||||
const performanceChart = echarts.init(document.getElementById('performanceChart'));
|
||||
performanceChart.setOption({
|
||||
animation: false,
|
||||
tooltip: {
|
||||
trigger: 'item'
|
||||
},
|
||||
legend: {
|
||||
orient: 'vertical',
|
||||
right: 10,
|
||||
top: 'center',
|
||||
data: ['A(优秀)', 'B(良好)', 'C(合格)', 'D(待改进)']
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '绩效分布',
|
||||
type: 'pie',
|
||||
radius: ['40%', '70%'],
|
||||
avoidLabelOverlap: false,
|
||||
itemStyle: {
|
||||
borderRadius: 4,
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2
|
||||
},
|
||||
label: {
|
||||
show: false,
|
||||
position: 'center'
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: '18',
|
||||
fontWeight: 'bold'
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: false
|
||||
},
|
||||
data: [
|
||||
{ value: 180, name: 'A(优秀)' },
|
||||
{ value: 420, name: 'B(良好)' },
|
||||
{ value: 480, name: 'C(合格)' },
|
||||
{ value: 68, name: 'D(待改进)' }
|
||||
]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// 招聘渠道图表
|
||||
const recruitmentChart = echarts.init(document.getElementById('recruitmentChart'));
|
||||
recruitmentChart.setOption({
|
||||
animation: false,
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'shadow'
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
data: ['猎头', '招聘网站', '内部推荐', '校园招聘', '社交媒体']
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
xAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
yAxis: {
|
||||
type: 'category',
|
||||
data: ['1月', '2月', '3月', '4月', '5月', '6月']
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '猎头',
|
||||
type: 'bar',
|
||||
stack: 'total',
|
||||
label: {
|
||||
show: true
|
||||
},
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [5, 3, 7, 4, 6, 8]
|
||||
},
|
||||
{
|
||||
name: '招聘网站',
|
||||
type: 'bar',
|
||||
stack: 'total',
|
||||
label: {
|
||||
show: true
|
||||
},
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [12, 10, 15, 18, 14, 16]
|
||||
},
|
||||
{
|
||||
name: '内部推荐',
|
||||
type: 'bar',
|
||||
stack: 'total',
|
||||
label: {
|
||||
show: true
|
||||
},
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [8, 6, 10, 7, 9, 11]
|
||||
},
|
||||
{
|
||||
name: '校园招聘',
|
||||
type: 'bar',
|
||||
stack: 'total',
|
||||
label: {
|
||||
show: true
|
||||
},
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [0, 0, 0, 15, 12, 10]
|
||||
},
|
||||
{
|
||||
name: '社交媒体',
|
||||
type: 'bar',
|
||||
stack: 'total',
|
||||
label: {
|
||||
show: true
|
||||
},
|
||||
emphasis: {
|
||||
focus: 'series'
|
||||
},
|
||||
data: [3, 5, 4, 6, 5, 7]
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// 窗口大小变化时重新调整图表大小
|
||||
window.addEventListener('resize', function() {
|
||||
departmentChart.resize();
|
||||
positionChart.resize();
|
||||
ageChart.resize();
|
||||
seniorityChart.resize();
|
||||
performanceChart.resize();
|
||||
recruitmentChart.resize();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,400 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>人力管理系统 - 知识库</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Pacifico&display=swap" rel="stylesheet">
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.5.0/echarts.min.js"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#2D5CF6',
|
||||
secondary: '#F5F6FA',
|
||||
},
|
||||
borderRadius: {
|
||||
'none': '0px',
|
||||
'sm': '2px',
|
||||
DEFAULT: '4px',
|
||||
'md': '8px',
|
||||
'lg': '12px',
|
||||
'xl': '16px',
|
||||
'2xl': '20px',
|
||||
'3xl': '24px',
|
||||
'full': '9999px',
|
||||
'button': '4px'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.fa-icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.scroll-container {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.scroll-content {
|
||||
display: inline-block;
|
||||
animation: scroll 20s linear infinite;
|
||||
}
|
||||
@keyframes scroll {
|
||||
0% { transform: translateX(0); }
|
||||
100% { transform: translateX(-100%); }
|
||||
}
|
||||
.card-hover:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="min-h-[1024px] flex flex-col bg-secondary">
|
||||
<!-- 顶部导航栏 -->
|
||||
<!-- <header class="w-full bg-primary text-white shadow-md">
|
||||
<div class="container mx-auto px-6 h-[60px] flex items-center justify-between">
|
||||
<div class="flex items-center space-x-8">
|
||||
<a href="#" class="text-2xl font-['Pacifico']">人力</a>
|
||||
<nav class="hidden md:flex space-x-6">
|
||||
<a href="#" class="text-sm hover:opacity-80">多维统计</a>
|
||||
<a href="#" class="text-sm hover:opacity-80">人员管理</a>
|
||||
<a href="#" class="text-sm hover:opacity-80">组织管理</a>
|
||||
<a href="#" class="text-sm hover:opacity-80">考勤管理</a>
|
||||
<a href="#" class="text-sm hover:opacity-80">绩效管理</a>
|
||||
<a href="#" class="text-sm hover:opacity-80">薪酬管理</a>
|
||||
<a href="#" class="text-sm font-semibold hover:opacity-80">知识库</a>
|
||||
<a href="#" class="text-sm hover:opacity-80">后台管理</a>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<div class="relative hidden md:block">
|
||||
<input type="text" placeholder="搜索..." class="py-1 pl-8 pr-4 text-sm rounded-button bg-white bg-opacity-20 placeholder-white focus:outline-none focus:ring-1 focus:ring-white">
|
||||
<i class="fas fa-search fa-icon text-sm absolute left-2 top-1/2 transform -translate-y-1/2"></i>
|
||||
</div>
|
||||
<button class="flex items-center space-x-1 bg-white bg-opacity-20 px-3 py-1 rounded-button hover:bg-opacity-30">
|
||||
<i class="fas fa-robot fa-icon text-sm"></i>
|
||||
<span class="text-sm whitespace-nowrap">AI 助手</span>
|
||||
</button>
|
||||
<div class="w-8 h-8 rounded-full bg-white flex items-center justify-center overflow-hidden">
|
||||
<img src="https://mastergo.com/ai/api/search-image?query=professional20business20profile20photo20of20a20young20asian20female20executive20with20short20hair20wearing20formal20attire20against20a20neutral20light20gray20background&width=80&height=80&orientation=squarish&flag=7fe686c57027aca4551bef56744d5fdf" alt="用户头像" class="w-full h-full object-cover">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header> -->
|
||||
|
||||
<!-- 主内容区域 -->
|
||||
<main class="flex-1 container mx-auto px-6 py-8">
|
||||
<!-- 面包屑导航 -->
|
||||
<!-- <div class="flex items-center text-sm text-gray-600 mb-4">
|
||||
<a href="#" class="hover:text-primary">首页</a>
|
||||
<i class="fas fa-chevron-right fa-icon mx-2 text-xs"></i>
|
||||
<span>知识库</span>
|
||||
</div> -->
|
||||
|
||||
<!-- 页面标题和操作区 -->
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-2xl font-bold text-gray-800">知识库管理</h1>
|
||||
<div class="flex space-x-3">
|
||||
<div class="relative">
|
||||
<input type="text" placeholder="搜索知识..." class="py-2 pl-10 pr-4 text-sm rounded-button border border-gray-300 focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary">
|
||||
<i class="fas fa-search fa-icon text-gray-400 absolute left-3 top-1/2 transform -translate-y-1/2"></i>
|
||||
</div>
|
||||
<button class="bg-primary text-white px-4 py-2 rounded-button hover:bg-opacity-90 flex items-center space-x-2">
|
||||
<i class="fas fa-plus fa-icon text-sm"></i>
|
||||
<span class="whitespace-nowrap">新建知识</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 公告栏 -->
|
||||
<div class="bg-white rounded-md shadow-sm p-3 mb-6">
|
||||
<div class="flex items-center">
|
||||
<div class="bg-yellow-100 text-yellow-800 px-2 py-1 rounded-button text-xs font-medium mr-3">公告</div>
|
||||
<div class="scroll-container w-full">
|
||||
<div class="scroll-content text-sm text-gray-700">
|
||||
<span class="mr-8">系统将于 2023 年 12 月 15 日 00:00 - 02:00 进行维护升级</span>
|
||||
<span class="mr-8">新员工入职指南已更新,请及时查阅</span>
|
||||
<span class="mr-8">2023 年度绩效考核标准已发布</span>
|
||||
<span class="mr-8">系统将于 2023 年 12 月 15 日 00:00 - 02:00 进行维护升级</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分类筛选 -->
|
||||
<div class="flex items-center space-x-4 mb-6 overflow-x-auto pb-2">
|
||||
<button class="px-4 py-2 bg-primary text-white rounded-button whitespace-nowrap">全部</button>
|
||||
<button class="px-4 py-2 bg-white border border-gray-200 rounded-button hover:bg-gray-50 whitespace-nowrap">政策制度</button>
|
||||
<button class="px-4 py-2 bg-white border border-gray-200 rounded-button hover:bg-gray-50 whitespace-nowrap">操作手册</button>
|
||||
<button class="px-4 py-2 bg-white border border-gray-200 rounded-button hover:bg-gray-50 whitespace-nowrap">培训资料</button>
|
||||
<button class="px-4 py-2 bg-white border border-gray-200 rounded-button hover:bg-gray-50 whitespace-nowrap">常见问题</button>
|
||||
<button class="px-4 py-2 bg-white border border-gray-200 rounded-button hover:bg-gray-50 whitespace-nowrap">模板下载</button>
|
||||
</div>
|
||||
|
||||
<!-- 知识卡片列表 -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-8">
|
||||
<!-- 卡片1 -->
|
||||
<div class="bg-white rounded-md shadow-sm overflow-hidden transition-all duration-300 card-hover">
|
||||
<div class="h-40 overflow-hidden">
|
||||
<img src="https://mastergo.com/ai/api/search-image?query=a20modern20business20document20with20clean20design20and20minimalist20layout20on20a20white20desk20with20a20pen20and20coffee20cup20in20the20background&width=400&height=200&orientation=landscape&flag=1e4cf2beacde2cc80fc63a0f89a9703a" alt="文档封面" class="w-full h-full object-cover">
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<h3 class="font-medium text-gray-800">2023 年员工手册</h3>
|
||||
<span class="bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-button">政策制度</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 mb-3 line-clamp-2">包含公司文化、行为规范、考勤制度、福利政策等最新修订版员工手册,适用于全体员工。</p>
|
||||
<div class="flex justify-between items-center text-xs text-gray-500">
|
||||
<span>更新于 2023-11-20</span>
|
||||
<span>下载 128 次</span>
|
||||
</div>
|
||||
<div class="mt-3 flex space-x-2">
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-eye fa-icon mr-1"></i> 预览
|
||||
</button>
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-download fa-icon mr-1"></i> 下载
|
||||
</button>
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-share-alt fa-icon mr-1"></i> 分享
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 卡片2 -->
|
||||
<div class="bg-white rounded-md shadow-sm overflow-hidden transition-all duration-300 card-hover">
|
||||
<div class="h-40 overflow-hidden">
|
||||
<img src="https://mastergo.com/ai/api/search-image?query=a20step20by20step20illustration20of20HR20software20interface20with20clear20numbering20and20annotations20on20a20light20gray20background&width=400&height=200&orientation=landscape&flag=108451af3b1eb2058f31b710d4071080" alt="操作手册封面" class="w-full h-full object-cover">
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<h3 class="font-medium text-gray-800">考勤系统操作指南</h3>
|
||||
<span class="bg-green-100 text-green-800 text-xs px-2 py-1 rounded-button">操作手册</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 mb-3 line-clamp-2">详细说明如何使用公司考勤系统,包括打卡、请假申请、加班申请、考勤异常处理等操作步骤。</p>
|
||||
<div class="flex justify-between items-center text-xs text-gray-500">
|
||||
<span>更新于 2023-10-15</span>
|
||||
<span>下载 256 次</span>
|
||||
</div>
|
||||
<div class="mt-3 flex space-x-2">
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-eye fa-icon mr-1"></i> 预览
|
||||
</button>
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-download fa-icon mr-1"></i> 下载
|
||||
</button>
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-share-alt fa-icon mr-1"></i> 分享
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 卡片3 -->
|
||||
<div class="bg-white rounded-md shadow-sm overflow-hidden transition-all duration-300 card-hover">
|
||||
<div class="h-40 overflow-hidden">
|
||||
<img src="https://mastergo.com/ai/api/search-image?query=a20professional20training20presentation20slide20with20bullet20points20and20infographics20on20a20projector20screen20in20a20meeting20room&width=400&height=200&orientation=landscape&flag=91a52e2f3cc2550ca2a643ea105f2d4b" alt="培训资料封面" class="w-full h-full object-cover">
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<h3 class="font-medium text-gray-800">新员工入职培训</h3>
|
||||
<span class="bg-purple-100 text-purple-800 text-xs px-2 py-1 rounded-button">培训资料</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 mb-3 line-clamp-2">新员工入职培训全套资料,包含公司介绍、部门职能、产品知识、安全规范等内容。</p>
|
||||
<div class="flex justify-between items-center text-xs text-gray-500">
|
||||
<span>更新于 2023-09-28</span>
|
||||
<span>下载 189 次</span>
|
||||
</div>
|
||||
<div class="mt-3 flex space-x-2">
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-eye fa-icon mr-1"></i> 预览
|
||||
</button>
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-download fa-icon mr-1"></i> 下载
|
||||
</button>
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-share-alt fa-icon mr-1"></i> 分享
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 卡片4 -->
|
||||
<div class="bg-white rounded-md shadow-sm overflow-hidden transition-all duration-300 card-hover">
|
||||
<div class="h-40 overflow-hidden">
|
||||
<img src="https://mastergo.com/ai/api/search-image?query=a20frequently20asked20questions20list20with20question20marks20and20answers20in20a20modern20digital20interface20design&width=400&height=200&orientation=landscape&flag=923ef06f9362683938111ad04bb8643c" alt="FAQ封面" class="w-full h-full object-cover">
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<h3 class="font-medium text-gray-800">HR 系统常见问题</h3>
|
||||
<span class="bg-orange-100 text-orange-800 text-xs px-2 py-1 rounded-button">常见问题</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 mb-3 line-clamp-2">整理了员工在使用 HR 系统过程中遇到的常见问题及解决方案,持续更新中。</p>
|
||||
<div class="flex justify-between items-center text-xs text-gray-500">
|
||||
<span>更新于 2023-11-05</span>
|
||||
<span>浏览 342 次</span>
|
||||
</div>
|
||||
<div class="mt-3 flex space-x-2">
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-eye fa-icon mr-1"></i> 查看
|
||||
</button>
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-bookmark fa-icon mr-1"></i> 收藏
|
||||
</button>
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-share-alt fa-icon mr-1"></i> 分享
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 卡片5 -->
|
||||
<div class="bg-white rounded-md shadow-sm overflow-hidden transition-all duration-300 card-hover">
|
||||
<div class="h-40 overflow-hidden">
|
||||
<img src="https://mastergo.com/ai/api/search-image?query=a20collection20of20office20document20templates20including20forms20and20contracts20neatly20stacked20on20a20desk20with20a20laptop&width=400&height=200&orientation=landscape&flag=2a11c867bb72b869508c9cbccb7f198c" alt="模板封面" class="w-full h-full object-cover">
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<h3 class="font-medium text-gray-800">人力资源常用模板</h3>
|
||||
<span class="bg-red-100 text-red-800 text-xs px-2 py-1 rounded-button">模板下载</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 mb-3 line-clamp-2">包含劳动合同、离职申请表、转正申请表、调岗申请表等常用人力资源表格模板。</p>
|
||||
<div class="flex justify-between items-center text-xs text-gray-500">
|
||||
<span>更新于 2023-08-12</span>
|
||||
<span>下载 421 次</span>
|
||||
</div>
|
||||
<div class="mt-3 flex space-x-2">
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-eye fa-icon mr-1"></i> 预览
|
||||
</button>
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-download fa-icon mr-1"></i> 下载
|
||||
</button>
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-share-alt fa-icon mr-1"></i> 分享
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 卡片6 -->
|
||||
<div class="bg-white rounded-md shadow-sm overflow-hidden transition-all duration-300 card-hover">
|
||||
<div class="h-40 overflow-hidden">
|
||||
<img src="https://mastergo.com/ai/api/search-image?query=a20performance20management20framework20diagram20with20key20metrics20and20evaluation20criteria20presented20in20a20modern20corporate20style&width=400&height=200&orientation=landscape&flag=72c9f106f07f07f22208f2c8edfd99fb" alt="绩效封面" class="w-full h-full object-cover">
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<h3 class="font-medium text-gray-800">绩效考核标准与流程</h3>
|
||||
<span class="bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-button">政策制度</span>
|
||||
</div>
|
||||
<p class="text-sm text-gray-600 mb-3 line-clamp-2">详细说明公司绩效考核的标准、流程、时间节点及评分细则,适用于管理人员参考。</p>
|
||||
<div class="flex justify-between items-center text-xs text-gray-500">
|
||||
<span>更新于 2023-07-30</span>
|
||||
<span>下载 178 次</span>
|
||||
</div>
|
||||
<div class="mt-3 flex space-x-2">
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-eye fa-icon mr-1"></i> 预览
|
||||
</button>
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-download fa-icon mr-1"></i> 下载
|
||||
</button>
|
||||
<button class="text-primary hover:text-primary-dark text-sm flex items-center">
|
||||
<i class="fas fa-share-alt fa-icon mr-1"></i> 分享
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="flex justify-center mt-8">
|
||||
<nav class="inline-flex rounded-md shadow-sm">
|
||||
<button class="px-3 py-1 rounded-l-md border border-gray-300 bg-white text-gray-700 hover:bg-gray-50">
|
||||
<i class="fas fa-chevron-left fa-icon"></i>
|
||||
</button>
|
||||
<button class="px-3 py-1 border-t border-b border-gray-300 bg-primary text-white">1</button>
|
||||
<button class="px-3 py-1 border-t border-b border-gray-300 bg-white text-gray-700 hover:bg-gray-50">2</button>
|
||||
<button class="px-3 py-1 border-t border-b border-gray-300 bg-white text-gray-700 hover:bg-gray-50">3</button>
|
||||
<button class="px-3 py-1 border-t border-b border-gray-300 bg-white text-gray-700 hover:bg-gray-50">4</button>
|
||||
<button class="px-3 py-1 border-t border-b border-gray-300 bg-white text-gray-700 hover:bg-gray-50">5</button>
|
||||
<button class="px-3 py-1 rounded-r-md border border-gray-300 bg-white text-gray-700 hover:bg-gray-50">
|
||||
<i class="fas fa-chevron-right fa-icon"></i>
|
||||
</button>
|
||||
</nav>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- 页脚 -->
|
||||
<footer class="w-full bg-gray-800 text-white py-8">
|
||||
<div class="container mx-auto px-6">
|
||||
<div class="grid grid-cols-1 md:grid-cols-4 gap-8 mb-6">
|
||||
<div>
|
||||
<h3 class="text-lg font-medium mb-4">关于我们</h3>
|
||||
<ul class="space-y-2 text-sm text-gray-300">
|
||||
<li><a href="#" class="hover:text-white">公司简介</a></li>
|
||||
<li><a href="#" class="hover:text-white">发展历程</a></li>
|
||||
<li><a href="#" class="hover:text-white">企业文化</a></li>
|
||||
<li><a href="#" class="hover:text-white">团队介绍</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-lg font-medium mb-4">帮助中心</h3>
|
||||
<ul class="space-y-2 text-sm text-gray-300">
|
||||
<li><a href="#" class="hover:text-white">使用指南</a></li>
|
||||
<li><a href="#" class="hover:text-white">常见问题</a></li>
|
||||
<li><a href="#" class="hover:text-white">视频教程</a></li>
|
||||
<li><a href="#" class="hover:text-white">在线客服</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-lg font-medium mb-4">联系我们</h3>
|
||||
<ul class="space-y-2 text-sm text-gray-300">
|
||||
<li><i class="fas fa-map-marker-alt fa-icon mr-2"></i> 北京市海淀区中关村南大街5号</li>
|
||||
<li><i class="fas fa-phone fa-icon mr-2"></i> 400-888-8888</li>
|
||||
<li><i class="fas fa-envelope fa-icon mr-2"></i> hr@company.com</li>
|
||||
<li><i class="fas fa-clock fa-icon mr-2"></i> 周一至周五 9:00-18:00</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-lg font-medium mb-4">关注我们</h3>
|
||||
<div class="flex space-x-4 mb-4">
|
||||
<a href="#" class="w-8 h-8 bg-gray-700 rounded-full flex items-center justify-center hover:bg-primary">
|
||||
<i class="fab fa-weixin fa-icon"></i>
|
||||
</a>
|
||||
<a href="#" class="w-8 h-8 bg-gray-700 rounded-full flex items-center justify-center hover:bg-primary">
|
||||
<i class="fab fa-weibo fa-icon"></i>
|
||||
</a>
|
||||
<a href="#" class="w-8 h-8 bg-gray-700 rounded-full flex items-center justify-center hover:bg-primary">
|
||||
<i class="fab fa-linkedin-in fa-icon"></i>
|
||||
</a>
|
||||
<a href="#" class="w-8 h-8 bg-gray-700 rounded-full flex items-center justify-center hover:bg-primary">
|
||||
<i class="fab fa-github fa-icon"></i>
|
||||
</a>
|
||||
</div>
|
||||
<p class="text-sm text-gray-300">订阅我们的新闻通讯</p>
|
||||
<div class="mt-2 flex">
|
||||
<input type="email" placeholder="您的邮箱" class="py-2 px-3 text-sm rounded-l-md border-none focus:outline-none focus:ring-1 focus:ring-primary w-full">
|
||||
<button class="bg-primary text-white px-3 py-2 rounded-r-md hover:bg-opacity-90">
|
||||
<i class="fas fa-paper-plane fa-icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pt-6 border-t border-gray-700 text-center text-sm text-gray-400">
|
||||
<p>© 2023 人力管理系统 版权所有 | 京ICP备12345678号-1 | 京公网安备11010802012345号</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,566 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>人力资源管理系统</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Pacifico&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#2D5CF6',
|
||||
secondary: '#F5F6FA'
|
||||
},
|
||||
borderRadius: {
|
||||
'none': '0px',
|
||||
'sm': '2px',
|
||||
DEFAULT: '4px',
|
||||
'md': '8px',
|
||||
'lg': '12px',
|
||||
'xl': '16px',
|
||||
'2xl': '20px',
|
||||
'3xl': '24px',
|
||||
'full': '9999px',
|
||||
'button': '4px'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.marquee {
|
||||
animation: marquee 15s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes marquee {
|
||||
0% {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
}
|
||||
|
||||
.tree-item {
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.tree-item:hover {
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
|
||||
.table-row:hover {
|
||||
background-color: #f0f4ff;
|
||||
}
|
||||
|
||||
.search-input:focus {
|
||||
outline: none;
|
||||
box-shadow: 0 0 0 2px rgba(45, 92, 246, 0.2);
|
||||
}
|
||||
|
||||
.dropdown:hover .dropdown-menu {
|
||||
display: block;
|
||||
}
|
||||
|
||||
i.fa-icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="bg-gray-50 min-h-screen flex flex-col">
|
||||
<!-- 顶部导航栏 -->
|
||||
<!-- <header class="w-full bg-primary text-white">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="flex items-center justify-between h-16">
|
||||
<div class="flex items-center">
|
||||
<span class="font-['Pacifico'] text-xl">人力</span>
|
||||
</div>
|
||||
<nav class="hidden md:flex space-x-6">
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">多维统计</a>
|
||||
<a href="#" class="text-sm font-medium">人员管理</a>
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">组织管理</a>
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">考勤管理</a>
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">绩效管理</a>
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">薪酬管理</a>
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">知识库</a>
|
||||
<a href="#" class="text-sm hover:text-gray-200 transition">后台管理</a>
|
||||
</nav>
|
||||
<div class="flex items-center space-x-4">
|
||||
<div class="relative">
|
||||
<input type="text" placeholder="搜索..."
|
||||
class="search-input bg-white bg-opacity-20 text-sm rounded-button pl-8 pr-4 py-1 w-40 focus:w-56 transition-all duration-300 placeholder-white">
|
||||
<i
|
||||
class="fas fa-search absolute left-2 top-1/2 transform -translate-y-1/2 text-white text-sm"></i>
|
||||
</div>
|
||||
<button
|
||||
class="bg-white bg-opacity-20 hover:bg-opacity-30 text-white text-xs px-3 py-1 rounded-button flex items-center space-x-1 transition">
|
||||
<i class="fas fa-robot text-sm"></i>
|
||||
<span>AI助手</span>
|
||||
</button>
|
||||
<div class="dropdown relative">
|
||||
<button class="flex items-center space-x-1">
|
||||
<div class="w-8 h-8 rounded-full bg-white bg-opacity-20 flex items-center justify-center">
|
||||
<i class="fas fa-user text-sm"></i>
|
||||
</div>
|
||||
</button>
|
||||
<div class="dropdown-menu absolute right-0 mt-2 w-48 bg-white rounded-md shadow-lg z-10 hidden">
|
||||
<div class="py-1">
|
||||
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">个人中心</a>
|
||||
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">系统设置</a>
|
||||
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">退出登录</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-yellow-50 h-10 flex items-center overflow-hidden">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="relative">
|
||||
<div class="marquee whitespace-nowrap text-xs text-gray-900">
|
||||
<span class="inline-block mr-8">【公告】2023年度绩效考核工作将于12月1日正式启动</span>
|
||||
<span class="inline-block mr-8">【通知】关于2024年春节放假安排的通知</span>
|
||||
<span class="inline-block mr-8">【提醒】请各部门及时更新员工信息</span>
|
||||
<span class="inline-block">【培训】新员工入职培训将于下周一举行</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header> -->
|
||||
<!-- 主内容区 -->
|
||||
<main class="flex-1 container mx-auto px-4 py-6">
|
||||
<div class="flex">
|
||||
<!-- 左侧组织架构树 -->
|
||||
<div class="w-1/5 pr-4">
|
||||
<div class="bg-white rounded-md shadow p-4 h-full">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<h3 class="text-sm font-medium">组织架构</h3>
|
||||
<button class="text-primary text-xs hover:text-primary-dark">
|
||||
<i class="fas fa-sync-alt fa-icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="space-y-1">
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md hover:bg-secondary">
|
||||
<div class="flex items-center">
|
||||
<i class="fas fa-building fa-icon mr-2 text-gray-500"></i>
|
||||
<span class="text-sm">集团公司</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pl-6">
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md hover:bg-secondary">
|
||||
<div class="flex items-center">
|
||||
<i class="fas fa-sitemap fa-icon mr-2 text-gray-500"></i>
|
||||
<span class="text-sm">人力资源部</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pl-6">
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md hover:bg-secondary">
|
||||
<div class="flex items-center">
|
||||
<i class="fas fa-users fa-icon mr-2 text-gray-500"></i>
|
||||
<span class="text-sm">招聘组</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md hover:bg-secondary">
|
||||
<div class="flex items-center">
|
||||
<i class="fas fa-chart-line fa-icon mr-2 text-gray-500"></i>
|
||||
<span class="text-sm">绩效组</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md hover:bg-secondary">
|
||||
<div class="flex items-center">
|
||||
<i class="fas fa-money-bill-wave fa-icon mr-2 text-gray-500"></i>
|
||||
<span class="text-sm">薪酬组</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md hover:bg-secondary">
|
||||
<div class="flex items-center">
|
||||
<i class="fas fa-sitemap fa-icon mr-2 text-gray-500"></i>
|
||||
<span class="text-sm">财务部</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md hover:bg-secondary">
|
||||
<div class="flex items-center">
|
||||
<i class="fas fa-sitemap fa-icon mr-2 text-gray-500"></i>
|
||||
<span class="text-sm">技术研发中心</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧内容区 -->
|
||||
<div class="w-4/5">
|
||||
<div class="bg-white rounded-md shadow p-6">
|
||||
<!-- 筛选区 -->
|
||||
<div class="mb-6">
|
||||
<h2 class="text-lg font-medium mb-4">人员筛选</h2>
|
||||
<div class="grid grid-cols-4 gap-4">
|
||||
<div>
|
||||
<label class="block text-sm text-gray-600 mb-1">姓名</label>
|
||||
<input type="text"
|
||||
class="w-full border border-gray-300 rounded-button px-3 py-1 text-sm focus:border-primary focus:ring-1 focus:ring-primary">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm text-gray-600 mb-1">电话</label>
|
||||
<input type="text"
|
||||
class="w-full border border-gray-300 rounded-button px-3 py-1 text-sm focus:border-primary focus:ring-1 focus:ring-primary">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm text-gray-600 mb-1">身份证号</label>
|
||||
<input type="text"
|
||||
class="w-full border border-gray-300 rounded-button px-3 py-1 text-sm focus:border-primary focus:ring-1 focus:ring-primary">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm text-gray-600 mb-1">部门</label>
|
||||
<div class="relative">
|
||||
<select
|
||||
class="w-full border border-gray-300 rounded-button px-3 py-1 text-sm appearance-none bg-white">
|
||||
<option>全部部门</option>
|
||||
<option>人力资源部</option>
|
||||
<option>财务部</option>
|
||||
<option>技术研发中心</option>
|
||||
</select>
|
||||
<div class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
||||
<i class="fas fa-chevron-down fa-icon text-gray-400"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm text-gray-600 mb-1">性别</label>
|
||||
<div class="flex space-x-2">
|
||||
<label class="inline-flex items-center">
|
||||
<input type="radio" name="gender" class="text-primary focus:ring-primary">
|
||||
<span class="ml-1 text-sm">男</span>
|
||||
</label>
|
||||
<label class="inline-flex items-center">
|
||||
<input type="radio" name="gender" class="text-primary focus:ring-primary">
|
||||
<span class="ml-1 text-sm">女</span>
|
||||
</label>
|
||||
<label class="inline-flex items-center">
|
||||
<input type="radio" name="gender" class="text-primary focus:ring-primary">
|
||||
<span class="ml-1 text-sm">不限</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm text-gray-600 mb-1">年龄范围</label>
|
||||
<div class="flex space-x-2">
|
||||
<input type="number" placeholder="最小"
|
||||
class="w-1/2 border border-gray-300 rounded-button px-3 py-1 text-sm">
|
||||
<input type="number" placeholder="最大"
|
||||
class="w-1/2 border border-gray-300 rounded-button px-3 py-1 text-sm">
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm text-gray-600 mb-1">绩效状态</label>
|
||||
<div class="relative">
|
||||
<select
|
||||
class="w-full border border-gray-300 rounded-button px-3 py-1 text-sm appearance-none bg-white">
|
||||
<option>全部状态</option>
|
||||
<option>新建</option>
|
||||
<option>已审批</option>
|
||||
<option>审批中</option>
|
||||
<option>已确认</option>
|
||||
</select>
|
||||
<div class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
||||
<i class="fas fa-chevron-down fa-icon text-gray-400"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-end">
|
||||
<button
|
||||
class="bg-primary hover:bg-primary-dark text-white px-4 py-1 rounded-button text-sm flex items-center">
|
||||
<i class="fas fa-search fa-icon mr-1"></i>
|
||||
<span>搜索</span>
|
||||
</button>
|
||||
<button
|
||||
class="ml-2 border border-gray-300 hover:bg-gray-50 px-4 py-1 rounded-button text-sm">
|
||||
重置
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 操作按钮区 -->
|
||||
<div class="flex justify-between items-center mb-4">
|
||||
<h2 class="text-lg font-medium">人员绩效列表</h2>
|
||||
<div class="flex space-x-2">
|
||||
<button
|
||||
class="bg-primary hover:bg-primary-dark text-white px-3 py-1 rounded-button text-sm flex items-center">
|
||||
<i class="fas fa-plus fa-icon mr-1"></i>
|
||||
<span>新增</span>
|
||||
</button>
|
||||
<button
|
||||
class="border border-gray-300 hover:bg-gray-50 px-3 py-1 rounded-button text-sm flex items-center">
|
||||
<i class="fas fa-download fa-icon mr-1"></i>
|
||||
<span>导出</span>
|
||||
</button>
|
||||
<button
|
||||
class="border border-gray-300 hover:bg-gray-50 px-3 py-1 rounded-button text-sm flex items-center">
|
||||
<i class="fas fa-print fa-icon mr-1"></i>
|
||||
<span>打印</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 表格区 -->
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th scope="col"
|
||||
class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
序号</th>
|
||||
<th scope="col"
|
||||
class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
姓名</th>
|
||||
<th scope="col"
|
||||
class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
性别</th>
|
||||
<th scope="col"
|
||||
class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
年龄</th>
|
||||
<th scope="col"
|
||||
class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
部门</th>
|
||||
<th scope="col"
|
||||
class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
职位</th>
|
||||
<th scope="col"
|
||||
class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
绩效总分</th>
|
||||
<th scope="col"
|
||||
class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
绩效状态</th>
|
||||
<th scope="col"
|
||||
class="px-4 py-2 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">1</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm font-medium">张明远</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">男</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">32</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">人力资源部</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">招聘主管</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">92.5</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">
|
||||
<span
|
||||
class="px-2 py-1 text-xs rounded-full bg-green-100 text-green-800">已确认</span>
|
||||
</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">
|
||||
<button class="text-primary hover:text-primary-dark mr-2">
|
||||
<i class="fas fa-edit fa-icon"></i>
|
||||
</button>
|
||||
<button class="text-red-500 hover:text-red-700">
|
||||
<i class="fas fa-trash-alt fa-icon"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">2</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm font-medium">李思雨</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">女</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">28</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">财务部</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">会计</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">88.0</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">
|
||||
<span
|
||||
class="px-2 py-1 text-xs rounded-full bg-blue-100 text-blue-800">审批中</span>
|
||||
</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">
|
||||
<button class="text-primary hover:text-primary-dark mr-2">
|
||||
<i class="fas fa-edit fa-icon"></i>
|
||||
</button>
|
||||
<button class="text-red-500 hover:text-red-700">
|
||||
<i class="fas fa-trash-alt fa-icon"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">3</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm font-medium">王建国</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">男</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">45</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">技术研发中心</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">技术总监</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">95.5</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">
|
||||
<span
|
||||
class="px-2 py-1 text-xs rounded-full bg-green-100 text-green-800">已确认</span>
|
||||
</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">
|
||||
<button class="text-primary hover:text-primary-dark mr-2">
|
||||
<i class="fas fa-edit fa-icon"></i>
|
||||
</button>
|
||||
<button class="text-red-500 hover:text-red-700">
|
||||
<i class="fas fa-trash-alt fa-icon"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">4</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm font-medium">赵雪</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">女</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">26</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">人力资源部</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">薪酬专员</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">85.0</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">
|
||||
<span
|
||||
class="px-2 py-1 text-xs rounded-full bg-yellow-100 text-yellow-800">已审批</span>
|
||||
</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">
|
||||
<button class="text-primary hover:text-primary-dark mr-2">
|
||||
<i class="fas fa-edit fa-icon"></i>
|
||||
</button>
|
||||
<button class="text-red-500 hover:text-red-700">
|
||||
<i class="fas fa-trash-alt fa-icon"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">5</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm font-medium">陈志强</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">男</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">35</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">技术研发中心</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">高级工程师</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">90.5</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">
|
||||
<span class="px-2 py-1 text-xs rounded-full bg-gray-100 text-gray-800">新建</span>
|
||||
</td>
|
||||
<td class="px-4 py-2 whitespace-nowrap text-sm">
|
||||
<button class="text-primary hover:text-primary-dark mr-2">
|
||||
<i class="fas fa-edit fa-icon"></i>
|
||||
</button>
|
||||
<button class="text-red-500 hover:text-red-700">
|
||||
<i class="fas fa-trash-alt fa-icon"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<!-- 分页区 -->
|
||||
<div class="flex items-center justify-between mt-4">
|
||||
<div class="text-sm text-gray-500">
|
||||
每页显示 <span class="font-medium">10</span> 条,当前 <span class="font-medium">1-10</span> 条,共
|
||||
<span class="font-medium">128</span> 条记录
|
||||
</div>
|
||||
<div class="flex space-x-1">
|
||||
<button
|
||||
class="px-3 py-1 border border-gray-300 rounded-button text-sm bg-white hover:bg-gray-50">
|
||||
<i class="fas fa-angle-left fa-icon"></i>
|
||||
</button>
|
||||
<button
|
||||
class="px-3 py-1 border border-gray-300 rounded-button text-sm bg-primary text-white">1</button>
|
||||
<button
|
||||
class="px-3 py-1 border border-gray-300 rounded-button text-sm bg-white hover:bg-gray-50">2</button>
|
||||
<button
|
||||
class="px-3 py-1 border border-gray-300 rounded-button text-sm bg-white hover:bg-gray-50">3</button>
|
||||
<button
|
||||
class="px-3 py-1 border border-gray-300 rounded-button text-sm bg-white hover:bg-gray-50">4</button>
|
||||
<button
|
||||
class="px-3 py-1 border border-gray-300 rounded-button text-sm bg-white hover:bg-gray-50">5</button>
|
||||
<button
|
||||
class="px-3 py-1 border border-gray-300 rounded-button text-sm bg-white hover:bg-gray-50">
|
||||
<i class="fas fa-angle-right fa-icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<!-- 页脚 -->
|
||||
<footer class="w-full bg-gray-800 text-white py-8">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="grid grid-cols-4 gap-8">
|
||||
<div>
|
||||
<h3 class="text-sm font-medium mb-4">关于我们</h3>
|
||||
<ul class="space-y-2 text-xs text-gray-300">
|
||||
<li><a href="#" class="hover:text-white">公司简介</a></li>
|
||||
<li><a href="#" class="hover:text-white">发展历程</a></li>
|
||||
<li><a href="#" class="hover:text-white">企业文化</a></li>
|
||||
<li><a href="#" class="hover:text-white">联系我们</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-medium mb-4">产品服务</h3>
|
||||
<ul class="space-y-2 text-xs text-gray-300">
|
||||
<li><a href="#" class="hover:text-white">人力资源管理系统</a></li>
|
||||
<li><a href="#" class="hover:text-white">薪酬管理系统</a></li>
|
||||
<li><a href="#" class="hover:text-white">绩效管理系统</a></li>
|
||||
<li><a href="#" class="hover:text-white">考勤管理系统</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-medium mb-4">帮助中心</h3>
|
||||
<ul class="space-y-2 text-xs text-gray-300">
|
||||
<li><a href="#" class="hover:text-white">使用指南</a></li>
|
||||
<li><a href="#" class="hover:text-white">常见问题</a></li>
|
||||
<li><a href="#" class="hover:text-white">更新日志</a></li>
|
||||
<li><a href="#" class="hover:text-white">API文档</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-medium mb-4">联系我们</h3>
|
||||
<ul class="space-y-2 text-xs text-gray-300">
|
||||
<li class="flex items-start">
|
||||
<i class="fas fa-map-marker-alt fa-icon mr-2 mt-1"></i>
|
||||
<span>北京市海淀区中关村软件园2号楼</span>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<i class="fas fa-phone fa-icon mr-2"></i>
|
||||
<span>400-888-8888</span>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<i class="fas fa-envelope fa-icon mr-2"></i>
|
||||
<span>contact@hrsystem.com</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-700 mt-8 pt-6 flex flex-col md:flex-row justify-between items-center">
|
||||
<div class="text-xs text-gray-400 mb-4 md:mb-0">
|
||||
© 2023 人力资源管理系统 版权所有
|
||||
</div>
|
||||
<div class="flex space-x-4">
|
||||
<a href="#" class="text-gray-400 hover:text-white">
|
||||
<i class="fab fa-weixin fa-icon"></i>
|
||||
</a>
|
||||
<a href="#" class="text-gray-400 hover:text-white">
|
||||
<i class="fab fa-weibo fa-icon"></i>
|
||||
</a>
|
||||
<a href="#" class="text-gray-400 hover:text-white">
|
||||
<i class="fab fa-github fa-icon"></i>
|
||||
</a>
|
||||
<a href="#" class="text-gray-400 hover:text-white">
|
||||
<i class="fab fa-linkedin-in fa-icon"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="text-xs text-gray-400 mt-4 md:mt-0">
|
||||
京ICP备12345678号-1
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -0,0 +1,738 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>人力管理系统 - 数据字典</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Pacifico&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#2D5CF6',
|
||||
secondary: '#F5F6FA'
|
||||
},
|
||||
borderRadius: {
|
||||
'none': '0px',
|
||||
'sm': '2px',
|
||||
DEFAULT: '4px',
|
||||
'md': '8px',
|
||||
'lg': '12px',
|
||||
'xl': '16px',
|
||||
'2xl': '20px',
|
||||
'3xl': '24px',
|
||||
'full': '9999px',
|
||||
'button': '4px'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.tree-item {
|
||||
padding-left: 20px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tree-item::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
border-left: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.tree-item:last-child::before {
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.tree-item::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 8px;
|
||||
top: 50%;
|
||||
width: 8px;
|
||||
border-bottom: 1px solid #e5e7eb;
|
||||
}
|
||||
|
||||
.scroll-container {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: #cbd5e1 #f1f5f9;
|
||||
}
|
||||
|
||||
.scroll-container::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
.scroll-container::-webkit-scrollbar-track {
|
||||
background: #f1f5f9;
|
||||
}
|
||||
|
||||
.scroll-container::-webkit-scrollbar-thumb {
|
||||
background-color: #cbd5e1;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.hover-card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
i.fa-icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="min-h-[1024px] bg-gray-50 flex flex-col">
|
||||
<!-- 顶部导航 -->
|
||||
<!-- <header class="bg-primary text-white shadow-md">
|
||||
<div class="container mx-auto px-6 py-3 flex items-center justify-between">
|
||||
<div class="flex items-center space-x-8">
|
||||
<a href="#" class="text-xl font-['Pacifico']">人力</a>
|
||||
<nav class="hidden md:flex space-x-6 text-sm">
|
||||
<a href="#" class="hover:bg-white/20 px-2 py-1 rounded-button transition">多维统计</a>
|
||||
<a href="#" class="hover:bg-white/20 px-2 py-1 rounded-button transition">人员管理</a>
|
||||
<a href="#" class="hover:bg-white/20 px-2 py-1 rounded-button transition">组织管理</a>
|
||||
<a href="#" class="hover:bg-white/20 px-2 py-1 rounded-button transition">考勤管理</a>
|
||||
<a href="#" class="hover:bg-white/20 px-2 py-1 rounded-button transition">绩效管理</a>
|
||||
<a href="#" class="hover:bg-white/20 px-2 py-1 rounded-button transition">薪酬管理</a>
|
||||
<a href="#" class="hover:bg-white/20 px-2 py-1 rounded-button transition">知识库</a>
|
||||
<a href="#" class="hover:bg-white/20 px-2 py-1 rounded-button transition">后台管理</a>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
<div class="relative">
|
||||
<input type="text" placeholder="搜索..."
|
||||
class="bg-white/20 text-white placeholder-white/70 text-sm rounded-button px-3 py-1 pl-8 w-40 focus:w-60 transition-all duration-300 focus:outline-none focus:ring-1 focus:ring-white/50">
|
||||
<i
|
||||
class="fa-icon fa-solid fa-magnifying-glass absolute left-2 top-1/2 transform -translate-y-1/2 text-white/70 text-xs"></i>
|
||||
</div>
|
||||
<button
|
||||
class="bg-white/10 hover:bg-white/20 rounded-button px-3 py-1 text-sm flex items-center space-x-1 transition">
|
||||
<i class="fa-icon fa-solid fa-robot text-xs"></i>
|
||||
<span>AI 助手</span>
|
||||
</button>
|
||||
<div class="relative">
|
||||
<img src="https://mastergo.com/ai/api/search-image?query=professional20business20profile20photo20of20a20young20asian20male20executive20with20white20background&width=32&height=32&orientation=squarish&flag=a6d20992702c7a888c93eb051f248a43"
|
||||
alt="用户头像" class="w-8 h-8 rounded-full object-cover cursor-pointer">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header> -->
|
||||
<!-- 主内容区域 -->
|
||||
<main class="flex-grow container mx-auto px-6 py-8">
|
||||
<div class="flex flex-col space-y-6">
|
||||
<!-- 面包屑导航 -->
|
||||
<!-- <div class="flex items-center text-sm text-gray-600">
|
||||
<a href="#" class="hover:text-primary">首页</a>
|
||||
<i class="fa-icon fa-solid fa-chevron-right mx-2 text-xs"></i>
|
||||
<a href="#" class="hover:text-primary">系统管理</a>
|
||||
<i class="fa-icon fa-solid fa-chevron-right mx-2 text-xs"></i>
|
||||
<span class="text-gray-800">数据字典管理</span>
|
||||
</div> -->
|
||||
<!-- 页面标题和操作按钮 -->
|
||||
<div class="flex justify-between items-center">
|
||||
<h1 class="text-2xl font-bold text-gray-800">数据字典管理</h1>
|
||||
<div class="flex space-x-3">
|
||||
<button
|
||||
class="bg-primary hover:bg-blue-700 text-white rounded-button px-4 py-2 text-sm flex items-center space-x-2 transition">
|
||||
<i class="fa-icon fa-solid fa-plus text-xs"></i>
|
||||
<span>新增元数据域</span>
|
||||
</button>
|
||||
<button
|
||||
class="bg-white border border-gray-300 hover:bg-gray-50 text-gray-700 rounded-button px-4 py-2 text-sm flex items-center space-x-2 transition">
|
||||
<i class="fa-icon fa-solid fa-download text-xs"></i>
|
||||
<span>导出配置</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 数据字典内容区域 -->
|
||||
<div class="bg-white rounded-lg shadow-sm border border-gray-200 overflow-hidden">
|
||||
<div class="flex h-[1200px]">
|
||||
<!-- 左侧树形结构 -->
|
||||
<div class="w-1/4 border-r border-gray-200 overflow-y-auto scroll-container">
|
||||
<div class="p-4 space-y-2">
|
||||
<div class="flex items-center justify-between">
|
||||
<h3 class="font-medium text-gray-700">员工模型</h3>
|
||||
<button class="text-gray-400 hover:text-gray-600">
|
||||
<i class="fa-icon fa-solid fa-ellipsis-vertical text-xs"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-2 space-y-1">
|
||||
<!-- 树形结构项 -->
|
||||
<div class="tree-item">
|
||||
<div
|
||||
class="flex items-center justify-between py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<div class="flex items-center space-x-2">
|
||||
<i class="fa-icon fa-solid fa-folder text-yellow-400 text-sm"></i>
|
||||
<span class="text-sm">基础信息</span>
|
||||
</div>
|
||||
<i class="fa-icon fa-solid fa-chevron-down text-gray-400 text-xs"></i>
|
||||
</div>
|
||||
<div class="ml-4 mt-1 space-y-1">
|
||||
<div
|
||||
class="flex items-center py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<i class="fa-icon fa-solid fa-file text-blue-400 text-sm mr-2"></i>
|
||||
<span class="text-sm">员工编号</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<i class="fa-icon fa-solid fa-file text-blue-400 text-sm mr-2"></i>
|
||||
<span class="text-sm">姓名</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<i class="fa-icon fa-solid fa-file text-blue-400 text-sm mr-2"></i>
|
||||
<span class="text-sm">性别</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tree-item">
|
||||
<div
|
||||
class="flex items-center justify-between py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<div class="flex items-center space-x-2">
|
||||
<i class="fa-icon fa-solid fa-folder text-yellow-400 text-sm"></i>
|
||||
<span class="text-sm">技术职务</span>
|
||||
</div>
|
||||
<i class="fa-icon fa-solid fa-chevron-right text-gray-400 text-xs"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tree-item">
|
||||
<div
|
||||
class="flex items-center justify-between py-1 px-2 rounded hover:bg-gray-100 cursor-pointer bg-blue-50">
|
||||
<div class="flex items-center space-x-2">
|
||||
<i class="fa-icon fa-solid fa-folder-open text-yellow-400 text-sm"></i>
|
||||
<span class="text-sm font-medium text-primary">绩效参数</span>
|
||||
</div>
|
||||
<i class="fa-icon fa-solid fa-chevron-down text-gray-400 text-xs"></i>
|
||||
</div>
|
||||
<div class="ml-4 mt-1 space-y-1">
|
||||
<div
|
||||
class="flex items-center py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<i class="fa-icon fa-solid fa-file text-blue-400 text-sm mr-2"></i>
|
||||
<span class="text-sm">代码量</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<i class="fa-icon fa-solid fa-file text-blue-400 text-sm mr-2"></i>
|
||||
<span class="text-sm">文档字数</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<i class="fa-icon fa-solid fa-file text-blue-400 text-sm mr-2"></i>
|
||||
<span class="text-sm">出勤时长</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<i class="fa-icon fa-solid fa-file text-blue-400 text-sm mr-2"></i>
|
||||
<span class="text-sm">项目金额</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<i class="fa-icon fa-solid fa-file text-blue-400 text-sm mr-2"></i>
|
||||
<span class="text-sm">培训时长</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<i class="fa-icon fa-solid fa-file text-blue-400 text-sm mr-2"></i>
|
||||
<span class="text-sm">会议次数</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<i class="fa-icon fa-solid fa-file text-blue-400 text-sm mr-2"></i>
|
||||
<span class="text-sm">会议时长</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<i class="fa-icon fa-solid fa-file text-blue-400 text-sm mr-2"></i>
|
||||
<span class="text-sm">千行 bug 数</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<i class="fa-icon fa-solid fa-file text-blue-400 text-sm mr-2"></i>
|
||||
<span class="text-sm">运维响应时间</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex items-center py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<i class="fa-icon fa-solid fa-file text-blue-400 text-sm mr-2"></i>
|
||||
<span class="text-sm">员工满意度</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tree-item">
|
||||
<div
|
||||
class="flex items-center justify-between py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<div class="flex items-center space-x-2">
|
||||
<i class="fa-icon fa-solid fa-folder text-yellow-400 text-sm"></i>
|
||||
<span class="text-sm">联系方式</span>
|
||||
</div>
|
||||
<i class="fa-icon fa-solid fa-chevron-right text-gray-400 text-xs"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tree-item">
|
||||
<div
|
||||
class="flex items-center justify-between py-1 px-2 rounded hover:bg-gray-100 cursor-pointer">
|
||||
<div class="flex items-center space-x-2">
|
||||
<i class="fa-icon fa-solid fa-folder text-yellow-400 text-sm"></i>
|
||||
<span class="text-sm">其他信息</span>
|
||||
</div>
|
||||
<i class="fa-icon fa-solid fa-chevron-right text-gray-400 text-xs"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧属性配置面板 -->
|
||||
<div class="w-3/4 overflow-y-auto scroll-container">
|
||||
<div class="p-6">
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h2 class="text-lg font-semibold text-gray-800">绩效参数属性配置</h2>
|
||||
<button
|
||||
class="bg-primary hover:bg-blue-700 text-white rounded-button px-3 py-1 text-sm flex items-center space-x-2 transition">
|
||||
<i class="fa-icon fa-solid fa-plus text-xs"></i>
|
||||
<span>新增属性</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="bg-gray-50 rounded-lg p-4 mb-6">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">元数据域名称</label>
|
||||
<input type="text" value="绩效参数"
|
||||
class="w-full border border-gray-300 rounded-button px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">元数据域编码</label>
|
||||
<input type="text" value="performance_params"
|
||||
class="w-full border border-gray-300 rounded-button px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary">
|
||||
</div>
|
||||
<div class="col-span-2">
|
||||
<label class="block text-sm font-medium text-gray-700 mb-1">描述</label>
|
||||
<textarea
|
||||
class="w-full border border-gray-300 rounded-button px-3 py-2 text-sm focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary"
|
||||
rows="2">用于记录员工各项绩效指标的参数集合</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th scope="col"
|
||||
class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
属性名称</th>
|
||||
<th scope="col"
|
||||
class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
编码</th>
|
||||
<th scope="col"
|
||||
class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
数据类型</th>
|
||||
<th scope="col"
|
||||
class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
单位</th>
|
||||
<th scope="col"
|
||||
class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
必填</th>
|
||||
<th scope="col"
|
||||
class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
|
||||
操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-200">
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">
|
||||
代码量</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">code_amount
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<select
|
||||
class="border border-gray-300 rounded-button px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary">
|
||||
<option>数字</option>
|
||||
<option>文本</option>
|
||||
<option>日期</option>
|
||||
<option selected>列表</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">行</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<input type="checkbox" checked
|
||||
class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded">
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<button class="text-blue-600 hover:text-blue-900 mr-2">
|
||||
<i class="fa-icon fa-solid fa-pen text-xs"></i>
|
||||
</button>
|
||||
<button class="text-red-600 hover:text-red-900">
|
||||
<i class="fa-icon fa-solid fa-trash text-xs"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">
|
||||
文档字数</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">doc_words</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<select
|
||||
class="border border-gray-300 rounded-button px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary">
|
||||
<option>数字</option>
|
||||
<option>文本</option>
|
||||
<option>日期</option>
|
||||
<option selected>列表</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">字</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<input type="checkbox" checked
|
||||
class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded">
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<button class="text-blue-600 hover:text-blue-900 mr-2">
|
||||
<i class="fa-icon fa-solid fa-pen text-xs"></i>
|
||||
</button>
|
||||
<button class="text-red-600 hover:text-red-900">
|
||||
<i class="fa-icon fa-solid fa-trash text-xs"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">
|
||||
出勤时长</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
attendance_hours</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<select
|
||||
class="border border-gray-300 rounded-button px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary">
|
||||
<option>数字</option>
|
||||
<option>文本</option>
|
||||
<option>日期</option>
|
||||
<option selected>列表</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">小时</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<input type="checkbox" checked
|
||||
class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded">
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<button class="text-blue-600 hover:text-blue-900 mr-2">
|
||||
<i class="fa-icon fa-solid fa-pen text-xs"></i>
|
||||
</button>
|
||||
<button class="text-red-600 hover:text-red-900">
|
||||
<i class="fa-icon fa-solid fa-trash text-xs"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">
|
||||
项目金额</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">project_amount
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<select
|
||||
class="border border-gray-300 rounded-button px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary">
|
||||
<option>数字</option>
|
||||
<option>文本</option>
|
||||
<option>日期</option>
|
||||
<option selected>列表</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">元</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<input type="checkbox"
|
||||
class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded">
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<button class="text-blue-600 hover:text-blue-900 mr-2">
|
||||
<i class="fa-icon fa-solid fa-pen text-xs"></i>
|
||||
</button>
|
||||
<button class="text-red-600 hover:text-red-900">
|
||||
<i class="fa-icon fa-solid fa-trash text-xs"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">
|
||||
培训时长</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">training_hours
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<select
|
||||
class="border border-gray-300 rounded-button px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary">
|
||||
<option>数字</option>
|
||||
<option>文本</option>
|
||||
<option>日期</option>
|
||||
<option selected>列表</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">小时</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<input type="checkbox"
|
||||
class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded">
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<button class="text-blue-600 hover:text-blue-900 mr-2">
|
||||
<i class="fa-icon fa-solid fa-pen text-xs"></i>
|
||||
</button>
|
||||
<button class="text-red-600 hover:text-red-900">
|
||||
<i class="fa-icon fa-solid fa-trash text-xs"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">
|
||||
会议次数</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">meeting_count
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<select
|
||||
class="border border-gray-300 rounded-button px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary">
|
||||
<option>数字</option>
|
||||
<option>文本</option>
|
||||
<option>日期</option>
|
||||
<option selected>列表</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">次</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<input type="checkbox" checked
|
||||
class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded">
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<button class="text-blue-600 hover:text-blue-900 mr-2">
|
||||
<i class="fa-icon fa-solid fa-pen text-xs"></i>
|
||||
</button>
|
||||
<button class="text-red-600 hover:text-red-900">
|
||||
<i class="fa-icon fa-solid fa-trash text-xs"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">
|
||||
会议时长</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">meeting_hours
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<select
|
||||
class="border border-gray-300 rounded-button px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary">
|
||||
<option>数字</option>
|
||||
<option>文本</option>
|
||||
<option>日期</option>
|
||||
<option selected>列表</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">分钟</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<input type="checkbox"
|
||||
class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded">
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<button class="text-blue-600 hover:text-blue-900 mr-2">
|
||||
<i class="fa-icon fa-solid fa-pen text-xs"></i>
|
||||
</button>
|
||||
<button class="text-red-600 hover:text-red-900">
|
||||
<i class="fa-icon fa-solid fa-trash text-xs"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">千行
|
||||
bug 数</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">bug_count</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<select
|
||||
class="border border-gray-300 rounded-button px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary">
|
||||
<option>数字</option>
|
||||
<option>文本</option>
|
||||
<option>日期</option>
|
||||
<option selected>列表</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">个/千行</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<input type="checkbox" checked
|
||||
class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded">
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<button class="text-blue-600 hover:text-blue-900 mr-2">
|
||||
<i class="fa-icon fa-solid fa-pen text-xs"></i>
|
||||
</button>
|
||||
<button class="text-red-600 hover:text-red-900">
|
||||
<i class="fa-icon fa-solid fa-trash text-xs"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">
|
||||
运维响应时间</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">response_time
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<select
|
||||
class="border border-gray-300 rounded-button px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary">
|
||||
<option>数字</option>
|
||||
<option>文本</option>
|
||||
<option>日期</option>
|
||||
<option selected>列表</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">分钟</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<input type="checkbox" checked
|
||||
class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded">
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<button class="text-blue-600 hover:text-blue-900 mr-2">
|
||||
<i class="fa-icon fa-solid fa-pen text-xs"></i>
|
||||
</button>
|
||||
<button class="text-red-600 hover:text-red-900">
|
||||
<i class="fa-icon fa-solid fa-trash text-xs"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm font-medium text-gray-900">
|
||||
员工满意度</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">satisfaction
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<select
|
||||
class="border border-gray-300 rounded-button px-2 py-1 text-sm focus:outline-none focus:ring-1 focus:ring-primary focus:border-primary">
|
||||
<option>数字</option>
|
||||
<option>文本</option>
|
||||
<option>日期</option>
|
||||
<option selected>列表</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">分</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<input type="checkbox"
|
||||
class="h-4 w-4 text-primary focus:ring-primary border-gray-300 rounded">
|
||||
</td>
|
||||
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
||||
<button class="text-blue-600 hover:text-blue-900 mr-2">
|
||||
<i class="fa-icon fa-solid fa-pen text-xs"></i>
|
||||
</button>
|
||||
<button class="text-red-600 hover:text-red-900">
|
||||
<i class="fa-icon fa-solid fa-trash text-xs"></i>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mt-6 flex items-center justify-between">
|
||||
<div class="text-sm text-gray-500">
|
||||
显示 <span class="font-medium">1</span> 到 <span class="font-medium">10</span> 条,共
|
||||
<span class="font-medium">10</span> 条记录
|
||||
</div>
|
||||
<div class="flex space-x-1">
|
||||
<button
|
||||
class="px-3 py-1 border border-gray-300 rounded-button text-sm text-gray-700 bg-white hover:bg-gray-50">
|
||||
上一页
|
||||
</button>
|
||||
<button
|
||||
class="px-3 py-1 border border-primary bg-primary text-white rounded-button text-sm">
|
||||
1
|
||||
</button>
|
||||
<button
|
||||
class="px-3 py-1 border border-gray-300 rounded-button text-sm text-gray-700 bg-white hover:bg-gray-50">
|
||||
2
|
||||
</button>
|
||||
<button
|
||||
class="px-3 py-1 border border-gray-300 rounded-button text-sm text-gray-700 bg-white hover:bg-gray-50">
|
||||
下一页
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<!-- 页脚 -->
|
||||
<footer class="w-full bg-gray-800 text-white py-8">
|
||||
<div class="container mx-auto px-4">
|
||||
<div class="grid grid-cols-4 gap-8">
|
||||
<div>
|
||||
<h3 class="text-sm font-medium mb-4">关于我们</h3>
|
||||
<ul class="space-y-2 text-xs text-gray-300">
|
||||
<li><a href="#" class="hover:text-white">公司简介</a></li>
|
||||
<li><a href="#" class="hover:text-white">发展历程</a></li>
|
||||
<li><a href="#" class="hover:text-white">企业文化</a></li>
|
||||
<li><a href="#" class="hover:text-white">联系我们</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-medium mb-4">产品服务</h3>
|
||||
<ul class="space-y-2 text-xs text-gray-300">
|
||||
<li><a href="#" class="hover:text-white">人力资源管理系统</a></li>
|
||||
<li><a href="#" class="hover:text-white">薪酬管理系统</a></li>
|
||||
<li><a href="#" class="hover:text-white">绩效管理系统</a></li>
|
||||
<li><a href="#" class="hover:text-white">考勤管理系统</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-medium mb-4">帮助中心</h3>
|
||||
<ul class="space-y-2 text-xs text-gray-300">
|
||||
<li><a href="#" class="hover:text-white">使用指南</a></li>
|
||||
<li><a href="#" class="hover:text-white">常见问题</a></li>
|
||||
<li><a href="#" class="hover:text-white">更新日志</a></li>
|
||||
<li><a href="#" class="hover:text-white">API文档</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-sm font-medium mb-4">联系我们</h3>
|
||||
<ul class="space-y-2 text-xs text-gray-300">
|
||||
<li class="flex items-start">
|
||||
<i class="fas fa-map-marker-alt fa-icon mr-2 mt-1"></i>
|
||||
<span>北京市海淀区中关村软件园2号楼</span>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<i class="fas fa-phone fa-icon mr-2"></i>
|
||||
<span>400-888-8888</span>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<i class="fas fa-envelope fa-icon mr-2"></i>
|
||||
<span>contact@hrsystem.com</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-700 mt-8 pt-6 flex flex-col md:flex-row justify-between items-center">
|
||||
<div class="text-xs text-gray-400 mb-4 md:mb-0">
|
||||
© 2023 人力资源管理系统 版权所有
|
||||
</div>
|
||||
<div class="flex space-x-4">
|
||||
<a href="#" class="text-gray-400 hover:text-white">
|
||||
<i class="fab fa-weixin fa-icon"></i>
|
||||
</a>
|
||||
<a href="#" class="text-gray-400 hover:text-white">
|
||||
<i class="fab fa-weibo fa-icon"></i>
|
||||
</a>
|
||||
<a href="#" class="text-gray-400 hover:text-white">
|
||||
<i class="fab fa-github fa-icon"></i>
|
||||
</a>
|
||||
<a href="#" class="text-gray-400 hover:text-white">
|
||||
<i class="fab fa-linkedin-in fa-icon"></i>
|
||||
</a>
|
||||
</div>
|
||||
<div class="text-xs text-gray-400 mt-4 md:mt-0">
|
||||
京ICP备12345678号-1
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -0,0 +1,366 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>人力资源管理系统</title>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Pacifico&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#2D5CF6',
|
||||
secondary: '#F5F6FA',
|
||||
},
|
||||
borderRadius: {
|
||||
'none': '0px',
|
||||
'sm': '2px',
|
||||
DEFAULT: '4px',
|
||||
'md': '8px',
|
||||
'lg': '12px',
|
||||
'xl': '16px',
|
||||
'2xl': '20px',
|
||||
'3xl': '24px',
|
||||
'full': '9999px',
|
||||
'button': '4px'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.fa-icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.scroll-container {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.scroll-container::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="min-h-[1024px] bg-secondary font-sans text-sm text-gray-800">
|
||||
|
||||
<!-- <header class="w-full h-[60px] bg-primary text-white fixed top-0 z-50 shadow-md">
|
||||
<div class="w-[1200px] h-full mx-auto flex items-center justify-between">
|
||||
|
||||
<div class="flex items-center">
|
||||
<span class="font-['Pacifico'] text-2xl mr-10">人力</span>
|
||||
</div>
|
||||
|
||||
|
||||
<nav class="flex-1 flex items-center">
|
||||
<ul class="flex space-x-6">
|
||||
<li><a href="#" class="hover:text-gray-200 transition">多维统计</a></li>
|
||||
<li><a href="#" class="hover:text-gray-200 transition">人员管理</a></li>
|
||||
<li><a href="#" class="hover:text-gray-200 transition">组织管理</a></li>
|
||||
<li><a href="#" class="hover:text-gray-200 transition font-semibold">考勤管理</a></li>
|
||||
<li><a href="#" class="hover:text-gray-200 transition">绩效管理</a></li>
|
||||
<li><a href="#" class="hover:text-gray-200 transition">薪酬管理</a></li>
|
||||
<li><a href="#" class="hover:text-gray-200 transition">知识库</a></li>
|
||||
<li><a href="#" class="hover:text-gray-200 transition">后台管理</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
|
||||
<div class="flex items-center space-x-4">
|
||||
|
||||
<div class="relative">
|
||||
<input type="text" placeholder="搜索..." class="pl-8 pr-3 py-1 rounded-button bg-white bg-opacity-20 text-white placeholder-white focus:outline-none focus:ring-1 focus:ring-white w-[180px]">
|
||||
<i class="fas fa-search absolute left-2 top-1/2 transform -translate-y-1/2 fa-icon"></i>
|
||||
</div>
|
||||
|
||||
|
||||
<button class="flex items-center space-x-1 bg-white bg-opacity-20 hover:bg-opacity-30 px-3 py-1 rounded-button transition">
|
||||
<i class="fas fa-robot fa-icon"></i>
|
||||
<span>AI助手</span>
|
||||
</button>
|
||||
|
||||
<div class="w-8 h-8 rounded-full bg-white flex items-center justify-center overflow-hidden">
|
||||
<i class="fas fa-user fa-icon text-primary"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header> -->
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<main class="w-[1200px] mx-auto px-4 py-6">
|
||||
<div class="flex space-x-4">
|
||||
<!-- 左侧组织架构树 -->
|
||||
<div class="w-1/5 bg-white rounded-md shadow-sm p-4">
|
||||
<h2 class="font-medium text-gray-700 mb-4">组织架构</h2>
|
||||
<div class="space-y-2">
|
||||
<div class="flex items-center space-x-2 cursor-pointer">
|
||||
<i class="fas fa-building fa-icon text-gray-500"></i>
|
||||
<span class="hover:text-primary">公司总部</span>
|
||||
</div>
|
||||
<div class="ml-6 space-y-2">
|
||||
<div class="flex items-center space-x-2 cursor-pointer">
|
||||
<i class="fas fa-users fa-icon text-gray-500"></i>
|
||||
<span class="hover:text-primary">人力资源部</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2 cursor-pointer">
|
||||
<i class="fas fa-users fa-icon text-gray-500"></i>
|
||||
<span class="hover:text-primary">财务部</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2 cursor-pointer">
|
||||
<i class="fas fa-users fa-icon text-gray-500"></i>
|
||||
<span class="hover:text-primary">技术研发部</span>
|
||||
</div>
|
||||
<div class="ml-6 space-y-2">
|
||||
<div class="flex items-center space-x-2 cursor-pointer">
|
||||
<i class="fas fa-user fa-icon text-gray-500"></i>
|
||||
<span class="hover:text-primary">前端开发组</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2 cursor-pointer">
|
||||
<i class="fas fa-user fa-icon text-gray-500"></i>
|
||||
<span class="hover:text-primary">后端开发组</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2 cursor-pointer">
|
||||
<i class="fas fa-user fa-icon text-gray-500"></i>
|
||||
<span class="hover:text-primary">测试组</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2 cursor-pointer">
|
||||
<i class="fas fa-users fa-icon text-gray-500"></i>
|
||||
<span class="hover:text-primary">产品部</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2 cursor-pointer">
|
||||
<i class="fas fa-users fa-icon text-gray-500"></i>
|
||||
<span class="hover:text-primary">市场部</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧考勤管理区 -->
|
||||
<div class="w-4/5 bg-white rounded-md shadow-sm p-4">
|
||||
<h2 class="font-medium text-gray-700 mb-4">考勤管理</h2>
|
||||
|
||||
<!-- 筛选区 -->
|
||||
<div class="grid grid-cols-4 gap-4 mb-6">
|
||||
<div>
|
||||
<label class="block text-gray-600 mb-1">员工ID</label>
|
||||
<input type="text" class="w-full border rounded-button px-3 py-1 focus:outline-none focus:ring-1 focus:ring-primary">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-gray-600 mb-1">员工姓名</label>
|
||||
<input type="text" class="w-full border rounded-button px-3 py-1 focus:outline-none focus:ring-1 focus:ring-primary">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-gray-600 mb-1">日期范围</label>
|
||||
<div class="relative">
|
||||
<input type="text" class="w-full border rounded-button px-3 py-1 focus:outline-none focus:ring-1 focus:ring-primary" placeholder="选择日期">
|
||||
<i class="fas fa-calendar-alt absolute right-2 top-1/2 transform -translate-y-1/2 fa-icon text-gray-400"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-gray-600 mb-1">考勤状态</label>
|
||||
<div class="relative">
|
||||
<select class="w-full border rounded-button px-3 py-1 appearance-none focus:outline-none focus:ring-1 focus:ring-primary">
|
||||
<option>全部</option>
|
||||
<option>正常</option>
|
||||
<option>迟到</option>
|
||||
<option>早退</option>
|
||||
<option>缺勤</option>
|
||||
</select>
|
||||
<i class="fas fa-chevron-down absolute right-2 top-1/2 transform -translate-y-1/2 fa-icon text-gray-400"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<div class="flex justify-between mb-4">
|
||||
<div class="flex space-x-2">
|
||||
<button class="bg-primary text-white px-3 py-1 rounded-button hover:bg-opacity-90 transition">
|
||||
<i class="fas fa-search fa-icon mr-1"></i>
|
||||
<span>查询</span>
|
||||
</button>
|
||||
<button class="border border-gray-300 px-3 py-1 rounded-button hover:bg-gray-50 transition">
|
||||
<i class="fas fa-redo fa-icon mr-1"></i>
|
||||
<span>重置</span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="bg-primary text-white px-3 py-1 rounded-button hover:bg-opacity-90 transition">
|
||||
<i class="fas fa-download fa-icon mr-1"></i>
|
||||
<span>导出</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead class="bg-secondary">
|
||||
<tr>
|
||||
<th class="px-4 py-2 text-left">员工ID</th>
|
||||
<th class="px-4 py-2 text-left">员工姓名</th>
|
||||
<th class="px-4 py-2 text-left">日期</th>
|
||||
<th class="px-4 py-2 text-left">单位</th>
|
||||
<th class="px-4 py-2 text-left">部门</th>
|
||||
<th class="px-4 py-2 text-left">考勤状态</th>
|
||||
<th class="px-4 py-2 text-left">上班时间</th>
|
||||
<th class="px-4 py-2 text-left">下班时间</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200">
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-2">10001</td>
|
||||
<td class="px-4 py-2">张伟</td>
|
||||
<td class="px-4 py-2">2023-06-01</td>
|
||||
<td class="px-4 py-2">总部</td>
|
||||
<td class="px-4 py-2">技术研发部</td>
|
||||
<td class="px-4 py-2 text-green-500">正常</td>
|
||||
<td class="px-4 py-2">09:00:00</td>
|
||||
<td class="px-4 py-2">18:00:00</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-2">10002</td>
|
||||
<td class="px-4 py-2">王芳</td>
|
||||
<td class="px-4 py-2">2023-06-01</td>
|
||||
<td class="px-4 py-2">总部</td>
|
||||
<td class="px-4 py-2">人力资源部</td>
|
||||
<td class="px-4 py-2 text-yellow-500">迟到</td>
|
||||
<td class="px-4 py-2">09:30:00</td>
|
||||
<td class="px-4 py-2">18:00:00</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-2">10003</td>
|
||||
<td class="px-4 py-2">李娜</td>
|
||||
<td class="px-4 py-2">2023-06-01</td>
|
||||
<td class="px-4 py-2">总部</td>
|
||||
<td class="px-4 py-2">财务部</td>
|
||||
<td class="px-4 py-2 text-green-500">正常</td>
|
||||
<td class="px-4 py-2">09:00:00</td>
|
||||
<td class="px-4 py-2">18:00:00</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-2">10004</td>
|
||||
<td class="px-4 py-2">赵明</td>
|
||||
<td class="px-4 py-2">2023-06-01</td>
|
||||
<td class="px-4 py-2">总部</td>
|
||||
<td class="px-4 py-2">产品部</td>
|
||||
<td class="px-4 py-2 text-green-500">正常</td>
|
||||
<td class="px-4 py-2">09:00:00</td>
|
||||
<td class="px-4 py-2">18:00:00</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-2">10005</td>
|
||||
<td class="px-4 py-2">刘强</td>
|
||||
<td class="px-4 py-2">2023-06-01</td>
|
||||
<td class="px-4 py-2">总部</td>
|
||||
<td class="px-4 py-2">市场部</td>
|
||||
<td class="px-4 py-2 text-red-500">早退</td>
|
||||
<td class="px-4 py-2">09:00:00</td>
|
||||
<td class="px-4 py-2">17:30:00</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-2">10006</td>
|
||||
<td class="px-4 py-2">陈静</td>
|
||||
<td class="px-4 py-2">2023-06-01</td>
|
||||
<td class="px-4 py-2">总部</td>
|
||||
<td class="px-4 py-2">技术研发部</td>
|
||||
<td class="px-4 py-2 text-green-500">正常</td>
|
||||
<td class="px-4 py-2">09:00:00</td>
|
||||
<td class="px-4 py-2">18:00:00</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-2">10007</td>
|
||||
<td class="px-4 py-2">杨光</td>
|
||||
<td class="px-4 py-2">2023-06-01</td>
|
||||
<td class="px-4 py-2">总部</td>
|
||||
<td class="px-4 py-2">人力资源部</td>
|
||||
<td class="px-4 py-2 text-green-500">正常</td>
|
||||
<td class="px-4 py-2">09:00:00</td>
|
||||
<td class="px-4 py-2">18:00:00</td>
|
||||
</tr>
|
||||
<tr class="hover:bg-gray-50">
|
||||
<td class="px-4 py-2">10008</td>
|
||||
<td class="px-4 py-2">周涛</td>
|
||||
<td class="px-4 py-2">2023-06-01</td>
|
||||
<td class="px-4 py-2">总部</td>
|
||||
<td class="px-4 py-2">财务部</td>
|
||||
<td class="px-4 py-2 text-green-500">正常</td>
|
||||
<td class="px-4 py-2">09:00:00</td>
|
||||
<td class="px-4 py-2">18:00:00</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="flex justify-between items-center mt-4">
|
||||
<div class="text-gray-500">
|
||||
显示 1 到 8 条,共 120 条记录
|
||||
</div>
|
||||
<div class="flex space-x-1">
|
||||
<button class="w-8 h-8 border rounded-button flex items-center justify-center hover:bg-gray-50">
|
||||
<i class="fas fa-angle-left fa-icon"></i>
|
||||
</button>
|
||||
<button class="w-8 h-8 border rounded-button flex items-center justify-center bg-primary text-white">1</button>
|
||||
<button class="w-8 h-8 border rounded-button flex items-center justify-center hover:bg-gray-50">2</button>
|
||||
<button class="w-8 h-8 border rounded-button flex items-center justify-center hover:bg-gray-50">3</button>
|
||||
<button class="w-8 h-8 border rounded-button flex items-center justify-center hover:bg-gray-50">4</button>
|
||||
<button class="w-8 h-8 border rounded-button flex items-center justify-center hover:bg-gray-50">5</button>
|
||||
<button class="w-8 h-8 border rounded-button flex items-center justify-center hover:bg-gray-50">
|
||||
<i class="fas fa-angle-right fa-icon"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- 页脚 -->
|
||||
<footer class="w-full bg-gray-800 text-gray-400 py-6">
|
||||
<div class="w-[1200px] mx-auto">
|
||||
<div class="grid grid-cols-3 gap-8">
|
||||
<div>
|
||||
<h3 class="text-white text-sm font-medium mb-3">关于我们</h3>
|
||||
<p class="text-xs leading-6">人力资源管理系统致力于为企业提供专业的人力资源管理解决方案,帮助企业提升管理效率,优化人力资源配置。</p>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-white text-sm font-medium mb-3">快速链接</h3>
|
||||
<ul class="space-y-2 text-xs">
|
||||
<li><a href="#" class="hover:text-white transition">帮助中心</a></li>
|
||||
<li><a href="#" class="hover:text-white transition">API文档</a></li>
|
||||
<li><a href="#" class="hover:text-white transition">系统更新</a></li>
|
||||
<li><a href="#" class="hover:text-white transition">联系我们</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="text-white text-sm font-medium mb-3">联系方式</h3>
|
||||
<ul class="space-y-2 text-xs">
|
||||
<li class="flex items-center">
|
||||
<i class="fas fa-phone fa-icon mr-2"></i>
|
||||
<span>400-888-8888</span>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<i class="fas fa-envelope fa-icon mr-2"></i>
|
||||
<span>service@hrms.com</span>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<i class="fas fa-map-marker-alt fa-icon mr-2"></i>
|
||||
<span>北京市海淀区科技园路88号</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-700 mt-6 pt-4 text-xs text-center">
|
||||
<p>© 2023 人力资源管理系统 版权所有 | 京ICP备12345678号</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@ -0,0 +1,451 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>人力资源管理系统</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Pacifico&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<script>
|
||||
tailwind.config = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#2D5CF6',
|
||||
secondary: '#F5F6FA'
|
||||
},
|
||||
borderRadius: {
|
||||
'none': '0px',
|
||||
'sm': '2px',
|
||||
DEFAULT: '4px',
|
||||
'md': '8px',
|
||||
'lg': '12px',
|
||||
'xl': '16px',
|
||||
'2xl': '20px',
|
||||
'3xl': '24px',
|
||||
'full': '9999px',
|
||||
'button': '4px'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
body {
|
||||
min-height: 1024px;
|
||||
}
|
||||
.nav-item:hover {
|
||||
background-color: rgba(255,255,255,0.1);
|
||||
}
|
||||
.tree-item:hover {
|
||||
background-color: rgba(45,92,246,0.1);
|
||||
}
|
||||
.table-row:hover {
|
||||
background-color: #F5F6FA;
|
||||
}
|
||||
.search-icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
.user-avatar {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
.ai-icon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-white font-sans text-gray-800">
|
||||
<!-- 顶部导航栏 -->
|
||||
<!-- <header class="w-full bg-primary text-white fixed top-0 left-0 z-50 shadow-md">
|
||||
<div class="container mx-auto px-4 h-16 flex items-center justify-between">
|
||||
|
||||
<div class="flex items-center">
|
||||
<div class="font-['Pacifico'] text-xl mr-8">人力</div>
|
||||
|
||||
|
||||
<nav class="hidden md:flex space-x-5">
|
||||
<a href="#" class="nav-item px-3 py-2 text-sm rounded-button whitespace-nowrap">多维统计</a>
|
||||
<a href="#" class="nav-item px-3 py-2 text-sm rounded-button whitespace-nowrap">人员管理</a>
|
||||
<a href="#" class="nav-item px-3 py-2 text-sm rounded-button whitespace-nowrap">组织管理</a>
|
||||
<a href="#" class="nav-item px-3 py-2 text-sm rounded-button whitespace-nowrap">考勤管理</a>
|
||||
<a href="#" class="nav-item px-3 py-2 text-sm rounded-button whitespace-nowrap">绩效管理</a>
|
||||
<a href="#" class="nav-item px-3 py-2 text-sm rounded-button whitespace-nowrap">薪酬管理</a>
|
||||
<a href="#" class="nav-item px-3 py-2 text-sm rounded-button whitespace-nowrap">知识库</a>
|
||||
<a href="#" class="nav-item px-3 py-2 text-sm rounded-button whitespace-nowrap">后台管理</a>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="flex items-center space-x-4">
|
||||
|
||||
<div class="relative hidden md:block">
|
||||
<input type="text" placeholder="搜索..." class="bg-white bg-opacity-20 text-white text-sm pl-8 pr-4 py-1 rounded-full border-none focus:ring-2 focus:ring-white focus:ring-opacity-50 placeholder-white placeholder-opacity-70 w-48">
|
||||
<i class="fas fa-search search-icon absolute left-3 top-1/2 transform -translate-y-1/2 text-white text-opacity-70"></i>
|
||||
</div>
|
||||
|
||||
|
||||
<button class="flex items-center space-x-1 bg-white bg-opacity-20 hover:bg-opacity-30 px-3 py-1 rounded-button text-sm whitespace-nowrap">
|
||||
<i class="fas fa-robot ai-icon text-white"></i>
|
||||
<span>AI助手</span>
|
||||
</button>
|
||||
|
||||
<div class="flex items-center space-x-2 cursor-pointer">
|
||||
<div class="user-avatar rounded-full bg-white text-primary flex items-center justify-center font-semibold">张</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header> -->
|
||||
|
||||
<!-- 主体内容 -->
|
||||
<main class="container mx-auto px-4 pb-10">
|
||||
<div class="flex mt-6">
|
||||
<!-- 左侧组织架构树 -->
|
||||
<div class="w-1/5 pr-4">
|
||||
<div class="bg-secondary rounded-md shadow-sm p-4 h-full">
|
||||
<h3 class="text-sm font-semibold mb-4 text-gray-700">组织架构</h3>
|
||||
<div class="space-y-1">
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md text-sm flex items-center">
|
||||
<i class="fas fa-building mr-2 text-gray-500"></i>
|
||||
<span>集团公司</span>
|
||||
</div>
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md text-sm flex items-center ml-4">
|
||||
<i class="fas fa-sitemap mr-2 text-gray-500"></i>
|
||||
<span>技术中心</span>
|
||||
</div>
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md text-sm flex items-center ml-8 bg-primary bg-opacity-10 text-primary">
|
||||
<i class="fas fa-code-branch mr-2"></i>
|
||||
<span>研发部</span>
|
||||
</div>
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md text-sm flex items-center ml-8">
|
||||
<i class="fas fa-code-branch mr-2 text-gray-500"></i>
|
||||
<span>测试部</span>
|
||||
</div>
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md text-sm flex items-center ml-4">
|
||||
<i class="fas fa-sitemap mr-2 text-gray-500"></i>
|
||||
<span>市场中心</span>
|
||||
</div>
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md text-sm flex items-center ml-8">
|
||||
<i class="fas fa-code-branch mr-2 text-gray-500"></i>
|
||||
<span>市场部</span>
|
||||
</div>
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md text-sm flex items-center ml-8">
|
||||
<i class="fas fa-code-branch mr-2 text-gray-500"></i>
|
||||
<span>品牌部</span>
|
||||
</div>
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md text-sm flex items-center ml-4">
|
||||
<i class="fas fa-sitemap mr-2 text-gray-500"></i>
|
||||
<span>运营中心</span>
|
||||
</div>
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md text-sm flex items-center ml-8">
|
||||
<i class="fas fa-code-branch mr-2 text-gray-500"></i>
|
||||
<span>客服部</span>
|
||||
</div>
|
||||
<div class="tree-item cursor-pointer p-2 rounded-md text-sm flex items-center ml-8">
|
||||
<i class="fas fa-code-branch mr-2 text-gray-500"></i>
|
||||
<span>运营部</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 右侧内容区 -->
|
||||
<div class="w-4/5">
|
||||
<!-- 筛选区域 -->
|
||||
<div class="bg-white rounded-md shadow-sm p-4 mb-4">
|
||||
<h3 class="text-sm font-semibold mb-4 text-gray-700">薪酬查询</h3>
|
||||
<div class="grid grid-cols-4 gap-4">
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 mb-1">姓名</label>
|
||||
<input type="text" class="w-full border border-gray-200 rounded-md px-3 py-1 text-sm focus:ring-primary focus:border-primary">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 mb-1">电话</label>
|
||||
<input type="text" class="w-full border border-gray-200 rounded-md px-3 py-1 text-sm focus:ring-primary focus:border-primary">
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-xs text-gray-500 mb-1">月份</label>
|
||||
<div class="relative">
|
||||
<input type="text" class="w-full border border-gray-200 rounded-md px-3 py-1 text-sm focus:ring-primary focus:border-primary" placeholder="选择月份">
|
||||
<i class="fas fa-calendar-alt absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-400 text-sm"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-end">
|
||||
<button class="bg-primary text-white px-4 py-1 rounded-button text-sm whitespace-nowrap hover:bg-opacity-90">查询</button>
|
||||
<button class="ml-2 border border-gray-200 px-4 py-1 rounded-button text-sm whitespace-nowrap hover:bg-gray-50">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 薪酬列表 -->
|
||||
<div class="bg-white rounded-md shadow-sm overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="min-w-full divide-y divide-gray-200 text-sm">
|
||||
<thead class="bg-secondary">
|
||||
<tr>
|
||||
<th class="px-4 py-2 text-left font-medium text-gray-700">序号</th>
|
||||
<th class="px-4 py-2 text-left font-medium text-gray-700">姓名</th>
|
||||
<th class="px-4 py-2 text-left font-medium text-gray-700">性别</th>
|
||||
<th class="px-4 py-2 text-left font-medium text-gray-700">年龄</th>
|
||||
<th class="px-4 py-2 text-left font-medium text-gray-700">部门</th>
|
||||
<th class="px-4 py-2 text-left font-medium text-gray-700">岗位</th>
|
||||
<th class="px-4 py-2 text-left font-medium text-gray-700">月份</th>
|
||||
<th class="px-4 py-2 text-left font-medium text-gray-700">税前工资</th>
|
||||
<th class="px-4 py-2 text-left font-medium text-gray-700">税后工资</th>
|
||||
<th class="px-4 py-2 text-left font-medium text-gray-700">基本工资</th>
|
||||
<th class="px-4 py-2 text-left font-medium text-gray-700">浮动工资</th>
|
||||
<th class="px-4 py-2 text-left font-medium text-gray-700">详情</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200">
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2">1</td>
|
||||
<td class="px-4 py-2">张明远</td>
|
||||
<td class="px-4 py-2">男</td>
|
||||
<td class="px-4 py-2">32</td>
|
||||
<td class="px-4 py-2">研发部</td>
|
||||
<td class="px-4 py-2">高级工程师</td>
|
||||
<td class="px-4 py-2">2023-10</td>
|
||||
<td class="px-4 py-2">¥28,500</td>
|
||||
<td class="px-4 py-2">¥24,225</td>
|
||||
<td class="px-4 py-2">¥18,000</td>
|
||||
<td class="px-4 py-2">¥10,500</td>
|
||||
<td class="px-4 py-2">
|
||||
<button class="text-primary hover:underline">查看</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2">2</td>
|
||||
<td class="px-4 py-2">李思雨</td>
|
||||
<td class="px-4 py-2">女</td>
|
||||
<td class="px-4 py-2">28</td>
|
||||
<td class="px-4 py-2">市场部</td>
|
||||
<td class="px-4 py-2">市场经理</td>
|
||||
<td class="px-4 py-2">2023-10</td>
|
||||
<td class="px-4 py-2">¥25,800</td>
|
||||
<td class="px-4 py-2">¥22,170</td>
|
||||
<td class="px-4 py-2">¥16,000</td>
|
||||
<td class="px-4 py-2">¥9,800</td>
|
||||
<td class="px-4 py-2">
|
||||
<button class="text-primary hover:underline">查看</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2">3</td>
|
||||
<td class="px-4 py-2">王建国</td>
|
||||
<td class="px-4 py-2">男</td>
|
||||
<td class="px-4 py-2">45</td>
|
||||
<td class="px-4 py-2">技术中心</td>
|
||||
<td class="px-4 py-2">技术总监</td>
|
||||
<td class="px-4 py-2">2023-10</td>
|
||||
<td class="px-4 py-2">¥42,000</td>
|
||||
<td class="px-4 py-2">¥34,860</td>
|
||||
<td class="px-4 py-2">¥25,000</td>
|
||||
<td class="px-4 py-2">¥17,000</td>
|
||||
<td class="px-4 py-2">
|
||||
<button class="text-primary hover:underline">查看</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2">4</td>
|
||||
<td class="px-4 py-2">赵雪</td>
|
||||
<td class="px-4 py-2">女</td>
|
||||
<td class="px-4 py-2">26</td>
|
||||
<td class="px-4 py-2">运营部</td>
|
||||
<td class="px-4 py-2">运营专员</td>
|
||||
<td class="px-4 py-2">2023-10</td>
|
||||
<td class="px-4 py-2">¥15,000</td>
|
||||
<td class="px-4 py-2">¥13,350</td>
|
||||
<td class="px-4 py-2">¥10,000</td>
|
||||
<td class="px-4 py-2">¥5,000</td>
|
||||
<td class="px-4 py-2">
|
||||
<button class="text-primary hover:underline">查看</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2">5</td>
|
||||
<td class="px-4 py-2">陈志强</td>
|
||||
<td class="px-4 py-2">男</td>
|
||||
<td class="px-4 py-2">35</td>
|
||||
<td class="px-4 py-2">测试部</td>
|
||||
<td class="px-4 py-2">测试经理</td>
|
||||
<td class="px-4 py-2">2023-10</td>
|
||||
<td class="px-4 py-2">¥22,500</td>
|
||||
<td class="px-4 py-2">¥19,575</td>
|
||||
<td class="px-4 py-2">¥15,000</td>
|
||||
<td class="px-4 py-2">¥7,500</td>
|
||||
<td class="px-4 py-2">
|
||||
<button class="text-primary hover:underline">查看</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2">6</td>
|
||||
<td class="px-4 py-2">刘芳</td>
|
||||
<td class="px-4 py-2">女</td>
|
||||
<td class="px-4 py-2">30</td>
|
||||
<td class="px-4 py-2">品牌部</td>
|
||||
<td class="px-4 py-2">品牌主管</td>
|
||||
<td class="px-4 py-2">2023-10</td>
|
||||
<td class="px-4 py-2">¥19,800</td>
|
||||
<td class="px-4 py-2">¥17,406</td>
|
||||
<td class="px-4 py-2">¥12,000</td>
|
||||
<td class="px-4 py-2">¥7,800</td>
|
||||
<td class="px-4 py-2">
|
||||
<button class="text-primary hover:underline">查看</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2">7</td>
|
||||
<td class="px-4 py-2">周伟</td>
|
||||
<td class="px-4 py-2">男</td>
|
||||
<td class="px-4 py-2">29</td>
|
||||
<td class="px-4 py-2">研发部</td>
|
||||
<td class="px-4 py-2">前端工程师</td>
|
||||
<td class="px-4 py-2">2023-10</td>
|
||||
<td class="px-4 py-2">¥20,000</td>
|
||||
<td class="px-4 py-2">¥17,600</td>
|
||||
<td class="px-4 py-2">¥13,000</td>
|
||||
<td class="px-4 py-2">¥7,000</td>
|
||||
<td class="px-4 py-2">
|
||||
<button class="text-primary hover:underline">查看</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2">8</td>
|
||||
<td class="px-4 py-2">吴晓梅</td>
|
||||
<td class="px-4 py-2">女</td>
|
||||
<td class="px-4 py-2">27</td>
|
||||
<td class="px-4 py-2">客服部</td>
|
||||
<td class="px-4 py-2">客服主管</td>
|
||||
<td class="px-4 py-2">2023-10</td>
|
||||
<td class="px-4 py-2">¥16,500</td>
|
||||
<td class="px-4 py-2">¥14,685</td>
|
||||
<td class="px-4 py-2">¥11,000</td>
|
||||
<td class="px-4 py-2">¥5,500</td>
|
||||
<td class="px-4 py-2">
|
||||
<button class="text-primary hover:underline">查看</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2">9</td>
|
||||
<td class="px-4 py-2">郑阳</td>
|
||||
<td class="px-4 py-2">男</td>
|
||||
<td class="px-4 py-2">33</td>
|
||||
<td class="px-4 py-2">研发部</td>
|
||||
<td class="px-4 py-2">后端工程师</td>
|
||||
<td class="px-4 py-2">2023-10</td>
|
||||
<td class="px-4 py-2">¥23,000</td>
|
||||
<td class="px-4 py-2">¥19,910</td>
|
||||
<td class="px-4 py-2">¥15,000</td>
|
||||
<td class="px-4 py-2">¥8,000</td>
|
||||
<td class="px-4 py-2">
|
||||
<button class="text-primary hover:underline">查看</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="table-row">
|
||||
<td class="px-4 py-2">10</td>
|
||||
<td class="px-4 py-2">林静</td>
|
||||
<td class="px-4 py-2">女</td>
|
||||
<td class="px-4 py-2">31</td>
|
||||
<td class="px-4 py-2">市场部</td>
|
||||
<td class="px-4 py-2">市场策划</td>
|
||||
<td class="px-4 py-2">2023-10</td>
|
||||
<td class="px-4 py-2">¥18,500</td>
|
||||
<td class="px-4 py-2">¥16,315</td>
|
||||
<td class="px-4 py-2">¥12,000</td>
|
||||
<td class="px-4 py-2">¥6,500</td>
|
||||
<td class="px-4 py-2">
|
||||
<button class="text-primary hover:underline">查看</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="px-4 py-3 flex items-center justify-between border-t border-gray-200">
|
||||
<div class="text-xs text-gray-500">
|
||||
显示 1 到 10 条,共 128 条记录
|
||||
</div>
|
||||
<div class="flex space-x-1">
|
||||
<button class="px-3 py-1 border border-gray-200 rounded-md text-sm hover:bg-gray-50">«</button>
|
||||
<button class="px-3 py-1 border border-gray-200 rounded-md text-sm bg-primary text-white">1</button>
|
||||
<button class="px-3 py-1 border border-gray-200 rounded-md text-sm hover:bg-gray-50">2</button>
|
||||
<button class="px-3 py-1 border border-gray-200 rounded-md text-sm hover:bg-gray-50">3</button>
|
||||
<button class="px-3 py-1 border border-gray-200 rounded-md text-sm hover:bg-gray-50">...</button>
|
||||
<button class="px-3 py-1 border border-gray-200 rounded-md text-sm hover:bg-gray-50">13</button>
|
||||
<button class="px-3 py-1 border border-gray-200 rounded-md text-sm hover:bg-gray-50">»</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<!-- 底部页脚 -->
|
||||
<footer class="w-full bg-secondary border-t border-gray-200 mt-10">
|
||||
<div class="container mx-auto px-4 py-8">
|
||||
<div class="grid grid-cols-4 gap-8">
|
||||
<div>
|
||||
<h4 class="text-sm font-semibold mb-4">关于我们</h4>
|
||||
<p class="text-xs text-gray-600 mb-4">人力科技是一家专注于企业人力资源数字化解决方案的高科技企业,致力于为企业提供专业、高效的人力资源管理服务。</p>
|
||||
<div class="flex space-x-4">
|
||||
<a href="#" class="text-gray-500 hover:text-primary"><i class="fab fa-weixin"></i></a>
|
||||
<a href="#" class="text-gray-500 hover:text-primary"><i class="fab fa-weibo"></i></a>
|
||||
<a href="#" class="text-gray-500 hover:text-primary"><i class="fab fa-linkedin"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-sm font-semibold mb-4">产品服务</h4>
|
||||
<ul class="space-y-2 text-xs text-gray-600">
|
||||
<li><a href="#" class="hover:text-primary">人力资源管理系统</a></li>
|
||||
<li><a href="#" class="hover:text-primary">薪酬计算系统</a></li>
|
||||
<li><a href="#" class="hover:text-primary">绩效考核系统</a></li>
|
||||
<li><a href="#" class="hover:text-primary">招聘管理系统</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-sm font-semibold mb-4">帮助中心</h4>
|
||||
<ul class="space-y-2 text-xs text-gray-600">
|
||||
<li><a href="#" class="hover:text-primary">使用文档</a></li>
|
||||
<li><a href="#" class="hover:text-primary">视频教程</a></li>
|
||||
<li><a href="#" class="hover:text-primary">常见问题</a></li>
|
||||
<li><a href="#" class="hover:text-primary">在线客服</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-sm font-semibold mb-4">联系我们</h4>
|
||||
<ul class="space-y-2 text-xs text-gray-600">
|
||||
<li class="flex items-start">
|
||||
<i class="fas fa-map-marker-alt mr-2 mt-0.5"></i>
|
||||
<span>北京市海淀区中关村软件园二期</span>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<i class="fas fa-phone-alt mr-2"></i>
|
||||
<span>400-888-8888</span>
|
||||
</li>
|
||||
<li class="flex items-center">
|
||||
<i class="fas fa-envelope mr-2"></i>
|
||||
<span>service@hrtech.com</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 mt-8 pt-6 text-center text-xs text-gray-500">
|
||||
<p>© 2023 人力科技 版权所有 京ICP备12345678号</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 209 KiB |
|
After Width: | Height: | Size: 238 B |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 302 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 892 B |
|
After Width: | Height: | Size: 917 B |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 318 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 629 B |
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 177 KiB |
@ -0,0 +1,162 @@
|
||||
import React, { PureComponent } from 'react';
|
||||
import { connect } from 'umi';
|
||||
import { Modal, Tooltip, Input, Button } from 'antd';
|
||||
|
||||
import './index.less';
|
||||
import style from "@/global.less";
|
||||
|
||||
import StandardTable from '@/components/StandardTable';
|
||||
import { AX } from '@/utils/pr_new_datadictionary';
|
||||
import { initTreeSelect } from '@/utils/globalCommon'
|
||||
|
||||
@connect(({ baseinfodata, loading }) => ({
|
||||
baseinfodata,
|
||||
loading: loading.models.baseinfodata,
|
||||
}))
|
||||
|
||||
class A01UserTable extends PureComponent {
|
||||
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
visible: false,
|
||||
selectedRows: [],
|
||||
selectedRowKeys: [],
|
||||
formValues: '',
|
||||
};
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
if (undefined != nextProps.visible) {
|
||||
this.setState({ visible: nextProps.visible });
|
||||
if(!nextProps.visible) {
|
||||
this.setState({ selectedRows: [], formValues: '', selectedRowKeys: [] });
|
||||
}
|
||||
}
|
||||
// if (undefined != nextProps.value) {
|
||||
// this.setState({ selectedRowKeys: nextProps.value. });
|
||||
// }
|
||||
}
|
||||
|
||||
columns = [
|
||||
{
|
||||
title: '姓名',
|
||||
dataIndex: 'za0101',
|
||||
key: 'za0101',
|
||||
width: 80,
|
||||
fixed: 'left',
|
||||
},
|
||||
{
|
||||
title: '性别',
|
||||
dataIndex: 'aa0107',
|
||||
key: 'aa0107',
|
||||
render: val => {
|
||||
const list = AX || [];
|
||||
if (val) {
|
||||
return (
|
||||
<Tooltip title={initTreeSelect(list, val)}>
|
||||
<span className={style.nowrapper} style={{ width: '150px' }}>
|
||||
{initTreeSelect(list, val)}</span>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
componentDidMount() {
|
||||
const { dispatch } = this.props;
|
||||
dispatch({
|
||||
type: 'baseinfodata/query_page_for_aa01',
|
||||
});
|
||||
}
|
||||
|
||||
handleModalVisible() {
|
||||
const { getChildrenMsg } = this.props;
|
||||
const { selectedRows } = this.state;
|
||||
if (getChildrenMsg && selectedRows[0]) {
|
||||
getChildrenMsg(false, selectedRows[0]);
|
||||
} else {
|
||||
getChildrenMsg(false);
|
||||
}
|
||||
}
|
||||
|
||||
handleSelectRows = (selectedRowKeys, selectedRows) => {
|
||||
this.setState({
|
||||
selectedRowKeys: selectedRowKeys,
|
||||
selectedRows: selectedRows,
|
||||
});
|
||||
};
|
||||
|
||||
handleStandardTableChange = (pagination, filtersArg, sorter) => {
|
||||
|
||||
const { dispatch } = this.props;
|
||||
const { formValues } = this.state;
|
||||
|
||||
const params = {
|
||||
currentPage: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
id: formValues || undefined,
|
||||
};
|
||||
|
||||
if (sorter.field) {
|
||||
params.sorter = `${sorter.field}_${sorter.order}`;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: 'baseinfodata/query_page_for_aa01',
|
||||
payload: params,
|
||||
});
|
||||
};
|
||||
|
||||
handleChangeSearch(e) {
|
||||
this.setState({ formValues: e.target.value })
|
||||
}
|
||||
|
||||
handleSearch() {
|
||||
const { formValues } = this.state;
|
||||
const params = { id: formValues }
|
||||
dispatch({
|
||||
type: 'baseinfodata/query_page_for_aa01',
|
||||
payload: params,
|
||||
});
|
||||
}
|
||||
render() {
|
||||
const {
|
||||
baseinfodata: { data },
|
||||
loading,
|
||||
} = this.props;
|
||||
const { visible, selectedRows, selectedRowKeys } = this.state;
|
||||
return (
|
||||
<div className='a01-user-table'>
|
||||
<Modal
|
||||
title="用户列表"
|
||||
width={300}
|
||||
height={500}
|
||||
bodyStyle={{ padding: '20px', maxHeight: '500px', overflowY: 'auto' }}
|
||||
open={visible}
|
||||
onOk={() => this.handleModalVisible(false)}
|
||||
onCancel={() => this.handleModalVisible(false)}
|
||||
>
|
||||
<div style={{ marginBottom: '6px', display: 'flex' }}>
|
||||
<Input onChange={(e) => this.handleChangeSearch(e)} placeholder="" style={{ width: '100%' }} />
|
||||
<Button type="primary" onClick={this.handleSearch}>搜索</Button>
|
||||
</div>
|
||||
<StandardTable
|
||||
rowKey={"id"}
|
||||
selectedRows={selectedRows}
|
||||
loading={loading}
|
||||
data={data}
|
||||
columns={this.columns}
|
||||
// onSelectRow={this.handleSelectRows}
|
||||
onChange={this.handleStandardTableChange}
|
||||
rowSelection={{ type: 'radio', selectedRowKeys: selectedRowKeys, onChange: this.handleSelectRows }}
|
||||
/>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default A01UserTable;
|
||||
@ -0,0 +1,3 @@
|
||||
.a01-user-table {
|
||||
|
||||
}
|
||||
@ -0,0 +1,446 @@
|
||||
import React, {PureComponent} from 'react';
|
||||
import {Input, message, Tree, Modal} from 'antd';
|
||||
import {DeleteOutlined, EditOutlined, FileOutlined, PlusCircleOutlined, ExclamationCircleOutlined} from '@ant-design/icons';
|
||||
import {contextMenu, Item, Menu} from 'react-contexify';
|
||||
import 'react-contexify/dist/ReactContexify.min.css';
|
||||
import {getNodeByKeyAndCallbackProcess} from '@/components/_utils/algorithmTools';
|
||||
import {connect} from '@umijs/max';
|
||||
|
||||
const {Search} = Input;
|
||||
|
||||
@connect(({globaldata, loading}) => ({
|
||||
globaldata,
|
||||
loading: loading.models.globaldata,
|
||||
}))
|
||||
class AsyncTree extends PureComponent {
|
||||
state = {
|
||||
expandedKeys: ['000000000000'],
|
||||
autoExpandParent: true,
|
||||
selectedKeys: [],
|
||||
treeData: [],
|
||||
selectedTreeByRightClick: "",
|
||||
searchValue: '',
|
||||
dataList: [],
|
||||
display: "block",
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state.treeData = [
|
||||
{title: props.rootNodeName, id: '000000000000', key: '000000000000', value: '000000000000', levelcode: "000000000000"},
|
||||
]
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const {dispatch, getTreeMethod, reQueryParent} = this.props;
|
||||
if(!reQueryParent) {
|
||||
return
|
||||
}
|
||||
dispatch({
|
||||
type: 'globaldata/' + getTreeMethod,
|
||||
payload: {
|
||||
parentid: "#"
|
||||
},
|
||||
callback: (res) => {
|
||||
console.log(res)
|
||||
if (res.success == true && res?.list.length > 0) {
|
||||
const temList = res.list?.map((item) => {
|
||||
return {
|
||||
key: item.id,
|
||||
...item
|
||||
}
|
||||
})
|
||||
this.setState({
|
||||
treeData: temList
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//展开收起
|
||||
onExpand = expandedKeys => {
|
||||
this.setState({
|
||||
expandedKeys,
|
||||
autoExpandParent: false,
|
||||
});
|
||||
};
|
||||
|
||||
// 选中的树节点
|
||||
onSelect = (selectedKeys, {node}) => {
|
||||
const {checkedTreeChild} = this.props;
|
||||
this.setState({selectedKeys});
|
||||
if(checkedTreeChild) {
|
||||
checkedTreeChild(node);
|
||||
}
|
||||
};
|
||||
|
||||
addMenuTreeNode = () => {
|
||||
const {handleModalVisible} = this.props;
|
||||
handleModalVisible(true, this.state.selectedTreeByRightClick, this.reLoadCurrentTreeNode);
|
||||
};
|
||||
|
||||
updateMenuTreeNode = () => {
|
||||
const {handleUpdateModalVisible} = this.props;
|
||||
handleUpdateModalVisible(true, this.state.selectedTreeByRightClick, this.reLoadCurrentTreeNodeUpdate);
|
||||
};
|
||||
|
||||
viewMenuTreeNode = () => {
|
||||
const {handleViewModalVisible} = this.props;
|
||||
handleViewModalVisible(true, this.state.selectedTreeByRightClick);
|
||||
};
|
||||
|
||||
deleteMenuTreeNode = () => {
|
||||
const {handleDeleteRecord} = this.props;
|
||||
Modal.confirm({
|
||||
title: '你确定要删除吗?',
|
||||
icon: <ExclamationCircleOutlined />,
|
||||
content: '删除该节点后其子节点也会删除!这并不会删除该节点及其子节点的的关联数据',
|
||||
okText: '确认',
|
||||
cancelText: '取消',
|
||||
onOk: () => {
|
||||
handleDeleteRecord(this.state.selectedTreeByRightClick, this.reLoadCurrentTreeNodeDelete)
|
||||
},
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// 响应右键点击
|
||||
rightClickTreeNode = ({event, node}) => {
|
||||
event.preventDefault();
|
||||
contextMenu.show({
|
||||
id: 'menu_id',
|
||||
event: event,
|
||||
props: {
|
||||
foo: 'bar'
|
||||
}
|
||||
});
|
||||
|
||||
if (node.key != '000000000000') {
|
||||
this.setState({
|
||||
selectedTreeByRightClick: node,
|
||||
display: "block",
|
||||
});
|
||||
} else {
|
||||
this.setState({
|
||||
selectedTreeByRightClick: node,
|
||||
display: "none",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 右键菜单
|
||||
MyAwesomeMenu = () => (
|
||||
<Menu id='menu_id' theme="light" style={{zIndex: 1000}}>
|
||||
<Item onClick={this.addMenuTreeNode}>
|
||||
<PlusCircleOutlined style={{fontSize: 16, paddingTop: 3}}/>
|
||||
<span style={{paddingLeft: 10}}>添加</span>
|
||||
</Item>
|
||||
<Item onClick={this.updateMenuTreeNode} style={{display: this.state.display}}>
|
||||
<EditOutlined style={{fontSize: 16, paddingTop: 3}}/>
|
||||
<span style={{paddingLeft: 10}}>修改</span>
|
||||
</Item>
|
||||
<Item onClick={this.viewMenuTreeNode} style={{display: this.state.display}}>
|
||||
<FileOutlined style={{fontSize: 16, paddingTop: 3}}/>
|
||||
<span style={{paddingLeft: 10}}>查看</span>
|
||||
</Item>
|
||||
<Item onClick={this.deleteMenuTreeNode} style={{display: this.state.display}}>
|
||||
<DeleteOutlined style={{fontSize: 16, paddingTop: 3}}/>
|
||||
<span style={{paddingLeft: 10}}>删除</span>
|
||||
</Item>
|
||||
</Menu>
|
||||
);
|
||||
|
||||
// 组装树数据
|
||||
updateTreeData(list, key, children) {
|
||||
return list.map(node => {
|
||||
if (node.key === key) {
|
||||
return {
|
||||
...node,
|
||||
children,
|
||||
};
|
||||
} else if (node.children) {
|
||||
return {
|
||||
...node,
|
||||
children: this.updateTreeData(node.children, key, children),
|
||||
};
|
||||
}
|
||||
return node;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步加载树数据
|
||||
* @param key
|
||||
* @param children
|
||||
* @returns {Promise<unknown>}
|
||||
*/
|
||||
onLoadData = ({key, children}) => {
|
||||
const {dispatch, getTreeMethod} = this.props;
|
||||
|
||||
const params = {
|
||||
parentid: key
|
||||
};
|
||||
|
||||
return new Promise((resolve) => {
|
||||
// if (children) {
|
||||
// resolve();
|
||||
// return;
|
||||
// }
|
||||
dispatch({
|
||||
type: 'globaldata/' + getTreeMethod,
|
||||
payload: params,
|
||||
callback: (res) => {
|
||||
if (res.success == true) {
|
||||
const temList = res.list?.map((item) => {
|
||||
return {
|
||||
key: item.id,
|
||||
...item
|
||||
}
|
||||
})
|
||||
this.setState({
|
||||
treeData: this.updateTreeData(this.state.treeData, key, temList)
|
||||
});
|
||||
}
|
||||
resolve();
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
reLoadCurrentTreeNode = (treeNode, dropKey) => {
|
||||
const data = [...this.state.treeData];
|
||||
treeNode.key = treeNode.id;
|
||||
getNodeByKeyAndCallbackProcess(data, dropKey, (item) => {
|
||||
item.children = item.children || [];
|
||||
// where to insert 示例添加到尾部,可以是随意位置
|
||||
item.children.push(treeNode);
|
||||
});
|
||||
|
||||
this.setState({
|
||||
treeData: data,
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
reLoadCurrentTreeNodeUpdate = (treeNode, currentTreeNodeKey, parentTreeNodeKey) => {
|
||||
const data = [...this.state.treeData];
|
||||
|
||||
getNodeByKeyAndCallbackProcess(data, parentTreeNodeKey, (item) => {
|
||||
item.children = item.children || {};
|
||||
item.children = item.children.map((item, key) => item.key == currentTreeNodeKey ? {...item, ...treeNode} : item)
|
||||
// item.children.push(treeNode);
|
||||
});
|
||||
this.setState({
|
||||
treeData: data,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
reLoadCurrentTreeNodeDelete = (currentTreeNodeKey) => {
|
||||
|
||||
const data = [...this.state.treeData];
|
||||
getNodeByKeyAndCallbackProcess(data, currentTreeNodeKey, (item, index, arr) => {
|
||||
arr.splice(index, 1);
|
||||
});
|
||||
|
||||
this.setState({
|
||||
treeData: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 搜索事件
|
||||
onChange = e => {
|
||||
const {treeData, dataList} = this.state;
|
||||
const {value} = e.target;
|
||||
const expandedKeys = dataList.map(item => {
|
||||
if (item.title.indexOf(value) > -1) {
|
||||
return this.getParentKey(item.title, treeData);
|
||||
}
|
||||
return null;
|
||||
}).filter((item, i, self) => item && self.indexOf(item) === i);
|
||||
this.setState({
|
||||
expandedKeys,
|
||||
searchValue: value,
|
||||
autoExpandParent: true,
|
||||
});
|
||||
};
|
||||
|
||||
getParentKey = (title, tree) => {
|
||||
let parentKey;
|
||||
for (let i = 0; i < tree.length; i++) {
|
||||
const node = tree[i];
|
||||
if (node.children) {
|
||||
if (node.children.some(item => item.title === title)) {
|
||||
parentKey = node.key;
|
||||
} else if (this.getParentKey(title, node.children)) {
|
||||
parentKey = this.getParentKey(title, node.children);
|
||||
}
|
||||
}
|
||||
}
|
||||
return parentKey;
|
||||
};
|
||||
|
||||
generateList = data => {
|
||||
|
||||
if (undefined == data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
const node = data[i];
|
||||
const {key, title} = node;
|
||||
this.state.dataList.push({key, title: title});
|
||||
if (node.children) {
|
||||
this.generateList(node.children);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
onDrop = async info => {
|
||||
const dropKey = info.node.key;
|
||||
const dragKey = info.dragNode.key;
|
||||
const dropPos = info.node.pos.split('-');
|
||||
const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1]);
|
||||
|
||||
const source_parent_id = info.dragNode.parentid;
|
||||
const source_levelcode = info.dragNode.levelcode;
|
||||
let new_levelcode = "";
|
||||
let dragKey_parent_id = "";
|
||||
let sequences = "";
|
||||
let sequencesArray = [];
|
||||
|
||||
const data = [...this.state.treeData];
|
||||
|
||||
// Find dragObject
|
||||
let dragObj;
|
||||
getNodeByKeyAndCallbackProcess(data, dragKey, (item, index, arr) => {
|
||||
arr.splice(index, 1);
|
||||
dragObj = item;
|
||||
});
|
||||
|
||||
if (!info.dropToGap) {
|
||||
let ar;
|
||||
// Drop on the content 移动到未展开的节点里
|
||||
getNodeByKeyAndCallbackProcess(data, dropKey, (item, index) => {
|
||||
new_levelcode = item.levelcode + "/" + dragKey;
|
||||
dragKey_parent_id = item.key;
|
||||
ar = item.children || [];
|
||||
|
||||
dragObj.levelcode = new_levelcode;
|
||||
dragObj.parentid = dragKey_parent_id;
|
||||
item.children = item.children || [];
|
||||
sequences = item.children.length;
|
||||
// where to insert 示例添加到尾部,可以是随意位置 push
|
||||
item.children.unshift(dragObj);
|
||||
});
|
||||
ar.forEach((item, index) => {
|
||||
let arrs = {
|
||||
id: item.key,
|
||||
sequences: index
|
||||
}
|
||||
sequencesArray.push(arrs);
|
||||
})
|
||||
} else if (
|
||||
(info.node.props.children || []).length > 0 && // Has children
|
||||
info.node.props.expanded && // Is expanded
|
||||
dropPosition === 1 // On the bottom gap
|
||||
) {
|
||||
getNodeByKeyAndCallbackProcess(data, dropKey, (item) => {
|
||||
new_levelcode = item.levelcode + "/" + dragKey;
|
||||
dragKey_parent_id = item.key
|
||||
|
||||
dragObj.levelcode = new_levelcode;
|
||||
dragObj.parentid = dragKey_parent_id;
|
||||
item.children = item.children || [];
|
||||
item.children.unshift(dragObj);
|
||||
});
|
||||
} else {
|
||||
let ar;
|
||||
let i;
|
||||
getNodeByKeyAndCallbackProcess(data, dropKey, (item, index, arr) => {
|
||||
new_levelcode = item.levelcode.replace(item.key, "") + dragKey;
|
||||
dragKey_parent_id = item.parentid
|
||||
|
||||
dragObj.levelcode = new_levelcode;
|
||||
dragObj.parentid = dragKey_parent_id;
|
||||
ar = arr;
|
||||
i = index;
|
||||
});
|
||||
if (dropPosition === -1) {
|
||||
sequences = i;
|
||||
ar.splice(i, 0, dragObj);
|
||||
} else {
|
||||
sequences = i + 1;
|
||||
ar.splice(i + 1, 0, dragObj);
|
||||
}
|
||||
ar.forEach((item, index, arr) => {
|
||||
if(sequences <= index) {
|
||||
let arrs = {
|
||||
id: item.key,
|
||||
sequences: index
|
||||
}
|
||||
sequencesArray.push(arrs);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const {dispatch, updateTreeNodeByDragUrl} = this.props;
|
||||
|
||||
await dispatch({
|
||||
type: 'globaldata/' + updateTreeNodeByDragUrl,
|
||||
payload: {
|
||||
source_id: dragKey,
|
||||
source_parentid: source_parent_id,
|
||||
source_levelcode: source_levelcode,
|
||||
target_id: dragKey_parent_id,
|
||||
levelcode: new_levelcode,
|
||||
sequences: sequences,
|
||||
sequencesArray: sequencesArray
|
||||
},
|
||||
callback: async (res) => {
|
||||
if(res.success == true) {
|
||||
message.success('修改成功');
|
||||
await this.setState({
|
||||
treeData: data,
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const { height, modify } = this.props;
|
||||
const {autoExpandParent, expandedKeys, selectedKeys, treeData} = this.state;
|
||||
this.generateList(treeData);
|
||||
|
||||
return (
|
||||
<div style={{float: 'left', width: '30%'}}>
|
||||
<Search style={{marginBottom: 8, width: '100%'}} placeholder={'请输入'}
|
||||
onChange={this.onChange}/>
|
||||
<Tree
|
||||
loadData={this.onLoadData}
|
||||
onExpand={this.onExpand}
|
||||
expandedKeys={expandedKeys}
|
||||
autoExpandParent={autoExpandParent}
|
||||
onSelect={this.onSelect}
|
||||
selectedKeys={selectedKeys}
|
||||
onRightClick={this.rightClickTreeNode}
|
||||
draggable={modify}
|
||||
onDrop={this.onDrop}
|
||||
treeData={treeData}
|
||||
height={height || 700}
|
||||
>
|
||||
</Tree>
|
||||
{modify ? this.MyAwesomeMenu() : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default AsyncTree;
|
||||
@ -0,0 +1,2 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
@ -0,0 +1,57 @@
|
||||
@avatar-size-base: 32px;
|
||||
@avatar-size-lg: 40px;
|
||||
@avatar-size-sm: 24px;
|
||||
@font-size-base: 14px;
|
||||
@border-color-base: hsv(0, 0, 85%);
|
||||
|
||||
.avatarList {
|
||||
display: inline-block;
|
||||
|
||||
ul {
|
||||
display: inline-block;
|
||||
margin-left: 8px;
|
||||
font-size: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.avatarItem {
|
||||
display: inline-block;
|
||||
width: @avatar-size-base;
|
||||
height: @avatar-size-base;
|
||||
margin-left: -8px;
|
||||
font-size: @font-size-base;
|
||||
|
||||
:global {
|
||||
.ant-avatar {
|
||||
border: 1px solid @border-color-base;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.avatarItemLarge {
|
||||
width: @avatar-size-lg;
|
||||
height: @avatar-size-lg;
|
||||
}
|
||||
|
||||
.avatarItemSmall {
|
||||
width: @avatar-size-sm;
|
||||
height: @avatar-size-sm;
|
||||
}
|
||||
|
||||
.avatarItemMini {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
||||
:global {
|
||||
.ant-avatar {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
|
||||
.ant-avatar-string {
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
import { Avatar, Tooltip } from 'antd'
|
||||
import React from 'react'
|
||||
import classNames from 'classnames'
|
||||
import styles from './index.less'
|
||||
|
||||
export declare type SizeType = number | 'small' | 'default' | 'large'
|
||||
|
||||
export interface AvatarItemProps {
|
||||
tips: React.ReactNode
|
||||
src: string
|
||||
size?: SizeType
|
||||
style?: React.CSSProperties
|
||||
onClick?: () => void
|
||||
}
|
||||
|
||||
export interface AvatarListProps {
|
||||
Item?: React.ReactElement<AvatarItemProps>
|
||||
size?: SizeType
|
||||
maxLength?: number
|
||||
excessItemsStyle?: React.CSSProperties
|
||||
style?: React.CSSProperties
|
||||
children: React.ReactElement<AvatarItemProps> | React.ReactElement<AvatarItemProps>[]
|
||||
}
|
||||
|
||||
const avatarSizeToClassName = (size?: SizeType | 'mini') =>
|
||||
classNames(styles.avatarItem, {
|
||||
[styles.avatarItemLarge]: size === 'large',
|
||||
[styles.avatarItemSmall]: size === 'small',
|
||||
[styles.avatarItemMini]: size === 'mini'
|
||||
})
|
||||
|
||||
const Item: React.FC<AvatarItemProps> = ({ src, size, tips, onClick = () => {} }) => {
|
||||
const cls = avatarSizeToClassName(size)
|
||||
|
||||
return (
|
||||
<li className={cls} onClick={onClick}>
|
||||
{tips ? (
|
||||
<Tooltip title={tips}>
|
||||
<Avatar src={src} size={size} style={{ cursor: 'pointer' }} />
|
||||
</Tooltip>
|
||||
) : (
|
||||
<Avatar src={src} size={size} />
|
||||
)}
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
const AvatarList: React.FC<AvatarListProps> & { Item: typeof Item } = ({children, size, maxLength = 5, excessItemsStyle, ...other}) => {
|
||||
const numOfChildren = React.Children.count(children)
|
||||
const numToShow = maxLength >= numOfChildren ? numOfChildren : maxLength
|
||||
const childrenArray = React.Children.toArray(children) as React.ReactElement<AvatarItemProps>[]
|
||||
const childrenWithProps = childrenArray.slice(0, numToShow).map((child) => React.cloneElement(child, { size }))
|
||||
|
||||
if (numToShow < numOfChildren) {
|
||||
const cls = avatarSizeToClassName(size)
|
||||
|
||||
childrenWithProps.push(
|
||||
<li key='exceed' className={cls}>
|
||||
<Avatar size={size} style={excessItemsStyle}>{`+${numOfChildren - maxLength}`}</Avatar>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div {...other} className={styles.avatarList}>
|
||||
<ul> {childrenWithProps} </ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
AvatarList.Item = Item
|
||||
|
||||
export default AvatarList
|
||||
@ -0,0 +1,98 @@
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
Form,
|
||||
Input,
|
||||
DatePicker,
|
||||
Button,
|
||||
} from 'antd';
|
||||
import SelectOptionTree from '@/components/SelectOptionTree';
|
||||
import { AX, OR, } from '@/utils/pr_new_datadictionary';
|
||||
import { UpOutlined } from '@ant-design/icons';
|
||||
import style from "@/global.less";
|
||||
const FormItem = Form.Item;
|
||||
|
||||
const Aa01RenderAdvancedForm = (props) => {
|
||||
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const { handleSearch, handleFormReset, toggleForm } = props;
|
||||
|
||||
const onFinish = values => {
|
||||
//console.log('Received values of form: ', values);
|
||||
handleSearch(values);
|
||||
};
|
||||
|
||||
const myhandleFormReset = () => {
|
||||
form.resetFields();
|
||||
handleFormReset();
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
<Form form={form} onFinish={onFinish} layout="inline">
|
||||
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }} style={{ width: '100%' }} className={style.searchinput}>
|
||||
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="本单位工龄" name="aa0101">
|
||||
<Input placeholder="" style={{ width: '100%' }} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="人工成本统计标识" name="aa0106">
|
||||
<Input placeholder="" style={{ width: '100%' }} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }} style={{ width: '100%' }} className={style.searchinput}>
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="性别" name="aa0107">
|
||||
<SelectOptionTree treeData={AX || []} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="备注" name="aa0108">
|
||||
<Input placeholder="" style={{ width: '100%' }} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="人员类别" name="aa010d">
|
||||
<SelectOptionTree treeData={OR || []} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }} style={{ width: '100%' }} className={style.searchbox}>
|
||||
|
||||
<Col md={24} sm={24}>
|
||||
<div style={{ marginBottom: 12, display: 'flex', justifyContent: 'flex-end' }}>
|
||||
<Button type="primary" htmlType="submit">
|
||||
查询
|
||||
</Button>
|
||||
<Button style={{ marginLeft: 8 }} onClick={myhandleFormReset}>
|
||||
重置
|
||||
</Button>
|
||||
<a style={{ marginLeft: 8, lineHeight: '32px' }} onClick={toggleForm}>
|
||||
收起 <UpOutlined />
|
||||
</a>
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
|
||||
</Form>
|
||||
|
||||
);
|
||||
|
||||
|
||||
};
|
||||
|
||||
export default Aa01RenderAdvancedForm;
|
||||
@ -0,0 +1,70 @@
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
Form,
|
||||
Input,
|
||||
DatePicker,
|
||||
Button,
|
||||
} from 'antd';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import style from "@/global.less";
|
||||
const FormItem = Form.Item;
|
||||
|
||||
const Aa01RenderSimpleForm = (props) => {
|
||||
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const { submitButtons, handleSearch, handleFormReset, toggleForm } = props;
|
||||
|
||||
const onFinish = values => {
|
||||
//console.log('Received values of form: ', values);
|
||||
handleSearch(values);
|
||||
};
|
||||
|
||||
const myhandleFormReset = () => {
|
||||
form.resetFields();
|
||||
handleFormReset();
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
<Form form={form} onFinish={onFinish} layout="inline">
|
||||
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }} style={{ width: '100%' }} className={style.searchinput}>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="本单位工龄" name="aa0101">
|
||||
<Input placeholder="" style={{ width: '100%' }} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="人工成本统计标识" name="aa0106">
|
||||
<Input placeholder="" style={{ width: '100%' }} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<div style={{ marginBottom: 12, display: 'flex', justifyContent: 'flex-end' }}>
|
||||
<Button type="primary" htmlType="submit">
|
||||
查询
|
||||
</Button>
|
||||
<Button style={{ marginLeft: 8 }} onClick={myhandleFormReset}>
|
||||
重置
|
||||
</Button>
|
||||
<a style={{ marginLeft: 8, lineHeight: '32px' }} onClick={toggleForm}>
|
||||
展开 <DownOutlined />
|
||||
</a>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
</Form>
|
||||
|
||||
);
|
||||
|
||||
|
||||
};
|
||||
|
||||
export default Aa01RenderSimpleForm;
|
||||
@ -0,0 +1,83 @@
|
||||
.aa01tableList {
|
||||
.aa01tableListOperator {
|
||||
margin-bottom: 16px;
|
||||
button {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.aa01tableListForm {
|
||||
:global {
|
||||
.ant-form-item {
|
||||
display: flex;
|
||||
margin-right: 0;
|
||||
margin-bottom: 24px;
|
||||
> .ant-form-item-label {
|
||||
width: auto;
|
||||
padding-right: 8px;
|
||||
line-height: 32px;
|
||||
}
|
||||
.ant-form-item-control {
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
.ant-form-item-control-wrapper {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
.submitButtons {
|
||||
display: block;
|
||||
margin-bottom: 24px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ant-upload{
|
||||
width: 130px !important;
|
||||
height: 140px !important;
|
||||
}
|
||||
|
||||
.staffPhoto {
|
||||
font-size: 70px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.photoBox {
|
||||
.headIcon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
svg {
|
||||
height: 150px;
|
||||
width: 140px;
|
||||
opacity: .75;
|
||||
}
|
||||
}
|
||||
:global {
|
||||
.ant-upload-select-picture-card{
|
||||
height: 150px;
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: @screen-lg) {
|
||||
.aa01tableListForm :global(.ant-form-item) {
|
||||
margin-right: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: @screen-md) {
|
||||
.aa01tableListForm :global(.ant-form-item) {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,579 @@
|
||||
import { PureComponent, Fragment } from 'react';
|
||||
import { DownOutlined, SearchOutlined, EditOutlined, DeleteOutlined, PlusOutlined } from '@ant-design/icons';
|
||||
import { history, connect } from 'umi';
|
||||
|
||||
import {
|
||||
Card,
|
||||
Button,
|
||||
Dropdown,
|
||||
Menu,
|
||||
message,
|
||||
DatePicker,
|
||||
Divider,
|
||||
Popconfirm,
|
||||
Tooltip
|
||||
} from 'antd';
|
||||
|
||||
import { initTreeSelect, userInfo } from '@/utils/globalCommon'
|
||||
import { XQ, AE, AX, _09, AB, OR, BG, AT, HC, OC, OD, RF, X4 } from '@/utils/pr_new_datadictionary';
|
||||
import Aa01VipCreateForm from './form/Aa01VipCreateForm'; //新增表单
|
||||
import Aa01VipUpdateForm from './form/Aa01VipUpdateForm'; //修改表单
|
||||
import Aa01VipViewForm from './form/Aa01VipViewForm'; //查看表单
|
||||
import Aa01VipRenderSimpleForm from './form/Aa01VipRenderSimpleForm'; //简单查询表单
|
||||
import Aa01VipRenderAdvancedForm from './form/Aa01VipRenderAdvancedForm'; //高级查询表单
|
||||
import moment from 'moment';
|
||||
|
||||
import StandardTable from '@/components/StandardTable';
|
||||
|
||||
import style from '@/global.less';
|
||||
import styles from './index.less';
|
||||
|
||||
const { RangePicker } = DatePicker;
|
||||
|
||||
|
||||
/* eslint react/no-multi-comp:0 */
|
||||
@connect(({ baseinfodata, loading }) => ({
|
||||
baseinfodata,
|
||||
loading: loading.models.baseinfodata,
|
||||
}))
|
||||
class Aa01VipTable extends PureComponent {
|
||||
|
||||
state = {
|
||||
modalVisible: false,
|
||||
updateModalVisible: false,
|
||||
viewModalVisible: false,
|
||||
expandForm: false,
|
||||
selectedRows: [],
|
||||
formValues: {},
|
||||
updateFormValues: {},
|
||||
viewFormValues: {},
|
||||
};
|
||||
|
||||
columns = [
|
||||
{
|
||||
title: '姓名',
|
||||
dataIndex: 'za0101',
|
||||
key: 'za0101',
|
||||
width: 80,
|
||||
fixed: 'left',
|
||||
},
|
||||
{
|
||||
title: '性别',
|
||||
dataIndex: 'aa0107',
|
||||
key: 'aa0107',
|
||||
render: val => {
|
||||
const list = AX || [];
|
||||
if (val) {
|
||||
return (
|
||||
<Tooltip title={initTreeSelect(list, val)}>
|
||||
<span className={style.nowrapper} style={{ width: '150px' }}>
|
||||
{initTreeSelect(list, val)}</span>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '民族',
|
||||
dataIndex: 'aa0121',
|
||||
key: 'aa0121',
|
||||
render: val => {
|
||||
const list = AE || [];
|
||||
if (val) {
|
||||
return (
|
||||
<Tooltip title={initTreeSelect(list, val)}>
|
||||
<span className={style.nowrapper} style={{ width: '150px' }}>
|
||||
{initTreeSelect(list, val)}</span>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '出生年月',
|
||||
dataIndex: 'aa0111',
|
||||
key: 'aa0111',
|
||||
render: val => (<span>{moment(val).format("YYYY-MM")}</span>)
|
||||
},
|
||||
{
|
||||
title: '籍贯',
|
||||
dataIndex: 'aa0114',
|
||||
key: 'aa0114',
|
||||
render: val => {
|
||||
const list = AB || [];
|
||||
if (val) {
|
||||
return (
|
||||
<Tooltip title={initTreeSelect(list, val)}>
|
||||
<span className={style.nowrapper} style={{ width: '150px' }}>
|
||||
{initTreeSelect(list, val)}</span>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '参加工作时间',
|
||||
dataIndex: 'aa0141',
|
||||
key: 'aa0141',
|
||||
},
|
||||
{
|
||||
title: '职称',
|
||||
dataIndex: 'v_aa011a',
|
||||
key: 'v_aa011a',
|
||||
},
|
||||
{
|
||||
title: '婚姻状况',
|
||||
dataIndex: 'aa0127',
|
||||
key: 'aa0127',
|
||||
render: val => {
|
||||
const list = BG || [];
|
||||
if (val) {
|
||||
return (
|
||||
<Tooltip title={initTreeSelect(list, val)}>
|
||||
<span className={style.nowrapper} style={{ width: '150px' }}>
|
||||
{initTreeSelect(list, val)}</span>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '健康状况',
|
||||
dataIndex: 'v_aa011b',
|
||||
key: 'v_aa011b',
|
||||
},
|
||||
{
|
||||
title: '身份证号码',
|
||||
dataIndex: 'aa0177',
|
||||
key: 'aa0177',
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
width: 220,
|
||||
fixed: 'right',
|
||||
render: (text, record) => (
|
||||
<Fragment>
|
||||
<a onClick={() => this.handleViewModalVisible(true, record)}> <SearchOutlined style={{ color: '#00FFFF' }} />查看 </a>
|
||||
<Divider type="vertical" />
|
||||
<a onClick={() => this.handleUpdateModalVisible(true, record)}> <EditOutlined style={{ color: '#FF4500' }} />编辑 </a>
|
||||
<Divider type="vertical" />
|
||||
<Popconfirm title="你确定要删除吗?" okText="确定" cancelText="取消" onConfirm={() => this.handleDeleteRecord(record)} >
|
||||
<a href={"javascript"} > <DeleteOutlined style={{ color: '#40E0D0' }} /> 删除</a>
|
||||
</Popconfirm>
|
||||
</Fragment>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
const { dispatch } = this.props;
|
||||
dispatch({
|
||||
type: 'baseinfodata/query_page_for_aa01',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
handleStandardTableChange = (pagination, filtersArg, sorter) => {
|
||||
|
||||
const { dispatch } = this.props;
|
||||
const { formValues } = this.state;
|
||||
|
||||
const params = {
|
||||
currentPage: pagination.current,
|
||||
pageSize: pagination.pageSize,
|
||||
...formValues,
|
||||
};
|
||||
|
||||
if (sorter.field) {
|
||||
params.sorter = `${sorter.field}_${sorter.order}`;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: 'baseinfodata/query_page_for_aa01',
|
||||
payload: params,
|
||||
});
|
||||
|
||||
|
||||
};
|
||||
|
||||
previewItem = record => {
|
||||
const id = record.id;
|
||||
//history.push(`/baseinfodata/basic/${id}{id}`);
|
||||
};
|
||||
|
||||
handleFormReset = () => {
|
||||
const { dispatch } = this.props;
|
||||
this.setState({
|
||||
formValues: {},
|
||||
});
|
||||
dispatch({
|
||||
type: 'baseinfodata/query_page_for_aa01',
|
||||
payload: {},
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
toggleForm = () => {
|
||||
|
||||
const { expandForm } = this.state;
|
||||
this.setState({
|
||||
expandForm: !expandForm,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
handleSelectRows = rows => {
|
||||
this.setState({
|
||||
selectedRows: rows,
|
||||
});
|
||||
};
|
||||
|
||||
handleSearch = values => {
|
||||
const { dispatch } = this.props;
|
||||
this.setState({
|
||||
formValues: values,
|
||||
});
|
||||
|
||||
dispatch({
|
||||
type: 'baseinfodata/query_page_for_aa01',
|
||||
payload: values,
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
handleModalVisible = flag => {
|
||||
this.setState({
|
||||
modalVisible: !!flag,
|
||||
});
|
||||
};
|
||||
|
||||
handleUpdateModalVisible = (flag, record) => {
|
||||
this.setState({
|
||||
updateModalVisible: !!flag,
|
||||
updateFormValues: record || {},
|
||||
});
|
||||
};
|
||||
|
||||
handleViewModalVisible = (flag, record) => {
|
||||
|
||||
this.setState({
|
||||
viewModalVisible: !!flag,
|
||||
viewFormValues: record || {},
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
handleAdd = (fields, form, loading) => {
|
||||
|
||||
const { dispatch } = this.props;
|
||||
const params = {
|
||||
za0101: fields.za0101, // 姓 名
|
||||
aa0107: fields.aa0107, // 性 别 aa0107
|
||||
aa0121: fields.aa0121, // 民 族 aa0121
|
||||
aa0111: fields.aa0111, // 出 生 年 月 aa0111
|
||||
aa0114: fields.aa0114, // 籍 贯 aa0114
|
||||
aa0117: fields.aa0117, // 出生地 aa0117
|
||||
aa0141: fields.aa0141, // 参加工作时间 aa0141
|
||||
v_aa011n: fields.v_aa011n, // 党派交叉情况 v_aa011n
|
||||
v_aa011a: fields.v_aa011a, // 职 称 v_aa011a
|
||||
aa0127: fields.aa0127, // 婚 姻 状 况 aa0127
|
||||
v_aa011b: fields.v_aa011b, // 健 康 状 况 v_aa011b
|
||||
aa0177: fields.aa0177, // 身份证号 码 aa0177
|
||||
v_aa011c: fields.v_aa011c, // 工作单位 v_aa011c
|
||||
v_aa011d: fields.v_aa011d, // 职 务 v_aa011d
|
||||
v_aa011h: fields.v_aa011h, // 职务层次 v_aa011h
|
||||
v_aa011f: fields.v_aa011f, // 任现职务层次时间 v_aa011f
|
||||
v_aa011e: fields.v_aa011e, // 职 级 v_aa011e
|
||||
v_aa011g: fields.v_aa011g, // 任 现 职 级 时 间 v_aa011g
|
||||
v_aa011i: fields.v_aa011i, // 单位地址 v_aa011i
|
||||
v_aa011j: fields.v_aa011j, // 固定电话 v_aa011j
|
||||
v_aa011k: fields.v_aa011k, // 家庭地址 v_aa011k
|
||||
ak010g: fields.ak010g, // 邮政编码 ak010g
|
||||
ak010b: fields.ak010b, // 手机号码 ak010b
|
||||
v_aa011l: fields.v_aa011l, // 电子邮箱 v_aa011l
|
||||
v_aa011m: fields.v_aa011m, // 专业专长 v_aa011m
|
||||
// za9998: fields.za9998, // 头像
|
||||
}
|
||||
if(fields.file) {
|
||||
const formData = new FormData();
|
||||
formData.append('file', fields.file);
|
||||
dispatch({
|
||||
type: 'baseinfodata/upload_single_file',
|
||||
payload: formData,
|
||||
callback: ({ success, datarecord}) => {
|
||||
loading(false);
|
||||
if (success == true) {
|
||||
params.za9998 = datarecord.id
|
||||
dispatch({
|
||||
type: 'baseinfodata/insert_for_aa01',
|
||||
payload: params,
|
||||
callback: (res) => {
|
||||
loading(false);
|
||||
if (res.success == true) {
|
||||
message.success('添加成功');
|
||||
form.resetFields();
|
||||
this.handleModalVisible();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
message.error('照片上传失败');
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'baseinfodata/insert_for_aa01',
|
||||
payload: params,
|
||||
callback: (res) => {
|
||||
loading(false);
|
||||
if (res.success == true) {
|
||||
message.success('添加成功');
|
||||
form.resetFields();
|
||||
this.handleModalVisible();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
handleDeleteRecord = record => {
|
||||
|
||||
const { dispatch } = this.props;
|
||||
|
||||
dispatch({
|
||||
type: 'baseinfodata/delete_by_primarykey_for_aa01',
|
||||
payload: {
|
||||
recordid: record.id,
|
||||
},
|
||||
callback: () => {
|
||||
this.setState({
|
||||
selectedRows: [],
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
message.success('删除成功');
|
||||
|
||||
|
||||
};
|
||||
|
||||
handleUpdate = (fields, form, loading) => {
|
||||
|
||||
const { dispatch } = this.props;
|
||||
const params = {
|
||||
id: fields.id,
|
||||
za0101: fields.za0101, // 姓 名
|
||||
aa0107: fields.aa0107, // 性 别 aa0107
|
||||
aa0121: fields.aa0121, // 民 族 aa0121
|
||||
aa0111: fields.aa0111, // 出 生 年 月 aa0111
|
||||
aa0114: fields.aa0114, // 籍 贯 aa0114
|
||||
aa0117: fields.aa0117, // 出生地 aa0117
|
||||
aa0141: fields.aa0141, // 参加工作时间 aa0141
|
||||
v_aa011n: fields.v_aa011n, // 党派交叉情况 v_aa011n
|
||||
v_aa011a: fields.v_aa011a, // 职 称 v_aa011a
|
||||
aa0127: fields.aa0127, // 婚 姻 状 况 aa0127
|
||||
v_aa011b: fields.v_aa011b, // 健 康 状 况 v_aa011b
|
||||
aa0177: fields.aa0177, // 身份证号 码 aa0177
|
||||
v_aa011c: fields.v_aa011c, // 工作单位 v_aa011c
|
||||
v_aa011d: fields.v_aa011d, // 职 务 v_aa011d
|
||||
v_aa011h: fields.v_aa011h, // 职务层次 v_aa011h
|
||||
v_aa011f: fields.v_aa011f, // 任现职务层次时间 v_aa011f
|
||||
v_aa011e: fields.v_aa011e, // 职 级 v_aa011e
|
||||
v_aa011g: fields.v_aa011g, // 任 现 职 级 时 间 v_aa011g
|
||||
v_aa011i: fields.v_aa011i, // 单位地址 v_aa011i
|
||||
v_aa011j: fields.v_aa011j, // 固定电话 v_aa011j
|
||||
v_aa011k: fields.v_aa011k, // 家庭地址 v_aa011k
|
||||
ak010g: fields.ak010g, // 邮政编码 ak010g
|
||||
ak010b: fields.ak010b, // 手机号码 ak010b
|
||||
v_aa011l: fields.v_aa011l, // 电子邮箱 v_aa011l
|
||||
v_aa011m: fields.v_aa011m, // 专业专长 v_aa011m
|
||||
// za9998: fields.za9998, // 头像
|
||||
}
|
||||
if(fields.file) {
|
||||
const formData = new FormData();
|
||||
formData.append('file', fields.file);
|
||||
dispatch({
|
||||
type: 'baseinfodata/upload_single_file',
|
||||
payload: formData,
|
||||
callback: ({ success, datarecord}) => {
|
||||
loading(false);
|
||||
if (success == true) {
|
||||
params.za9998 = datarecord.id
|
||||
dispatch({
|
||||
type: 'baseinfodata/update_for_aa01',
|
||||
payload: params,
|
||||
callback: (res) => {
|
||||
loading(false);
|
||||
if (res.success == true) {
|
||||
message.success('修改成功');
|
||||
form.resetFields();
|
||||
this.handleUpdateModalVisible();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
message.error('照片上传失败');
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
dispatch({
|
||||
type: 'baseinfodata/update_for_aa01',
|
||||
payload: params,
|
||||
callback: (res) => {
|
||||
loading(false);
|
||||
if (res.success == true) {
|
||||
message.success('修改成功');
|
||||
form.resetFields();
|
||||
this.handleUpdateModalVisible();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
renderSimpleForm() {
|
||||
|
||||
const parentMethods = {
|
||||
handleSearch: this.handleSearch,
|
||||
handleFormReset: this.handleFormReset,
|
||||
toggleForm: this.toggleForm,
|
||||
submitButtons: styles.submitButtons,
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
<Aa01VipRenderSimpleForm {...parentMethods} />
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
renderAdvancedForm() {
|
||||
|
||||
const parentMethods = {
|
||||
handleSearch: this.handleSearch,
|
||||
handleFormReset: this.handleFormReset,
|
||||
toggleForm: this.toggleForm,
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
<Aa01VipRenderAdvancedForm {...parentMethods} />
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
renderForm() {
|
||||
const { expandForm } = this.state;
|
||||
return expandForm ? this.renderAdvancedForm() : this.renderSimpleForm();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const {
|
||||
baseinfodata: { data },
|
||||
loading,
|
||||
} = this.props;
|
||||
|
||||
|
||||
const { selectedRows, modalVisible, updateModalVisible, viewModalVisible, updateFormValues, viewFormValues } = this.state;
|
||||
const menu = (
|
||||
<Menu onClick={this.handleMenuClick} selectedKeys={[]}>
|
||||
<Menu.Item key="remove">删除</Menu.Item>
|
||||
<Menu.Item key="approval">批量审批</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
const parentMethods = {
|
||||
handleAdd: this.handleAdd,
|
||||
handleModalVisible: this.handleModalVisible,
|
||||
};
|
||||
const updateMethods = {
|
||||
handleUpdateModalVisible: this.handleUpdateModalVisible,
|
||||
handleUpdate: this.handleUpdate,
|
||||
};
|
||||
const viewMethods = {
|
||||
handleViewModalVisible: this.handleViewModalVisible
|
||||
};
|
||||
return (
|
||||
|
||||
<>
|
||||
<Card bordered={false}>
|
||||
<div className={styles.aa01tableList}>
|
||||
|
||||
<div className={styles.aa01tableListForm}>{this.renderForm()}</div>
|
||||
|
||||
|
||||
<div className={styles.aa01tableListOperator}>
|
||||
|
||||
<Button type="primary" onClick={() => this.handleModalVisible(true)}>
|
||||
<PlusOutlined /> 新建
|
||||
</Button>
|
||||
{selectedRows.length > 0 && (
|
||||
<span>
|
||||
<Button>批量操作</Button>
|
||||
<Dropdown overlay={menu}>
|
||||
<Button>
|
||||
更多操作 <DownOutlined />
|
||||
</Button>
|
||||
</Dropdown>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<StandardTable
|
||||
rowKey={"id"}
|
||||
selectedRows={selectedRows}
|
||||
loading={loading}
|
||||
data={data}
|
||||
columns={this.columns}
|
||||
scroll={{ x: 1500 }}
|
||||
onSelectRow={this.handleSelectRows}
|
||||
onChange={this.handleStandardTableChange}
|
||||
/>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
<Aa01VipCreateForm {...parentMethods} modalVisible={modalVisible} />
|
||||
|
||||
|
||||
{updateFormValues && Object.keys(updateFormValues).length ? (
|
||||
<Aa01VipUpdateForm
|
||||
{...updateMethods}
|
||||
updateModalVisible={updateModalVisible}
|
||||
values={updateFormValues}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
|
||||
{viewFormValues && Object.keys(viewFormValues).length ? (
|
||||
<Aa01VipViewForm
|
||||
{...viewMethods}
|
||||
viewModalVisible={viewModalVisible}
|
||||
values={viewFormValues}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
</>
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default Aa01VipTable;
|
||||
|
||||
@ -0,0 +1,99 @@
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
Form,
|
||||
Input,
|
||||
DatePicker,
|
||||
Button,
|
||||
} from 'antd';
|
||||
import { UpOutlined } from '@ant-design/icons';
|
||||
import style from "@/global.less";
|
||||
const FormItem = Form.Item;
|
||||
|
||||
const Aa01RenderAdvancedForm = (props) => {
|
||||
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const { handleSearch, handleFormReset, toggleForm } = props;
|
||||
|
||||
const onFinish = values => {
|
||||
//console.log('Received values of form: ', values);
|
||||
handleSearch(values);
|
||||
};
|
||||
|
||||
const myhandleFormReset = () => {
|
||||
form.resetFields();
|
||||
handleFormReset();
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
<Form form={form} onFinish={onFinish} layout="inline">
|
||||
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }} style={{ width: '100%' }} className={style.searchinput}>
|
||||
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="本单位工龄" name="aa0101">
|
||||
<Input placeholder="" style={{ width: '100%' }} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="人工成本统计标识" name="aa0106">
|
||||
<Input placeholder="" style={{ width: '100%' }} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }} style={{ width: '100%' }} className={style.searchinput}>
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="性别" name="aa0107">
|
||||
<Input placeholder="" style={{ width: '100%' }} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="备注" name="aa0108">
|
||||
<Input placeholder="" style={{ width: '100%' }} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="人员类别" name="aa010d">
|
||||
<Input placeholder="" style={{ width: '100%' }} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }} style={{ width: '100%' }} className={style.searchbox}>
|
||||
|
||||
<Col md={24} sm={24}>
|
||||
<div style={{ marginBottom: 12, display: 'flex', justifyContent: 'flex-end' }}>
|
||||
<Button type="primary" htmlType="submit">
|
||||
查询
|
||||
</Button>
|
||||
<Button style={{ marginLeft: 8 }} onClick={myhandleFormReset}>
|
||||
重置
|
||||
</Button>
|
||||
<a style={{ marginLeft: 8, lineHeight: '32px' }} onClick={toggleForm}>
|
||||
收起 <UpOutlined />
|
||||
</a>
|
||||
</div>
|
||||
</Col>
|
||||
|
||||
</Row>
|
||||
|
||||
</Form>
|
||||
|
||||
);
|
||||
|
||||
|
||||
};
|
||||
|
||||
export default Aa01RenderAdvancedForm;
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
Form,
|
||||
Input,
|
||||
DatePicker,
|
||||
Button,
|
||||
} from 'antd';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import style from "@/global.less";
|
||||
const FormItem = Form.Item;
|
||||
|
||||
const Aa01RenderSimpleForm = (props) => {
|
||||
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const { submitButtons, handleSearch, handleFormReset, toggleForm } = props;
|
||||
|
||||
const onFinish = values => {
|
||||
//console.log('Received values of form: ', values);
|
||||
handleSearch(values);
|
||||
};
|
||||
|
||||
const myhandleFormReset = () => {
|
||||
form.resetFields();
|
||||
handleFormReset();
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
<Form form={form} onFinish={onFinish} layout="inline">
|
||||
|
||||
<Row gutter={{ md: 8, lg: 24, xl: 48 }} style={{ width: '100%' }} className={style.searchinput}>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="本单位工龄" name="aa0101">
|
||||
<Input placeholder="" style={{ width: '100%' }} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<FormItem label="人工成本统计标识" name="aa0106">
|
||||
<Input placeholder="" style={{ width: '100%' }} />
|
||||
</FormItem>
|
||||
</Col>
|
||||
|
||||
|
||||
<Col md={8} sm={24}>
|
||||
<div style={{ marginBottom: 12, display: 'flex', justifyContent: 'flex-end' }}>
|
||||
<Button type="primary" htmlType="submit">
|
||||
查询
|
||||
</Button>
|
||||
<Button style={{ marginLeft: 8 }} onClick={myhandleFormReset}>
|
||||
重置
|
||||
</Button>
|
||||
<a style={{ marginLeft: 8, lineHeight: '32px' }} onClick={toggleForm}>
|
||||
展开 <DownOutlined />
|
||||
</a>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
</Form>
|
||||
|
||||
);
|
||||
|
||||
|
||||
};
|
||||
|
||||
export default Aa01RenderSimpleForm;
|
||||
@ -0,0 +1,83 @@
|
||||
.aa01tableList {
|
||||
.aa01tableListOperator {
|
||||
margin-bottom: 16px;
|
||||
button {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.aa01tableListForm {
|
||||
:global {
|
||||
.ant-form-item {
|
||||
display: flex;
|
||||
margin-right: 0;
|
||||
margin-bottom: 24px;
|
||||
> .ant-form-item-label {
|
||||
width: auto;
|
||||
padding-right: 8px;
|
||||
line-height: 32px;
|
||||
}
|
||||
.ant-form-item-control {
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
.ant-form-item-control-wrapper {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
.submitButtons {
|
||||
display: block;
|
||||
margin-bottom: 24px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 0.8em;
|
||||
height: 0.8em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ant-upload{
|
||||
width: 130px !important;
|
||||
height: 140px !important;
|
||||
}
|
||||
|
||||
.staffPhoto {
|
||||
font-size: 70px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.photoBox {
|
||||
.headIcon {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
svg {
|
||||
height: 150px;
|
||||
width: 140px;
|
||||
opacity: .75;
|
||||
}
|
||||
}
|
||||
:global {
|
||||
.ant-upload-select-picture-card{
|
||||
height: 150px;
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: @screen-lg) {
|
||||
.aa01tableListForm :global(.ant-form-item) {
|
||||
margin-right: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: @screen-md) {
|
||||
.aa01tableListForm :global(.ant-form-item) {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
import { PureComponent } from 'react'
|
||||
import * as plugins from 'antd'
|
||||
|
||||
class GlobalComponent extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.props = props
|
||||
|
||||
this.Affix = plugins.Affix
|
||||
this.Alert = plugins.Alert
|
||||
this.Anchor = plugins.Anchor
|
||||
this.AutoComplete = plugins.AutoComplete
|
||||
this.Avatar = plugins.Avatar
|
||||
this.BackTop = plugins.BackTop
|
||||
this.Badge = plugins.Badge
|
||||
this.Breadcrumb = plugins.Breadcrumb
|
||||
this.Button = plugins.Button
|
||||
this.Calendar = plugins.Calendar
|
||||
this.Card = plugins.Card
|
||||
this.Carousel = plugins.Carousel
|
||||
this.Cascader = plugins.Cascader
|
||||
this.Checkbox = plugins.Checkbox
|
||||
this.Col = plugins.Col
|
||||
this.Collapse = plugins.Collapse
|
||||
// this.Comment = plugins.Comment
|
||||
this.ConfigProvider = plugins.ConfigProvider
|
||||
this.Descriptions = plugins.Descriptions
|
||||
this.Divider = plugins.Divider
|
||||
this.Drawer = plugins.Drawer
|
||||
this.Dropdown = plugins.Dropdown
|
||||
this.Empty = plugins.Empty
|
||||
this.Form = plugins.Form
|
||||
this.Grid = plugins.Grid
|
||||
this.Image = plugins.Image
|
||||
this.Input = plugins.Input
|
||||
this.InputNumber = plugins.InputNumber
|
||||
this.Layout = plugins.Layout
|
||||
this.List = plugins.List
|
||||
this.Mentions = plugins.Mentions
|
||||
this.Menu = plugins.Menu
|
||||
this.Modal = plugins.Modal
|
||||
// this.PageHeader = plugins.PageHeader
|
||||
this.Pagination = plugins.Pagination
|
||||
this.Popconfirm = plugins.Popconfirm
|
||||
this.Popover = plugins.Popover
|
||||
this.Progress = plugins.Progress
|
||||
this.Radio = plugins.Radio
|
||||
this.Rate = plugins.Rate
|
||||
this.Result = plugins.Result
|
||||
this.Row = plugins.Row
|
||||
this.Segmented = plugins.Segmented
|
||||
this.Select = plugins.Select
|
||||
this.Skeleton = plugins.Skeleton
|
||||
this.Slider = plugins.Slider
|
||||
this.Space = plugins.Space
|
||||
this.Spin = plugins.Spin
|
||||
this.Statistic = plugins.Statistic
|
||||
this.Steps = plugins.Steps
|
||||
this.Switch = plugins.Switch
|
||||
this.Table = plugins.Table
|
||||
this.Tabs = plugins.Tabs
|
||||
this.Tag = plugins.Tag
|
||||
this.TimePicker = plugins.TimePicker
|
||||
this.Timeline = plugins.Timeline
|
||||
this.Tooltip = plugins.Tooltip
|
||||
this.Transfer = plugins.Transfer
|
||||
this.Tree = plugins.Tree
|
||||
this.TreeSelect = plugins.TreeSelect
|
||||
this.Typography = plugins.Typography
|
||||
this.Upload = plugins.Upload
|
||||
this.message = plugins.message
|
||||
}
|
||||
}
|
||||
|
||||
export default GlobalComponent
|
||||
@ -0,0 +1,6 @@
|
||||
import { createFromIconfontCN } from '@ant-design/icons';
|
||||
import defaultSettings from "../../../config/defaultSettings";
|
||||
|
||||
export const IconFont = createFromIconfontCN({
|
||||
scriptUrl: `//at.alicdn.com/t/font_2163129_p3ldyoksz3s.js`
|
||||
});
|
||||
@ -0,0 +1,5 @@
|
||||
import { IconFont } from "@/components/Icon/IconFont";
|
||||
|
||||
export default ({type, font = 13, style, className}) => {
|
||||
return <IconFont type={type} style={{fontSize: font, ...style}} className={className}/>
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
import MyIcon from "@/components/Icon/MyIcon"
|
||||
|
||||
export default ({icon, text, font = 13, style, className, onClick, back = true}) => {
|
||||
return back ?
|
||||
<span onClick={onClick} style={{...style}}>
|
||||
<MyIcon icon={icon} font={font} style={{...style}} className={className}/> {text}
|
||||
</span> :
|
||||
<span onClick={onClick} style={{...style}}>
|
||||
{text} <MyIcon font={font} style={{...style}} icon={icon} className={className}/>
|
||||
</span>
|
||||
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
import { Tooltip } from "antd";
|
||||
|
||||
export default ({icon, title, font, style, onClick}) => {
|
||||
return <Tooltip title={title}>
|
||||
<span onClick={onClick} style={{cursor: 'pointer', fontSize: font, ...style}}>{icon}</span>
|
||||
</Tooltip>
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
import { Tooltip } from "antd";
|
||||
|
||||
export default ({icon, title, font, style, text, onClick}) => {
|
||||
return <Tooltip title={title}>
|
||||
<span onClick={onClick} style={{cursor: 'pointer', fontSize: font, ...style}}>{icon} {text}</span>
|
||||
</Tooltip>
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
import MyIcon from './MyIcon';
|
||||
import TextIcon from './TextIcon';
|
||||
import TooltipIcon from './TooltipIcon';
|
||||
import TooltipTextIcon from './TooltipTextIcon';
|
||||
|
||||
const Icon = {
|
||||
MyIcon,
|
||||
TextIcon,
|
||||
TooltipIcon,
|
||||
TooltipTextIcon
|
||||
};
|
||||
|
||||
export {
|
||||
Icon as default,
|
||||
MyIcon,
|
||||
TextIcon,
|
||||
TooltipIcon,
|
||||
TooltipTextIcon
|
||||
};
|
||||
|
||||
@ -0,0 +1,141 @@
|
||||
import React, { PureComponent, createElement } from 'react'
|
||||
import { Modal, Tabs, Tooltip, Input} from 'antd'
|
||||
import * as Icon from '@ant-design/icons'
|
||||
import classNames from 'classnames'
|
||||
import styles from './index.less'
|
||||
|
||||
const { Search } = Input
|
||||
|
||||
const webIcons = ['AccountBookOutlined','AimOutlined','AlertOutlined','ApartmentOutlined','ApiOutlined','AppstoreAddOutlined','AppstoreOutlined','AudioOutlined','AudioMutedOutlined','AuditOutlined','BankOutlined','BarcodeOutlined','BarsOutlined','BellOutlined','BlockOutlined','BookOutlined','BorderOutlined','BorderlessTableOutlined','BranchesOutlined','BugOutlined','BuildOutlined','BulbOutlined','CalculatorOutlined','CalendarOutlined','CameraOutlined','CarOutlined','CarryOutOutlined','CiCircleOutlined','CiOutlined','ClearOutlined','CloudDownloadOutlined','CloudOutlined','CloudServerOutlined','CloudSyncOutlined','CloudUploadOutlined','ClusterOutlined','CodeOutlined','CoffeeOutlined','CommentOutlined','CompassOutlined','CompressOutlined','ConsoleSqlOutlined','ContactsOutlined','ContainerOutlined','ControlOutlined','CopyrightOutlined','CreditCardOutlined','CrownOutlined','CustomerServiceOutlined','DashboardOutlined','DatabaseOutlined','DeleteColumnOutlined','DeleteRowOutlined','DeliveredProcedureOutlined','DeploymentUnitOutlined','DesktopOutlined','DingtalkOutlined','DisconnectOutlined','DislikeOutlined','DollarCircleOutlined','DollarOutlined','DownloadOutlined','EllipsisOutlined','EnvironmentOutlined','EuroCircleOutlined','EuroOutlined','ExceptionOutlined','ExpandAltOutlined','ExpandOutlined','ExperimentOutlined','ExportOutlined','EyeOutlined','EyeInvisibleOutlined','FieldBinaryOutlined','FieldNumberOutlined','FieldStringOutlined','FieldTimeOutlined','FileAddOutlined','FileDoneOutlined','FileExcelOutlined','FileExclamationOutlined','FileOutlined','FileGifOutlined','FileImageOutlined','FileJpgOutlined','FileMarkdownOutlined','FilePdfOutlined','FilePptOutlined','FileProtectOutlined','FileSearchOutlined','FileSyncOutlined','FileTextOutlined','FileUnknownOutlined','FileWordOutlined','FileZipOutlined','FilterOutlined','FireOutlined','FlagOutlined','FolderAddOutlined','FolderOutlined','FolderOpenOutlined','FolderViewOutlined','ForkOutlined','FormatPainterOutlined','FrownOutlined','FunctionOutlined','FundProjectionScreenOutlined','FundViewOutlined','FunnelPlotOutlined','GatewayOutlined','GifOutlined','GiftOutlined','GlobalOutlined','GoldOutlined','GroupOutlined','HddOutlined','HeartOutlined','HistoryOutlined','HomeOutlined','HourglassOutlined','IdcardOutlined','ImportOutlined','InboxOutlined','InsertRowAboveOutlined','InsertRowBelowOutlined','InsertRowLeftOutlined','InsertRowRightOutlined','InsuranceOutlined','InteractionOutlined','KeyOutlined','LaptopOutlined','LayoutOutlined','LikeOutlined','LineOutlined','LinkOutlined','Loading3QuartersOutlined','LoadingOutlined','LockOutlined','MacCommandOutlined','MailOutlined','ManOutlined','MedicineBoxOutlined','MehOutlined','MenuOutlined','MergeCellsOutlined','MessageOutlined','MobileOutlined','MoneyCollectOutlined','MonitorOutlined','MoreOutlined','NodeCollapseOutlined','NodeExpandOutlined','NodeIndexOutlined','NotificationOutlined','NumberOutlined','OneToOneOutlined','PaperClipOutlined','PartitionOutlined','PayCircleOutlined','PercentageOutlined','PhoneOutlined','PictureOutlined','PlaySquareOutlined','PoundCircleOutlined','PoundOutlined','PoweroffOutlined','PrinterOutlined','ProfileOutlined','ProjectOutlined','PropertySafetyOutlined','PullRequestOutlined','PushpinOutlined','QrcodeOutlined','ReadOutlined','ReconciliationOutlined','RedEnvelopeOutlined','ReloadOutlined','RestOutlined','RobotOutlined','RocketOutlined','RotateLeftOutlined','RotateRightOutlined','SafetyCertificateOutlined','SafetyOutlined','SaveOutlined','ScanOutlined','ScheduleOutlined','SearchOutlined','SecurityScanOutlined','SelectOutlined','SendOutlined','SettingOutlined','ShakeOutlined','ShareAltOutlined','ShopOutlined','ShoppingCartOutlined','ShoppingOutlined','SisternodeOutlined','SkinOutlined','SmileOutlined','SolutionOutlined','SoundOutlined','SplitCellsOutlined','StarOutlined','SubnodeOutlined','SwitcherOutlined','SyncOutlined','TableOutlined','TabletOutlined','TagOutlined','TagsOutlined','TeamOutlined','ThunderboltOutlined','ToTopOutlined','ToolOutlined','TrademarkCircleOutlined','TrademarkOutlined','TransactionOutlined','TranslationOutlined','TrophyOutlined','UngroupOutlined','UnlockOutlined','UploadOutlined','UsbOutlined','UserAddOutlined','UserDeleteOutlined','UserOutlined','UserSwitchOutlined','UsergroupAddOutlined','UsergroupDeleteOutlined','VerifiedOutlined','VideoCameraAddOutlined','VideoCameraOutlined','WalletOutlined','WhatsAppOutlined','WifiOutlined','WomanOutlined']
|
||||
const directionIcons = ['StepBackwardOutlined','StepForwardOutlined','FastBackwardOutlined','FastForwardOutlined','ShrinkOutlined','ArrowsAltOutlined','DownOutlined','UpOutlined','LeftOutlined','RightOutlined','CaretUpOutlined','CaretDownOutlined','CaretLeftOutlined','CaretRightOutlined','UpCircleOutlined','DownCircleOutlined','LeftCircleOutlined','RightCircleOutlined','DoubleRightOutlined','DoubleLeftOutlined','VerticalLeftOutlined','VerticalRightOutlined','VerticalAlignTopOutlined','VerticalAlignMiddleOutlined','VerticalAlignBottomOutlined','ForwardOutlined','BackwardOutlined','RollbackOutlined','EnterOutlined','RetweetOutlined','SwapOutlined','SwapLeftOutlined','SwapRightOutlined','ArrowUpOutlined','ArrowDownOutlined','ArrowLeftOutlined','ArrowRightOutlined','PlayCircleOutlined','UpSquareOutlined','DownSquareOutlined','LeftSquareOutlined','RightSquareOutlined','LoginOutlined','LogoutOutlined','MenuFoldOutlined','MenuUnfoldOutlined','BorderBottomOutlined','BorderHorizontalOutlined','BorderInnerOutlined','BorderOuterOutlined','BorderLeftOutlined','BorderRightOutlined','BorderTopOutlined','BorderVerticleOutlined','PicCenterOutlined','PicLeftOutlined','PicRightOutlined','RadiusBottomleftOutlined','RadiusBottomrightOutlined','RadiusUpleftOutlined','RadiusUprightOutlined','FullscreenOutlined','FullscreenExitOutlined']
|
||||
const suggestionIcons = ['QuestionOutlined','QuestionCircleOutlined','PlusOutlined','PlusCircleOutlined','PauseOutlined','PauseCircleOutlined','MinusOutlined','MinusCircleOutlined','PlusSquareOutlined','MinusSquareOutlined','InfoOutlined','InfoCircleOutlined','ExclamationOutlined','ExclamationCircleOutlined','CloseOutlined','CloseCircleOutlined','CloseSquareOutlined','CheckOutlined','CheckCircleOutlined','CheckSquareOutlined','ClockCircleOutlined','WarningOutlined','IssuesCloseOutlined','StopOutlined']
|
||||
const editIcons = ['EditOutlined','FormOutlined','CopyOutlined','ScissorOutlined','DeleteOutlined','SnippetsOutlined','DiffOutlined','HighlightOutlined','AlignCenterOutlined','AlignLeftOutlined','AlignRightOutlined','BgColorsOutlined','BoldOutlined','ItalicOutlined','UnderlineOutlined','StrikethroughOutlined','RedoOutlined','UndoOutlined','ZoomInOutlined','ZoomOutOutlined','FontColorsOutlined','FontSizeOutlined','LineHeightOutlined','DashOutlined','SmallDashOutlined','SortAscendingOutlined','SortDescendingOutlined','DragOutlined','OrderedListOutlined','UnorderedListOutlined','RadiusSettingOutlined','ColumnWidthOutlined','ColumnHeightOutlined']
|
||||
const dataIcons = ['AreaChartOutlined','PieChartOutlined','BarChartOutlined','DotChartOutlined','LineChartOutlined','RadarChartOutlined','HeatMapOutlined','FallOutlined','RiseOutlined','StockOutlined','BoxPlotOutlined','FundOutlined','SlidersOutlined']
|
||||
const logoIcons = ['AndroidOutlined','AppleOutlined','WindowsOutlined','IeOutlined','ChromeOutlined','GithubOutlined','AliwangwangOutlined','DingdingOutlined','WeiboSquareOutlined','WeiboCircleOutlined','TaobaoCircleOutlined','Html5Outlined','WeiboOutlined','TwitterOutlined','WechatOutlined','YoutubeOutlined','AlipayCircleOutlined','TaobaoOutlined','SkypeOutlined','QqOutlined','MediumWorkmarkOutlined','GitlabOutlined','MediumOutlined','LinkedinOutlined','GooglePlusOutlined','DropboxOutlined','FacebookOutlined','CodepenOutlined','CodeSandboxOutlined','AmazonOutlined','GoogleOutlined','CodepenCircleOutlined','AlipayOutlined','AntDesignOutlined','AntCloudOutlined','AliyunOutlined','ZhihuOutlined','SlackOutlined','SlackSquareOutlined','BehanceOutlined','BehanceSquareOutlined','DribbbleOutlined','DribbbleSquareOutlined','InstagramOutlined','YuqueOutlined','AlibabaOutlined','YahooOutlined','RedditOutlined','SketchOutlined']
|
||||
|
||||
class IconModal extends PureComponent {
|
||||
state = {}
|
||||
|
||||
render() {
|
||||
const { visible, handleOk, handleCancel, handleSearch, selectIcon, selectedItem, searchItem } = this.props
|
||||
let webIconsTem
|
||||
let directionIconsTem
|
||||
let suggestionIconsTem
|
||||
let editIconsTem
|
||||
let dataIconsTem
|
||||
let logoIconsTem
|
||||
|
||||
if (searchItem) {
|
||||
webIconsTem = webIcons.filter(item=>item.toLocaleLowerCase().indexOf(searchItem?.toLocaleLowerCase()) > -1)
|
||||
editIconsTem = editIcons.filter(item=>item.toLocaleLowerCase().indexOf(searchItem?.toLocaleLowerCase()) > -1)
|
||||
dataIconsTem = dataIcons.filter(item=>item.toLocaleLowerCase().indexOf(searchItem?.toLocaleLowerCase()) > -1)
|
||||
logoIconsTem = logoIcons.filter(item=>item.toLocaleLowerCase().indexOf(searchItem?.toLocaleLowerCase()) > -1)
|
||||
} else {
|
||||
webIconsTem = webIcons
|
||||
editIconsTem = editIcons
|
||||
dataIconsTem = dataIcons
|
||||
logoIconsTem = logoIcons
|
||||
}
|
||||
|
||||
const tabItems = [
|
||||
{
|
||||
key: '1',
|
||||
label: '网站通用图标',
|
||||
children: (
|
||||
<div style={{ height: '220px', overflowY: 'auto' }}>
|
||||
{webIconsTem.map((item) => {
|
||||
return <Tooltip title={item} text key={item}>
|
||||
{
|
||||
createElement(
|
||||
Icon[item],{
|
||||
className: classNames(styles.icon, {[styles.selectedicon]: item?.toLocaleLowerCase() === selectedItem?.toLocaleLowerCase()}),
|
||||
onClick: () => { selectIcon(item) }
|
||||
}
|
||||
)
|
||||
}
|
||||
</Tooltip>
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: '编辑类图标',
|
||||
children: (
|
||||
<div style={{ height: '220px', overflowY: 'auto' }}>
|
||||
{editIconsTem.map((item) => {
|
||||
return <Tooltip title={item} text key={item}>
|
||||
{
|
||||
createElement(
|
||||
Icon[item],{
|
||||
className: classNames(styles.icon, {[styles.selectedicon]: item?.toLocaleLowerCase() === selectedItem?.toLocaleLowerCase()}),
|
||||
onClick: () => { selectIcon(item) }
|
||||
}
|
||||
)
|
||||
}
|
||||
</Tooltip>
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
label: '数据类图标',
|
||||
children: (
|
||||
<div style={{ height: '220px', overflowY: 'auto' }}>
|
||||
{dataIconsTem.map((item) => {
|
||||
return <Tooltip title={item} text key={item}>
|
||||
{
|
||||
createElement(
|
||||
Icon[item],{
|
||||
className: classNames(styles.icon, {[styles.selectedicon]: item?.toLocaleLowerCase() === selectedItem?.toLocaleLowerCase()}),
|
||||
onClick: () => { selectIcon(item) }
|
||||
}
|
||||
)
|
||||
}
|
||||
</Tooltip>
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
key: '4',
|
||||
label: '品牌和标识',
|
||||
children: (
|
||||
<div style={{ height: '220px', overflowY: 'auto' }}>
|
||||
{logoIconsTem.map((item) => {
|
||||
return <Tooltip title={item} text key={item}>
|
||||
{
|
||||
createElement(
|
||||
Icon[item],{
|
||||
className: classNames(styles.icon, {[styles.selectedicon]: item?.toLocaleLowerCase() === selectedItem?.toLocaleLowerCase()}),
|
||||
onClick: () => { selectIcon(item) }
|
||||
}
|
||||
)
|
||||
}
|
||||
</Tooltip>
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
]
|
||||
|
||||
return (
|
||||
<Modal
|
||||
title='图标选择'
|
||||
open={visible}
|
||||
width='640px'
|
||||
centered
|
||||
destroyOnClose
|
||||
onOk={handleOk}
|
||||
onCancel={handleCancel}
|
||||
>
|
||||
<Search placeholder='在此搜索图标' onSearch={handleSearch} enterButton />
|
||||
|
||||
<Tabs items={tabItems} defaultActiveKey='1' />
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default IconModal
|
||||
@ -0,0 +1,21 @@
|
||||
.icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
font-size: 20px;
|
||||
line-height: 40px;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.icon:hover {
|
||||
cursor: pointer;
|
||||
background: #515151;
|
||||
color: honeydew;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.selectedicon {
|
||||
background: #515151;
|
||||
color: honeydew;
|
||||
border-radius: 5px;
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
import React, { PureComponent } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Tooltip } from 'antd'
|
||||
import styles from './index.less'
|
||||
|
||||
export default class LineWrap extends PureComponent {
|
||||
static propTypes = {
|
||||
title: PropTypes.string,
|
||||
lineClampNum: PropTypes.number,
|
||||
// colWidth: PropTypes.string
|
||||
}
|
||||
|
||||
render() {
|
||||
const { title, lineClampNum, colWidth } = this.props
|
||||
const lineWidth = colWidth !== '' && colWidth !== undefined ? colWidth : '80px'
|
||||
|
||||
return (
|
||||
<Tooltip placement="topLeft" title={title}>
|
||||
<span className={styles.col} style={{ WebkitLineClamp: lineClampNum, width: lineWidth }}>
|
||||
{title}
|
||||
</span>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
.col {
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.content > span {
|
||||
display: block;
|
||||
}
|
||||
@ -0,0 +1,26 @@
|
||||
import './index.less'
|
||||
|
||||
const Loading = () => {
|
||||
return (
|
||||
<div className='um_content'>
|
||||
<div className='spinner'>
|
||||
<div id='loading'>
|
||||
<div className='spinDot'></div>
|
||||
<div className='spinDot'></div>
|
||||
<div className='spinDot'></div>
|
||||
<div className='spinDot'></div>
|
||||
<div className='spinDot'></div>
|
||||
<div className='spinDot'></div>
|
||||
<div className='spinDot'></div>
|
||||
<div className='spinDot'></div>
|
||||
</div>
|
||||
|
||||
<div className='loadingInfo'>
|
||||
<span>页面初始化中......</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Loading
|
||||
@ -0,0 +1,126 @@
|
||||
.um_content {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-color: rgba(255,255,255);
|
||||
z-index: 1200;
|
||||
overflow: auto;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
|
||||
.spinner {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
margin-right: -50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 120px;
|
||||
height: 80px;
|
||||
|
||||
#loading {
|
||||
position: relative;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin: 0 auto;
|
||||
|
||||
.spinDot {
|
||||
width: 0.3em;
|
||||
height: 0.3em;
|
||||
border-radius: 2px;
|
||||
background: #68b2ce;
|
||||
position: absolute;
|
||||
animation: spinDot linear 0.8s infinite;
|
||||
-webkit-animation: spinDot linear 0.8s infinite;
|
||||
|
||||
&:nth-child(1) {
|
||||
left: 24px;
|
||||
top: 2px;
|
||||
animation-delay: 0s;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
left: 40px;
|
||||
top: 8px;
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
left: 47px;
|
||||
top: 24px;
|
||||
animation-delay: 0.1s;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
left: 40px;
|
||||
top: 40px;
|
||||
animation-delay: 0.2s;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
left: 24px;
|
||||
top: 47px;
|
||||
animation-delay: 0.4s;
|
||||
}
|
||||
|
||||
&:nth-child(6) {
|
||||
left: 8px;
|
||||
top: 40px;
|
||||
animation-delay: 0.5s;
|
||||
}
|
||||
|
||||
&:nth-child(7) {
|
||||
left: 2px;
|
||||
top: 24px;
|
||||
animation-delay: 0.6s;
|
||||
}
|
||||
|
||||
&:nth-child(8) {
|
||||
left: 8px;
|
||||
top: 8px;
|
||||
animation-delay: 0.7s;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spinDot {
|
||||
0%, 40%, 100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
20% {
|
||||
transform: scale(3);
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes spinDot {
|
||||
0%, 40%, 100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
|
||||
20% {
|
||||
transform: scale(3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.loadingInfo {
|
||||
width: 140px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
top: 70%;
|
||||
text-align: center;
|
||||
text-indent: 4px;
|
||||
|
||||
> span {
|
||||
font-family: "Microsoft YaHei", Helvetica, Arial, Lucida Grande, Tahoma, sans-serif, Raleway, sans-serif;
|
||||
color: black;
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
import { PureComponent } from 'react'
|
||||
|
||||
class NotificationTemplate extends PureComponent {
|
||||
// 根据需求,此组件不再显示任何内容
|
||||
render() {
|
||||
return <div style={{ display: 'none' }} />;
|
||||
}
|
||||
}
|
||||
|
||||
export default NotificationTemplate
|
||||
@ -0,0 +1,23 @@
|
||||
.deptContentHidden {
|
||||
font-family: PingFangSC-Regular, serif;
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
letter-spacing: 0.2px;
|
||||
text-align: justify;
|
||||
line-height: 22px;
|
||||
height: 45px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.deptContent {
|
||||
font-family: PingFangSC-Regular, serif;
|
||||
font-size: 14px;
|
||||
color: #666666;
|
||||
letter-spacing: 0.2px;
|
||||
text-align: justify;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.more-btn {
|
||||
float: right;
|
||||
}
|
||||
@ -0,0 +1,59 @@
|
||||
import React, {PureComponent} from 'react';
|
||||
import { Input } from 'antd';
|
||||
import styles from '../index.less'
|
||||
|
||||
const formatNumber = (value) => {
|
||||
value += '';
|
||||
const list = value.split('.');
|
||||
const prefix = list[0].charAt(0) === '-' ? '-' : '';
|
||||
let num = prefix ? list[0].slice(1) : list[0];
|
||||
let result = '';
|
||||
while (num.length > 3) {
|
||||
result = `,${num.slice(-3)}${result}`;
|
||||
num = num.slice(0, num.length - 3);
|
||||
}
|
||||
if (num) {
|
||||
result = num + result;
|
||||
}
|
||||
return `${prefix}${result}${list[1] ? `.${list[1]}` : ''}`;
|
||||
}
|
||||
|
||||
class NumberInput extends PureComponent {
|
||||
onChange = e => {
|
||||
const { value } = e.target;
|
||||
const reg = /^\d*?$/;
|
||||
if ((!isNaN(value) && reg.test(value)) || value === '') {
|
||||
this.props.onChange(value);
|
||||
}
|
||||
};
|
||||
|
||||
// '.' at the end or only '-' in the input box.
|
||||
onBlur = () => {
|
||||
const { value, onBlur, onChange } = this.props;
|
||||
let valueTemp = value;
|
||||
if (value.charAt(value.length - 1) === '.') {
|
||||
valueTemp = value.slice(0, -1);
|
||||
}
|
||||
onChange(valueTemp.replace(/0*(\d+)/, '$1'));
|
||||
if (onBlur) {
|
||||
onBlur();
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { placeholder, min } = this.props;
|
||||
|
||||
return (
|
||||
<Input
|
||||
min={min !== 0 ? min : 0}
|
||||
{...this.props}
|
||||
onChange={this.onChange}
|
||||
// onBlur={this.onBlur}
|
||||
placeholder={placeholder !== "" ? placeholder : ""}
|
||||
// maxLength={25}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default NumberInput;
|
||||
@ -0,0 +1,102 @@
|
||||
import React, {PureComponent} from 'react';
|
||||
import { Tooltip, InputNumber } from 'antd';
|
||||
import styles from '../index.less'
|
||||
import {NumberInput} from "@/components/NumberInput";
|
||||
|
||||
|
||||
const formatNumber = (value) => {
|
||||
value += '';
|
||||
const list = value.split('.');
|
||||
const prefix = list[0].charAt(0) === '-' ? '-' : '';
|
||||
let num = prefix ? list[0].slice(1) : list[0];
|
||||
let result = '';
|
||||
while (num.length > 3) {
|
||||
result = `,${num.slice(-3)}${result}`;
|
||||
num = num.slice(0, num.length - 3);
|
||||
}
|
||||
if (num) {
|
||||
result = num + result;
|
||||
}
|
||||
return `${prefix}${result}${list[1] ? `.${list[1]}` : ''}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 金额处理
|
||||
*/
|
||||
class NumericInput extends PureComponent {
|
||||
|
||||
state = {
|
||||
disabled: false,
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
if(undefined != nextProps.disabled && nextProps.disabled !== this.props.disabled) {
|
||||
this.setState({disabled: nextProps.disabled});
|
||||
}
|
||||
}
|
||||
|
||||
onChange = e => {
|
||||
// const { value } = e.target; // input 取值方式
|
||||
const value = e + '';
|
||||
const reg = /^\d*(\.\d*)?$/;
|
||||
if ((!isNaN(value) && reg.test(value)) || value === '') {
|
||||
this.props.onChange(value);
|
||||
}
|
||||
};
|
||||
|
||||
// '.' at the end or only '-' in the input box.
|
||||
onBlur = () => {
|
||||
const { value, onBlur, onChange } = this.props;
|
||||
|
||||
if(value) {
|
||||
|
||||
let valueTemp = value + '';
|
||||
if (typeof(valueTemp) == 'string' && valueTemp?.charAt(valueTemp.length - 1) === '.') {
|
||||
valueTemp = valueTemp.slice(0, -1);
|
||||
}
|
||||
onChange(valueTemp?.replace(/0*(\d+)/, '$1'));
|
||||
if (onBlur) {
|
||||
onBlur();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
render() {
|
||||
const { value, placeholder, min,precision } = this.props;
|
||||
const valueTem = value || value != undefined ? value + '' : '';
|
||||
const {disabled} = this.state;
|
||||
const title = valueTem ? (
|
||||
<span className={styles.numericInputTitle}>{valueTem !== '-' ? '¥' + formatNumber(valueTem) : '-'}</span>
|
||||
) : (
|
||||
'请输入'
|
||||
);
|
||||
return (
|
||||
<Tooltip
|
||||
trigger={['focus']}
|
||||
title={title}
|
||||
placement="topLeft"
|
||||
overlayClassName="numeric-input"
|
||||
>
|
||||
<InputNumber
|
||||
min={min !== 0 ? min : 0}
|
||||
max={10000000000}
|
||||
{...this.props}
|
||||
value={valueTem}
|
||||
onChange={this.onChange}
|
||||
onBlur={this.onBlur}
|
||||
placeholder={placeholder !== "" ? placeholder : ""}
|
||||
formatter={value => `¥${value}`.replace(/\B(?=(\d{3})+(?!\d))/g, ',').replace(/¥+/g, "¥")}
|
||||
parser={value => `${value}`.replace(/\¥|\$\sR?|(,*)/g, '').replace(/¥+/g, "")}
|
||||
precision={precision? precision : 2}
|
||||
maxLength={14}
|
||||
disabled={disabled}
|
||||
// addonAfter={('元')}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default NumericInput;
|
||||
@ -0,0 +1,12 @@
|
||||
import NumberInput from './NumberInput';
|
||||
import NumericInput from './NumericInput';
|
||||
|
||||
const input = {
|
||||
NumberInput,
|
||||
NumericInput,
|
||||
};
|
||||
export {
|
||||
input as default,
|
||||
NumberInput,
|
||||
NumericInput,
|
||||
};
|
||||
@ -0,0 +1,10 @@
|
||||
|
||||
|
||||
.numeric-input .ant-tooltip-inner {
|
||||
min-width: 32px;
|
||||
min-height: 37px;
|
||||
}
|
||||
|
||||
.numeric-input .numeric-input-title {
|
||||
font-size: 14px;
|
||||
}
|
||||
@ -0,0 +1,125 @@
|
||||
import {PureComponent} from 'react';
|
||||
import {TreeSelect} from 'antd';
|
||||
import { connect, history } from '@umijs/max';
|
||||
|
||||
const {TreeNode} = TreeSelect;
|
||||
|
||||
@connect(({globaldata, loading}) => ({
|
||||
globaldata,
|
||||
loading: loading.models.globaldata
|
||||
}))
|
||||
|
||||
class SelectDeptTree extends PureComponent {
|
||||
state = {
|
||||
value: this.props.value,
|
||||
treeData: [
|
||||
{title: '部门', id: '000000000000', key: '000000000000', value: '000000000000', dept_id: '000000000000', dept_code: "000"},
|
||||
],
|
||||
};
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
if(undefined != nextProps.value && nextProps.value !== this.props.value) {
|
||||
this.setState({value: nextProps.value});
|
||||
}
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
onChange = (value, label, extra) => {
|
||||
|
||||
if (value != '000000000000') {
|
||||
|
||||
const {selectedDeptTreeValue} = this.props;
|
||||
if(selectedDeptTreeValue){
|
||||
const selectDept = {
|
||||
dept_code: value,
|
||||
title: label[0],
|
||||
}
|
||||
selectedDeptTreeValue(selectDept, label, extra);
|
||||
}
|
||||
this.setState({value});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
onSelect = value => {
|
||||
const {onSelect} = this.props;
|
||||
if(onSelect){
|
||||
onSelect(value)
|
||||
}
|
||||
}
|
||||
|
||||
onTreeExpand = expandedKeys => {
|
||||
const {onTreeExpand} = this.props;
|
||||
if(onTreeExpand){
|
||||
onTreeExpand(expandedKeys)
|
||||
}
|
||||
}
|
||||
|
||||
updateTreeData(list, key, children) {
|
||||
return list.map(node => {
|
||||
if (node.key === key) {
|
||||
return {
|
||||
...node,
|
||||
children,
|
||||
};
|
||||
} else if (node.children) {
|
||||
return {
|
||||
...node,
|
||||
children: this.updateTreeData(node.children, key, children),
|
||||
};
|
||||
}
|
||||
return node;
|
||||
});
|
||||
}
|
||||
|
||||
onLoadData = ({id, key, children}) => {
|
||||
const {dispatch} = this.props;
|
||||
const params = {
|
||||
parentid: id,
|
||||
};
|
||||
return new Promise((resolve) => {
|
||||
if (children) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
dispatch({
|
||||
type: 'globaldata/get_prodepttree_by_parentid_for_prodept',
|
||||
payload: params,
|
||||
callback: (res) => {
|
||||
if(res.success == true) {
|
||||
// treeNode.props.dataRef.children = res.data;
|
||||
this.setState({
|
||||
treeData: this.updateTreeData(this.state.treeData, key, res.data)
|
||||
});
|
||||
resolve();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
const { treeData, value } = this.state;
|
||||
const { placeholder } = this.props;
|
||||
return (
|
||||
<TreeSelect
|
||||
showSearch
|
||||
value={value}
|
||||
dropdownStyle={{maxHeight: 400, overflow: 'auto'}}
|
||||
placeholder={placeholder == null ? null : "请选择部门"}
|
||||
treeDefaultExpandAll
|
||||
onSelect={this.onSelect}
|
||||
onChange={this.onChange}
|
||||
onTreeExpand={this.onTreeExpand}
|
||||
loadData={this.onLoadData}
|
||||
treeData={treeData}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SelectDeptTree;
|
||||
@ -0,0 +1,119 @@
|
||||
import { PureComponent } from 'react'
|
||||
import { TreeSelect } from 'antd'
|
||||
const { TreeNode } = TreeSelect
|
||||
|
||||
class SelectEbookArticleTypeTree extends PureComponent {
|
||||
state = {
|
||||
value: undefined,
|
||||
treeData: [
|
||||
{ title: '分类', key: '000000000000', id: '000000000000', levelcode: '000000000000', value: '000000000000' }
|
||||
]
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state.value = props?.value
|
||||
}
|
||||
|
||||
onChange = (value, label, extra) => {
|
||||
if (extra.key !== '000000000000') {
|
||||
const { selectedEbookArticleTypeTreeValue } = this.props
|
||||
selectedEbookArticleTypeTreeValue({key: value, label: label[0]})
|
||||
this.setState({ value: {label: label[0]} })
|
||||
}
|
||||
}
|
||||
|
||||
onSelect = value => {
|
||||
|
||||
}
|
||||
|
||||
onTreeExpand = expandedKeys => {
|
||||
|
||||
}
|
||||
|
||||
updateTreeData(list, key, children) {
|
||||
return list.map(node => {
|
||||
if (node.key === key) {
|
||||
return {
|
||||
...node,
|
||||
key: node.id,
|
||||
value: node.value,
|
||||
children
|
||||
}
|
||||
} else if (node.children) {
|
||||
return {
|
||||
...node,
|
||||
key: node.id,
|
||||
value: node.value,
|
||||
children: this.updateTreeData(node.children, key, children)
|
||||
}
|
||||
}
|
||||
|
||||
return node
|
||||
})
|
||||
}
|
||||
|
||||
onLoadData = ({id, key, children}) => {
|
||||
const { dispatch } = this.props
|
||||
const params = {
|
||||
parentid: id
|
||||
}
|
||||
|
||||
return new Promise((resolve) => {
|
||||
if (children) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: 'globaldata/get_proebookarticletypetree_by_parentid',
|
||||
payload: params,
|
||||
callback: (res) => {
|
||||
if(res.success === true) {
|
||||
// treeNode.props.dataRef.children = res.list
|
||||
this.setState({
|
||||
treeData: this.updateTreeData(this.state.treeData, key, res.list)
|
||||
})
|
||||
|
||||
resolve()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
renderTreeNodes = data =>
|
||||
data.map(item => {
|
||||
if (item.children) {
|
||||
return (
|
||||
<TreeNode title={item.title} key={item.key} dataRef={item} value={item.key}>
|
||||
{this.renderTreeNodes(item.children)}
|
||||
</TreeNode>
|
||||
)
|
||||
}
|
||||
|
||||
return <TreeNode {...item} value={item.key} dataRef={item} title={item.title} key={item.key} />
|
||||
})
|
||||
|
||||
render() {
|
||||
const { value } = this.props
|
||||
const { treeData } = this.state
|
||||
|
||||
return (
|
||||
<TreeSelect
|
||||
showSearch
|
||||
value={value?.label}
|
||||
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||
placeholder='请选择分类'
|
||||
treeDefaultExpandAll
|
||||
onSelect={this.onSelect}
|
||||
onChange={this.onChange}
|
||||
onTreeExpand={this.onTreeExpand}
|
||||
loadData={this.onLoadData}
|
||||
treeData={treeData}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default SelectEbookArticleTypeTree
|
||||
@ -0,0 +1,122 @@
|
||||
import { PureComponent } from 'react'
|
||||
import { TreeSelect } from 'antd'
|
||||
import { connect } from '@umijs/max'
|
||||
|
||||
const emptyValue = { label: null, value: null }
|
||||
|
||||
@connect(({ globaldata, loading }) => ({
|
||||
globaldata,
|
||||
loading: loading.models.globaldata
|
||||
}))
|
||||
|
||||
class SelectMenuTree extends PureComponent {
|
||||
state = {
|
||||
treeData: [],
|
||||
cacheTreeData: [],
|
||||
value: emptyValue,
|
||||
cacheValue: emptyValue
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps (nextProps, state) {
|
||||
let newState = {}
|
||||
|
||||
if (!!nextProps.treeData && nextProps.treeData !== state.cacheTreeData) {
|
||||
newState = {
|
||||
...newState,
|
||||
treeData: nextProps?.treeData ?? [],
|
||||
cacheTreeData: nextProps?.treeData ?? []
|
||||
}
|
||||
}
|
||||
|
||||
if (!!nextProps.value && nextProps.value !== state.cacheValue) {
|
||||
newState = {
|
||||
...newState,
|
||||
value: nextProps?.value ?? emptyValue,
|
||||
cacheValue: nextProps?.cacheValue ?? emptyValue
|
||||
}
|
||||
}
|
||||
|
||||
return Object.keys(newState)?.length > 0 ? newState : null
|
||||
}
|
||||
|
||||
updateTreeData(list, key, children) {
|
||||
return list.map(node => {
|
||||
if (node.id === key) {
|
||||
return {
|
||||
...node,
|
||||
children
|
||||
}
|
||||
} else if (node.children) {
|
||||
return {
|
||||
...node,
|
||||
children: this.updateTreeData(node.children, key, children)
|
||||
}
|
||||
}
|
||||
|
||||
return node
|
||||
})
|
||||
}
|
||||
|
||||
loadData = ({ id, key, children }) => {
|
||||
const { dispatch, params: loadParams } = this.props
|
||||
const params = {
|
||||
parentid: id,
|
||||
...loadParams
|
||||
}
|
||||
|
||||
return new Promise(resolve => {
|
||||
if (children) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: 'globaldata/get_promenutree_by_parentid_for_promenu',
|
||||
payload: params,
|
||||
callback: res => {
|
||||
if(res.success) {
|
||||
this.setState({
|
||||
treeData: this.updateTreeData(this.state.treeData, key, res.list)
|
||||
})
|
||||
|
||||
resolve()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
onChange = (data, _, extra) => {
|
||||
const { selectMenuTree, onChange } = this.props
|
||||
const { label, value } = data ?? {}
|
||||
|
||||
if (value === '000000000000') return
|
||||
const params = { label: label ?? null, value: value ?? null }
|
||||
|
||||
selectMenuTree && selectMenuTree(params, label, extra)
|
||||
!selectMenuTree && onChange && onChange(params)
|
||||
this.setState({ value: params })
|
||||
}
|
||||
|
||||
render () {
|
||||
const { treeData, value } = this.state
|
||||
|
||||
return (
|
||||
<TreeSelect
|
||||
allowClear
|
||||
showSearch
|
||||
treeDefaultExpandAll
|
||||
labelInValue
|
||||
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||
loadData={this.loadData}
|
||||
treeData={treeData}
|
||||
value={value}
|
||||
onChange={this.onChange}
|
||||
placeholder='请选择菜单'
|
||||
fieldNames={{ label: 'title', value: 'id', children: 'children' }}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default SelectMenuTree
|
||||
@ -0,0 +1,91 @@
|
||||
import {PureComponent} from 'react';
|
||||
import {TreeSelect} from 'antd';
|
||||
|
||||
const {TreeNode} = TreeSelect;
|
||||
|
||||
class SelectOptionTree extends PureComponent {
|
||||
state = {
|
||||
value: undefined,
|
||||
treeData: this.props.treeData || []
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
if(undefined !== nextProps.value && nextProps.value !== this.props.value) {
|
||||
this.setState({value: nextProps.value});
|
||||
}
|
||||
if(undefined !== nextProps.treeData) {
|
||||
this.setState({treeData: nextProps.treeData});
|
||||
}
|
||||
}
|
||||
|
||||
onSelect = (value) => {
|
||||
const {onChange} = this.props;
|
||||
|
||||
if(onChange){
|
||||
onChange(value);
|
||||
}
|
||||
}
|
||||
|
||||
onChangeValue = (value) => {
|
||||
const {onChange} = this.props;
|
||||
let values = '';
|
||||
|
||||
if (undefined !== value) {
|
||||
values = value;
|
||||
}
|
||||
if(onChange){
|
||||
onChange(values);
|
||||
}
|
||||
this.setState({
|
||||
value: values
|
||||
})
|
||||
}
|
||||
|
||||
renderTreeNodes = data =>
|
||||
Array.from(data).map(item => {
|
||||
const {type} = this.props;
|
||||
let val = item.value ? item.value : null;
|
||||
let title = `${item.title ? item.title : ''}[${val}]`;
|
||||
|
||||
if (item.children?.length > 0) {
|
||||
item.disabled = type !== 'area';
|
||||
|
||||
return (
|
||||
<TreeNode title={title} key={val} value={val} disabled={item.disabled}>
|
||||
{this.renderTreeNodes(item.children)}
|
||||
</TreeNode>
|
||||
);
|
||||
}
|
||||
return <TreeNode {...item} title={title} key={val} value={val}/>;
|
||||
});
|
||||
|
||||
render() {
|
||||
const { placeholder, disabled, selectWidth } = this.props;
|
||||
const { treeData, value } = this.state;
|
||||
|
||||
return (
|
||||
<TreeSelect
|
||||
allowClear
|
||||
showSearch
|
||||
value={value}
|
||||
dropdownStyle={{maxHeight: 400, overflow: 'auto'}}
|
||||
style={{width: '100%'}}
|
||||
dropdownMatchSelectWidth={selectWidth ? selectWidth : 255}
|
||||
placeholder={placeholder ? placeholder : ''}
|
||||
disabled={disabled ? disabled : false}
|
||||
onSelect={this.onSelect}
|
||||
onChange={this.onChangeValue}
|
||||
treeLine
|
||||
treeNodeFilterProp="title"
|
||||
>
|
||||
{this.renderTreeNodes(treeData)}
|
||||
</TreeSelect>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default SelectOptionTree;
|
||||
@ -0,0 +1,133 @@
|
||||
import {PureComponent} from 'react'
|
||||
import {TreeSelect} from 'antd'
|
||||
import {connect} from '@umijs/max'
|
||||
|
||||
const {TreeNode} = TreeSelect
|
||||
|
||||
@connect(({globaldata, loading}) => ({
|
||||
globaldata,
|
||||
loading: loading.models.globaldata,
|
||||
}))
|
||||
class SelectOrganTree extends PureComponent {
|
||||
state = {
|
||||
value: undefined,
|
||||
treeData: [
|
||||
{ title: '机构', key: '000000000000', value: '000000000000', org_id: '000000000000', org_code: '0000', id: '000000000000' }
|
||||
],
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
|
||||
UNSAFE_componentWillReceiveProps(nextProps) {
|
||||
if(undefined !== nextProps.value && nextProps.value !== this.props.value) {
|
||||
this.setState({value: nextProps.value})
|
||||
}
|
||||
}
|
||||
|
||||
onChange = (value, label, extra) => {
|
||||
if (value !== '000000000000') {
|
||||
const {selectedOrganTreeValue} = this.props
|
||||
if(selectedOrganTreeValue){
|
||||
const selectDept = {
|
||||
org_code: value,
|
||||
title: label[0]
|
||||
}
|
||||
selectedOrganTreeValue(selectDept, label, extra)
|
||||
}
|
||||
this.setState({value})
|
||||
}
|
||||
}
|
||||
|
||||
onSelect = value => {
|
||||
const {onSelect} = this.props
|
||||
if(onSelect){
|
||||
onSelect(value)
|
||||
}
|
||||
}
|
||||
|
||||
onTreeExpand = expandedKeys => {
|
||||
const {onTreeExpand} = this.props
|
||||
if(onTreeExpand){
|
||||
onTreeExpand(expandedKeys)
|
||||
}
|
||||
}
|
||||
|
||||
updateTreeData(list, key, children) {
|
||||
return list.map(node => {
|
||||
if (node.value === key) {
|
||||
return {
|
||||
...node,
|
||||
children
|
||||
}
|
||||
} else if (node.children) {
|
||||
return {
|
||||
...node,
|
||||
children: this.updateTreeData(node.children, key, children)
|
||||
}
|
||||
}
|
||||
|
||||
return node
|
||||
})
|
||||
}
|
||||
|
||||
onLoadData = ({ key, children, id }) => {
|
||||
const { dispatch } = this.props
|
||||
const params = { parentid: id }
|
||||
|
||||
return new Promise((resolve) => {
|
||||
if (children) {
|
||||
resolve()
|
||||
return
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: 'globaldata/get_proorgtree_by_parentid_for_proorg',
|
||||
payload: params,
|
||||
callback: (res) => {
|
||||
if(res.success === true) {
|
||||
this.setState({
|
||||
treeData: this.updateTreeData(this.state.treeData, key, res.list)
|
||||
})
|
||||
|
||||
resolve()
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
renderTreeNodes = data =>
|
||||
data.map(item => {
|
||||
if (item.children) {
|
||||
return (
|
||||
<TreeNode title={item.title} key={item.title} dataRef={item} value={item.title}>
|
||||
{this.renderTreeNodes(item.children)}
|
||||
</TreeNode>
|
||||
)
|
||||
}
|
||||
return <TreeNode {...item} value={item.title} dataRef={item} title={item.title} key={item.title}/>
|
||||
})
|
||||
|
||||
render() {
|
||||
const { treeData, value } = this.state
|
||||
|
||||
return (
|
||||
<TreeSelect
|
||||
showSearch
|
||||
value={value}
|
||||
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
|
||||
placeholder='请选择机构'
|
||||
treeDefaultExpandAll
|
||||
onSelect={this.onSelect}
|
||||
onChange={this.onChange}
|
||||
onTreeExpand={this.onTreeExpand}
|
||||
loadData={this.onLoadData}
|
||||
treeData={treeData}
|
||||
/>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default SelectOrganTree
|
||||
@ -0,0 +1,95 @@
|
||||
import { PureComponent } from 'react'
|
||||
import { List } from 'antd'
|
||||
import styles from './index.less'
|
||||
|
||||
const { Item: ListItem } = List
|
||||
|
||||
class StandardList extends PureComponent {
|
||||
state = {
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
const { selectedRows, data = {} } = props
|
||||
}
|
||||
|
||||
/*static getDerivedStateFromProps(nextProps) {
|
||||
// clean state
|
||||
if (nextProps.selectedRows.length === 0) {
|
||||
return {
|
||||
selectedRowKeys: [],
|
||||
}
|
||||
}
|
||||
return null
|
||||
}*/
|
||||
|
||||
handleListChange = (pagination) => {
|
||||
const { onChange } = this.props
|
||||
/*this.setState({
|
||||
indeterminate: false,
|
||||
checkAll: false,
|
||||
})*/
|
||||
|
||||
onChange && onChange(pagination)
|
||||
}
|
||||
|
||||
onCheckAllChange = e => {
|
||||
const { data = {}, onSelectRow } = this.props
|
||||
|
||||
this.setState({
|
||||
selectedRows: e.target.checked ? data.list : [],
|
||||
indeterminate: false,
|
||||
checkAll: e.target.checked
|
||||
})
|
||||
|
||||
onSelectRow && onSelectRow(e.target.checked ? data.list : [])
|
||||
}
|
||||
|
||||
onChange = checkedValues => {
|
||||
const { data = {}, onSelectRow } = this.props
|
||||
|
||||
this.setState({
|
||||
selectedRows: checkedValues,
|
||||
indeterminate: !!checkedValues.length && checkedValues.length < data.list.length,
|
||||
checkAll: checkedValues.length === data.list.length
|
||||
})
|
||||
|
||||
onSelectRow && onSelectRow(checkedValues)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { data = {}, rowKey, loading, actions, details, className } = this.props
|
||||
const { list = [], pagination } = data
|
||||
const paginationProps = {
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
...pagination,
|
||||
pageSizeOptions: [8, 16, 40, 80],
|
||||
onChange: page => {
|
||||
pagination.current = page
|
||||
this.handleListChange(pagination)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={className ?? styles.cardList}>
|
||||
{list &&
|
||||
<List
|
||||
rowKey={rowKey || 'key'}
|
||||
grid={{ gutter: 16, xs: 1, sm: 2, md: 3, lg: 3, xl: 4, xxl: 4 }}
|
||||
loading={loading}
|
||||
pagination={paginationProps}
|
||||
dataSource={list}
|
||||
renderItem={item => (
|
||||
<ListItem>
|
||||
{details(item)}
|
||||
</ListItem>
|
||||
)}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default StandardList
|
||||
@ -0,0 +1,53 @@
|
||||
@heading-color: fade(#000, 85%);
|
||||
@primary-color: #1890ff;
|
||||
@text-color-secondary: fade(#000, 45%);
|
||||
|
||||
.card {
|
||||
:global {
|
||||
.ant-card-meta-title {
|
||||
margin-bottom: 4px;
|
||||
|
||||
& > a {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
color: @heading-color;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-card-meta-description {
|
||||
height: 44px;
|
||||
overflow: hidden;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
:global {
|
||||
.ant-card-meta-title > a {
|
||||
color: @primary-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cardItemContent {
|
||||
display: flex;
|
||||
height: 20px;
|
||||
margin-top: 16px;
|
||||
margin-bottom: -4px;
|
||||
line-height: 20px;
|
||||
|
||||
& > span {
|
||||
flex: 1;
|
||||
color: @text-color-secondary;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.avatarList {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
}
|
||||
|
||||
.cardList {
|
||||
margin-top: 24px;
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import { PaginationConfig, SorterResult, TableCurrentDataSource } from 'antd/lib/table';
|
||||
|
||||
export interface StandardTableProps {
|
||||
columns: any;
|
||||
onSelectRow: (row: any) => void;
|
||||
data: any;
|
||||
rowKey?: string;
|
||||
selectedRows: any[];
|
||||
onChange?: (
|
||||
pagination: PaginationConfig,
|
||||
filters: Record<keyof any, string[]>,
|
||||
sorter: SorterResult<any>,
|
||||
extra?: TableCurrentDataSource<any>
|
||||
) => void;
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
export default class StandardTable extends React.Component<StandardTableProps, any> {}
|
||||
@ -0,0 +1,195 @@
|
||||
import React, {Fragment, PureComponent} from 'react';
|
||||
import {Alert, Table} from 'antd';
|
||||
import styles from './index.less';
|
||||
|
||||
function initTotalList(columns) {
|
||||
const totalList = [];
|
||||
columns.forEach(column => {
|
||||
if (column.needTotal) {
|
||||
totalList.push({...column, total: 0});
|
||||
}
|
||||
});
|
||||
return totalList;
|
||||
}
|
||||
|
||||
class StandardTable extends PureComponent {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const {columns} = props;
|
||||
const needTotalList = initTotalList(columns);
|
||||
|
||||
this.state = {
|
||||
selectedRowKeys: [],
|
||||
selectedRows: [],
|
||||
needTotalList,
|
||||
};
|
||||
}
|
||||
|
||||
static getDerivedStateFromProps(nextProps) {
|
||||
// clean state
|
||||
if (nextProps.selectedRows.length === 0) {
|
||||
const needTotalList = initTotalList(nextProps.columns);
|
||||
return {
|
||||
selectedRowKeys: [],
|
||||
selectedRows: [],
|
||||
needTotalList,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
handleRowSelectChange = (selectedRowKeys, selectedRows) => {
|
||||
let {needTotalList} = this.state;
|
||||
needTotalList = needTotalList.map(item => ({
|
||||
...item,
|
||||
total: selectedRows.reduce((sum, val) => sum + parseFloat(val[item.dataIndex], 10), 0),
|
||||
}));
|
||||
const {onSelectRow} = this.props;
|
||||
if (onSelectRow) {
|
||||
onSelectRow(selectedRows);
|
||||
}
|
||||
this.setState({selectedRowKeys, selectedRows, needTotalList});
|
||||
};
|
||||
|
||||
handleTableChange = (pagination, filters, sorter) => {
|
||||
const {onChange} = this.props;
|
||||
if (onChange) {
|
||||
onChange(pagination, filters, sorter);
|
||||
}
|
||||
};
|
||||
|
||||
cleanSelectedKeys = () => {
|
||||
this.handleRowSelectChange([], []);
|
||||
};
|
||||
|
||||
// 单击行事件
|
||||
rowClick = (record) => {
|
||||
const {selectionType, rowKey} = this.props;
|
||||
const {selectedRowKeys, selectedRows} = this.state;
|
||||
const key = record[rowKey] || record.key;
|
||||
|
||||
let newSelectedRowKeys = [];
|
||||
let newSelectedRows = [];
|
||||
|
||||
|
||||
if (selectedRowKeys.includes(key)) {
|
||||
newSelectedRowKeys = selectedRowKeys.filter(item => item !== key)
|
||||
newSelectedRows = selectedRows.filter(item => item.id !== key)
|
||||
} else {
|
||||
if("radio" != selectionType) {
|
||||
newSelectedRowKeys = [...selectedRowKeys, key];
|
||||
newSelectedRows = [...selectedRows, record];
|
||||
}else {
|
||||
newSelectedRowKeys = [key];
|
||||
newSelectedRows = [record];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
this.handleRowSelectChange(newSelectedRowKeys, newSelectedRows);
|
||||
}
|
||||
|
||||
// 行操作事件
|
||||
rowCallback = (record) => {
|
||||
const {rowClick, rowDoubleClick, rowContextMenu, rowMouseEnter, rowMouseLeave} = this.props;
|
||||
return {
|
||||
onClick: event => {
|
||||
const node = event.target;
|
||||
const toolNode = event.currentTarget.lastChild;
|
||||
const hasNode = toolNode.contains(node);
|
||||
if (!hasNode) {
|
||||
this.rowClick(record)
|
||||
}
|
||||
if(rowClick) {
|
||||
rowClick(event, record);
|
||||
}
|
||||
}, // 点击行
|
||||
onDoubleClick: event => {
|
||||
if(rowDoubleClick) {
|
||||
rowDoubleClick(event, record);
|
||||
}
|
||||
},
|
||||
onContextMenu: event => {
|
||||
if(rowContextMenu) {
|
||||
rowContextMenu(event, record);
|
||||
}
|
||||
},
|
||||
onMouseEnter: event => {
|
||||
if(rowMouseEnter) {
|
||||
rowMouseEnter(event, record);
|
||||
}
|
||||
}, // 鼠标移入行
|
||||
onMouseLeave: event => {
|
||||
if(rowMouseLeave) {
|
||||
rowMouseLeave(event, record);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
render() {
|
||||
const {selectedRowKeys, needTotalList} = this.state;
|
||||
|
||||
const {data = {}, selectionType, rowKey, size, bodyStyle, isshowAlert,...rest} = this.props;
|
||||
const {list = [], pagination} = data;
|
||||
const toggleAlert = this.props.showAlert !== '' && this.props.showAlert !== undefined ? this.props.showAlert : true;
|
||||
const paginationProps = {
|
||||
showSizeChanger: true,
|
||||
showQuickJumper: true,
|
||||
current: pagination?.currentPage == 0 ? 1 : pagination?.currentPage,
|
||||
...pagination,
|
||||
};
|
||||
|
||||
const rowSelection = {
|
||||
type: selectionType || "checkbox",
|
||||
selectedRowKeys,
|
||||
onChange: this.handleRowSelectChange,
|
||||
getCheckboxProps: record => ({
|
||||
disabled: record.disabled,
|
||||
}),
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<div className={bodyStyle || styles.standardTable}>
|
||||
{ isshowAlert&&(toggleAlert && toggleAlert !== undefined) ? (
|
||||
<div className={styles.tableAlert}>
|
||||
<Alert
|
||||
message={
|
||||
<Fragment>
|
||||
已选择 <a style={{fontWeight: 600}}>{selectedRowKeys.length}</a> 项
|
||||
{needTotalList.map(item => (
|
||||
<span style={{marginLeft: 8}} key={item.dataIndex}>
|
||||
{item.title} 总计
|
||||
<span style={{fontWeight: 600}}>
|
||||
{item.render ? item.render(item.total) : item.total}
|
||||
</span>
|
||||
</span>
|
||||
))}
|
||||
<a onClick={this.cleanSelectedKeys} style={{marginLeft: 24}}>
|
||||
清空
|
||||
</a>
|
||||
</Fragment>
|
||||
}
|
||||
type="info"
|
||||
showIcon
|
||||
/>
|
||||
</div>
|
||||
) : null}
|
||||
<Table
|
||||
rowKey={rowKey || 'key'}
|
||||
rowSelection={selectionType?rowSelection:null}
|
||||
dataSource={list}
|
||||
pagination={paginationProps}
|
||||
onChange={this.handleTableChange}
|
||||
onRow={this.rowCallback}
|
||||
size={size || 'small'}
|
||||
{...rest}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default StandardTable;
|
||||
@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
.standardTable {
|
||||
:global {
|
||||
.ant-table-pagination {
|
||||
margin-top: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.tableAlert {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,11 @@
|
||||
export function getNodeByKeyAndCallbackProcess (data, targetkey, callback) {
|
||||
data.forEach((item, index, arr) => {
|
||||
if (item.key === targetkey) {
|
||||
return callback(item, index, arr)
|
||||
}
|
||||
|
||||
if (item.children) {
|
||||
return getNodeByKeyAndCallbackProcess(item.children, targetkey, callback)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -0,0 +1,6 @@
|
||||
// /userinfo/2144/id => ['/userinfo','/useinfo/2144,'/userindo/2144/id']
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export function urlToList(url) {
|
||||
const urllist = url.split('/').filter(i => i);
|
||||
return urllist.map((urlItem, index) => `/${urllist.slice(0, index + 1).join('/')}`);
|
||||
}
|
||||
@ -0,0 +1,17 @@
|
||||
import { urlToList } from './pathTools';
|
||||
|
||||
describe('test urlToList', () => {
|
||||
it('A path', () => {
|
||||
expect(urlToList('/userinfo')).toEqual(['/userinfo']);
|
||||
});
|
||||
it('Secondary path', () => {
|
||||
expect(urlToList('/userinfo/2144')).toEqual(['/userinfo', '/userinfo/2144']);
|
||||
});
|
||||
it('Three paths', () => {
|
||||
expect(urlToList('/userinfo/2144/addr')).toEqual([
|
||||
'/userinfo',
|
||||
'/userinfo/2144',
|
||||
'/userinfo/2144/addr',
|
||||
]);
|
||||
});
|
||||
});
|
||||
@ -0,0 +1,98 @@
|
||||
import React, { useMemo, forwardRef } from 'react'
|
||||
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import classnames from 'classnames'
|
||||
|
||||
|
||||
import { deepMerge,deepClone } from '../../datav/usefull/index'
|
||||
|
||||
import useAutoResize from '../../datav/use/autoResize'
|
||||
|
||||
import './style.less'
|
||||
|
||||
const border = ['left-top', 'right-top', 'left-bottom', 'right-bottom']
|
||||
const defaultColor = ['#4fd2dd', '#235fa7']
|
||||
|
||||
const BorderBox1 = forwardRef(({ children, className, style, color = [], backgroundColor = 'transparent' }, ref) => {
|
||||
const { width, height, domRef } = useAutoResize(ref)
|
||||
|
||||
const mergedColor = useMemo(() => deepMerge(deepClone(defaultColor, true), color || []), [color])
|
||||
|
||||
const classNames = useMemo(() => classnames('dv-border-box-1', className), [
|
||||
className
|
||||
])
|
||||
|
||||
return (
|
||||
<div className={classNames} style={style} ref={domRef}>
|
||||
<svg className='border' width={width} height={height}>
|
||||
<polygon fill={backgroundColor} points={`10, 27 10, ${height - 27} 13, ${height - 24} 13, ${height - 21} 24, ${height - 11}
|
||||
38, ${height - 11} 41, ${height - 8} 73, ${height - 8} 75, ${height - 10} 81, ${height - 10}
|
||||
85, ${height - 6} ${width - 85}, ${height - 6} ${width - 81}, ${height - 10} ${width - 75}, ${height - 10}
|
||||
${width - 73}, ${height - 8} ${width - 41}, ${height - 8} ${width - 38}, ${height - 11}
|
||||
${width - 24}, ${height - 11} ${width - 13}, ${height - 21} ${width - 13}, ${height - 24}
|
||||
${width - 10}, ${height - 27} ${width - 10}, 27 ${width - 13}, 25 ${width - 13}, 21
|
||||
${width - 24}, 11 ${width - 38}, 11 ${width - 41}, 8 ${width - 73}, 8 ${width - 75}, 10
|
||||
${width - 81}, 10 ${width - 85}, 6 85, 6 81, 10 75, 10 73, 8 41, 8 38, 11 24, 11 13, 21 13, 24`} />
|
||||
</svg>
|
||||
|
||||
{border.map(borderName => (
|
||||
<svg
|
||||
width='150px'
|
||||
height='150px'
|
||||
key={borderName}
|
||||
className={`${borderName} border`}
|
||||
>
|
||||
<polygon
|
||||
fill={mergedColor[0]}
|
||||
points='6,66 6,18 12,12 18,12 24,6 27,6 30,9 36,9 39,6 84,6 81,9 75,9 73.2,7 40.8,7 37.8,10.2 24,10.2 12,21 12,24 9,27 9,51 7.8,54 7.8,63'
|
||||
>
|
||||
<animate
|
||||
attributeName='fill'
|
||||
values={`${mergedColor[0]};${mergedColor[1]};${mergedColor[0]}`}
|
||||
dur='0.5s'
|
||||
begin='0s'
|
||||
repeatCount='indefinite'
|
||||
/>
|
||||
</polygon>
|
||||
<polygon
|
||||
fill={mergedColor[1]}
|
||||
points='27.599999999999998,4.8 38.4,4.8 35.4,7.8 30.599999999999998,7.8'
|
||||
>
|
||||
<animate
|
||||
attributeName='fill'
|
||||
values={`${mergedColor[1]};${mergedColor[0]};${mergedColor[1]}`}
|
||||
dur='0.5s'
|
||||
begin='0s'
|
||||
repeatCount='indefinite'
|
||||
/>
|
||||
</polygon>
|
||||
<polygon
|
||||
fill={mergedColor[0]}
|
||||
points='9,54 9,63 7.199999999999999,66 7.199999999999999,75 7.8,78 7.8,110 8.4,110 8.4,66 9.6,66 9.6,54'
|
||||
>
|
||||
<animate
|
||||
attributeName='fill'
|
||||
values={`${mergedColor[0]};${mergedColor[1]};transparent`}
|
||||
dur='1s'
|
||||
begin='0s'
|
||||
repeatCount='indefinite'
|
||||
/>
|
||||
</polygon>
|
||||
</svg>
|
||||
))}
|
||||
|
||||
<div className='border-box-content'>{children}</div>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
||||
BorderBox1.propTypes = {
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string,
|
||||
style: PropTypes.object,
|
||||
color: PropTypes.array,
|
||||
backgroundColor: PropTypes.string
|
||||
}
|
||||
|
||||
export default BorderBox1
|
||||