forked from wts/wts
运行lint,将theLastPage的内容存储在sessionStorage里
This commit is contained in:
3
front/src/app.d.ts
vendored
3
front/src/app.d.ts
vendored
@@ -10,7 +10,4 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export {};
|
export {};
|
||||||
|
|||||||
@@ -4,9 +4,9 @@
|
|||||||
import Settings from 'carbon-icons-svelte/lib/Settings.svelte';
|
import Settings from 'carbon-icons-svelte/lib/Settings.svelte';
|
||||||
import Home from 'carbon-icons-svelte/lib/Home.svelte';
|
import Home from 'carbon-icons-svelte/lib/Home.svelte';
|
||||||
import Return from 'carbon-icons-svelte/lib/Return.svelte';
|
import Return from 'carbon-icons-svelte/lib/Return.svelte';
|
||||||
import SearchAdvanced from "carbon-icons-svelte/lib/SearchAdvanced.svelte";
|
import SearchAdvanced from 'carbon-icons-svelte/lib/SearchAdvanced.svelte';
|
||||||
import CarbonForIbmDotcom from "carbon-icons-svelte/lib/CarbonForIbmDotcom.svelte";
|
import CarbonForIbmDotcom from 'carbon-icons-svelte/lib/CarbonForIbmDotcom.svelte';
|
||||||
import EventSchedule from "carbon-icons-svelte/lib/EventSchedule.svelte";
|
import EventSchedule from 'carbon-icons-svelte/lib/EventSchedule.svelte';
|
||||||
import { page } from '$app/state';
|
import { page } from '$app/state';
|
||||||
|
|
||||||
let isAdminView = $derived(page.url.pathname.startsWith('/admin'));
|
let isAdminView = $derived(page.url.pathname.startsWith('/admin'));
|
||||||
@@ -45,12 +45,15 @@
|
|||||||
<span>后台中心</span>
|
<span>后台中心</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="/op/ticket_search" class="nav-item" class:active={page.url.pathname === '/op/ticket_search'}>
|
<a
|
||||||
|
href="/op/ticket_search"
|
||||||
|
class="nav-item"
|
||||||
|
class:active={page.url.pathname === '/op/ticket_search'}
|
||||||
|
>
|
||||||
<SearchAdvanced />
|
<SearchAdvanced />
|
||||||
<span>检索工单</span>
|
<span>检索工单</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="/op/scheduler" class="nav-item" class:active={page.url.pathname === '/op/scheduler'}>
|
<a href="/op/scheduler" class="nav-item" class:active={page.url.pathname === '/op/scheduler'}>
|
||||||
|
|
||||||
<EventSchedule />
|
<EventSchedule />
|
||||||
<span>我的排班</span>
|
<span>我的排班</span>
|
||||||
</a>
|
</a>
|
||||||
@@ -69,12 +72,19 @@
|
|||||||
<span>管理中心</span>
|
<span>管理中心</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="/admin/add_ticket" class="nav-item" class:active={page.url.pathname === '/admin/add_ticket'}>
|
<a
|
||||||
|
href="/admin/add_ticket"
|
||||||
|
class="nav-item"
|
||||||
|
class:active={page.url.pathname === '/admin/add_ticket'}
|
||||||
|
>
|
||||||
<SearchAdvanced />
|
<SearchAdvanced />
|
||||||
<span>增添工单</span>
|
<span>增添工单</span>
|
||||||
</a>
|
</a>
|
||||||
<a href="/admin/scheduler" class="nav-item" class:active={page.url.pathname === '/admin/scheduler'}>
|
<a
|
||||||
|
href="/admin/scheduler"
|
||||||
|
class="nav-item"
|
||||||
|
class:active={page.url.pathname === '/admin/scheduler'}
|
||||||
|
>
|
||||||
<EventSchedule />
|
<EventSchedule />
|
||||||
<span>成员排班</span>
|
<span>成员排班</span>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { BlockMap } from '$lib/types/enum';
|
import { BlockMap } from '$lib/types/enum';
|
||||||
import type { WtsBlock } from '$lib/types/enum';
|
import type { WtsBlock } from '$lib/types/enum';
|
||||||
let { b,r }: { b: WtsBlock, r: string } = $props();
|
let { b, r }: { b: WtsBlock; r: string } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<span>
|
<span>
|
||||||
|
|||||||
@@ -4,6 +4,6 @@
|
|||||||
let { a }: { a: WtsAccess } = $props();
|
let { a }: { a: WtsAccess } = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<span class="inline-block bg-gray-300 px-3 py-1 text-[15px] rounded-[19px]">
|
<span class="inline-block rounded-[19px] bg-gray-300 px-3 py-1 text-[15px]">
|
||||||
{AccessMap[a]}
|
{AccessMap[a]}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
canceled: 'text-gray-500'
|
canceled: 'text-gray-500'
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if s === 'scheduled' && isSameDay(ap, new Date())}
|
{#if s === 'scheduled' && isSameDay(ap, new Date())}
|
||||||
<span>
|
<span>
|
||||||
<strong class="text-blue-600">已预约</strong>
|
<strong class="text-blue-600">已预约</strong>
|
||||||
|
|||||||
@@ -25,7 +25,12 @@
|
|||||||
open = $bindable(TicketModal.Opened),
|
open = $bindable(TicketModal.Opened),
|
||||||
src = TicketModal.SRC,
|
src = TicketModal.SRC,
|
||||||
onTicketChanged
|
onTicketChanged
|
||||||
}: { t?: Ticket | null; open?: boolean; src?: 'user' | 'operator'; onTicketChanged?: () => void | Promise<void>;} = $props();
|
}: {
|
||||||
|
t?: Ticket | null;
|
||||||
|
open?: boolean;
|
||||||
|
src?: 'user' | 'operator';
|
||||||
|
onTicketChanged?: () => void | Promise<void>;
|
||||||
|
} = $props();
|
||||||
|
|
||||||
let loading = $state(false);
|
let loading = $state(false);
|
||||||
let traces: Trace[] = $state([]);
|
let traces: Trace[] = $state([]);
|
||||||
@@ -129,7 +134,15 @@
|
|||||||
<NotificationQueue bind:this={q1} />
|
<NotificationQueue bind:this={q1} />
|
||||||
<ModalHeader title=" 🖋️请更新No.{getTid(t)}的状态" />
|
<ModalHeader title=" 🖋️请更新No.{getTid(t)}的状态" />
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<TraceUpdateView {t} bind:view bind:open bind:isUpReady {q} {q1} onUpdated={onTicketChanged} />
|
<TraceUpdateView
|
||||||
|
{t}
|
||||||
|
bind:view
|
||||||
|
bind:open
|
||||||
|
bind:isUpReady
|
||||||
|
{q}
|
||||||
|
{q1}
|
||||||
|
onUpdated={onTicketChanged}
|
||||||
|
/>
|
||||||
</ModalBody>
|
</ModalBody>
|
||||||
<UpViewButton bind:view bind:isUpReady />
|
<UpViewButton bind:view bind:isUpReady />
|
||||||
</ComposedModal>
|
</ComposedModal>
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
let {
|
let {
|
||||||
view = $bindable<'trace' | 'cancel' | 'update'>(),
|
view = $bindable<'trace' | 'cancel' | 'update'>(),
|
||||||
isUpReady = $bindable<boolean>(),
|
isUpReady = $bindable<boolean>()
|
||||||
}: {
|
}: {
|
||||||
view: 'trace' | 'cancel' | 'update',
|
view: 'trace' | 'cancel' | 'update';
|
||||||
isUpReady: boolean,
|
isUpReady: boolean;
|
||||||
} = $props();
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ export function Guard(a: (subject: WtsAccess) => boolean) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!a(jwt.access)) {
|
if (!a(jwt.access)) {
|
||||||
if(jwt.access === "unregistered"){
|
if (jwt.access === 'unregistered') {
|
||||||
goto('/register');
|
goto('/register');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,28 @@
|
|||||||
|
import { browser } from '$app/environment';
|
||||||
|
|
||||||
//全局状态,保存用户刚刚访问的页面以便JWT获取后跳转回来
|
//全局状态,保存用户刚刚访问的页面以便JWT获取后跳转回来
|
||||||
class theLastPage {
|
class theLastPage {
|
||||||
p = $state('/');
|
p = $state('/');
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
if (browser) {
|
||||||
|
this.p = sessionStorage.getItem('_the_last_page') || '/';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Write(p: string) {
|
Write(p: string) {
|
||||||
this.p = p;
|
this.p = p;
|
||||||
|
if (browser) {
|
||||||
|
sessionStorage.setItem('_the_last_page', p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Read(): string {
|
Read(): string {
|
||||||
const p1 = this.p;
|
const p1 = this.p;
|
||||||
this.p = '/';
|
this.p = '/';
|
||||||
|
if (browser) {
|
||||||
|
sessionStorage.removeItem('_the_last_page');
|
||||||
|
}
|
||||||
return p1;
|
return p1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export let criteria: Criteria = {
|
|||||||
category: [],
|
category: [],
|
||||||
isp: [],
|
isp: [],
|
||||||
newer_than: undefined,
|
newer_than: undefined,
|
||||||
older_than: undefined,
|
older_than: undefined
|
||||||
},
|
},
|
||||||
_order: 'priority',
|
_order: 'priority',
|
||||||
_floor: null,
|
_floor: null,
|
||||||
@@ -38,12 +38,11 @@ export function resetCriteria() {
|
|||||||
category: [],
|
category: [],
|
||||||
isp: [],
|
isp: [],
|
||||||
newer_than: undefined,
|
newer_than: undefined,
|
||||||
older_than: undefined,
|
older_than: undefined
|
||||||
},
|
},
|
||||||
_order: 'priority',
|
_order: 'priority',
|
||||||
_floor: null,
|
_floor: null,
|
||||||
_blocks_in_zone: [],
|
_blocks_in_zone: [],
|
||||||
_view_today_scheduled: false
|
_view_today_scheduled: false
|
||||||
} as Criteria;
|
} as Criteria;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export const sample1issuer: UserProfile = {
|
|||||||
phone: '13800138000',
|
phone: '13800138000',
|
||||||
isp: 'mobile',
|
isp: 'mobile',
|
||||||
account: '12345678901@139.gd',
|
account: '12345678901@139.gd',
|
||||||
wx: 'zhangsan_wx',
|
wx: 'zhangsan_wx'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sample1: Ticket = {
|
export const sample1: Ticket = {
|
||||||
@@ -21,7 +21,7 @@ export const sample1: Ticket = {
|
|||||||
category: 'ip-or-device',
|
category: 'ip-or-device',
|
||||||
status: 'scheduled',
|
status: 'scheduled',
|
||||||
priority: 'assigned',
|
priority: 'assigned',
|
||||||
appointed_at: NowRFC3339(),
|
appointed_at: NowRFC3339()
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sample2issuer: UserProfile = {
|
export const sample2issuer: UserProfile = {
|
||||||
@@ -33,7 +33,7 @@ export const sample2issuer: UserProfile = {
|
|||||||
phone: '13800138000',
|
phone: '13800138000',
|
||||||
isp: 'telecom',
|
isp: 'telecom',
|
||||||
account: '18923456789',
|
account: '18923456789',
|
||||||
wx: 'zhangsan_wx',
|
wx: 'zhangsan_wx'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sample2: Ticket = {
|
export const sample2: Ticket = {
|
||||||
@@ -44,7 +44,7 @@ export const sample2: Ticket = {
|
|||||||
submitted_at: RFC3339('2024-01-01T00:10:00Z'),
|
submitted_at: RFC3339('2024-01-01T00:10:00Z'),
|
||||||
category: 'first-install',
|
category: 'first-install',
|
||||||
status: 'fresh',
|
status: 'fresh',
|
||||||
priority: 'mainline',
|
priority: 'mainline'
|
||||||
};
|
};
|
||||||
|
|
||||||
export const sampleTrace: Trace[] = [
|
export const sampleTrace: Trace[] = [
|
||||||
@@ -56,7 +56,7 @@ export const sampleTrace: Trace[] = [
|
|||||||
op_name: '(用户操作)',
|
op_name: '(用户操作)',
|
||||||
remark: '工单已提交',
|
remark: '工单已提交',
|
||||||
new_status: 'fresh',
|
new_status: 'fresh',
|
||||||
new_priority: 'mainline',
|
new_priority: 'mainline'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
opid: 2,
|
opid: 2,
|
||||||
@@ -66,7 +66,7 @@ export const sampleTrace: Trace[] = [
|
|||||||
op_name: '哈哈哈',
|
op_name: '哈哈哈',
|
||||||
remark: '用户预约了时间',
|
remark: '用户预约了时间',
|
||||||
new_status: 'scheduled',
|
new_status: 'scheduled',
|
||||||
new_appointment: RFC3339('2024-01-13T14:00:00Z'),
|
new_appointment: RFC3339('2024-01-13T14:00:00Z')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
opid: 3,
|
opid: 3,
|
||||||
@@ -75,7 +75,7 @@ export const sampleTrace: Trace[] = [
|
|||||||
op: '2395',
|
op: '2395',
|
||||||
op_name: '啊啊啊',
|
op_name: '啊啊啊',
|
||||||
remark: '材料不足,改日修',
|
remark: '材料不足,改日修',
|
||||||
new_status: 'delay',
|
new_status: 'delay'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
opid: 4,
|
opid: 4,
|
||||||
@@ -85,7 +85,7 @@ export const sampleTrace: Trace[] = [
|
|||||||
op_name: '嘿嘿嘿',
|
op_name: '嘿嘿嘿',
|
||||||
remark: '与用户重新约定时间,预约在2024-01-21下午',
|
remark: '与用户重新约定时间,预约在2024-01-21下午',
|
||||||
new_status: 'scheduled',
|
new_status: 'scheduled',
|
||||||
new_appointment: RFC3339('2024-01-21T15:00:00Z'),
|
new_appointment: RFC3339('2024-01-21T15:00:00Z')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
opid: 5,
|
opid: 5,
|
||||||
@@ -94,6 +94,6 @@ export const sampleTrace: Trace[] = [
|
|||||||
op: '2395',
|
op: '2395',
|
||||||
op_name: '喵喵喵',
|
op_name: '喵喵喵',
|
||||||
remark: '问题解决:用户路由器线路接触不良,更换后恢复正常',
|
remark: '问题解决:用户路由器线路接触不良,更换后恢复正常',
|
||||||
new_status: 'solved',
|
new_status: 'solved'
|
||||||
},
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,32 +1,80 @@
|
|||||||
export type WtsBlock =
|
export type WtsBlock =
|
||||||
| '1'| '2'| '3'| '4'| '5'| '6' //凤翔
|
| '1'
|
||||||
| '7'| '8'| '9'| '10'| '11' //北门
|
| '2'
|
||||||
| '12'| '13'| '14'| '15'| '20'| '21'| '22' //东门
|
| '3'
|
||||||
| '16'| '17'| '18'| '19' //岐头
|
| '4'
|
||||||
| 'XHA'| 'XHB'| 'XHC'| 'XHD' //香晖
|
| '5'
|
||||||
|
| '6' //凤翔
|
||||||
|
| '7'
|
||||||
|
| '8'
|
||||||
|
| '9'
|
||||||
|
| '10'
|
||||||
|
| '11' //北门
|
||||||
|
| '12'
|
||||||
|
| '13'
|
||||||
|
| '14'
|
||||||
|
| '15'
|
||||||
|
| '20'
|
||||||
|
| '21'
|
||||||
|
| '22' //东门
|
||||||
|
| '16'
|
||||||
|
| '17'
|
||||||
|
| '18'
|
||||||
|
| '19' //岐头
|
||||||
|
| 'XHA'
|
||||||
|
| 'XHB'
|
||||||
|
| 'XHC'
|
||||||
|
| 'XHD' //香晖
|
||||||
| 'ZH' //朝晖
|
| 'ZH' //朝晖
|
||||||
| 'other';
|
| 'other';
|
||||||
|
|
||||||
export const BlockMap: Record<WtsBlock, string> = {
|
export const BlockMap: Record<WtsBlock, string> = {
|
||||||
'1':'1栋','2':'2栋','3':'3栋','4':'4栋','5':'5栋','6':'6栋',
|
'1': '1栋',
|
||||||
'7':'7栋','8':'8栋','9':'9栋','10':'10栋','11':'11栋',
|
'2': '2栋',
|
||||||
'12':'12栋','13':'13栋','14':'14栋','15':'15栋','20':'20栋','21':'21栋','22':'22栋',
|
'3': '3栋',
|
||||||
'16':'16栋','17':'17栋','18':'18栋','19':'19栋',
|
'4': '4栋',
|
||||||
'XHA':'香晖A','XHB':'香晖B','XHC':'香晖C','XHD':'香晖D',
|
'5': '5栋',
|
||||||
'ZH':'朝晖',
|
'6': '6栋',
|
||||||
'other':'其它',
|
'7': '7栋',
|
||||||
}
|
'8': '8栋',
|
||||||
|
'9': '9栋',
|
||||||
|
'10': '10栋',
|
||||||
|
'11': '11栋',
|
||||||
|
'12': '12栋',
|
||||||
|
'13': '13栋',
|
||||||
|
'14': '14栋',
|
||||||
|
'15': '15栋',
|
||||||
|
'20': '20栋',
|
||||||
|
'21': '21栋',
|
||||||
|
'22': '22栋',
|
||||||
|
'16': '16栋',
|
||||||
|
'17': '17栋',
|
||||||
|
'18': '18栋',
|
||||||
|
'19': '19栋',
|
||||||
|
XHA: '香晖A',
|
||||||
|
XHB: '香晖B',
|
||||||
|
XHC: '香晖C',
|
||||||
|
XHD: '香晖D',
|
||||||
|
ZH: '朝晖',
|
||||||
|
other: '其它'
|
||||||
|
};
|
||||||
|
|
||||||
export type WtsAccess =
|
export type WtsAccess =
|
||||||
| 'dev'
|
| 'dev'
|
||||||
| 'chief'| 'api'| 'group-leader'
|
| 'chief'
|
||||||
| 'formal-member'| 'informal-member'
|
| 'api'
|
||||||
| 'pre-member'| 'user'
|
| 'group-leader'
|
||||||
|
| 'formal-member'
|
||||||
|
| 'informal-member'
|
||||||
|
| 'pre-member'
|
||||||
|
| 'user'
|
||||||
| 'unregistered';
|
| 'unregistered';
|
||||||
|
|
||||||
export const IsAccessIn = (...targets: WtsAccess[]) => (subject: WtsAccess): boolean => {
|
export const IsAccessIn =
|
||||||
|
(...targets: WtsAccess[]) =>
|
||||||
|
(subject: WtsAccess): boolean => {
|
||||||
return targets.includes(subject);
|
return targets.includes(subject);
|
||||||
}
|
};
|
||||||
|
|
||||||
export const IsOperator = IsAccessIn(
|
export const IsOperator = IsAccessIn(
|
||||||
'api',
|
'api',
|
||||||
@@ -37,12 +85,7 @@ export const IsOperator = IsAccessIn(
|
|||||||
'informal-member'
|
'informal-member'
|
||||||
);
|
);
|
||||||
|
|
||||||
export const IsAdmin = IsAccessIn(
|
export const IsAdmin = IsAccessIn('group-leader', 'api', 'chief', 'dev');
|
||||||
'group-leader',
|
|
||||||
'api',
|
|
||||||
'chief',
|
|
||||||
'dev'
|
|
||||||
);
|
|
||||||
|
|
||||||
export const IsUser = IsAccessIn(
|
export const IsUser = IsAccessIn(
|
||||||
'api',
|
'api',
|
||||||
@@ -57,108 +100,129 @@ export const IsUser = IsAccessIn(
|
|||||||
|
|
||||||
export const IsPreMember = IsAccessIn('pre-member');
|
export const IsPreMember = IsAccessIn('pre-member');
|
||||||
|
|
||||||
export const IsFormalMember = IsAccessIn(
|
export const IsFormalMember = IsAccessIn('group-leader', 'api', 'chief', 'dev', 'formal-member');
|
||||||
'group-leader',
|
|
||||||
'api',
|
|
||||||
'chief',
|
|
||||||
'dev',
|
|
||||||
'formal-member'
|
|
||||||
);
|
|
||||||
|
|
||||||
export const IsUnregistered = IsAccessIn('unregistered');
|
export const IsUnregistered = IsAccessIn('unregistered');
|
||||||
|
|
||||||
export const AccessMap: Record<WtsAccess, string> = {
|
export const AccessMap: Record<WtsAccess, string> = {
|
||||||
'dev': '开发组','chief':'科长','api':'API','group-leader':'组长',
|
dev: '开发组',
|
||||||
'formal-member':'正式成员','informal-member':'实习成员',
|
chief: '科长',
|
||||||
'pre-member':'前成员','user':'用户',
|
api: 'API',
|
||||||
'unregistered':'未注册用户',
|
'group-leader': '组长',
|
||||||
}
|
'formal-member': '正式成员',
|
||||||
|
'informal-member': '实习成员',
|
||||||
|
'pre-member': '前成员',
|
||||||
|
user: '用户',
|
||||||
|
unregistered: '未注册用户'
|
||||||
|
};
|
||||||
|
|
||||||
export type WtsISP = 'telecom' | 'unicom' | 'mobile' | 'broadnet' | 'others';
|
export type WtsISP = 'telecom' | 'unicom' | 'mobile' | 'broadnet' | 'others';
|
||||||
|
|
||||||
export const ISPMap: Record<WtsISP, string> = {
|
export const ISPMap: Record<WtsISP, string> = {
|
||||||
'telecom': '电信',
|
telecom: '电信',
|
||||||
'unicom': '联通',
|
unicom: '联通',
|
||||||
'mobile': '移动',
|
mobile: '移动',
|
||||||
'broadnet': '广电',
|
broadnet: '广电',
|
||||||
'others': '其它',
|
others: '其它'
|
||||||
}
|
};
|
||||||
|
|
||||||
export type WtsStatus = 'fresh' | 'scheduled' | 'delay' | 'escalated' | 'solved' | 'canceled';
|
export type WtsStatus = 'fresh' | 'scheduled' | 'delay' | 'escalated' | 'solved' | 'canceled';
|
||||||
|
|
||||||
export const StatusMap: Record<WtsStatus, string> = {
|
export const StatusMap: Record<WtsStatus, string> = {
|
||||||
'fresh': '待解决',
|
fresh: '待解决',
|
||||||
'scheduled': '已预约',
|
scheduled: '已预约',
|
||||||
'delay': '改日修',
|
delay: '改日修',
|
||||||
'escalated': '已上报',
|
escalated: '已上报',
|
||||||
'solved': '已解决',
|
solved: '已解决',
|
||||||
'canceled': '已取消',
|
canceled: '已取消'
|
||||||
}
|
};
|
||||||
|
|
||||||
export type WtsPriority = 'highest' | 'assigned' | 'mainline' | 'normal' | 'in-passing' | 'least';
|
export type WtsPriority = 'highest' | 'assigned' | 'mainline' | 'normal' | 'in-passing' | 'least';
|
||||||
|
|
||||||
export const PriorityMap: Record<WtsPriority, string> = {
|
export const PriorityMap: Record<WtsPriority, string> = {
|
||||||
'highest': '>>紧急派单!<<',
|
highest: '>>紧急派单!<<',
|
||||||
'assigned': '运营商工单',
|
assigned: '运营商工单',
|
||||||
'mainline': '主线任务',
|
mainline: '主线任务',
|
||||||
'normal': '普通报修',
|
normal: '普通报修',
|
||||||
'in-passing': '顺路看看',
|
'in-passing': '顺路看看',
|
||||||
'least': '最低',
|
least: '最低'
|
||||||
}
|
};
|
||||||
|
|
||||||
export type WtsCategory =
|
export type WtsCategory =
|
||||||
| 'first-install'| 'low-speed'| 'ip-or-device'| 'client-or-account'| 'others';
|
| 'first-install'
|
||||||
|
| 'low-speed'
|
||||||
|
| 'ip-or-device'
|
||||||
|
| 'client-or-account'
|
||||||
|
| 'others';
|
||||||
|
|
||||||
export const CategoryMap: Record<WtsCategory, string> = {
|
export const CategoryMap: Record<WtsCategory, string> = {
|
||||||
'first-install': '新装',
|
'first-install': '新装',
|
||||||
'low-speed': '网速慢',
|
'low-speed': '网速慢',
|
||||||
'ip-or-device': 'IP或设备问题',
|
'ip-or-device': 'IP或设备问题',
|
||||||
'client-or-account': '客户端或账号问题',
|
'client-or-account': '客户端或账号问题',
|
||||||
'others': '其它问题',
|
others: '其它问题'
|
||||||
}
|
};
|
||||||
|
|
||||||
export type WtsAPIErrorType =
|
export type WtsAPIErrorType = 1 | 2 | 3 | 4 | 5;
|
||||||
| 1 | 2 | 3 | 4 | 5;
|
|
||||||
|
|
||||||
export const APIErrorTypeMap: Record<WtsAPIErrorType, string> = {
|
export const APIErrorTypeMap: Record<WtsAPIErrorType, string> = {
|
||||||
1: '服务器内部错误,请联系我们的技术人员。',
|
1: '服务器内部错误,请联系我们的技术人员。',
|
||||||
2: '你的请求无效,可能是由于格式错误或不支持的操作。',
|
2: '你的请求无效,可能是由于格式错误或不支持的操作。',
|
||||||
3: '您没有进行该操作的权限。',
|
3: '您没有进行该操作的权限。',
|
||||||
4: '数据库出现错误。',
|
4: '数据库出现错误。',
|
||||||
5: '您的请求在逻辑上不被允许。',
|
5: '您的请求在逻辑上不被允许。'
|
||||||
}
|
};
|
||||||
export type WtsZone = 'FX' | 'BM' | 'DM' | 'QT' | 'XHAB' | 'XHCD' | 'ZH' | 'other' | 'all';
|
export type WtsZone = 'FX' | 'BM' | 'DM' | 'QT' | 'XHAB' | 'XHCD' | 'ZH' | 'other' | 'all';
|
||||||
|
|
||||||
export const ZoneMap: Record<WtsZone, string> = {
|
export const ZoneMap: Record<WtsZone, string> = {
|
||||||
'FX':'凤翔',
|
FX: '凤翔',
|
||||||
'BM':'北门',
|
BM: '北门',
|
||||||
'DM':'东门',
|
DM: '东门',
|
||||||
'QT':'岐头',
|
QT: '岐头',
|
||||||
'XHAB':'香晖AB',
|
XHAB: '香晖AB',
|
||||||
'XHCD':'香晖CD',
|
XHCD: '香晖CD',
|
||||||
'ZH':'朝晖',
|
ZH: '朝晖',
|
||||||
'other':'其它',
|
other: '其它',
|
||||||
'all':'全部',
|
all: '全部'
|
||||||
}
|
};
|
||||||
|
|
||||||
export const ZoneToBlock: Record<WtsZone, WtsBlock[]> = {
|
export const ZoneToBlock: Record<WtsZone, WtsBlock[]> = {
|
||||||
'FX':['1','2','3','4','5','6'],
|
FX: ['1', '2', '3', '4', '5', '6'],
|
||||||
'BM':['7','8','9','10','11'],
|
BM: ['7', '8', '9', '10', '11'],
|
||||||
'DM':['12','13','14','15','20','21','22'],
|
DM: ['12', '13', '14', '15', '20', '21', '22'],
|
||||||
'QT':['16','17','18','19'],
|
QT: ['16', '17', '18', '19'],
|
||||||
'XHAB':['XHA','XHB'],
|
XHAB: ['XHA', 'XHB'],
|
||||||
'XHCD':['XHC','XHD'],
|
XHCD: ['XHC', 'XHD'],
|
||||||
'ZH':['ZH'],
|
ZH: ['ZH'],
|
||||||
'other':['other'],
|
other: ['other'],
|
||||||
'all':[
|
all: [
|
||||||
'1','2','3','4','5','6',
|
'1',
|
||||||
'7','8','9','10','11',
|
'2',
|
||||||
'12','13','14','15','20','21','22',
|
'3',
|
||||||
'16','17','18','19',
|
'4',
|
||||||
'XHA','XHB',
|
'5',
|
||||||
'XHC','XHD',
|
'6',
|
||||||
|
'7',
|
||||||
|
'8',
|
||||||
|
'9',
|
||||||
|
'10',
|
||||||
|
'11',
|
||||||
|
'12',
|
||||||
|
'13',
|
||||||
|
'14',
|
||||||
|
'15',
|
||||||
|
'20',
|
||||||
|
'21',
|
||||||
|
'22',
|
||||||
|
'16',
|
||||||
|
'17',
|
||||||
|
'18',
|
||||||
|
'19',
|
||||||
|
'XHA',
|
||||||
|
'XHB',
|
||||||
|
'XHC',
|
||||||
|
'XHD',
|
||||||
'ZH',
|
'ZH',
|
||||||
'other'
|
'other'
|
||||||
],
|
]
|
||||||
}
|
};
|
||||||
|
|||||||
@@ -41,12 +41,15 @@
|
|||||||
<div style="display: flex; flex-direction: column; gap: 0.25rem;">
|
<div style="display: flex; flex-direction: column; gap: 0.25rem;">
|
||||||
<h2>🥺不会使用校园网?</h2>
|
<h2>🥺不会使用校园网?</h2>
|
||||||
<p>点击下方按钮,我们准备了校园网方方面面的攻略!</p>
|
<p>点击下方按钮,我们准备了校园网方方面面的攻略!</p>
|
||||||
<Button href="/help" kind="secondary" style="align-self: flex-end;transform: translate(-25px,0px);">网络攻略</Button>
|
<Button
|
||||||
|
href="/help"
|
||||||
|
kind="secondary"
|
||||||
|
style="align-self: flex-end;transform: translate(-25px,0px);">网络攻略</Button
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</RetroCard>
|
</RetroCard>
|
||||||
|
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
|
|||||||
@@ -2,7 +2,10 @@
|
|||||||
<br />
|
<br />
|
||||||
<hr />
|
<hr />
|
||||||
<br />
|
<br />
|
||||||
<p>中山学院网络维护科是一个独立的<strong>学生组织</strong>,成立于2005年,接受校信息中心的指导和管理。</p>
|
<p>
|
||||||
|
中山学院网络维护科是一个独立的<strong>学生组织</strong
|
||||||
|
>,成立于2005年,接受校信息中心的指导和管理。
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
网维的主要任务是保证校园宿舍网络的正常运行,处理解决在校学生所报修的有线校园网问题,这项业务主要通过依托于微信的网络报修系统来运行。
|
网维的主要任务是保证校园宿舍网络的正常运行,处理解决在校学生所报修的有线校园网问题,这项业务主要通过依托于微信的网络报修系统来运行。
|
||||||
</p>
|
</p>
|
||||||
@@ -11,7 +14,8 @@
|
|||||||
目前,我们与三大运营商建立了良好的合作关系,承接运营商在校园内的装维业务;在信息中心的关怀下,我们也承担学校部分IT后勤工作。
|
目前,我们与三大运营商建立了良好的合作关系,承接运营商在校园内的装维业务;在信息中心的关怀下,我们也承担学校部分IT后勤工作。
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
对于学生校园网报修,我们的成员会在<strong>每天16:30~18:00</strong>统一上门解决问题,用户在这个时间段必须本人在宿舍。
|
对于学生校园网报修,我们的成员会在<strong>每天16:30~18:00</strong
|
||||||
|
>统一上门解决问题,用户在这个时间段必须本人在宿舍。
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
网维一般会在每年的9~10月招新,对象为当年新生,要求有基础的计算机知识。具体招新事宜,请以实际通告为准。
|
网维一般会在每年的9~10月招新,对象为当年新生,要求有基础的计算机知识。具体招新事宜,请以实际通告为准。
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import RetroCard from "$lib/components/RetroCard.svelte";
|
import RetroCard from '$lib/components/RetroCard.svelte';
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h1>隐私权条款</h1>
|
<h1>隐私权条款</h1>
|
||||||
<br />
|
<br />
|
||||||
<hr />
|
<hr />
|
||||||
@@ -61,4 +61,3 @@
|
|||||||
<hr />
|
<hr />
|
||||||
<br />
|
<br />
|
||||||
<p>本条款最后更新于2025年12月27日,最终解释权归网维所有。</p>
|
<p>本条款最后更新于2025年12月27日,最终解释权归网维所有。</p>
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
let q: NotificationQueue;
|
let q: NotificationQueue;
|
||||||
|
|
||||||
let r = $state({
|
let r = $state({
|
||||||
priority: 'normal',
|
priority: 'normal'
|
||||||
} as NewTicketReq);
|
} as NewTicketReq);
|
||||||
|
|
||||||
function onOccurDateChange(event: CustomEvent) {
|
function onOccurDateChange(event: CustomEvent) {
|
||||||
@@ -223,4 +223,3 @@ helperText="选择工单的优先级类型,更高优先级会在系统中优
|
|||||||
<NotificationQueue bind:this={q} />
|
<NotificationQueue bind:this={q} />
|
||||||
|
|
||||||
<Loading active={!notLoading} />
|
<Loading active={!notLoading} />
|
||||||
|
|
||||||
|
|||||||
@@ -3,5 +3,6 @@
|
|||||||
|
|
||||||
let { data }: PageProps = $props();
|
let { data }: PageProps = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h1>Forbidden</h1>
|
<h1>Forbidden</h1>
|
||||||
<p>对不起,您没有权限访问这个页面。</p>
|
<p>对不起,您没有权限访问这个页面。</p>
|
||||||
@@ -3,11 +3,11 @@
|
|||||||
@plugin '@tailwindcss/typography';
|
@plugin '@tailwindcss/typography';
|
||||||
@plugin 'daisyui';
|
@plugin 'daisyui';
|
||||||
|
|
||||||
@plugin "daisyui/theme" {
|
@plugin 'daisyui/theme' {
|
||||||
name: "wireframe";
|
name: 'wireframe';
|
||||||
default: true;
|
default: true;
|
||||||
prefersdark: false;
|
prefersdark: false;
|
||||||
color-scheme: "light";
|
color-scheme: 'light';
|
||||||
--color-base-100: #f4f4f4;
|
--color-base-100: #f4f4f4;
|
||||||
--color-base-200: #e6e6e6;
|
--color-base-200: #e6e6e6;
|
||||||
--color-base-300: #d5d5d5;
|
--color-base-300: #d5d5d5;
|
||||||
@@ -38,9 +38,7 @@
|
|||||||
--noise: 1;
|
--noise: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@layer base {
|
@layer base {
|
||||||
|
|
||||||
html {
|
html {
|
||||||
/* 移动端优化:防止点击高亮 */
|
/* 移动端优化:防止点击高亮 */
|
||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
@@ -55,5 +53,4 @@
|
|||||||
/* 移动端优化:防止水平溢出 */
|
/* 移动端优化:防止水平溢出 */
|
||||||
@apply min-h-screen overflow-x-hidden bg-base-100 text-base-content;
|
@apply min-h-screen overflow-x-hidden bg-base-100 text-base-content;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
function gotoAuthAPI() {
|
function gotoAuthAPI() {
|
||||||
if (!env.PUBLIC_JWT) {
|
if (!env.PUBLIC_JWT) {
|
||||||
console.log("未找到PUBLIC_JWT")
|
console.log('未找到PUBLIC_JWT');
|
||||||
}
|
}
|
||||||
if (dev && env.PUBLIC_JWT) {
|
if (dev && env.PUBLIC_JWT) {
|
||||||
docCookies.setItem('jwt', env.PUBLIC_JWT, Infinity, '/');
|
docCookies.setItem('jwt', env.PUBLIC_JWT, Infinity, '/');
|
||||||
|
|||||||
@@ -67,7 +67,12 @@
|
|||||||
<RetroCard>
|
<RetroCard>
|
||||||
<span style="display: flex; align-items: center;">
|
<span style="display: flex; align-items: center;">
|
||||||
<h2 style="margin-right: 0.5rem;">个人信息</h2>
|
<h2 style="margin-right: 0.5rem;">个人信息</h2>
|
||||||
<Renew onclick={() => {TheLastPage.Write('/me'),goto('/login')}} style="cursor: pointer;" />
|
<Renew
|
||||||
|
onclick={() => {
|
||||||
|
(TheLastPage.Write('/me'), goto('/login'));
|
||||||
|
}}
|
||||||
|
style="cursor: pointer;"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
<StructuredList style="margin-bottom: 1rem;">
|
<StructuredList style="margin-bottom: 1rem;">
|
||||||
<StructuredListBody>
|
<StructuredListBody>
|
||||||
|
|||||||
@@ -115,7 +115,10 @@
|
|||||||
<div class="zone-tiles">
|
<div class="zone-tiles">
|
||||||
{#each zoneDisplayOrder as zone}
|
{#each zoneDisplayOrder as zone}
|
||||||
{#if typeof countByZone?.[zone] !== 'undefined'}
|
{#if typeof countByZone?.[zone] !== 'undefined'}
|
||||||
<Tile class={`zone-tile zone-${zoneTone(countByZone?.[zone])}`} on:click={() => jumpSearch(zone)}>
|
<Tile
|
||||||
|
class={`zone-tile zone-${zoneTone(countByZone?.[zone])}`}
|
||||||
|
on:click={() => jumpSearch(zone)}
|
||||||
|
>
|
||||||
<span class="zone-name">{ZoneMap[zone]}</span>
|
<span class="zone-name">{ZoneMap[zone]}</span>
|
||||||
<span class="zone-count">{countByZone?.[zone] ?? 0}</span>
|
<span class="zone-count">{countByZone?.[zone] ?? 0}</span>
|
||||||
</Tile>
|
</Tile>
|
||||||
|
|||||||
@@ -29,13 +29,15 @@
|
|||||||
import { criteria } from '$lib/states/ticketCriteriaSearch.svelte';
|
import { criteria } from '$lib/states/ticketCriteriaSearch.svelte';
|
||||||
import { goto } from '$app/navigation';
|
import { goto } from '$app/navigation';
|
||||||
import type { WtsStatus, WtsPriority, WtsCategory, WtsISP } from '$lib/types/enum';
|
import type { WtsStatus, WtsPriority, WtsCategory, WtsISP } from '$lib/types/enum';
|
||||||
import {WtsJWT} from '$lib/jwt'
|
import { WtsJWT } from '$lib/jwt';
|
||||||
|
|
||||||
onMount(() => Guard(IsOperator));
|
onMount(() => Guard(IsOperator));
|
||||||
|
|
||||||
let token: WtsJWT = $state({} as WtsJWT);
|
let token: WtsJWT = $state({} as WtsJWT);
|
||||||
|
|
||||||
onMount(()=>{token =CheckAndGetJWT('parsed');})
|
onMount(() => {
|
||||||
|
token = CheckAndGetJWT('parsed');
|
||||||
|
});
|
||||||
|
|
||||||
let req = $state(criteria.r as FilterTicketsReq);
|
let req = $state(criteria.r as FilterTicketsReq);
|
||||||
|
|
||||||
@@ -116,7 +118,7 @@
|
|||||||
'delay',
|
'delay',
|
||||||
'escalated'
|
'escalated'
|
||||||
] as const satisfies readonly WtsStatus[];
|
] as const satisfies readonly WtsStatus[];
|
||||||
const statusOptions: readonly WtsStatus[] = statusOptionsAdmin //之前的区分没有意义,在后端会拦截的,在这里高花样,好像反而会破坏正常功能,感觉这个页面还是重写的样子。。
|
const statusOptions: readonly WtsStatus[] = statusOptionsAdmin; //之前的区分没有意义,在后端会拦截的,在这里高花样,好像反而会破坏正常功能,感觉这个页面还是重写的样子。。
|
||||||
|
|
||||||
const priorityOptions = [
|
const priorityOptions = [
|
||||||
'highest',
|
'highest',
|
||||||
@@ -184,7 +186,7 @@
|
|||||||
|
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
isScheduledSelected = req.status?.includes('scheduled') ?? false;
|
isScheduledSelected = req.status?.includes('scheduled') ?? false;
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h1>报修单检索</h1>
|
<h1>报修单检索</h1>
|
||||||
@@ -244,7 +246,10 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</CheckboxGroup>
|
</CheckboxGroup>
|
||||||
<div class="toggle">
|
<div class="toggle">
|
||||||
<Toggle size="sm" toggled={allSelected(zoneSelected, zoneOptions)} on:toggle={(e)=> {
|
<Toggle
|
||||||
|
size="sm"
|
||||||
|
toggled={allSelected(zoneSelected, zoneOptions)}
|
||||||
|
on:toggle={(e) => {
|
||||||
const { toggled } = e.detail as { toggled: boolean };
|
const { toggled } = e.detail as { toggled: boolean };
|
||||||
zoneSelected = toggled ? [...zoneOptions] : [];
|
zoneSelected = toggled ? [...zoneOptions] : [];
|
||||||
}}
|
}}
|
||||||
@@ -283,7 +288,10 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</CheckboxGroup>
|
</CheckboxGroup>
|
||||||
<div class="toggle">
|
<div class="toggle">
|
||||||
<Toggle size="sm" toggled={allSelected(req.status, statusOptions)} on:toggle={(e)=> {
|
<Toggle
|
||||||
|
size="sm"
|
||||||
|
toggled={allSelected(req.status, statusOptions)}
|
||||||
|
on:toggle={(e) => {
|
||||||
const { toggled } = e.detail as { toggled: boolean };
|
const { toggled } = e.detail as { toggled: boolean };
|
||||||
req.status = toggled ? [...statusOptions] : [];
|
req.status = toggled ? [...statusOptions] : [];
|
||||||
}}
|
}}
|
||||||
@@ -320,7 +328,10 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</CheckboxGroup>
|
</CheckboxGroup>
|
||||||
<div class="toggle">
|
<div class="toggle">
|
||||||
<Toggle size="sm" toggled={allSelected(req.priority, priorityOptions)} on:toggle={(e)=> {
|
<Toggle
|
||||||
|
size="sm"
|
||||||
|
toggled={allSelected(req.priority, priorityOptions)}
|
||||||
|
on:toggle={(e) => {
|
||||||
const { toggled } = e.detail as { toggled: boolean };
|
const { toggled } = e.detail as { toggled: boolean };
|
||||||
req.priority = toggled ? [...priorityOptions] : [];
|
req.priority = toggled ? [...priorityOptions] : [];
|
||||||
}}
|
}}
|
||||||
@@ -353,7 +364,10 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</CheckboxGroup>
|
</CheckboxGroup>
|
||||||
<div class="toggle">
|
<div class="toggle">
|
||||||
<Toggle size="sm" toggled={allSelected(req.category, categoryOptions)} on:toggle={(e)=> {
|
<Toggle
|
||||||
|
size="sm"
|
||||||
|
toggled={allSelected(req.category, categoryOptions)}
|
||||||
|
on:toggle={(e) => {
|
||||||
const { toggled } = e.detail as { toggled: boolean };
|
const { toggled } = e.detail as { toggled: boolean };
|
||||||
req.category = toggled ? [...categoryOptions] : [];
|
req.category = toggled ? [...categoryOptions] : [];
|
||||||
}}
|
}}
|
||||||
@@ -388,7 +402,10 @@
|
|||||||
</Grid>
|
</Grid>
|
||||||
</CheckboxGroup>
|
</CheckboxGroup>
|
||||||
<div class="toggle">
|
<div class="toggle">
|
||||||
<Toggle size="sm" toggled={allSelected(req.isp, ispOptions)} on:toggle={(e)=> {
|
<Toggle
|
||||||
|
size="sm"
|
||||||
|
toggled={allSelected(req.isp, ispOptions)}
|
||||||
|
on:toggle={(e) => {
|
||||||
const { toggled } = e.detail as { toggled: boolean };
|
const { toggled } = e.detail as { toggled: boolean };
|
||||||
req.isp = toggled ? [...ispOptions] : [];
|
req.isp = toggled ? [...ispOptions] : [];
|
||||||
}}
|
}}
|
||||||
@@ -410,12 +427,23 @@
|
|||||||
|
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<NumberInput min={1} max={20} step={1} bind:value={floor} allowEmpty={true} allowDecimal={false}
|
<NumberInput
|
||||||
labelText="只看如下楼层(不填代表查看全部楼层)" />
|
min={1}
|
||||||
|
max={20}
|
||||||
|
step={1}
|
||||||
|
bind:value={floor}
|
||||||
|
allowEmpty={true}
|
||||||
|
allowDecimal={false}
|
||||||
|
labelText="只看如下楼层(不填代表查看全部楼层)"
|
||||||
|
/>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<Toggle labelText="只显示预约在今天的预约单" bind:toggled={viewTodayScheduled} disabled={!isScheduledSelected} />
|
<Toggle
|
||||||
|
labelText="只显示预约在今天的预约单"
|
||||||
|
bind:toggled={viewTodayScheduled}
|
||||||
|
disabled={!isScheduledSelected}
|
||||||
|
/>
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<Button on:click={search}>搜索</Button>
|
<Button on:click={search}>搜索</Button>
|
||||||
|
|||||||
@@ -40,8 +40,6 @@
|
|||||||
const roomNum = Number.parseInt(digits, 10);
|
const roomNum = Number.parseInt(digits, 10);
|
||||||
if (!Number.isFinite(roomNum)) return null;
|
if (!Number.isFinite(roomNum)) return null;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const floor = Math.floor(roomNum / 100);
|
const floor = Math.floor(roomNum / 100);
|
||||||
//console.log('getFloorFromRoom', { room, digits, roomNum, floor });
|
//console.log('getFloorFromRoom', { room, digits, roomNum, floor });
|
||||||
return Number.isFinite(floor) ? floor : null;
|
return Number.isFinite(floor) ? floor : null;
|
||||||
@@ -63,7 +61,11 @@
|
|||||||
if (criteria._view_today_scheduled) {
|
if (criteria._view_today_scheduled) {
|
||||||
const todayStart = new Date().setHours(0, 0, 0, 0);
|
const todayStart = new Date().setHours(0, 0, 0, 0);
|
||||||
const todayEnd = new Date().setHours(23, 59, 59, 999);
|
const todayEnd = new Date().setHours(23, 59, 59, 999);
|
||||||
tickets = tickets.filter((t) => t.status !== 'scheduled' || (toMs(t.appointed_at) >= todayStart && toMs(t.appointed_at) <= todayEnd));
|
tickets = tickets.filter(
|
||||||
|
(t) =>
|
||||||
|
t.status !== 'scheduled' ||
|
||||||
|
(toMs(t.appointed_at) >= todayStart && toMs(t.appointed_at) <= todayEnd)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
ok = true;
|
ok = true;
|
||||||
@@ -123,6 +125,11 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<span>没有找到符合条件的报修单。</span>
|
<span>没有找到符合条件的报修单。</span>
|
||||||
{/if}
|
{/if}
|
||||||
<TicketDetail t={TicketModal.NowTicket} bind:open={TicketModal.Opened} src={TicketModal.SRC} onTicketChanged={refreshTickets}/>
|
<TicketDetail
|
||||||
|
t={TicketModal.NowTicket}
|
||||||
|
bind:open={TicketModal.Opened}
|
||||||
|
src={TicketModal.SRC}
|
||||||
|
onTicketChanged={refreshTickets}
|
||||||
|
/>
|
||||||
|
|
||||||
<NotificationQueue bind:this={q} />
|
<NotificationQueue bind:this={q} />
|
||||||
|
|||||||
@@ -69,6 +69,11 @@
|
|||||||
<UserTicket {t} />
|
<UserTicket {t} />
|
||||||
{/each}
|
{/each}
|
||||||
|
|
||||||
<TicketDetail t={TicketModal.NowTicket} bind:open={TicketModal.Opened} src={TicketModal.SRC} onTicketChanged={refreshTickets1}/>
|
<TicketDetail
|
||||||
|
t={TicketModal.NowTicket}
|
||||||
|
bind:open={TicketModal.Opened}
|
||||||
|
src={TicketModal.SRC}
|
||||||
|
onTicketChanged={refreshTickets1}
|
||||||
|
/>
|
||||||
|
|
||||||
<NotificationQueue bind:this={q} />
|
<NotificationQueue bind:this={q} />
|
||||||
|
|||||||
Reference in New Issue
Block a user