| | |
| | | # 端å£å· |
| | | VITE_PORT=5666 |
| | | |
| | | # å½åå¼åç¯å¢åç |
| | | VITE_COMPANY=TRT |
| | | |
| | | VITE_BASE=/ |
| | | |
| | | # 请æ±è·¯å¾ |
| | |
| | | apiUrl: 'http://36.213.150.237:9013/admin-api', |
| | | }, |
| | | TRT: { |
| | | name: 'å京åä»å ', |
| | | name: 'åéèç©çº¿ç¼', |
| | | logo: '/logos/YZFXLogo.png', |
| | | favicon: '/logos/YZFXLogo.ico', |
| | | apiUrl: 'http://36.213.150.237:9015/admin-api', |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import type { PageParam, PageResult } from '#/packages/effects/request/src'; |
| | | |
| | | import { requestClient } from '#/api/request'; |
| | | |
| | | export namespace HrmRegularizeApi { |
| | | /** 转æ£ç³è¯· */ |
| | | export interface RegularizeApplication { |
| | | id?: number; |
| | | no?: string; |
| | | userId?: number; |
| | | userName?: string; |
| | | deptId?: number; |
| | | deptName?: string; |
| | | postId?: number; |
| | | postName?: string; |
| | | employmentType?: number; |
| | | employmentTypeName?: string; |
| | | expectedDate?: string; |
| | | reason?: string; |
| | | status?: number; |
| | | statusName?: string; |
| | | // 以ä¸ä¸ºå®¡æ ¸æ´¾çåæ®µï¼ç±å端å¨å®¡æ ¸æ¶åå
¥ï¼å端åªè¯»å±ç¤º |
| | | reviewerId?: number; // å®¡æ ¸äººIDï¼å®é
æ§è¡å®¡æ ¸çç¨æ·ï¼ |
| | | reviewerName?: string; // å®¡æ ¸äººå§å |
| | | reviewTime?: string; // å®¡æ ¸æ¶é´ |
| | | reviewRemark?: string; // å®¡æ ¸æè§ï¼å®¡æ ¸éè¿æ¶çæè§ / å®¡æ ¸ä¸éè¿æ¶çåå ï¼ |
| | | approveTime?: string; |
| | | remark?: string; |
| | | createTime?: string; |
| | | } |
| | | } |
| | | |
| | | /** æ¥è¯¢è½¬æ£ç³è¯·å页å表 */ |
| | | export function getRegularizePage(params: PageParam) { |
| | | return requestClient.get<PageResult<HrmRegularizeApi.RegularizeApplication>>( |
| | | '/hrm/regularize/page', |
| | | { params }, |
| | | ); |
| | | } |
| | | |
| | | /** æ¥è¯¢è½¬æ£ç³è¯·è¯¦æ
*/ |
| | | export function getRegularize(id: number) { |
| | | return requestClient.get<HrmRegularizeApi.RegularizeApplication>( |
| | | `/hrm/regularize/get?id=${id}`, |
| | | ); |
| | | } |
| | | |
| | | /** æ°å¢è½¬æ£ç³è¯·ï¼èç¨¿ï¼ */ |
| | | export function createRegularize(data: HrmRegularizeApi.RegularizeApplication) { |
| | | return requestClient.post('/hrm/regularize/create', data); |
| | | } |
| | | |
| | | /** æ´æ°è½¬æ£ç³è¯· */ |
| | | export function updateRegularize(data: HrmRegularizeApi.RegularizeApplication) { |
| | | return requestClient.put('/hrm/regularize/update', data); |
| | | } |
| | | |
| | | /** å é¤è½¬æ£ç³è¯· */ |
| | | export function deleteRegularize(id: number) { |
| | | return requestClient.delete(`/hrm/regularize/delete?id=${id}`); |
| | | } |
| | | |
| | | /** |
| | | * æäº¤è½¬æ£ç³è¯·å®¡æ¹ï¼è稿 / å®¡æ ¸ä¸éè¿ â 审æ¹ä¸ï¼ |
| | | * |
| | | * 审æ¹äººç±ãç³»ç»ç®¡ç - 审æ¹é
ç½®ãæä¸å¡ç±»åï¼hrm_regularize_approveï¼ç»ä¸é
ç½®ï¼æäº¤æ¶æ éæå®ã |
| | | */ |
| | | export function submitRegularize(id: number) { |
| | | return requestClient.put('/hrm/regularize/submit', null, { params: { id } }); |
| | | } |
| | | |
| | | /** è·å¾è½¬æ£ç³è¯·ç审æ¹äººç¼å·éåï¼ä¾åè¡¨é¡µå¤ææ¯å¦å±ç¤ºå®¡æ ¸æé® */ |
| | | export function getRegularizeApproverIds() { |
| | | return requestClient.get<number[]>('/hrm/regularize/approver-ids'); |
| | | } |
| | | |
| | | /** |
| | | * å®¡æ ¸è½¬æ£ç³è¯·ï¼å®¡æ¹ä¸ â å®¡æ ¸éè¿ / å®¡æ ¸ä¸éè¿ï¼ |
| | | * |
| | | * ä»
审æ¹é
ç½®ä¸ç审æ¹äººå¯è°ç¨ï¼å¤äººæ¶æç¾ï¼ï¼pass=false æ¶ reviewRemarkï¼ä¸éè¿åå ï¼å¿
å¡«ã |
| | | */ |
| | | export function auditRegularize( |
| | | id: number, |
| | | pass: boolean, |
| | | reviewRemark?: string, |
| | | ) { |
| | | return requestClient.put('/hrm/regularize/audit', { id, pass, reviewRemark }); |
| | | } |
| | |
| | | /** ç©æä¿¡æ¯ */ |
| | | export interface Item { |
| | | id?: number; |
| | | code: string; |
| | | code?: string; |
| | | name: string; |
| | | barCode?: string; |
| | | specification?: string; |
| | | technicalParameters?: string; |
| | | categoryId?: number; |
| | | categoryName?: string; |
| | | unitMeasureId?: number; |
| | |
| | | purchaseOrderCodeFlag?: boolean; |
| | | lotNumberFlag?: boolean; |
| | | qualityStatusFlag?: boolean; |
| | | } |
| | | |
| | | export interface TechnicalFile { |
| | | id: number; |
| | | itemId: number; |
| | | blobId: number; |
| | | versionNo: number; |
| | | fileName?: string; |
| | | previewURL?: string; |
| | | downloadURL?: string; |
| | | createTime?: string; |
| | | } |
| | | |
| | | /** ç©æå页æ¥è¯¢åæ° */ |
| | |
| | | updateSupport, |
| | | }); |
| | | } |
| | | |
| | | export function createTechnicalFile(itemId: number, blobId: number) { |
| | | return requestClient.post<number>('/mdm/item/technical-file/create', { itemId, blobId }); |
| | | } |
| | | |
| | | export function getTechnicalFileList(itemId: number) { |
| | | return requestClient.get<MdmItemApi.TechnicalFile[]>('/mdm/item/technical-file/list', { |
| | | params: { itemId }, |
| | | }); |
| | | } |
| | |
| | | import { getCompanyConfig } from '#/api/system/company-config'; |
| | | import { applyCompanyConfig } from '#/utils/company-config'; |
| | | |
| | | declare const __APP_LOGO__: string; |
| | | declare const __APP_NAME__: string; |
| | | |
| | | async function bootstrap(namespace: string) { |
| | | // åå§åç»ä»¶éé
å¨ |
| | | await initComponentAdapter(); |
| | |
| | | // å端ä¸å¯ç¨ææªé
ç½®ï¼ä¿æç¼è¯æé»è®¤ |
| | | } |
| | | |
| | | // æ¬å°æµè¯æå端é¨ç½²åçå±ç¤ºï¼é¿å
æµè¯åºä¸çæ§å
¬å¸é
ç½®è¦çå½å客æ·åçã |
| | | if (__APP_NAME__) { |
| | | applyCompanyConfig({ companyName: __APP_NAME__, logoUrl: __APP_LOGO__ }); |
| | | } |
| | | |
| | | // å®è£
æéæä»¤ |
| | | registerAccessDirective(app); |
| | | |
| | |
| | | <script setup lang="ts"> |
| | | withDefaults(defineProps<{ appName?: string; logo?: string; platformTitle?: string; platformDescription?: string }>(), { |
| | | appName: '', logo: '', platformTitle: 'æ»è¡¥åè¡ä¸æ°åå管çå¹³å°', platformDescription: 'ä¼ æ¿ä¸å»è¯ç²¾å · æå¡å¥åº·ç¾å¥½çæ´»', |
| | | appName: '', |
| | | logo: '', |
| | | platformTitle: '工䏿ºè½å¶é ç³»ç»', |
| | | platformDescription: 'æ°åå管ç · æºè½åç产 · ç²¾ç»åè¿è¥', |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="herbal-auth"> |
| | | <img class="herbal-auth__background" src="/images/auth/herbal-courtyard.png" alt="" fetchpriority="high" decoding="async" aria-hidden="true" /> |
| | | <div class="herbal-auth__veil" aria-hidden="true"></div> |
| | | <header class="herbal-auth__header"> |
| | | <div class="herbal-brand"> |
| | | <img v-if="logo" :src="logo" :alt="appName || 'å
¬å¸æ å¿'" class="herbal-brand__logo" /> |
| | | <span v-if="appName" class="herbal-brand__name">{{ appName }}</span> |
| | | <div class="herbal-brand__platform"> |
| | | <p class="herbal-brand__title">{{ platformTitle }}</p> |
| | | <p class="herbal-brand__description">{{ platformDescription }}</p> |
| | | <div class="industrial-auth"> |
| | | <div class="industrial-auth__toolbar"><slot name="toolbar"></slot></div> |
| | | <main class="industrial-auth__shell"> |
| | | <section class="industrial-auth__brand"> |
| | | <div class="industrial-auth__brandline"> |
| | | <img v-if="logo" :src="logo" :alt="appName || 'å
¬å¸æ å¿'" /> |
| | | <div> |
| | | <strong>{{ appName }}</strong> |
| | | <span>{{ platformTitle }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="herbal-auth__toolbar"><slot name="toolbar"></slot></div> |
| | | </header> |
| | | <main class="herbal-auth__main"> |
| | | <section class="herbal-motto" aria-labelledby="herbal-motto-title"> |
| | | <h2 id="herbal-motto-title"><span></span>å è®<span></span></h2> |
| | | <p>åå³è½è´µï¼å¿
䏿¢åç©å</p> |
| | | <p>ç®å¶è½ç¹ï¼å¿
䏿¢ç人工</p> |
| | | <div class="herbal-motto__rule" aria-hidden="true"><span></span><svg viewBox="0 0 60 24"><path d="M3 12h10c0-6 8-9 12-5 0-7 10-7 10 0 5-4 12-1 12 5h10M13 12c0 8 12 11 17 3 5 8 17 5 17-3M24 12c0-7 12-7 12 0s-12 7-12 0Z" /></svg><span></span></div> |
| | | </section> |
| | | <section class="herbal-panel" aria-label="è´¦æ·ç»å½"> |
| | | <div class="herbal-panel__frame" aria-hidden="true"> |
| | | <svg v-for="corner in ['tl','tr','bl','br']" :key="corner" :class="'herbal-corner herbal-corner--'+corner" viewBox="0 0 44 44"><path d="M2 42V12A10 10 0 0 1 12 2h30M9 42V9h33M2 21h19V2M9 28h19V9M2 35h33V2" /></svg> |
| | | <div class="industrial-auth__hero"> |
| | | <p class="industrial-auth__eyebrow">SMART MANUFACTURING / 01</p> |
| | | <h1>ç²¾çå¶é <br /><em>åå管ç</em></h1> |
| | | <p class="industrial-auth__description">让ç产ãåºåãè´¨éä¸ç»è¥æ°æ®å¨åä¸å¹³å°ä¸ååè¿è¡ã</p> |
| | | <div class="industrial-auth__signal" aria-hidden="true"><i></i><i></i><i></i><i></i></div> |
| | | </div> |
| | | <div class="herbal-panel__content"><slot></slot></div> |
| | | <p class="industrial-auth__tagline">æ°æ®é©±å¨ · æç»æ¹å</p> |
| | | </section> |
| | | <section class="industrial-auth__card" aria-label="è´¦æ·ç»å½"><slot></slot></section> |
| | | </main> |
| | | <footer class="industrial-auth__footer">{{ platformDescription }}</footer> |
| | | </div> |
| | | </template> |
| | | <style scoped> |
| | | .herbal-auth{position:relative;isolation:isolate;min-height:100svh;overflow-x:clip;background:#f6eddf;color:#29251f;padding:clamp(24px,3.2vw,52px) clamp(24px,5vw,88px) 42px;font-family:var(--font-family,system-ui,sans-serif)} |
| | | .herbal-auth__background,.herbal-auth__veil{position:absolute;inset:0;width:100%;height:100%;z-index:-2;object-fit:cover;object-position:center} |
| | | .herbal-auth__veil{z-index:-1;background:linear-gradient(90deg,transparent 48%,rgba(248,239,226,.14))} |
| | | .herbal-auth__header{display:flex;align-items:center;justify-content:space-between;gap:24px;position:relative;z-index:2} |
| | | .herbal-brand{display:flex;align-items:center;gap:18px;min-width:0} |
| | | .herbal-brand__logo{width:70px;height:70px;object-fit:contain;flex-shrink:0} |
| | | .herbal-brand__name{font-family:"STKaiti","KaiTi","FangSong",serif;font-weight:700;font-size:clamp(24px,2.3vw,38px);white-space:nowrap} |
| | | .herbal-brand__platform{border-left:1px solid #8e7e6a;padding-left:24px;min-width:0} |
| | | .herbal-brand__title{font-size:clamp(17px,1.5vw,24px);letter-spacing:.04em;margin:0 0 7px;line-height:1.4} |
| | | .herbal-brand__description{font-size:13px;color:#71685b;letter-spacing:.16em;margin:0;line-height:1.5} |
| | | .herbal-auth__toolbar{flex-shrink:0;position:relative;min-width:80px} |
| | | .herbal-auth__toolbar :deep(>div){position:static!important;background:rgba(255,253,248,.75);border:1px solid #e5d8c5;border-radius:30px;padding:4px 10px} |
| | | .herbal-auth__main{display:grid;grid-template-columns:minmax(0,1.35fr) minmax(400px,.85fr);gap:clamp(36px,5vw,88px);align-items:start;min-height:calc(100svh - 176px);padding-top:34px} |
| | | .herbal-motto{align-self:start;margin-top:12px;padding:0 0 24px;text-align:center} |
| | | .herbal-motto h2{display:flex;align-items:center;justify-content:center;gap:34px;font-family:"STKaiti","KaiTi","FangSong",serif;font-size:clamp(40px,4.3vw,72px);font-weight:700;line-height:1.2;letter-spacing:.2em;color:#8b1419;margin:0 0 12px} |
| | | .herbal-motto h2 span{height:1px;background:#ae7650;width:90px} |
| | | .herbal-motto p{font-family:"STKaiti","KaiTi","FangSong",serif;font-size:clamp(26px,3.15vw,54px);font-weight:700;line-height:1.65;letter-spacing:.015em;color:#863310;margin:0;white-space:nowrap} |
| | | .herbal-motto__rule{display:flex;align-items:center;justify-content:center;gap:22px;margin-top:22px;color:#a46628} |
| | | .herbal-motto__rule span{width:110px;height:1px;background:currentColor} |
| | | .herbal-motto__rule svg{width:55px;height:26px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round} |
| | | .herbal-panel{position:relative;width:100%;max-width:584px;justify-self:end;min-height:690px;border-radius:20px;background:rgba(255,253,249,.96);box-shadow:0 22px 55px rgba(91,49,19,.13);padding:clamp(76px,12.8vh,120px) clamp(34px,4.6vw,78px) 64px;display:flex;align-items:flex-start} |
| | | .herbal-panel__frame{position:absolute;inset:16px;border:1px solid #cda878;border-radius:12px;pointer-events:none} |
| | | .herbal-corner{position:absolute;width:38px;height:38px;fill:none;stroke:#cda878;stroke-width:1.3;background:#fffdf9} |
| | | .herbal-corner--tl{top:-1px;left:-1px;border-top-left-radius:12px}.herbal-corner--tr{top:-1px;right:-1px;transform:rotate(90deg);border-top-left-radius:12px}.herbal-corner--bl{bottom:-1px;left:-1px;transform:rotate(-90deg);border-top-left-radius:12px}.herbal-corner--br{bottom:-1px;right:-1px;transform:rotate(180deg);border-top-left-radius:12px} |
| | | .herbal-panel__content{width:100%;position:relative;min-width:0} |
| | | :global(.dark .herbal-auth){background:#211b17;color:#f4eadd} |
| | | :global(.dark .herbal-auth__background){filter:brightness(.4) saturate(.7)} |
| | | :global(.dark .herbal-auth__veil){background:rgba(24,19,15,.28)} |
| | | :global(.dark .herbal-brand__description){color:#d4c3ac} |
| | | :global(.dark .herbal-motto h2){color:#f0bab3} |
| | | :global(.dark .herbal-motto p){color:#edcfa5} |
| | | :global(.dark .herbal-panel){background:rgba(39,31,26,.97)} |
| | | :global(.dark .herbal-corner){background:#271f1a} |
| | | :global(.dark .herbal-auth__toolbar >div){background:#30271f;border-color:#8d7053;color:#f4eadd} |
| | | @media(min-width:1800px){.herbal-auth__main{grid-template-columns:minmax(0,1fr) 584px}.herbal-motto{max-width:900px;justify-self:center;width:100%}} |
| | | @media(max-width:1199px){.herbal-auth{padding:28px}.herbal-brand{gap:12px}.herbal-brand__logo{width:52px;height:52px}.herbal-brand__platform{padding-left:16px}.herbal-brand__description{letter-spacing:.06em}.herbal-auth__main{gap:26px;grid-template-columns:minmax(0,1fr) minmax(360px,.9fr)}.herbal-motto p{font-size:clamp(25px,3vw,36px)}.herbal-panel{padding:50px 36px;min-height:600px}} |
| | | @media(max-width:900px){.herbal-auth{padding:24px;}.herbal-brand__name{font-size:24px}.herbal-brand__description{display:none}.herbal-brand__title{font-size:17px}.herbal-auth__main{grid-template-columns:1fr;min-height:calc(100svh - 112px);padding:32px 0;}.herbal-motto{display:none}.herbal-panel{max-width:520px;min-height:560px;justify-self:center}.herbal-auth__background{object-position:35% center}.herbal-auth__veil{background:rgba(248,239,226,.48)}} |
| | | @media(max-width:540px){.herbal-auth{padding:20px 16px 24px}.herbal-auth__header{align-items:flex-start;gap:10px}.herbal-brand{gap:10px;flex-wrap:wrap;max-width:calc(100% - 86px)}.herbal-brand__logo{width:42px;height:42px}.herbal-brand__name{font-size:22px}.herbal-brand__platform{border:0;padding:0;flex-basis:100%}.herbal-brand__title{font-size:14px;letter-spacing:.02em;margin:0}.herbal-auth__toolbar{min-width:76px}.herbal-panel{padding:50px 28px;min-height:510px;border-radius:16px}.herbal-panel__frame{inset:12px}.herbal-auth__main{padding-top:28px}.herbal-corner{width:30px;height:30px}} |
| | | @media(max-height:760px) and (min-width:901px){.herbal-panel{min-height:530px;padding-top:48px;padding-bottom:48px}.herbal-auth__main{padding-top:22px}.herbal-motto{margin-top:20px}} |
| | | </style> |
| | | |
| | | <style scoped> |
| | | .industrial-auth{position:relative;isolation:isolate;min-height:100svh;display:grid;place-items:center;padding:0;background:#f3f6fa;color:#142b43;font-family:var(--font-family,Inter,system-ui,sans-serif);overflow:hidden} |
| | | .industrial-auth::before{content:'';position:absolute;width:720px;height:720px;right:-380px;top:-360px;border:1px solid #dbe6ef;border-radius:50%;box-shadow:0 0 0 34px rgba(219,230,239,.28),0 0 0 68px rgba(219,230,239,.18);z-index:-1} |
| | | .industrial-auth__toolbar{position:absolute;right:32px;top:24px;z-index:2} |
| | | .industrial-auth__toolbar :deep(>div){position:static!important;background:#fff;border:1px solid #e1e8ef;border-radius:10px;padding:4px 10px;box-shadow:0 4px 14px rgba(20,43,67,.06)} |
| | | .industrial-auth__shell{width:100%;min-height:100svh;display:grid;grid-template-columns:1.08fr .92fr;background:#fff;border:0;border-radius:0;box-shadow:none;overflow:hidden} |
| | | .industrial-auth__brand{position:relative;display:flex;flex-direction:column;padding:72px 82px;background:#102b46;color:#fff;overflow:hidden} |
| | | .industrial-auth__brand::before{content:'';position:absolute;width:540px;height:540px;right:-300px;bottom:-300px;border:1px solid rgba(111,179,222,.3);border-radius:50%;box-shadow:0 0 0 26px rgba(111,179,222,.08),0 0 0 52px rgba(111,179,222,.06)} |
| | | .industrial-auth__brandline{position:relative;z-index:1;display:flex;align-items:center;gap:16px}.industrial-auth__brandline img{width:54px;height:54px;object-fit:contain;border-radius:10px;background:#fff;padding:5px}.industrial-auth__brandline strong{display:block;font-size:23px;letter-spacing:.06em;line-height:1.35}.industrial-auth__brandline span{display:block;margin-top:5px;color:#9db6c9;font-size:12px;letter-spacing:.12em} |
| | | .industrial-auth__hero{position:relative;z-index:1;margin:auto 0}.industrial-auth__eyebrow{margin:0 0 24px;color:#79b9df;font-size:11px;font-weight:700;letter-spacing:.18em}.industrial-auth__hero h1{margin:0;color:#fff;font-size:clamp(42px,4.5vw,62px);font-weight:700;line-height:1.22;letter-spacing:.04em}.industrial-auth__hero h1 em{color:#78bce2;font-style:normal}.industrial-auth__description{max-width:360px;margin:26px 0 0;color:#b5c9d8;font-size:15px;line-height:1.9}.industrial-auth__signal{display:flex;gap:8px;margin-top:40px}.industrial-auth__signal i{display:block;width:40px;height:4px;border-radius:2px;background:#70b8df}.industrial-auth__signal i:nth-child(2){width:72px;background:#3d8fc0}.industrial-auth__signal i:nth-child(3){width:24px;background:#e08946}.industrial-auth__signal i:nth-child(4){width:12px;background:#fff}.industrial-auth__tagline{position:relative;z-index:1;margin:0;color:#8faabd;font-size:12px;letter-spacing:.14em} |
| | | .industrial-auth__card{display:flex;align-items:center;padding:80px 96px;background:#fff}.industrial-auth__card :deep(.herbal-login){width:100%;max-width:420px;margin:0 auto} |
| | | .industrial-auth__footer{position:absolute;bottom:18px;color:#8a9bab;font-size:11px;letter-spacing:.08em;z-index:2} |
| | | :global(.dark .industrial-auth){background:#0c1c2b;color:#e8f1f7}.industrial-auth :global(.dark .industrial-auth__card){background:#122b40}.industrial-auth :global(.dark .industrial-auth__toolbar >div){background:#17374f;border-color:#315873;color:#e8f1f7} |
| | | @media(max-width:860px){.industrial-auth__shell{grid-template-columns:1fr;min-height:100svh}.industrial-auth__brand{padding:38px 40px}.industrial-auth__hero{margin:54px 0}.industrial-auth__hero h1{font-size:42px}.industrial-auth__card{padding:48px 40px}.industrial-auth__footer{display:none}} |
| | | @media(max-width:520px){.industrial-auth__toolbar{right:16px;top:16px}.industrial-auth__brand{padding:30px 26px}.industrial-auth__brandline strong{font-size:19px}.industrial-auth__hero{margin:42px 0}.industrial-auth__hero h1{font-size:36px}.industrial-auth__card{padding:40px 24px}} |
| | | </style> |
| | |
| | | // æªé
ç½®å
¬å¸æ å¿æ¶ä¸å±ç¤ºæ¡æ¶æ¼ç¤º Logoã |
| | | return source?.includes('@vbenjs/static-source') ? '' : source; |
| | | }); |
| | | const pageTitle = computed(() => companyConfigStore.loginTitle || 'æ»è¡¥åè¡ä¸æ°åå管çå¹³å°'); |
| | | const pageDescription = computed(() => companyConfigStore.loginDescription || 'ä¼ æ¿ä¸å»è¯ç²¾å · æå¡å¥åº·ç¾å¥½çæ´»'); |
| | | const pageTitle = computed(() => companyConfigStore.loginTitle || `${appName.value}æºè½å¶é ç³»ç»`); |
| | | const pageDescription = computed(() => companyConfigStore.loginDescription || `${appName.value}æ°åå管çå¹³å°`); |
| | | </script> |
| | | |
| | | <template> |
| | |
| | | |
| | | // 馿¬¡åçº§åæ¥åç主è²ï¼é¿å
æ§çèè²å好é®çæ¬æ¬¡ä¸»é¢æ´æ°ã |
| | | // å级åç¨æ·å¨å好设置ä¸éæ©çé¢è²åæææ¨¡å¼ä»ä¼ä¿çã |
| | | document.documentElement.dataset.brandTheme = 'herbal'; |
| | | const brandThemeKey = `${namespace}-herbal-theme-v1`; |
| | | document.documentElement.dataset.brandTheme = 'industrial'; |
| | | const brandThemeKey = `${namespace}-industrial-theme-v1`; |
| | | try { |
| | | if (!localStorage.getItem(brandThemeKey)) { |
| | | preferencesManager.updatePreferences({ |
| | | theme: { builtinType: 'custom', colorPrimary: '#a51d24' }, |
| | | theme: { builtinType: 'custom', colorPrimary: '#2563eb' }, |
| | | }); |
| | | localStorage.setItem(brandThemeKey, '1'); |
| | | } |
| | | } catch { |
| | | preferencesManager.updatePreferences({ |
| | | theme: { builtinType: 'custom', colorPrimary: '#a51d24' }, |
| | | theme: { builtinType: 'custom', colorPrimary: '#2563eb' }, |
| | | }); |
| | | } |
| | | watch( |
| | | () => preferences.theme.colorPrimary, |
| | | (color) => { document.documentElement.dataset.herbalPalette = String(color.toLowerCase() === '#a51d24'); }, |
| | | (color) => { document.documentElement.dataset.industrialPalette = String(color.toLowerCase() === '#2563eb'); }, |
| | | { immediate: true, flush: 'sync' }, |
| | | ); |
| | | |
| | |
| | | // overrides |
| | | theme: { |
| | | builtinType: 'custom', |
| | | colorPrimary: '#a51d24', |
| | | colorPrimary: '#2563eb', |
| | | }, |
| | | app: { |
| | | /** åç«¯è·¯ç±æ¨¡å¼ */ |
| | |
| | | } from '#/api/system/company-config'; |
| | | import { applyCompanyConfig } from '#/utils/company-config'; |
| | | |
| | | declare const __APP_LOGO__: string; |
| | | declare const __APP_NAME__: string; |
| | | |
| | | /** |
| | | * å
¬å¸åçä¿¡æ¯å
¨å±é
ç½® |
| | | * |
| | |
| | | } catch { |
| | | // å端ä¸å¯ç¨ææªé
ç½®ï¼ä¿æç¼è¯æé»è®¤ |
| | | } |
| | | |
| | | // æ¬å°æµè¯æå端é¨ç½²åçå±ç¤ºï¼é¿å
æµè¯åºä¸çæ§å
¬å¸é
ç½®è¦çå½å客æ·åçã |
| | | if (__APP_NAME__) { |
| | | companyName.value = __APP_NAME__; |
| | | logoUrl.value = __APP_LOGO__; |
| | | loginTitle.value = `${__APP_NAME__}æºè½å¶é ç³»ç»`; |
| | | loginDescription.value = `${__APP_NAME__}æ°åå管çå¹³å°`; |
| | | applyToPreferences(); |
| | | } |
| | | } |
| | | |
| | | /** ä¿åå
¬å¸é
ç½®å°å端并åºç¨ */ |
| | |
| | | /* åç䏿§è²ä¸ä¸»è²å离ï¼ä¸»è²ä»éè¿ Vben preferences çæå
¨é¨è²é¶ã */ |
| | | html[data-brand-theme='herbal']:not(.dark) { |
| | | --background: 40 50% 99%; |
| | | --background-deep: 37 33% 95%; |
| | | --foreground: 27 16% 17%; |
| | | --card: 40 50% 99%; |
| | | --card-foreground: 27 16% 17%; |
| | | --popover: 40 50% 99%; |
| | | --popover-foreground: 27 16% 17%; |
| | | --muted: 35 25% 94%; |
| | | --muted-foreground: 28 10% 40%; |
| | | --secondary: 35 25% 94%; |
| | | --secondary-foreground: 27 16% 17%; |
| | | --accent: 33 35% 93%; |
| | | --accent-dark: 33 28% 90%; |
| | | --accent-darker: 33 24% 87%; |
| | | --accent-lighter: 38 45% 97%; |
| | | --accent-hover: 33 28% 90%; |
| | | --accent-foreground: 27 16% 17%; |
| | | --border: 33 25% 86%; |
| | | --input: 33 25% 86%; |
| | | --sidebar: 40 50% 99%; |
| | | --sidebar-deep: 37 35% 97%; |
| | | --menu: var(--sidebar); |
| | | --header: 40 50% 99%; |
| | | /* åéèç©çº¿ç¼å·¥ä¸æºè½ç³»ç»ï¼èç°è²ä¼ä¸åå°åºè° */ |
| | | html[data-brand-theme='industrial']:not(.dark) { |
| | | --background: 210 40% 98%; --background-deep: 210 32% 95%; --foreground: 215 35% 16%; |
| | | --card: 0 0% 100%; --card-foreground: 215 35% 16%; --popover: 0 0% 100%; --popover-foreground: 215 35% 16%; |
| | | --muted: 210 30% 94%; --muted-foreground: 215 16% 42%; --secondary: 210 30% 94%; --secondary-foreground: 215 35% 16%; |
| | | --accent: 210 60% 94%; --accent-dark: 210 45% 88%; --accent-darker: 210 40% 82%; --accent-lighter: 210 50% 98%; --accent-hover: 210 50% 90%; --accent-foreground: 215 35% 16%; |
| | | --border: 210 25% 86%; --input: 210 25% 86%; --sidebar: 215 38% 16%; --sidebar-deep: 215 42% 12%; --menu: var(--sidebar); --header: 0 0% 100%; |
| | | } |
| | | html[data-brand-theme='herbal'].dark { |
| | | --background: 26 16% 12%; |
| | | --background-deep: 25 18% 9%; |
| | | --foreground: 35 30% 90%; |
| | | --card: 26 15% 14%; |
| | | --card-foreground: 35 30% 90%; |
| | | --popover: 26 15% 14%; |
| | | --popover-foreground: 35 30% 90%; |
| | | --muted: 26 13% 19%; |
| | | --muted-foreground: 33 15% 68%; |
| | | --border: 27 15% 26%; |
| | | --input: 27 15% 26%; |
| | | --sidebar: 26 16% 12%; |
| | | --sidebar-deep: 25 18% 10%; |
| | | --menu: var(--sidebar); |
| | | --header: 26 16% 12%; |
| | | html[data-brand-theme='industrial'].dark { |
| | | --background: 215 40% 10%; --background-deep: 215 42% 8%; --foreground: 210 30% 94%; --card: 215 35% 14%; --card-foreground: 210 30% 94%; |
| | | --popover: 215 35% 14%; --popover-foreground: 210 30% 94%; --muted: 215 28% 20%; --muted-foreground: 210 18% 70%; --border: 215 24% 28%; --input: 215 24% 28%; |
| | | --sidebar: 215 42% 9%; --sidebar-deep: 215 45% 7%; --menu: var(--sidebar); --header: 215 38% 12%; |
| | | } |
| | | /* æè²ä¸ä½¿ç¨æäº®æ±ç è²ï¼ä¿è¯é¾æ¥ä¸é䏿å¯è¯»ï¼æé®æé
æ·±è²æåã */ |
| | | html[data-brand-theme='herbal'][data-herbal-palette='true'].dark { |
| | | --primary: 357 64% 73% !important; |
| | | --primary-500: 357 64% 73% !important; |
| | | --primary-600: 357 69% 77% !important; |
| | | --primary-700: 357 70% 83% !important; |
| | | --primary-foreground: 27 25% 12%; |
| | | } |
| | | /* æ¯æåæ·±è²å¯¼èªå好ï¼ä¸è®©æµ
è²åçåºè¦ç该å好ã */ |
| | | html[data-brand-theme='herbal']:not(.dark) .dark { |
| | | --sidebar: 26 16% 12%; |
| | | --sidebar-deep: 25 18% 10%; |
| | | --menu: var(--sidebar); |
| | | --header: 26 16% 12%; |
| | | } |
| | | html[data-brand-theme='industrial'][data-industrial-palette='true'].dark { --primary: 217 91% 72% !important; --primary-500: 217 91% 72% !important; --primary-600: 217 91% 76% !important; --primary-700: 217 91% 82% !important; --primary-foreground: 215 45% 10%; } |
| | | |
| | |
| | | .herbal-login__heading{margin-bottom:32px} |
| | | .herbal-login__heading h1{font-size:clamp(28px,2.4vw,36px);font-weight:700;line-height:1.4;letter-spacing:-.02em;margin:0 0 12px;color:#29251f;display:flex;align-items:center;gap:14px} |
| | | .herbal-login__heading p{font-size:15px;line-height:1.7;color:#756d63;margin:0} |
| | | .herbal-login__seal{width:20px;height:30px;flex-shrink:0;color:#a51d24;fill:none;stroke:currentColor;stroke-width:1.2} |
| | | .herbal-login :deep(input:not([type='checkbox'])){min-height:56px;border-radius:9px;border:1px solid #ddd6cc;background:rgba(255,255,255,.82);padding:12px 16px;font-size:16px;color:#30281f} |
| | | .herbal-login :deep(input::placeholder){color:#7a7167;opacity:1} |
| | | .herbal-login :deep(input:focus-visible){outline:2px solid #a51d24;outline-offset:3px} |
| | | .herbal-login__seal{width:20px;height:30px;flex-shrink:0;color:#2563eb;fill:none;stroke:currentColor;stroke-width:1.2} |
| | | .herbal-login :deep(input:not([type='checkbox'])){min-height:52px;border-radius:8px;border:1px solid #d7e1ea;background:#fff;padding:12px 16px;font-size:16px;color:#1e293b} |
| | | .herbal-login :deep(input::placeholder){color:#64748b;opacity:1} |
| | | .herbal-login :deep(input:focus-visible){outline:2px solid #2563eb;outline-offset:3px} |
| | | .herbal-login :deep(input[autocomplete='current-password']){padding-right:44px} |
| | | .herbal-login :deep(button[aria-label='login']){min-height:58px;margin-top:8px;border-radius:9px;background:#a51d24;color:#fff;font-size:19px;font-weight:600;letter-spacing:.12em;box-shadow:0 5px 12px rgba(137,24,30,.12)} |
| | | .herbal-login :deep(button[aria-label='login']:hover){background:#87171d} |
| | | .herbal-login :deep(button[aria-label='login']:focus-visible){outline:2px solid #a51d24;outline-offset:4px} |
| | | .herbal-login :deep(button[aria-label='login']){min-height:52px;margin-top:8px;border-radius:8px;background:#2563eb;color:#fff;font-size:16px;font-weight:600;letter-spacing:.12em;box-shadow:0 6px 16px rgba(37,99,235,.22)} |
| | | .herbal-login :deep(button[aria-label='login']:hover){background:#1d4ed8} |
| | | .herbal-login :deep(button[aria-label='login']:focus-visible){outline:2px solid #2563eb;outline-offset:4px} |
| | | .herbal-login :deep(button[aria-label='login']:disabled){opacity:.65;cursor:wait} |
| | | :global(.dark .herbal-login__heading h1){color:#f5eee4} |
| | | :global(.dark .herbal-login__heading p){color:#d1c1ae} |
| | |
| | | import type { VbenFormApi, VbenFormSchema } from "#/adapter/form"; |
| | | import type { VxeTableGridOptions } from "#/adapter/vxe-table"; |
| | | |
| | | import { h } from 'vue'; |
| | | |
| | | import { CommonStatusEnum, DICT_TYPE } from "#/packages/constants/src"; |
| | | import { getDictOptions } from "#/packages/effects/hooks/src"; |
| | | |
| | | import { z } from '#/adapter/form'; |
| | | import { generateAutoCode } from '#/api/mes/md/autocode/record'; |
| | | import { MesAutoCodeRuleCode } from '@vben/constants'; |
| | | import { getItemTypeSimpleList } from '#/api/mes/md/item/type'; |
| | | import { getUnitPage } from '#/api/mdm/unit'; |
| | | import { getWarehouseSimpleList } from '#/api/mes/wm/warehouse'; |
| | | |
| | | import { Button } from 'ant-design-vue'; |
| | | |
| | | // ç¼ååä½å表 |
| | | let unitListCache: any[] | null = null; |
| | |
| | | { |
| | | component: "Input", |
| | | fieldName: "code", |
| | | label: "ç©æç¼ç ", |
| | | label: "产åç¼å·", |
| | | componentProps: { |
| | | maxLength: 64, |
| | | placeholder: "请è¾å
¥ç©æç¼ç ", |
| | | placeholder: "éæ©äº§åç±»åå¹¶ä¿ååèªå¨çæ", |
| | | disabled: true, |
| | | }, |
| | | rules: z.string().min(1, 'ç©æç¼ç ä¸è½ä¸ºç©º').max(64), |
| | | suffix: () => |
| | | h( |
| | | Button, |
| | | { |
| | | type: 'default', |
| | | onClick: async () => { |
| | | const code = await generateAutoCode( |
| | | MesAutoCodeRuleCode.MD_ITEM_CODE, |
| | | ); |
| | | await formApi?.setFieldValue('code', code); |
| | | }, |
| | | }, |
| | | { default: () => 'çæ' }, |
| | | ), |
| | | help: "ç³»ç»æäº§åç±»åèªå¨çæä¹ä½ç¼å·ï¼ä¾å¦åææ 100100001", |
| | | }, |
| | | { |
| | | component: "Input", |
| | |
| | | treeDefaultExpandAll: true, |
| | | treeData: categoryTreeData, |
| | | fieldNames: { label: 'label', value: 'value', children: 'children' }, |
| | | }, |
| | | }, |
| | | { |
| | | component: 'Select', |
| | | fieldName: 'itemType', |
| | | label: '产åç±»å', |
| | | rules: 'selectRequired', |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©äº§åç±»å', |
| | | options: [ |
| | | { label: 'åææï¼1001ï¼', value: 1 }, |
| | | { label: 'åæåï¼1002ï¼', value: 2 }, |
| | | { label: 'æåï¼1003ï¼', value: 3 }, |
| | | { label: 'è¾
æï¼1004ï¼', value: 4 }, |
| | | { label: 'å
¶ä»ï¼1005ï¼', value: 5 }, |
| | | ], |
| | | }, |
| | | }, |
| | | { |
| | |
| | | }, |
| | | }, |
| | | { |
| | | component: 'Divider', |
| | | fieldName: 'basicDataDivider', |
| | | label: 'åºç¡æ°æ®', |
| | | formItemClass: 'col-span-2', |
| | | componentProps: { orientation: 'left', plain: true }, |
| | | }, |
| | | { |
| | | component: 'Textarea', |
| | | fieldName: 'technicalParameters', |
| | | label: 'ææ¯åæ°', |
| | | formItemClass: 'col-span-2', |
| | | componentProps: { |
| | | placeholder: '请è¾å
¥äº§åææ¯åæ°', |
| | | rows: 4, |
| | | }, |
| | | }, |
| | | { |
| | | component: "InputNumber", |
| | | fieldName: "safetyStock", |
| | | label: "åºåé¢è¦æ°é", |
| | | componentProps: { |
| | | class: "!w-full", |
| | | min: 0, |
| | | precision: 2, |
| | | placeholder: "请è¾å
¥åºåé¢è¦æ°é", |
| | | }, |
| | | }, |
| | | { |
| | | component: "InputNumber", |
| | | fieldName: "minStock", |
| | | label: "æä½åºå", |
| | | componentProps: { |
| | | class: "!w-full", |
| | | min: 0, |
| | | precision: 2, |
| | | placeholder: "请è¾å
¥æä½åºå", |
| | | }, |
| | | }, |
| | | { |
| | | component: "InputNumber", |
| | | fieldName: "maxStock", |
| | | label: "æé«åºå", |
| | | componentProps: { |
| | | class: "!w-full", |
| | | min: 0, |
| | | precision: 2, |
| | | placeholder: "请è¾å
¥æé«åºå", |
| | | }, |
| | | }, |
| | | { |
| | | component: "InputNumber", |
| | | fieldName: "purchasePrice", |
| | | label: "éè´ä»·", |
| | |
| | | min: 0, |
| | | precision: 2, |
| | | placeholder: "请è¾å
¥ææ¬ä»·", |
| | | }, |
| | | }, |
| | | { |
| | | component: "InputNumber", |
| | | fieldName: "safetyStock", |
| | | label: "å®å
¨åºå", |
| | | componentProps: { |
| | | class: "!w-full", |
| | | min: 0, |
| | | precision: 2, |
| | | placeholder: "请è¾å
¥å®å
¨åºå", |
| | | }, |
| | | }, |
| | | { |
| | | component: "InputNumber", |
| | | fieldName: "minStock", |
| | | label: "æä½åºå", |
| | | componentProps: { |
| | | class: "!w-full", |
| | | min: 0, |
| | | precision: 2, |
| | | placeholder: "请è¾å
¥æä½åºå", |
| | | }, |
| | | }, |
| | | { |
| | | component: "InputNumber", |
| | | fieldName: "maxStock", |
| | | label: "æé«åºå", |
| | | componentProps: { |
| | | class: "!w-full", |
| | | min: 0, |
| | | precision: 2, |
| | | placeholder: "请è¾å
¥æé«åºå", |
| | | }, |
| | | }, |
| | | { |
| | |
| | | return [ |
| | | { |
| | | fieldName: "code", |
| | | label: "ç©æç¼ç ", |
| | | label: "产åç¼å·", |
| | | component: "Input", |
| | | componentProps: { |
| | | placeholder: "请è¾å
¥ç©æç¼ç ", |
| | |
| | | { type: "checkbox", width: 40 }, |
| | | { |
| | | field: "code", |
| | | title: "ç©æç¼ç ", |
| | | title: "产åç¼å·", |
| | | minWidth: 120, |
| | | }, |
| | | { |
| | |
| | | <script lang="ts" setup> |
| | | import type { MdmItemApi } from '#/api/mdm/item'; |
| | | |
| | | import { ref } from 'vue'; |
| | | |
| | | import { useVbenModal } from "#/packages/effects/common-ui/src"; |
| | |
| | | import { message } from "ant-design-vue"; |
| | | |
| | | import { useVbenForm } from '#/adapter/form'; |
| | | import { createItem, getItem, updateItem } from '#/api/mdm/item'; |
| | | import { |
| | | createItem, |
| | | createTechnicalFile, |
| | | getItem, |
| | | getTechnicalFileList, |
| | | updateItem, |
| | | } from '#/api/mdm/item'; |
| | | import type { MdmItemApi } from '#/api/mdm/item'; |
| | | import { FileUpload } from '#/components/upload'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { useFormSchema, clearUnitListCache, buildCategoryTree } from '../data'; |
| | |
| | | |
| | | const emit = defineEmits(['success']); |
| | | const formData = ref<MdmItemApi.Item>(); |
| | | const technicalFiles = ref<MdmItemApi.TechnicalFile[]>([]); |
| | | const technicalUploadValue = ref<number[]>([]); |
| | | |
| | | const [Form, formApi] = useVbenForm({ |
| | | commonConfig: { |
| | |
| | | async onOpenChange(isOpen: boolean) { |
| | | if (!isOpen) { |
| | | formData.value = undefined; |
| | | technicalFiles.value = []; |
| | | technicalUploadValue.value = []; |
| | | return; |
| | | } |
| | | const data = modalApi.getData<MdmItemApi.Item>(); |
| | |
| | | // åæ¥ç¶ææ å°ï¼è¯¦æ
æ¥å£è¿å syncedMesï¼è¡¨ååæ®µä¸º syncMes |
| | | formData.value.syncMes = formData.value.syncedMes ?? true; |
| | | await formApi.setValues(formData.value); |
| | | technicalFiles.value = await getTechnicalFileList(data.id); |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | | } else { |
| | | // æ°å¢æ¨¡å¼ |
| | | formData.value = undefined; |
| | | technicalFiles.value = []; |
| | | technicalUploadValue.value = []; |
| | | await formApi.resetForm(); |
| | | } |
| | | }, |
| | | }); |
| | | |
| | | async function handleTechnicalFileChange(value: unknown) { |
| | | if (!formData.value?.id || !Array.isArray(value)) { |
| | | return; |
| | | } |
| | | const blobId = value.find((item): item is number => typeof item === 'number'); |
| | | if (!blobId) { |
| | | return; |
| | | } |
| | | try { |
| | | await createTechnicalFile(formData.value.id, blobId); |
| | | technicalFiles.value = await getTechnicalFileList(formData.value.id); |
| | | message.success('ææ¯æä»¶å·²ä¿åï¼åå²çæ¬å·²ä¿ç'); |
| | | } finally { |
| | | technicalUploadValue.value = []; |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal class="w-[1000px]" :title="formData?.id ? $t('ui.actionTitle.edit', ['ç©æ']) : $t('ui.actionTitle.create', ['ç©æ'])"> |
| | | <Form class="mx-4" /> |
| | | <div v-if="formData?.id" class="mx-4 mb-4 rounded border p-4"> |
| | | <div class="mb-3 text-base font-medium">ææ¯æä»¶åå²</div> |
| | | <FileUpload |
| | | v-model:value="technicalUploadValue" |
| | | value-key="id" |
| | | :max-number="1" |
| | | :multiple="false" |
| | | :accept="['.pdf', '.doc', '.docx', '.xls', '.xlsx', '.dwg', '.png', '.jpg', '.jpeg']" |
| | | help-text="ä¸ä¼ æ°æä»¶ä¼çææ°ççæ¬ï¼å岿件ä»å¯æ¥ç" |
| | | @change="handleTechnicalFileChange" |
| | | /> |
| | | <a-table |
| | | class="mt-3" |
| | | size="small" |
| | | :data-source="technicalFiles" |
| | | :pagination="false" |
| | | row-key="id" |
| | | > |
| | | <a-table-column key="versionNo" title="çæ¬" data-index="versionNo" /> |
| | | <a-table-column key="fileName" title="æä»¶å" data-index="fileName" /> |
| | | <a-table-column key="createTime" title="ä¸ä¼ æ¶é´" data-index="createTime" /> |
| | | <a-table-column key="action" title="æä½"> |
| | | <template #default="{ record }"> |
| | | <a :href="record.downloadURL || record.previewURL" target="_blank">æ¥çæä»¶</a> |
| | | </template> |
| | | </a-table-column> |
| | | </a-table> |
| | | </div> |
| | | </Modal> |
| | | </template> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | import type { VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { HrmRegularizeApi } from '#/api/hrm/regularize'; |
| | | |
| | | import { DICT_TYPE } from '#/packages/constants/src'; |
| | | import { getDictOptions } from '#/packages/effects/hooks/src'; |
| | | |
| | | import { getEmployeePage } from '#/api/hrm/employee'; |
| | | |
| | | /** 表åç±»å */ |
| | | export type FormType = 'create' | 'detail' | 'update'; |
| | | |
| | | /** |
| | | * ç¨å·¥æ§è´¨é项 |
| | | * |
| | | * ä¸å端 HrmEmploymentTypeEnum ä¿æä¸è´ï¼åå
¸è¡¨ä¸ææªç»´æ¤è¯¥åå
¸ã |
| | | */ |
| | | export const EMPLOYMENT_TYPE_OPTIONS = [ |
| | | { label: 'æ£å¼', value: 1 }, |
| | | { label: 'å³å¡', value: 2 }, |
| | | { label: 'å¤å
', value: 3 }, |
| | | { label: 'å®ä¹ ', value: 4 }, |
| | | { label: 'éä¼è¿è', value: 5 }, |
| | | { label: 'å
¶ä»', value: 6 }, |
| | | ]; |
| | | |
| | | /** ç³è¯·äººä¸æé项ï¼åå·¥å页æ¥å£é项转æ¢åä¿ççä¸å¡åæ®µï¼ */ |
| | | export interface ApplicantOption { |
| | | deptId?: number; |
| | | postId?: number; |
| | | employmentType?: number; |
| | | } |
| | | |
| | | /** æ°å¢/ä¿®æ¹è½¬æ£ç³è¯·ç表å */ |
| | | export function useFormSchema( |
| | | formType: FormType, |
| | | onApplicantChange?: (option: ApplicantOption) => void, |
| | | ): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | | fieldName: 'id', |
| | | component: 'Input', |
| | | dependencies: { |
| | | triggerFields: [''], |
| | | show: () => false, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'deptId', |
| | | component: 'Input', |
| | | dependencies: { |
| | | triggerFields: [''], |
| | | show: () => false, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'postId', |
| | | component: 'Input', |
| | | dependencies: { |
| | | triggerFields: [''], |
| | | show: () => false, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'userId', |
| | | label: 'ç³è¯·äºº', |
| | | component: 'ApiSelect', |
| | | componentProps: { |
| | | // éæ©åå·¥åï¼value åç¨æ·ç userIdï¼å端æ userId å
³èå工档æ¡ï¼ |
| | | api: getEmployeePage, |
| | | params: { pageNo: 1, pageSize: 1000 }, |
| | | resultField: 'list', |
| | | labelField: 'name', |
| | | valueField: 'userId', |
| | | // æªå
³èç³»ç»è´¦å·çå工没æ userIdï¼åç«¯æ æ³æ®æ¤ååå工档æ¡ï¼ç´æ¥æé¤ |
| | | afterFetch: async (res: { list?: Array<{ userId?: number }> }) => ({ |
| | | list: (res?.list ?? []).filter((item) => item.userId != null), |
| | | }), |
| | | placeholder: 'è¯·éæ©ç³è¯·äººï¼ä¸éé»è®¤ä¸ºæ¬äººï¼', |
| | | showSearch: true, |
| | | optionFilterProp: 'label', |
| | | // ä»
æ°å¢æ¶å¯éæ©ï¼ä¿®æ¹/æ¥çæ¶éå®ï¼é¿å
转æ£å¯¹è±¡è¢«æ¹é |
| | | disabled: formType !== 'create', |
| | | onChange: (_value: unknown, option: unknown) => { |
| | | onApplicantChange?.(option as ApplicantOption); |
| | | }, |
| | | }, |
| | | help: |
| | | formType === 'create' |
| | | ? 'ä¸éæ©æ¶é»è®¤ç³è¯·äººä¸ºå½åç»å½ç¨æ·ï¼äººäºå¯ä»£éè¯ç¨æåå·¥' |
| | | : undefined, |
| | | }, |
| | | { |
| | | fieldName: 'employmentType', |
| | | label: 'ç¨å·¥æ§è´¨', |
| | | component: 'Select', |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©ç¨å·¥æ§è´¨', |
| | | options: EMPLOYMENT_TYPE_OPTIONS, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'expectedDate', |
| | | label: 'æè½¬æ£æ¥æ', |
| | | component: 'DatePicker', |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©æè½¬æ£æ¥æ', |
| | | valueFormat: 'YYYY-MM-DD', |
| | | style: { width: '100%' }, |
| | | }, |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | fieldName: 'reason', |
| | | label: '转æ£åå ', |
| | | component: 'Textarea', |
| | | formItemClass: 'col-span-2', |
| | | componentProps: { |
| | | placeholder: '请è¾å
¥è½¬æ£åå ', |
| | | rows: 3, |
| | | maxlength: 500, |
| | | showCount: true, |
| | | }, |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | fieldName: 'remark', |
| | | label: '夿³¨', |
| | | component: 'Textarea', |
| | | formItemClass: 'col-span-2', |
| | | componentProps: { |
| | | placeholder: '请è¾å
¥å¤æ³¨', |
| | | rows: 2, |
| | | }, |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | /** å表çæç´¢è¡¨å */ |
| | | export function useGridFormSchema(): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | | fieldName: 'no', |
| | | label: 'ç³è¯·åå·', |
| | | component: 'Input', |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: '请è¾å
¥ç³è¯·åå·', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'employmentType', |
| | | label: 'ç¨å·¥æ§è´¨', |
| | | component: 'Select', |
| | | componentProps: { |
| | | allowClear: true, |
| | | options: EMPLOYMENT_TYPE_OPTIONS, |
| | | placeholder: 'è¯·éæ©ç¨å·¥æ§è´¨', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'status', |
| | | label: '审æ¹ç¶æ', |
| | | component: 'Select', |
| | | componentProps: { |
| | | allowClear: true, |
| | | options: getDictOptions(DICT_TYPE.HRM_AUDIT_STATUS, 'number'), |
| | | placeholder: 'è¯·éæ©å®¡æ¹ç¶æ', |
| | | }, |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | /** å表çåæ®µ */ |
| | | export function useGridColumns(): VxeTableGridOptions<HrmRegularizeApi.RegularizeApplication>['columns'] { |
| | | return [ |
| | | { field: 'no', title: 'ç³è¯·åå·', width: 150 }, |
| | | { field: 'userName', title: 'ç³è¯·äºº', minWidth: 100 }, |
| | | { field: 'deptName', title: 'é¨é¨', minWidth: 120 }, |
| | | { field: 'postName', title: 'å²ä½', minWidth: 120 }, |
| | | { field: 'employmentTypeName', title: 'ç¨å·¥æ§è´¨', width: 100 }, |
| | | { field: 'expectedDate', title: 'æè½¬æ£æ¥æ', width: 120 }, |
| | | { |
| | | field: 'status', |
| | | title: '审æ¹ç¶æ', |
| | | width: 100, |
| | | cellRender: { |
| | | name: 'CellDict', |
| | | props: { type: DICT_TYPE.HRM_AUDIT_STATUS }, |
| | | }, |
| | | }, |
| | | { |
| | | field: 'createTime', |
| | | title: 'å建æ¶é´', |
| | | width: 180, |
| | | formatter: 'formatDateTime', |
| | | }, |
| | | { |
| | | title: 'æä½', |
| | | width: 260, |
| | | fixed: 'right', |
| | | slots: { |
| | | default: 'actions', |
| | | }, |
| | | }, |
| | | ]; |
| | | } |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { HrmRegularizeApi } from '#/api/hrm/regularize'; |
| | | |
| | | import { ref } from 'vue'; |
| | | |
| | | import { Page, useVbenModal } from '#/packages/effects/common-ui/src'; |
| | | import { useUserStore } from '@vben/stores'; |
| | | |
| | | import { message } from 'ant-design-vue'; |
| | | |
| | | import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; |
| | | import { |
| | | deleteRegularize, |
| | | getRegularizeApproverIds, |
| | | getRegularizePage, |
| | | submitRegularize, |
| | | } from '#/api/hrm/regularize'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import AuditModal from './modules/audit-modal.vue'; |
| | | import Form from './modules/form.vue'; |
| | | |
| | | const userStore = useUserStore(); |
| | | const currentUserId = userStore.userInfo?.id; // å½åç»å½ç¨æ· IDï¼ç¨äºå®¡æ¹äººæé夿 |
| | | |
| | | /** 审æ¹é
ç½®ä¸è¯¥ä¸å¡ç审æ¹äººç¼å·éåï¼å³å®ãå®¡æ ¸ / å®¡æ ¸ä¸éè¿ãæé®æ¯å¦å±ç¤º */ |
| | | const approverIds = ref<number[]>([]); |
| | | |
| | | /** æå审æ¹äººéåï¼å¤±è´¥æ¶ä¿æä¸ºç©ºï¼æé®ä¸å±ç¤ºï¼ï¼ä¸é»æå表å è½½ */ |
| | | async function loadApproverIds() { |
| | | try { |
| | | approverIds.value = (await getRegularizeApproverIds()) ?? []; |
| | | } catch { |
| | | approverIds.value = []; |
| | | } |
| | | } |
| | | |
| | | /** å½åç»å½ç¨æ·æ¯å¦ä¸ºè¯¥ä¸å¡ç审æ¹äººï¼ä¸ç³è¯·å¤äºå®¡æ¹ä¸ï¼10ï¼ */ |
| | | function canAudit(row: HrmRegularizeApi.RegularizeApplication) { |
| | | return ( |
| | | row.status === 10 && |
| | | !!currentUserId && |
| | | approverIds.value.includes(currentUserId) |
| | | ); |
| | | } |
| | | |
| | | const [FormModal, formModalApi] = useVbenModal({ |
| | | connectedComponent: Form, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const [AuditModalComp, auditModalApi] = useVbenModal({ |
| | | connectedComponent: AuditModal, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | /** å·æ°è¡¨æ ¼ä¸å®¡æ¹äººéå */ |
| | | function handleRefresh() { |
| | | gridApi.query(); |
| | | loadApproverIds(); |
| | | } |
| | | |
| | | /** å建转æ£ç³è¯· */ |
| | | function handleCreate() { |
| | | formModalApi.setData({ formType: 'create' }).open(); |
| | | } |
| | | |
| | | /** æ¥ç转æ£ç³è¯· */ |
| | | function handleDetail(row: HrmRegularizeApi.RegularizeApplication) { |
| | | formModalApi.setData({ id: row.id, formType: 'detail' }).open(); |
| | | } |
| | | |
| | | /** ç¼è¾è½¬æ£ç³è¯· */ |
| | | function handleEdit(row: HrmRegularizeApi.RegularizeApplication) { |
| | | formModalApi.setData({ id: row.id, formType: 'update' }).open(); |
| | | } |
| | | |
| | | /** å é¤è½¬æ£ç³è¯· */ |
| | | async function handleDelete(row: HrmRegularizeApi.RegularizeApplication) { |
| | | const hideLoading = message.loading({ |
| | | content: $t('ui.actionMessage.deleting', ['转æ£ç³è¯·']), |
| | | duration: 0, |
| | | }); |
| | | try { |
| | | await deleteRegularize(row.id!); |
| | | message.success($t('ui.actionMessage.deleteSuccess', ['转æ£ç³è¯·'])); |
| | | handleRefresh(); |
| | | } finally { |
| | | hideLoading(); |
| | | } |
| | | } |
| | | |
| | | /** æäº¤å®¡æ¹ - 审æ¹äººç±ãç³»ç»ç®¡ç - 审æ¹é
ç½®ãç»ä¸æå®ï¼æ¤å¤æ ééæ© */ |
| | | async function handleSubmit(row: HrmRegularizeApi.RegularizeApplication) { |
| | | const hideLoading = message.loading({ |
| | | content: 'æ£å¨æäº¤å®¡æ¹...', |
| | | duration: 0, |
| | | }); |
| | | try { |
| | | await submitRegularize(row.id!); |
| | | message.success('æäº¤å®¡æ¹æå'); |
| | | handleRefresh(); |
| | | } finally { |
| | | hideLoading(); |
| | | } |
| | | } |
| | | |
| | | /** å®¡æ ¸ - éè¿ / ä¸éè¿ */ |
| | | function handleAudit( |
| | | row: HrmRegularizeApi.RegularizeApplication, |
| | | pass: boolean, |
| | | ) { |
| | | auditModalApi.setData({ pass, row }).open(); |
| | | } |
| | | |
| | | const [Grid, gridApi] = useVbenVxeGrid({ |
| | | formOptions: { |
| | | schema: useGridFormSchema(), |
| | | }, |
| | | gridOptions: { |
| | | columns: useGridColumns(), |
| | | height: 'auto', |
| | | keepSource: true, |
| | | proxyConfig: { |
| | | ajax: { |
| | | query: async ({ page }, formValues) => |
| | | await getRegularizePage({ |
| | | pageNo: page.currentPage, |
| | | pageSize: page.pageSize, |
| | | ...formValues, |
| | | }), |
| | | }, |
| | | }, |
| | | rowConfig: { |
| | | keyField: 'id', |
| | | isHover: true, |
| | | }, |
| | | toolbarConfig: { |
| | | refresh: true, |
| | | search: true, |
| | | }, |
| | | } as VxeTableGridOptions<HrmRegularizeApi.RegularizeApplication>, |
| | | }); |
| | | |
| | | // è¿å
¥é¡µé¢å³æå审æ¹äººéåï¼ç¨äºæ§å¶å®¡æ ¸æé®æ¾é |
| | | loadApproverIds(); |
| | | </script> |
| | | |
| | | <template> |
| | | <Page auto-content-height> |
| | | <FormModal @success="handleRefresh" /> |
| | | <AuditModalComp @success="handleRefresh" /> |
| | | <Grid table-title="转æ£ç³è¯·å表"> |
| | | <template #toolbar-tools> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: $t('ui.actionTitle.create', ['转æ£ç³è¯·']), |
| | | type: 'primary', |
| | | icon: ACTION_ICON.ADD, |
| | | auth: ['hrm:regularize:create'], |
| | | onClick: handleCreate, |
| | | }, |
| | | ]" |
| | | /> |
| | | </template> |
| | | <template #actions="{ row }"> |
| | | <TableAction |
| | | :actions="[ |
| | | { |
| | | label: 'æ¥ç', |
| | | type: 'link', |
| | | onClick: handleDetail.bind(null, row), |
| | | }, |
| | | { |
| | | label: $t('common.edit'), |
| | | type: 'link', |
| | | icon: ACTION_ICON.EDIT, |
| | | auth: ['hrm:regularize:update'], |
| | | ifShow: row.status === 0, |
| | | onClick: handleEdit.bind(null, row), |
| | | }, |
| | | { |
| | | label: 'æäº¤å®¡æ¹', |
| | | type: 'link', |
| | | auth: ['hrm:regularize:update'], |
| | | // 审æ¹äººç±å®¡æ¹é
ç½®ç»ä¸æå®ï¼æäº¤åä»
äºæ¬¡ç¡®è®¤ï¼ä¸åå¼¹éæµç¨æ¡ |
| | | popConfirm: { |
| | | title: '确认æäº¤å®¡æ¹ï¼æäº¤åç±å®¡æ¹é
ç½®ä¸æå®ç审æ¹äººå¤çã', |
| | | confirm: handleSubmit.bind(null, row), |
| | | }, |
| | | // è稿(0) ä¸ å®¡æ ¸ä¸éè¿(30) åå¯æäº¤ï¼åè
éä¿®æ¹åéæ°æäº¤ |
| | | ifShow: row.status === 0 || row.status === 30, |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸', |
| | | type: 'link', |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['hrm:regularize:audit'], |
| | | // ä»
ã审æ¹ä¸ + å½åç»å½ç¨æ·å¨å®¡æ¹é
ç½®ç审æ¹äººååå
ãææ¾ç¤º |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, true), |
| | | }, |
| | | { |
| | | label: 'å®¡æ ¸ä¸éè¿', |
| | | type: 'link', |
| | | danger: true, |
| | | auth: ['hrm:regularize:audit'], |
| | | // åä¸ï¼ä¸ãå®¡æ ¸ãæå¯¹åºç° |
| | | ifShow: canAudit(row), |
| | | onClick: handleAudit.bind(null, row, false), |
| | | }, |
| | | { |
| | | label: $t('common.delete'), |
| | | type: 'link', |
| | | danger: true, |
| | | icon: ACTION_ICON.DELETE, |
| | | auth: ['hrm:regularize:delete'], |
| | | // å端ä»
å
许å é¤è稿 |
| | | ifShow: row.status === 0, |
| | | popConfirm: { |
| | | title: $t('ui.actionMessage.deleteConfirm', ['转æ£ç³è¯·']), |
| | | confirm: handleDelete.bind(null, row), |
| | | }, |
| | | }, |
| | | ]" |
| | | /> |
| | | </template> |
| | | </Grid> |
| | | </Page> |
| | | </template> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { VbenFormSchema } from '#/adapter/form'; |
| | | import type { HrmRegularizeApi } from '#/api/hrm/regularize'; |
| | | |
| | | import { computed, ref } from 'vue'; |
| | | |
| | | import { useVbenModal } from '#/packages/effects/common-ui/src'; |
| | | |
| | | import { message } from 'ant-design-vue'; |
| | | |
| | | import { useVbenForm } from '#/adapter/form'; |
| | | import { auditRegularize } from '#/api/hrm/regularize'; |
| | | |
| | | const emit = defineEmits(['success']); |
| | | |
| | | const pass = ref(true); // true=å®¡æ ¸éè¿ / false=å®¡æ ¸ä¸éè¿ |
| | | const rowData = ref<HrmRegularizeApi.RegularizeApplication>(); |
| | | const getTitle = computed(() => (pass.value ? 'å®¡æ ¸éè¿' : 'å®¡æ ¸ä¸éè¿')); |
| | | |
| | | const [Form, formApi] = useVbenForm({ |
| | | commonConfig: { |
| | | componentProps: { |
| | | class: 'w-full', |
| | | }, |
| | | formItemClass: 'col-span-1', |
| | | labelWidth: 90, |
| | | }, |
| | | wrapperClass: 'grid-cols-1', |
| | | layout: 'horizontal', |
| | | schema: [], |
| | | showDefaultActions: false, |
| | | }); |
| | | |
| | | /** å®¡æ ¸è¡¨ååæ®µï¼ä¸éè¿æ¶å¿
须填ååå */ |
| | | function useAuditSchema(): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | | fieldName: 'reviewRemark', |
| | | label: 'å®¡æ ¸æè§', |
| | | component: 'Textarea', |
| | | formItemClass: 'col-span-1', |
| | | componentProps: { |
| | | rows: 3, |
| | | placeholder: pass.value |
| | | ? '请è¾å
¥å®¡æ ¸æè§ï¼å¯éï¼' |
| | | : '请è¾å
¥ä¸éè¿åå ï¼å¿
å¡«ï¼', |
| | | }, |
| | | rules: pass.value ? '' : 'required', |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | | async onConfirm() { |
| | | const { valid } = await formApi.validate(); |
| | | if (!valid) { |
| | | return; |
| | | } |
| | | modalApi.lock(); |
| | | const values = await formApi.getValues(); |
| | | try { |
| | | await auditRegularize( |
| | | rowData.value!.id!, |
| | | pass.value, |
| | | values.reviewRemark, |
| | | ); |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | message.success(pass.value ? 'å®¡æ ¸éè¿' : 'å·²éåï¼å¯ä¿®æ¹åéæ°æäº¤'); |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | | }, |
| | | async onOpenChange(isOpen: boolean) { |
| | | if (!isOpen) { |
| | | rowData.value = undefined; |
| | | return; |
| | | } |
| | | const data = modalApi.getData<{ |
| | | pass: boolean; |
| | | row: HrmRegularizeApi.RegularizeApplication; |
| | | }>(); |
| | | rowData.value = data.row; |
| | | pass.value = data.pass; |
| | | formApi.setState({ schema: useAuditSchema() }); |
| | | formApi.resetForm(); |
| | | }, |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal :title="getTitle" class="w-2/5"> |
| | | <div v-if="rowData" class="mx-4 mb-4 text-sm text-gray-600"> |
| | | <div>ç³è¯·äººï¼{{ rowData.userName }}</div> |
| | | <div>æå±é¨é¨ï¼{{ rowData.deptName }}</div> |
| | | <div>å²ä½ï¼{{ rowData.postName }}</div> |
| | | <div>æè½¬æ£æ¥æï¼{{ rowData.expectedDate }}</div> |
| | | <div>转æ£åå ï¼{{ rowData.reason }}</div> |
| | | </div> |
| | | <Form class="mx-4" /> |
| | | </Modal> |
| | | </template> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { ApplicantOption, FormType } from '../data'; |
| | | import type { HrmRegularizeApi } from '#/api/hrm/regularize'; |
| | | |
| | | import { computed, ref } from 'vue'; |
| | | |
| | | import { useVbenModal } from '#/packages/effects/common-ui/src'; |
| | | |
| | | import { message } from 'ant-design-vue'; |
| | | |
| | | import { useVbenForm } from '#/adapter/form'; |
| | | import { |
| | | createRegularize, |
| | | getRegularize, |
| | | updateRegularize, |
| | | } from '#/api/hrm/regularize'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { useFormSchema } from '../data'; |
| | | |
| | | const emit = defineEmits(['success']); |
| | | const formType = ref<FormType>('create'); |
| | | |
| | | const isDetail = computed(() => formType.value === 'detail'); |
| | | const getTitle = computed(() => { |
| | | if (formType.value === 'detail') { |
| | | return 'æ¥ç转æ£ç³è¯·'; |
| | | } |
| | | return formType.value === 'update' ? 'ä¿®æ¹è½¬æ£ç³è¯·' : 'æ°å¢è½¬æ£ç³è¯·'; |
| | | }); |
| | | |
| | | const [Form, formApi] = useVbenForm({ |
| | | commonConfig: { |
| | | componentProps: { |
| | | class: 'w-full', |
| | | }, |
| | | formItemClass: 'col-span-1', |
| | | labelWidth: 100, |
| | | }, |
| | | wrapperClass: 'grid-cols-2', |
| | | layout: 'horizontal', |
| | | schema: [], |
| | | showDefaultActions: false, |
| | | }); |
| | | |
| | | /** éæ©ç³è¯·äººåï¼èªå¨å¸¦å
¥å
¶é¨é¨ãå²ä½ä¸å½åç¨å·¥æ§è´¨ */ |
| | | async function handleApplicantChange(option?: ApplicantOption) { |
| | | if (!option) { |
| | | return; |
| | | } |
| | | const patch: Record<string, number> = {}; |
| | | if (option.deptId !== undefined && option.deptId !== null) { |
| | | patch.deptId = option.deptId; |
| | | } |
| | | if (option.postId !== undefined && option.postId !== null) { |
| | | patch.postId = option.postId; |
| | | } |
| | | if ( |
| | | option.employmentType !== undefined && |
| | | option.employmentType !== null |
| | | ) { |
| | | patch.employmentType = option.employmentType; |
| | | } |
| | | await formApi.setValues(patch); |
| | | } |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | | async onConfirm() { |
| | | if (isDetail.value) { |
| | | await modalApi.close(); |
| | | return; |
| | | } |
| | | const { valid } = await formApi.validate(); |
| | | if (!valid) { |
| | | return; |
| | | } |
| | | modalApi.lock(); |
| | | const data = (await formApi.getValues()) as HrmRegularizeApi.RegularizeApplication; |
| | | try { |
| | | if (data.id) { |
| | | await updateRegularize(data); |
| | | } else { |
| | | await createRegularize(data); |
| | | } |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | message.success($t('ui.actionMessage.operationSuccess')); |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | | }, |
| | | async onOpenChange(isOpen: boolean) { |
| | | if (!isOpen) { |
| | | return; |
| | | } |
| | | const data = modalApi.getData<{ formType: FormType; id?: number }>(); |
| | | formType.value = data.formType; |
| | | formApi.setState({ |
| | | schema: useFormSchema(data.formType, handleApplicantChange), |
| | | }); |
| | | formApi.setDisabled(data.formType === 'detail'); |
| | | modalApi.setState({ showConfirmButton: data.formType !== 'detail' }); |
| | | if (!data?.id) { |
| | | return; |
| | | } |
| | | modalApi.lock(); |
| | | try { |
| | | const detail = await getRegularize(data.id); |
| | | await formApi.setValues(detail); |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | | }, |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal :title="getTitle" class="w-[600px]"> |
| | | <Form class="mx-4" /> |
| | | </Modal> |
| | | </template> |
| | |
| | | proxy: { |
| | | "/admin-api": { |
| | | changeOrigin: true, |
| | | target: "http://localhost:48080", |
| | | target: "http://127.0.0.1:48080", |
| | | ws: true, |
| | | }, |
| | | }, |