@appthen/cli 1.2.10 → 1.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.gitignore +1 -0
- package/bin/main.js +45 -0
- package/dist/index.js +1108 -267
- package/package.json +1 -1
- package/tests/test-app/.appthen/shadow-space-100001-test-app-e99876b1.json +1406 -0
- package/tests/test-app/.appthen/shadow-space-unknown-user-test-app-e99876b1.json +1060 -0
- package/tests/test-app/.appthen/space-config.json +8 -0
- package/tests/test-app/docs/AI-Workflow.flow +112 -0
- package/tests/test-app/docs/Logic-1.flow +16 -0
- package/tests/test-app/docs/Logic.flow +16 -0
- package/tests/test-app/docs/Project-Blueprint-1.flow +119 -0
- package/tests/test-app/docs/Project-Blueprint.flow +119 -0
- package/tests/test-app/docs/README.md +3 -0
- package/tests/test-app/docs/claude.md +194 -0
- package/tests/test-app/docs/page_requirement_analysis.md +149 -0
- package/tests/test-app/docs//345/267/245/345/215/225/347/256/241/347/220/206/347/263/273/347/273/237/350/257/246/347/273/206/350/256/276/350/256/241.md +377 -0
- package/tests/test-app/src/apis/AddTodoPost.api.ts +42 -0
- package/tests/test-app/src/apis/DeleteTodoPost.api.ts +32 -0
- package/tests/test-app/src/apis/GetListPost.api.ts +38 -0
- package/tests/test-app/src/apis/TicketAttachmentUploadPost.api.ts +42 -0
- package/tests/test-app/src/apis/UpdateTodoPost.api.ts +46 -0
- package/tests/test-app/src/app.css +15 -0
- package/tests/test-app/src/cloud_functions/ticket|attachment|upload.node.ts +86 -0
- package/tests/test-app/src/cloud_functions/ticket|comment|add.node.ts +65 -0
- package/tests/test-app/src/cloud_functions/types|entity|Ticket.node.ts +88 -0
- package/tests/test-app/src/cloud_functions/types|entity|TicketAttachment.node.ts +70 -0
- package/tests/test-app/src/cloud_functions/types|entity|TicketCategory.node.ts +56 -0
- package/tests/test-app/src/cloud_functions/types|entity|TicketComment.node.ts +62 -0
- package/tests/test-app/src/cloud_functions/types|entity|TicketHistory.node.ts +74 -0
- package/tests/test-app/src/cloud_functions/types|entity|TicketPriority.node.ts +68 -0
- package/tests/test-app/src/cloud_functions/types|entity|TicketStatus.node.ts +63 -0
- package/tests/test-app/src/cloud_functions/types|models|CreateTicketParams.node.ts +20 -0
- package/tests/test-app/src/cloud_functions/types|models|TicketListParams.node.ts +30 -0
- package/tests/test-app/src/cloud_functions/types|models|UpdateTicketParams.node.ts +22 -0
- package/tests/test-app/src/components/Button.js +11 -0
- package/tests/test-app/src/components/MouduleDemoNzp.tsx +40 -0
- package/tests/test-app/src/components/Timeline.tsx +145 -0
- package/tests/test-app/src/index.ts +2 -0
- package/tests/test-app/src/modules/work_order_module/apis/TicketCommentAddPost.api.ts +48 -0
- package/tests/test-app/src/modules/work_order_module/apis/TicketCreatePost.api.ts +52 -0
- package/tests/test-app/src/modules/work_order_module/apis/TicketDeleteDelete.api.ts +39 -0
- package/tests/test-app/src/modules/work_order_module/apis/TicketDetailGet.api.ts +39 -0
- package/tests/test-app/src/modules/work_order_module/apis/TicketListGet.api.ts +61 -0
- package/tests/test-app/src/modules/work_order_module/apis/TicketUpdatePut.api.ts +57 -0
- package/tests/test-app/src/modules/work_order_module/apis/TrainDoorFaultListGet.ts +76 -0
- package/tests/test-app/src/modules/work_order_module/apis/TrainDoorListGet.ts +76 -0
- package/tests/test-app/src/modules/work_order_module/apis/TrainDoorOperationRecordsGet.ts +284 -0
- package/tests/test-app/src/modules/work_order_module/apis/TrainDoorStatisticsGet.ts +96 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/category|list.node.ts +40 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/priority|list.node.ts +26 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/status|list.node.ts +26 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|create.node.ts +54 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|delete.node.ts +55 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|detail.node.ts +65 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|list.node.ts +85 -0
- package/tests/test-app/src/modules/work_order_module/cloud_function/ticket|update.node.ts +73 -0
- package/tests/test-app/src/modules/work_order_module/data_model/Ticket.m.ts +85 -0
- package/tests/test-app/src/modules/work_order_module/data_model/TicketCategory.m.ts +53 -0
- package/tests/test-app/src/modules/work_order_module/data_model/TicketStatus.m.ts +60 -0
- package/tests/test-app/src/modules/work_order_module//345/267/245/345/215/225/347/263/273/347/273/237/344/272/247/345/223/201/350/256/276/350/256/241/346/226/207/346/241/243.md +301 -0
- package/tests/test-app/src/modules/work_order_module//345/267/245/345/215/225/347/263/273/347/273/237/345/274/200/345/217/221/344/273/273/345/212/241/345/210/206/345/267/245/346/226/207/346/241/243.md +345 -0
- package/tests/test-app/src/pages/SLAManagement.tsx +668 -0
- package/tests/test-app/src/pages/TicketCreate.tsx +27 -0
- package/tests/test-app/src/pages/TicketDetail.tsx +27 -0
- package/tests/test-app/src/pages/TicketList.tsx +27 -0
- package/tests/test-app/src/pages/TicketManagementPage.tsx +1238 -0
- package/tests/test-app/src/pages/VisualAIIDEUpgrade.tsx +245 -0
- package/tests/test-app/src/pages/appthen_guide/ComponentTreeUnderstanding.tsx +26 -0
- package/tests/test-app/src/pages/appthen_guide/DataBindingLearning.tsx +26 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout.tsx +155 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout10.tsx +157 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout2.tsx +156 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout3.tsx +156 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout4.tsx +157 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout5.tsx +157 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout6.tsx +157 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout7.tsx +157 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout8.tsx +157 -0
- package/tests/test-app/src/pages/back-end/adminRootLayout9.tsx +157 -0
- package/tests/test-app/src/pages/back-end/backgroundManagementSystem.css +5 -0
- package/tests/test-app/src/pages/back-end/backgroundManagementSystem.tsx +1745 -0
- package/tests/test-app/src/pages/component/WorkOrderCard.tsx +140 -0
- package/tests/test-app/src/pages/cover.tsx +42 -0
- package/tests/test-app/src/pages/data_dashboard/blueBrightGreenTechnologyWind.css +181 -0
- package/tests/test-app/src/pages/data_dashboard/blueBrightGreenTechnologyWind.tsx +225 -0
- package/tests/test-app/src/pages/data_dashboard/blueLargeScreen.css +181 -0
- package/tests/test-app/src/pages/data_dashboard/blueLargeScreen.tsx +138 -0
- package/tests/test-app/src/pages/data_dashboard/component_library/BlueBrightGreenBorder.tsx +47 -0
- package/tests/test-app/src/pages/data_dashboard/component_library/FullScreenContainer.tsx +133 -0
- package/tests/test-app/src/pages/description_of_mock_interface.md +32 -0
- package/tests/test-app/src/pages/digitalLargeScreen.css +181 -0
- package/tests/test-app/src/pages/digitalLargeScreen.tsx +1417 -0
- package/tests/test-app/src/pages/mobile_terminal/PersonalCenter.css +3 -0
- package/tests/test-app/src/pages/mobile_terminal/PersonalCenter.tsx +362 -0
- package/tests/test-app/src/pages/mobile_terminal/WorkOrderHomepage.tsx +337 -0
- package/tests/test-app/src/pages/mobile_terminal/newWorkOrder.tsx +224 -0
- package/tests/test-app/src/pages/mobile_terminal/tabbar.tsx +67 -0
- package/tests/test-app/src/pages/mobile_terminal/uiHandsOnPractice.tsx +638 -0
- package/tests/test-app/src/pages/mobile_terminal/workOrderDetails.tsx +346 -0
- package/tests/test-app/src/pages/mobile_terminal/workOrderPage.tsx +345 -0
- package/tests/test-app/src/pages/testPage.css +3 -0
- package/tests/test-app/src/pages/testPage.tsx +158 -0
- package/tests/test-app/src/pages/web_version/website.css +205 -0
- package/tests/test-app/src/pages/web_version/website.tsx +1066 -0
- package/tests/test-app/src/pages//345/276/205/345/212/236.apidoc.json +336 -0
- package/tests/test-app/src/project.json +1120 -0
- package/tests/test-app/src/store/global.store.ts +10 -0
- package/tests/test-app/src/types/CreateTicketParams.m.ts +20 -0
- package/tests/test-app/src/types/SLAPolicy.ts +50 -0
- package/tests/test-app/src/types/Ticket.ts +68 -0
- package/tests/test-app/src/types/TicketAttachment.m.ts +67 -0
- package/tests/test-app/src/types/TicketComment.m.ts +59 -0
- package/tests/test-app/src/types/TicketEvaluation.ts +44 -0
- package/tests/test-app/src/types/TicketHistory.m.ts +71 -0
- package/tests/test-app/src/types/TicketListParams.m.ts +30 -0
- package/tests/test-app/src/types/TicketPriority.m.ts +65 -0
- package/tests/test-app/src/types/TicketRecord.ts +47 -0
- package/tests/test-app/src/types/TrainDoor.ts +284 -0
- package/tests/test-app/src/types/UpdateTicketParams.m.ts +22 -0
- package/tests/test-app/src/utils/__afterRequest.util.ts +3 -0
- package/tests/test-app/src/utils/__beforeRequest.util.ts +10 -0
- package/tests/test-app/src/utils/testGlobalAction.util.ts +7 -0
|
@@ -0,0 +1,668 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SLA管理页面
|
|
3
|
+
* @type Page
|
|
4
|
+
* @route /sla-management
|
|
5
|
+
* @screen 1920x1080 #f5f5f5
|
|
6
|
+
* @frames web
|
|
7
|
+
*/
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import { Page, Text, View } from '@appthen/react';
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class IProps {}
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
* 数据与接口请求定义
|
|
16
|
+
*/
|
|
17
|
+
class IState {}
|
|
18
|
+
|
|
19
|
+
class Document extends React.Component<IProps, IState> {
|
|
20
|
+
state = {
|
|
21
|
+
activeTab: '[object Object]',
|
|
22
|
+
slaPolicies: [],
|
|
23
|
+
slaMonitoring: {},
|
|
24
|
+
slaStatistics: {},
|
|
25
|
+
showPolicyModal: false,
|
|
26
|
+
ticketTypes: [],
|
|
27
|
+
departments: [],
|
|
28
|
+
workingHours: [
|
|
29
|
+
{ day: 'monday', start: '09:00', end: '18:00', enabled: true },
|
|
30
|
+
{ day: 'tuesday', start: '09:00', end: '18:00', enabled: true },
|
|
31
|
+
{ day: 'wednesday', start: '09:00', end: '18:00', enabled: true },
|
|
32
|
+
{ day: 'thursday', start: '09:00', end: '18:00', enabled: true },
|
|
33
|
+
{ day: 'friday', start: '09:00', end: '18:00', enabled: true },
|
|
34
|
+
{ day: 'saturday', start: '09:00', end: '12:00', enabled: false },
|
|
35
|
+
{ day: 'sunday', start: '09:00', end: '12:00', enabled: false },
|
|
36
|
+
],
|
|
37
|
+
holidays: [],
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
render() {
|
|
41
|
+
return (
|
|
42
|
+
<Page className="min-h-screen bg-[var(--gray-50)]">
|
|
43
|
+
<View className="ml-[auto] mr-[auto] p-[24px]">
|
|
44
|
+
<View className="flex justify-between items-center mb-[24px]">
|
|
45
|
+
<h1 className="text-2xl font-bold text-[#111827]">
|
|
46
|
+
SLA管理1234567891010777889
|
|
47
|
+
</h1>
|
|
48
|
+
<button
|
|
49
|
+
onClick={() => this.showCreatePolicyModal()}
|
|
50
|
+
className="bg-blue-600 hover:bg-blue-700 pl-[16px] pr-[16px] pt-[8px] pb-[8px] text-[#ffffff] rounded-lg"
|
|
51
|
+
>
|
|
52
|
+
创建SLA策略
|
|
53
|
+
</button>
|
|
54
|
+
</View>
|
|
55
|
+
<View className="bg-[#ffffff] rounded-lg shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)] mb-[24px]">
|
|
56
|
+
<View className="border-gray-200 border-b-[1px] border-b-solid">
|
|
57
|
+
<nav className="-mb-px space-x-8 flex pl-[24px] pr-[24px]">
|
|
58
|
+
<button
|
|
59
|
+
onClick={() => this.switchTab('policies')}
|
|
60
|
+
className={`py-4 px-1 border-b-2 font-medium text-sm ${
|
|
61
|
+
this.state.activeTab === 'policies'
|
|
62
|
+
? 'border-blue-500 text-blue-600'
|
|
63
|
+
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
|
|
64
|
+
}`}
|
|
65
|
+
>
|
|
66
|
+
SLA策略
|
|
67
|
+
</button>
|
|
68
|
+
<button
|
|
69
|
+
onClick={() => this.switchTab('monitoring')}
|
|
70
|
+
className={`py-4 px-1 border-b-2 font-medium text-sm ${
|
|
71
|
+
this.state.activeTab === 'monitoring'
|
|
72
|
+
? 'border-blue-500 text-blue-600'
|
|
73
|
+
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
|
|
74
|
+
}`}
|
|
75
|
+
>
|
|
76
|
+
SLA监控
|
|
77
|
+
</button>
|
|
78
|
+
<button
|
|
79
|
+
onClick={() => this.switchTab('statistics')}
|
|
80
|
+
className={`py-4 px-1 border-b-2 font-medium text-sm ${
|
|
81
|
+
this.state.activeTab === 'statistics'
|
|
82
|
+
? 'border-blue-500 text-blue-600'
|
|
83
|
+
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
|
|
84
|
+
}`}
|
|
85
|
+
>
|
|
86
|
+
SLA统计
|
|
87
|
+
</button>
|
|
88
|
+
<button
|
|
89
|
+
onClick={() => this.switchTab('settings')}
|
|
90
|
+
className={`py-4 px-1 border-b-2 font-medium text-sm ${
|
|
91
|
+
this.state.activeTab === 'settings'
|
|
92
|
+
? 'border-blue-500 text-blue-600'
|
|
93
|
+
: 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
|
|
94
|
+
}`}
|
|
95
|
+
>
|
|
96
|
+
时间设置
|
|
97
|
+
</button>
|
|
98
|
+
</nav>
|
|
99
|
+
</View>
|
|
100
|
+
</View>
|
|
101
|
+
{!!(this.state.activeTab === 'policies') && (
|
|
102
|
+
<View className="bg-[#ffffff] rounded-lg shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)]">
|
|
103
|
+
<View className="p-[24px]">
|
|
104
|
+
<View className="overflow-x-auto">
|
|
105
|
+
<table className="divide-y divide-gray-200 min-w-full">
|
|
106
|
+
<thead className="bg-[var(--gray-50)]">
|
|
107
|
+
<tr>
|
|
108
|
+
<th className="pl-[24px] pr-[24px] pt-[12px] pb-[12px] text-[#6b7280] text-xs font-medium [textTransform:uppercase] tracking-[0.05em]">
|
|
109
|
+
策略名称
|
|
110
|
+
</th>
|
|
111
|
+
<th className="pl-[24px] pr-[24px] pt-[12px] pb-[12px] text-[#6b7280] text-xs font-medium [textTransform:uppercase] tracking-[0.05em]">
|
|
112
|
+
工单类型
|
|
113
|
+
</th>
|
|
114
|
+
<th className="pl-[24px] pr-[24px] pt-[12px] pb-[12px] text-[#6b7280] text-xs font-medium [textTransform:uppercase] tracking-[0.05em]">
|
|
115
|
+
优先级
|
|
116
|
+
</th>
|
|
117
|
+
<th className="pl-[24px] pr-[24px] pt-[12px] pb-[12px] text-[#6b7280] text-xs font-medium [textTransform:uppercase] tracking-[0.05em]">
|
|
118
|
+
响应时间
|
|
119
|
+
</th>
|
|
120
|
+
<th className="pl-[24px] pr-[24px] pt-[12px] pb-[12px] text-[#6b7280] text-xs font-medium [textTransform:uppercase] tracking-[0.05em]">
|
|
121
|
+
解决时间
|
|
122
|
+
</th>
|
|
123
|
+
<th className="pl-[24px] pr-[24px] pt-[12px] pb-[12px] text-[#6b7280] text-xs font-medium [textTransform:uppercase] tracking-[0.05em]">
|
|
124
|
+
状态
|
|
125
|
+
</th>
|
|
126
|
+
<th className="pl-[24px] pr-[24px] pt-[12px] pb-[12px] text-[#6b7280] text-xs font-medium [textTransform:uppercase] tracking-[0.05em]">
|
|
127
|
+
操作
|
|
128
|
+
</th>
|
|
129
|
+
</tr>
|
|
130
|
+
</thead>
|
|
131
|
+
<tbody className="divide-y divide-gray-200 bg-[#ffffff]">
|
|
132
|
+
{this.state.slaPolicies.map((policy, index) => (
|
|
133
|
+
<tr key={policy.id || index}>
|
|
134
|
+
<td className="pl-[24px] pr-[24px] pt-[16px] pb-[16px] text-sm text-[#111827]">
|
|
135
|
+
<Text>{policy.name}</Text>
|
|
136
|
+
</td>
|
|
137
|
+
<td className="pl-[24px] pr-[24px] pt-[16px] pb-[16px] text-sm text-[#111827]">
|
|
138
|
+
<Text>{policy.ticketType}</Text>
|
|
139
|
+
</td>
|
|
140
|
+
<td className="pl-[24px] pr-[24px] pt-[16px] pb-[16px]">
|
|
141
|
+
<Text
|
|
142
|
+
className="inline-flex px-2 py-1 text-xs font-semibold rounded-full"
|
|
143
|
+
style={{
|
|
144
|
+
backgroundColor:
|
|
145
|
+
this.getPriorityColor(policy.priority) + '20',
|
|
146
|
+
color: this.getPriorityColor(policy.priority),
|
|
147
|
+
}}
|
|
148
|
+
>
|
|
149
|
+
{policy.priority}
|
|
150
|
+
</Text>
|
|
151
|
+
</td>
|
|
152
|
+
<td className="pl-[24px] pr-[24px] pt-[16px] pb-[16px] text-sm text-[#111827]">
|
|
153
|
+
<Text>{this.formatTime(policy.responseTime)}</Text>
|
|
154
|
+
</td>
|
|
155
|
+
<td className="pl-[24px] pr-[24px] pt-[16px] pb-[16px] text-sm text-[#111827]">
|
|
156
|
+
<Text>{this.formatTime(policy.resolveTime)}</Text>
|
|
157
|
+
</td>
|
|
158
|
+
<td className="pl-[24px] pr-[24px] pt-[16px] pb-[16px]">
|
|
159
|
+
<Text
|
|
160
|
+
className={`inline-flex px-2 py-1 text-xs font-semibold rounded-full ${
|
|
161
|
+
policy.active
|
|
162
|
+
? 'bg-green-100 text-green-800'
|
|
163
|
+
: 'bg-gray-100 text-gray-800'
|
|
164
|
+
}`}
|
|
165
|
+
>
|
|
166
|
+
{policy.active ? '启用' : '禁用'}
|
|
167
|
+
</Text>
|
|
168
|
+
</td>
|
|
169
|
+
<td className="pl-[24px] pr-[24px] pt-[16px] pb-[16px] text-sm">
|
|
170
|
+
<button
|
|
171
|
+
onClick={() => this.showEditPolicyModal(policy)}
|
|
172
|
+
className="text-blue-600 hover:text-blue-800 mr-[12px]"
|
|
173
|
+
>
|
|
174
|
+
编辑
|
|
175
|
+
</button>
|
|
176
|
+
<button
|
|
177
|
+
onClick={() =>
|
|
178
|
+
this.togglePolicyStatus(
|
|
179
|
+
policy.id,
|
|
180
|
+
!policy.active
|
|
181
|
+
)
|
|
182
|
+
}
|
|
183
|
+
className="text-yellow-600 hover:text-yellow-800 mr-[12px]"
|
|
184
|
+
>
|
|
185
|
+
{policy.active ? '禁用' : '启用'}
|
|
186
|
+
</button>
|
|
187
|
+
<button
|
|
188
|
+
onClick={() => this.deletePolicy(policy.id)}
|
|
189
|
+
className="text-red-600 hover:text-red-800"
|
|
190
|
+
>
|
|
191
|
+
删除
|
|
192
|
+
</button>
|
|
193
|
+
</td>
|
|
194
|
+
</tr>
|
|
195
|
+
))}
|
|
196
|
+
</tbody>
|
|
197
|
+
</table>
|
|
198
|
+
</View>
|
|
199
|
+
</View>
|
|
200
|
+
</View>
|
|
201
|
+
)}
|
|
202
|
+
{!!(this.state.activeTab === 'monitoring') && (
|
|
203
|
+
<View className="space-y-6">
|
|
204
|
+
<View className="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
205
|
+
<View className="bg-[#ffffff] rounded-lg shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)] p-[16px]">
|
|
206
|
+
<View className="text-2xl font-bold text-[var(--blue-600)]">
|
|
207
|
+
{0}
|
|
208
|
+
</View>
|
|
209
|
+
<View className="text-[#4b5563] text-sm">
|
|
210
|
+
<Text>监控工单总数</Text>
|
|
211
|
+
</View>
|
|
212
|
+
</View>
|
|
213
|
+
<View className="bg-[#ffffff] rounded-lg shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)] p-[16px]">
|
|
214
|
+
<View className="text-2xl font-bold text-[var(--green-600)]">
|
|
215
|
+
{0}
|
|
216
|
+
</View>
|
|
217
|
+
<View className="text-[#4b5563] text-sm">
|
|
218
|
+
<Text>SLA正常</Text>
|
|
219
|
+
</View>
|
|
220
|
+
</View>
|
|
221
|
+
<View className="bg-[#ffffff] rounded-lg shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)] p-[16px]">
|
|
222
|
+
<View className="text-2xl font-bold text-[var(--yellow-600)]">
|
|
223
|
+
{0}
|
|
224
|
+
</View>
|
|
225
|
+
<View className="text-[#4b5563] text-sm">
|
|
226
|
+
<Text>SLA预警</Text>
|
|
227
|
+
</View>
|
|
228
|
+
</View>
|
|
229
|
+
<View className="bg-[#ffffff] rounded-lg shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)] p-[16px]">
|
|
230
|
+
<View className="text-2xl font-bold text-[var(--red-600)]">
|
|
231
|
+
{0}
|
|
232
|
+
</View>
|
|
233
|
+
<View className="text-[#4b5563] text-sm">
|
|
234
|
+
<Text>SLA超时</Text>
|
|
235
|
+
</View>
|
|
236
|
+
</View>
|
|
237
|
+
</View>
|
|
238
|
+
<View className="bg-[#ffffff] rounded-lg shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)]">
|
|
239
|
+
<View className="p-[24px]">
|
|
240
|
+
<h2 className="text-lg font-semibold text-[#111827] mb-[16px]">
|
|
241
|
+
SLA监控详情
|
|
242
|
+
</h2>
|
|
243
|
+
<View className="space-y-4">
|
|
244
|
+
{(this.state.slaMonitoring?.details).map((item, index) => (
|
|
245
|
+
<View
|
|
246
|
+
key={index}
|
|
247
|
+
className="border-l-4 pl-4 py-2"
|
|
248
|
+
style={{
|
|
249
|
+
borderLeftColor: this.getSLAStatusColor(item.status),
|
|
250
|
+
}}
|
|
251
|
+
>
|
|
252
|
+
<View className="flex justify-between items-start">
|
|
253
|
+
<View>
|
|
254
|
+
<View className="font-medium text-[#111827]">
|
|
255
|
+
<Text>工单 #</Text>
|
|
256
|
+
<Text>{item.ticketId}</Text>
|
|
257
|
+
<Text>-</Text>
|
|
258
|
+
<Text>{item.title}</Text>
|
|
259
|
+
</View>
|
|
260
|
+
<View className="text-sm text-[#6b7280]">
|
|
261
|
+
<Text>类型:</Text>
|
|
262
|
+
<Text>{item.type}</Text>
|
|
263
|
+
<Text>| 优先级:</Text>
|
|
264
|
+
<Text>{item.priority}</Text>
|
|
265
|
+
<Text>| 处理人:</Text>
|
|
266
|
+
<Text>{item.assignee}</Text>
|
|
267
|
+
</View>
|
|
268
|
+
</View>
|
|
269
|
+
<View className="text-[var(--right)]">
|
|
270
|
+
<View
|
|
271
|
+
className={`text-sm font-medium`}
|
|
272
|
+
style={{
|
|
273
|
+
color: this.getSLAStatusColor(item.status),
|
|
274
|
+
}}
|
|
275
|
+
>
|
|
276
|
+
<Text>{item.statusText}</Text>
|
|
277
|
+
</View>
|
|
278
|
+
<View className="text-xs text-[#6b7280]">
|
|
279
|
+
<Text>剩余:</Text>
|
|
280
|
+
<Text>{item.remainingTime}</Text>
|
|
281
|
+
</View>
|
|
282
|
+
</View>
|
|
283
|
+
</View>
|
|
284
|
+
</View>
|
|
285
|
+
))}
|
|
286
|
+
</View>
|
|
287
|
+
</View>
|
|
288
|
+
</View>
|
|
289
|
+
</View>
|
|
290
|
+
)}
|
|
291
|
+
{!!(this.state.activeTab === 'statistics') && (
|
|
292
|
+
<View className="space-y-6">
|
|
293
|
+
<View className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
|
294
|
+
<View className="bg-[#ffffff] rounded-lg shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)] p-[24px]">
|
|
295
|
+
<h3 className="text-lg font-medium text-[#111827] mb-[8px]">
|
|
296
|
+
SLA达成率
|
|
297
|
+
</h3>
|
|
298
|
+
<View className="text-3xl font-bold text-[var(--green-600)]">
|
|
299
|
+
<Text>
|
|
300
|
+
{(this.state.slaStatistics?.achievementRate || 0).toFixed(
|
|
301
|
+
1
|
|
302
|
+
)}
|
|
303
|
+
</Text>
|
|
304
|
+
<Text>%</Text>
|
|
305
|
+
</View>
|
|
306
|
+
<View className="text-sm text-[#6b7280]">
|
|
307
|
+
<Text>本月</Text>
|
|
308
|
+
</View>
|
|
309
|
+
</View>
|
|
310
|
+
<View className="bg-[#ffffff] rounded-lg shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)] p-[24px]">
|
|
311
|
+
<h3 className="text-lg font-medium text-[#111827] mb-[8px]">
|
|
312
|
+
平均响应时间
|
|
313
|
+
</h3>
|
|
314
|
+
<View className="text-3xl font-bold text-[var(--blue-600)]">
|
|
315
|
+
<Text>
|
|
316
|
+
{this.formatTime(
|
|
317
|
+
this.state.slaStatistics?.avgResponseTime || 0
|
|
318
|
+
)}
|
|
319
|
+
</Text>
|
|
320
|
+
</View>
|
|
321
|
+
<View className="text-sm text-[#6b7280]">
|
|
322
|
+
<Text>本月</Text>
|
|
323
|
+
</View>
|
|
324
|
+
</View>
|
|
325
|
+
<View className="bg-[#ffffff] rounded-lg shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)] p-[24px]">
|
|
326
|
+
<h3 className="text-lg font-medium text-[#111827] mb-[8px]">
|
|
327
|
+
平均解决时间
|
|
328
|
+
</h3>
|
|
329
|
+
<View className="text-3xl font-bold text-[var(--purple-600)]">
|
|
330
|
+
<Text>
|
|
331
|
+
{this.formatTime(
|
|
332
|
+
this.state.slaStatistics?.avgResolveTime || 0
|
|
333
|
+
)}
|
|
334
|
+
</Text>
|
|
335
|
+
</View>
|
|
336
|
+
<View className="text-sm text-[#6b7280]">
|
|
337
|
+
<Text>本月</Text>
|
|
338
|
+
</View>
|
|
339
|
+
</View>
|
|
340
|
+
</View>
|
|
341
|
+
<View className="bg-[#ffffff] rounded-lg shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)] p-[24px]">
|
|
342
|
+
<h3 className="text-lg font-medium text-[#111827] mb-[16px]">
|
|
343
|
+
SLA达成率趋势
|
|
344
|
+
</h3>
|
|
345
|
+
<View className="h-[256px] flex items-center justify-center bg-[var(--gray-50)] rounded">
|
|
346
|
+
<p className="text-[#6b7280]">趋势图表占位符</p>
|
|
347
|
+
</View>
|
|
348
|
+
</View>
|
|
349
|
+
<View className="bg-[#ffffff] rounded-lg shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)] p-[24px]">
|
|
350
|
+
<h3 className="text-lg font-medium text-[#111827] mb-[16px]">
|
|
351
|
+
分部门SLA统计
|
|
352
|
+
</h3>
|
|
353
|
+
<View className="overflow-x-auto">
|
|
354
|
+
<table className="divide-y divide-gray-200 min-w-full">
|
|
355
|
+
<thead className="bg-[var(--gray-50)]">
|
|
356
|
+
<tr>
|
|
357
|
+
<th className="pl-[24px] pr-[24px] pt-[12px] pb-[12px] text-[#6b7280] text-xs font-medium [textTransform:uppercase]">
|
|
358
|
+
部门
|
|
359
|
+
</th>
|
|
360
|
+
<th className="pl-[24px] pr-[24px] pt-[12px] pb-[12px] text-[#6b7280] text-xs font-medium [textTransform:uppercase]">
|
|
361
|
+
工单数量
|
|
362
|
+
</th>
|
|
363
|
+
<th className="pl-[24px] pr-[24px] pt-[12px] pb-[12px] text-[#6b7280] text-xs font-medium [textTransform:uppercase]">
|
|
364
|
+
SLA达成率
|
|
365
|
+
</th>
|
|
366
|
+
<th className="pl-[24px] pr-[24px] pt-[12px] pb-[12px] text-[#6b7280] text-xs font-medium [textTransform:uppercase]">
|
|
367
|
+
平均响应时间
|
|
368
|
+
</th>
|
|
369
|
+
<th className="pl-[24px] pr-[24px] pt-[12px] pb-[12px] text-[#6b7280] text-xs font-medium [textTransform:uppercase]">
|
|
370
|
+
平均解决时间
|
|
371
|
+
</th>
|
|
372
|
+
</tr>
|
|
373
|
+
</thead>
|
|
374
|
+
<tbody className="divide-y divide-gray-200 bg-[#ffffff]">
|
|
375
|
+
{(this.state.slaStatistics?.byDepartment).map(
|
|
376
|
+
(dept, index) => (
|
|
377
|
+
<tr key={index}>
|
|
378
|
+
<td className="pl-[24px] pr-[24px] pt-[16px] pb-[16px] text-sm text-[#111827]">
|
|
379
|
+
<Text>{dept.name}</Text>
|
|
380
|
+
</td>
|
|
381
|
+
<td className="pl-[24px] pr-[24px] pt-[16px] pb-[16px] text-sm text-[#111827]">
|
|
382
|
+
<Text>{dept.ticketCount}</Text>
|
|
383
|
+
</td>
|
|
384
|
+
<td className="pl-[24px] pr-[24px] pt-[16px] pb-[16px] text-sm text-[#111827]">{`${dept.achievementRate}%`}</td>
|
|
385
|
+
<td className="pl-[24px] pr-[24px] pt-[16px] pb-[16px] text-sm text-[#111827]">
|
|
386
|
+
<Text>
|
|
387
|
+
{this.formatTime(dept.avgResponseTime)}
|
|
388
|
+
</Text>
|
|
389
|
+
</td>
|
|
390
|
+
<td className="pl-[24px] pr-[24px] pt-[16px] pb-[16px] text-sm text-[#111827]">
|
|
391
|
+
<Text>
|
|
392
|
+
{this.formatTime(dept.avgResolveTime)}
|
|
393
|
+
</Text>
|
|
394
|
+
</td>
|
|
395
|
+
</tr>
|
|
396
|
+
)
|
|
397
|
+
)}
|
|
398
|
+
</tbody>
|
|
399
|
+
</table>
|
|
400
|
+
</View>
|
|
401
|
+
</View>
|
|
402
|
+
</View>
|
|
403
|
+
)}
|
|
404
|
+
{!!(this.state.activeTab === 'settings') && (
|
|
405
|
+
<View className="space-y-6">
|
|
406
|
+
<View className="bg-[#ffffff] rounded-lg shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)]">
|
|
407
|
+
<View className="p-[24px]">
|
|
408
|
+
<h3 className="text-lg font-medium text-[#111827] mb-[16px]">
|
|
409
|
+
工作时间设置
|
|
410
|
+
</h3>
|
|
411
|
+
<View className="space-y-3">
|
|
412
|
+
{this.state.workingHours.map((wh, index) => (
|
|
413
|
+
<View key={index} className="gap-4 flex items-center">
|
|
414
|
+
<View className="w-[96px]">
|
|
415
|
+
<Text className="text-sm font-medium text-[#374151]">
|
|
416
|
+
{wh.day === 'monday'
|
|
417
|
+
? '周一'
|
|
418
|
+
: wh.day === 'tuesday'
|
|
419
|
+
? '周二'
|
|
420
|
+
: wh.day === 'wednesday'
|
|
421
|
+
? '周三'
|
|
422
|
+
: wh.day === 'thursday'
|
|
423
|
+
? '周四'
|
|
424
|
+
: wh.day === 'friday'
|
|
425
|
+
? '周五'
|
|
426
|
+
: wh.day === 'saturday'
|
|
427
|
+
? '周六'
|
|
428
|
+
: '周日'}
|
|
429
|
+
</Text>
|
|
430
|
+
</View>
|
|
431
|
+
<input
|
|
432
|
+
type="checkbox"
|
|
433
|
+
checked={wh.enabled}
|
|
434
|
+
onChange={e =>
|
|
435
|
+
this.updateWorkingHours(
|
|
436
|
+
wh.day,
|
|
437
|
+
'enabled',
|
|
438
|
+
e.target.checked
|
|
439
|
+
)
|
|
440
|
+
}
|
|
441
|
+
className="rounded"
|
|
442
|
+
/>
|
|
443
|
+
<input
|
|
444
|
+
type="time"
|
|
445
|
+
value={wh.start}
|
|
446
|
+
onChange={e =>
|
|
447
|
+
this.updateWorkingHours(
|
|
448
|
+
wh.day,
|
|
449
|
+
'start',
|
|
450
|
+
e.target.value
|
|
451
|
+
)
|
|
452
|
+
}
|
|
453
|
+
disabled={!wh.enabled}
|
|
454
|
+
className="pl-[8px] pr-[8px] pt-[4px] pb-[4px] border border-solid rounded"
|
|
455
|
+
/>
|
|
456
|
+
<Text className="text-[#6b7280]">至</Text>
|
|
457
|
+
<input
|
|
458
|
+
type="time"
|
|
459
|
+
value={wh.end}
|
|
460
|
+
onChange={e =>
|
|
461
|
+
this.updateWorkingHours(
|
|
462
|
+
wh.day,
|
|
463
|
+
'end',
|
|
464
|
+
e.target.value
|
|
465
|
+
)
|
|
466
|
+
}
|
|
467
|
+
disabled={!wh.enabled}
|
|
468
|
+
className="pl-[8px] pr-[8px] pt-[4px] pb-[4px] border border-solid rounded"
|
|
469
|
+
/>
|
|
470
|
+
</View>
|
|
471
|
+
))}
|
|
472
|
+
</View>
|
|
473
|
+
</View>
|
|
474
|
+
</View>
|
|
475
|
+
<View className="bg-[#ffffff] rounded-lg shadow-[0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)]">
|
|
476
|
+
<View className="p-[24px]">
|
|
477
|
+
<View className="flex justify-between items-center mb-[16px]">
|
|
478
|
+
<h3 className="text-lg font-medium text-[#111827]">
|
|
479
|
+
节假日设置
|
|
480
|
+
</h3>
|
|
481
|
+
<button className="bg-blue-600 hover:bg-blue-700 pl-[16px] pr-[16px] pt-[8px] pb-[8px] text-[#ffffff] rounded-lg">
|
|
482
|
+
添加节假日
|
|
483
|
+
</button>
|
|
484
|
+
</View>
|
|
485
|
+
<View className="space-y-2">
|
|
486
|
+
{this.state.holidays.map((holiday, index) => (
|
|
487
|
+
<View
|
|
488
|
+
key={index}
|
|
489
|
+
className="flex items-center justify-between p-[12px] bg-[var(--gray-50)] rounded"
|
|
490
|
+
>
|
|
491
|
+
<View>
|
|
492
|
+
<View className="font-medium text-[#111827]">
|
|
493
|
+
<Text>{holiday.name}</Text>
|
|
494
|
+
</View>
|
|
495
|
+
<View className="text-sm text-[#6b7280]">
|
|
496
|
+
<Text>{holiday.date}</Text>
|
|
497
|
+
</View>
|
|
498
|
+
</View>
|
|
499
|
+
<button
|
|
500
|
+
onClick={() => this.removeHoliday(holiday.id)}
|
|
501
|
+
className="text-red-600 hover:text-red-800"
|
|
502
|
+
>
|
|
503
|
+
删除
|
|
504
|
+
</button>
|
|
505
|
+
</View>
|
|
506
|
+
))}
|
|
507
|
+
</View>
|
|
508
|
+
</View>
|
|
509
|
+
</View>
|
|
510
|
+
</View>
|
|
511
|
+
)}
|
|
512
|
+
{!!this.state.showPolicyModal && (
|
|
513
|
+
<View className="inset-0 fixed bg-[var(--opacity-50)] overflow-y-auto h-full w-full z-50">
|
|
514
|
+
<View className="relative top-[40px] ml-[auto] mr-[auto] p-[20px] border border-solid w-[384px] shadow-[0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)] rounded-md bg-[#ffffff]">
|
|
515
|
+
<View className="mt-[12px]">
|
|
516
|
+
<h3 className="text-lg [lineHeight:6] font-medium text-[#111827] mb-[16px]">
|
|
517
|
+
{this.state.editingPolicy?.id
|
|
518
|
+
? '编辑SLA策略'
|
|
519
|
+
: '创建SLA策略'}
|
|
520
|
+
</h3>
|
|
521
|
+
<View className="space-y-4">
|
|
522
|
+
<View>
|
|
523
|
+
<label className="block text-sm font-medium text-[#374151]">
|
|
524
|
+
策略名称
|
|
525
|
+
</label>
|
|
526
|
+
<input
|
|
527
|
+
type="text"
|
|
528
|
+
className="block border-gray-300 focus:outline-none focus:ring-blue-500 focus:border-blue-500 mt-[4px] w-full pl-[12px] pr-[12px] pt-[8px] pb-[8px] border border-solid rounded-md shadow-[0 1px 2px 0 rgb(0 0 0 / 0.05)]"
|
|
529
|
+
value={this.state.editingPolicy?.name || ''}
|
|
530
|
+
onChange={e =>
|
|
531
|
+
this.setState({
|
|
532
|
+
editingPolicy: {
|
|
533
|
+
...this.state.editingPolicy,
|
|
534
|
+
name: e.target.value,
|
|
535
|
+
},
|
|
536
|
+
})
|
|
537
|
+
}
|
|
538
|
+
/>
|
|
539
|
+
</View>
|
|
540
|
+
<View>
|
|
541
|
+
<label className="block text-sm font-medium text-[#374151]">
|
|
542
|
+
工单类型
|
|
543
|
+
</label>
|
|
544
|
+
<select
|
|
545
|
+
className="block border-gray-300 focus:outline-none focus:ring-blue-500 focus:border-blue-500 mt-[4px] w-full pl-[12px] pr-[12px] pt-[8px] pb-[8px] border border-solid rounded-md shadow-[0 1px 2px 0 rgb(0 0 0 / 0.05)]"
|
|
546
|
+
value={this.state.editingPolicy?.ticketType || ''}
|
|
547
|
+
onChange={e =>
|
|
548
|
+
this.setState({
|
|
549
|
+
editingPolicy: {
|
|
550
|
+
...this.state.editingPolicy,
|
|
551
|
+
ticketType: e.target.value,
|
|
552
|
+
},
|
|
553
|
+
})
|
|
554
|
+
}
|
|
555
|
+
>
|
|
556
|
+
<option value="">请选择工单类型</option>
|
|
557
|
+
{this.state.ticketTypes.map((type, index) => (
|
|
558
|
+
<option key={index} value={type.value}>
|
|
559
|
+
<Text>{type.label}</Text>
|
|
560
|
+
</option>
|
|
561
|
+
))}
|
|
562
|
+
</select>
|
|
563
|
+
</View>
|
|
564
|
+
<View>
|
|
565
|
+
<label className="block text-sm font-medium text-[#374151]">
|
|
566
|
+
优先级
|
|
567
|
+
</label>
|
|
568
|
+
<select
|
|
569
|
+
className="block border-gray-300 focus:outline-none focus:ring-blue-500 focus:border-blue-500 mt-[4px] w-full pl-[12px] pr-[12px] pt-[8px] pb-[8px] border border-solid rounded-md shadow-[0 1px 2px 0 rgb(0 0 0 / 0.05)]"
|
|
570
|
+
value={this.state.editingPolicy?.priority || ''}
|
|
571
|
+
onChange={e =>
|
|
572
|
+
this.setState({
|
|
573
|
+
editingPolicy: {
|
|
574
|
+
...this.state.editingPolicy,
|
|
575
|
+
priority: e.target.value,
|
|
576
|
+
},
|
|
577
|
+
})
|
|
578
|
+
}
|
|
579
|
+
>
|
|
580
|
+
<option value="">请选择优先级</option>
|
|
581
|
+
<option value="low">低</option>
|
|
582
|
+
<option value="medium">中</option>
|
|
583
|
+
<option value="high">高</option>
|
|
584
|
+
<option value="urgent">紧急</option>
|
|
585
|
+
</select>
|
|
586
|
+
</View>
|
|
587
|
+
<View>
|
|
588
|
+
<label className="block text-sm font-medium text-[#374151]">
|
|
589
|
+
响应时间(分钟)
|
|
590
|
+
</label>
|
|
591
|
+
<input
|
|
592
|
+
type="number"
|
|
593
|
+
className="block border-gray-300 focus:outline-none focus:ring-blue-500 focus:border-blue-500 mt-[4px] w-full pl-[12px] pr-[12px] pt-[8px] pb-[8px] border border-solid rounded-md shadow-[0 1px 2px 0 rgb(0 0 0 / 0.05)]"
|
|
594
|
+
value={this.state.editingPolicy?.responseTime || 0}
|
|
595
|
+
onChange={e =>
|
|
596
|
+
this.setState({
|
|
597
|
+
editingPolicy: {
|
|
598
|
+
...this.state.editingPolicy,
|
|
599
|
+
responseTime: parseInt(e.target.value) || 0,
|
|
600
|
+
},
|
|
601
|
+
})
|
|
602
|
+
}
|
|
603
|
+
/>
|
|
604
|
+
</View>
|
|
605
|
+
<View>
|
|
606
|
+
<label className="block text-sm font-medium text-[#374151]">
|
|
607
|
+
解决时间(分钟)
|
|
608
|
+
</label>
|
|
609
|
+
<input
|
|
610
|
+
type="number"
|
|
611
|
+
className="block border-gray-300 focus:outline-none focus:ring-blue-500 focus:border-blue-500 mt-[4px] w-full pl-[12px] pr-[12px] pt-[8px] pb-[8px] border border-solid rounded-md shadow-[0 1px 2px 0 rgb(0 0 0 / 0.05)]"
|
|
612
|
+
value={this.state.editingPolicy?.resolveTime || 0}
|
|
613
|
+
onChange={e =>
|
|
614
|
+
this.setState({
|
|
615
|
+
editingPolicy: {
|
|
616
|
+
...this.state.editingPolicy,
|
|
617
|
+
resolveTime: parseInt(e.target.value) || 0,
|
|
618
|
+
},
|
|
619
|
+
})
|
|
620
|
+
}
|
|
621
|
+
/>
|
|
622
|
+
</View>
|
|
623
|
+
<View>
|
|
624
|
+
<label className="flex items-center">
|
|
625
|
+
<input
|
|
626
|
+
type="checkbox"
|
|
627
|
+
checked={this.state.editingPolicy?.active || false}
|
|
628
|
+
onChange={e =>
|
|
629
|
+
this.setState({
|
|
630
|
+
editingPolicy: {
|
|
631
|
+
...this.state.editingPolicy,
|
|
632
|
+
active: e.target.checked,
|
|
633
|
+
},
|
|
634
|
+
})
|
|
635
|
+
}
|
|
636
|
+
className="rounded"
|
|
637
|
+
/>
|
|
638
|
+
<Text className="ml-[8px] text-sm text-[#374151]">
|
|
639
|
+
启用策略
|
|
640
|
+
</Text>
|
|
641
|
+
</label>
|
|
642
|
+
</View>
|
|
643
|
+
</View>
|
|
644
|
+
<View className="gap-3 flex justify-end mt-[24px]">
|
|
645
|
+
<button
|
|
646
|
+
onClick={() => this.closePolicyModal()}
|
|
647
|
+
className="bg-gray-300 hover:bg-gray-400 pl-[16px] pr-[16px] pt-[8px] pb-[8px] text-[#374151] rounded-md"
|
|
648
|
+
>
|
|
649
|
+
取消
|
|
650
|
+
</button>
|
|
651
|
+
<button
|
|
652
|
+
onClick={() => this.savePolicy()}
|
|
653
|
+
className="bg-blue-600 hover:bg-blue-700 pl-[16px] pr-[16px] pt-[8px] pb-[8px] text-[#ffffff] rounded-md"
|
|
654
|
+
>
|
|
655
|
+
保存
|
|
656
|
+
</button>
|
|
657
|
+
</View>
|
|
658
|
+
</View>
|
|
659
|
+
</View>
|
|
660
|
+
</View>
|
|
661
|
+
)}
|
|
662
|
+
</View>
|
|
663
|
+
</Page>
|
|
664
|
+
);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
export default Document;
|