Commit f2866040 authored by 罗超's avatar 罗超

提交

parent f6ea7b35
......@@ -42,6 +42,7 @@
"eslint": "^8.10.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-vue": "^9.0.0",
"naive-ui": "^2.33.5",
"prettier": "^2.5.1",
"typescript": "^4.5.4",
"vite-plugin-svg-icons": "^2.0.1"
......
......@@ -29,7 +29,7 @@ module.exports = configure(function (ctx) {
// app boot file (/src/boot)
// --> boot files are part of "main.js"
// https://v2.quasar.dev/quasar-cli/boot-files
boot: ['i18n', 'axios', 'dict', 'permission', 'globalcmp'],
boot: ['i18n', 'axios', 'dict', 'permission', 'globalcmp', 'naiveUI'],
// https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css
css: ['app.scss'],
......@@ -117,7 +117,7 @@ module.exports = configure(function (ctx) {
// https://v2.quasar.dev/quasar-cli/quasar-conf-js#Property%3A-framework
framework: {
config: {},
lang: 'zh-TW',
// iconSet: 'material-icons', // Quasar icon set
// lang: 'en-US', // Quasar language pack
......
......@@ -15,4 +15,23 @@ export default defineComponent({
body
font-family: '-apple-system','BlinkMacSystemFont','Segoe UI','Roboto','Helvetica Neue','Arial','Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji','MicrosoftJhengHeiBoldFix','Microsoft JhengHei' !important
color: var(--q-dark)
.n-base-selection .n-base-selection-label
background: #eee !important
border-radius: 5px
.n-base-selection .n-base-selection-label:active,
.n-base-selection .n-base-selection-label:focus
background: var(--q-dark) !important
.n-base-selection .n-base-selection-label:active .n-base-selection-input__content,
.n-base-selection .n-base-selection-label:focus .n-base-selection-input__content
color:#FFF !important
.n-base-selection
border:none
border-radius: 5px !important
.n-base-selection .n-base-selection__border, .n-base-selection .n-base-selection__state-border
border:0px solid #333 !important
box-shadow: none !important
.v-binder-follower-container
position: absolute
z-index: 99999999999 !important
</style>
import { HttpResponse } from '../@types'
import request from './request'
class HotelService {
/**
* 查詢城市信息
* @param params
* @returns
*/
static async GetDestination(params: any): Promise<HttpResponse> {
return request('dict_post_Destination_GetChildList', params)
}
/**
* 查詢酒店信息
* @param name 酒店名稱,支持空格分割
* @param province 省編號
* @param city 城市編號
* @returns
*/
static async GetHotels(name:string, province: number, city: number): Promise<HttpResponse> {
let params = {
pageIndex: 1,
pageSize: 1000,
Name: name,
QCountry: 651,
QProvince: province,
QCity: city,
Status: '0',
HotelPirceType: '-1',
HotelType: '-1',
QDistrict: '',
total: 0,
currentPage: 1,
ID: 0,
UpdateBy: 0,
ProductType: 1
}
return request('hotel_post_GetPageList', params)
}
}
export default HotelService
......@@ -19,7 +19,7 @@ const request = (cmd:string,msg:any): Promise<HttpResponse>=>{
"timestamp": timestamp,
"token": token,
"sign": md5Str,
"languageId": 0
"languageId": 1
}
return service.post('', postData)
}
......
import { boot } from 'quasar/wrappers'
import naive from 'naive-ui'
export default boot(({ app }) => {
// Set naive instance on app
app.use(naive)
})
\ No newline at end of file
<template>
<div>
<img src="../assets/images/lg-logo.png" style="height:200px;filter: grayscale(100%);"/>
<img src="../assets/images/lg-logo.png" style="height:200px;"/>
<div class="q-mt-lg text-h3 text-grey-4 text-center">歡迎使用JVS同業預定系統</div>
</div>
</template>
......
......@@ -65,6 +65,14 @@ svg g [fill]{
transition: fill 0.3s ease;
fill: #50cd89 !important;
}
.svg-icon-dark g [fill] {
transition: fill 0.3s ease;
fill: var(--q-dark) !important;
}
.hover:hover .svg-icon-dark g [fill] {
transition: fill 0.3s ease;
fill: var(--q-primary) !important;
}
.svg-icon-nav g [fill] {
transition: fill 0.3s ease;
fill: #9d9da6 !important;
......
......@@ -9,7 +9,7 @@
</q-item-section>
</template>
<template v-if="menu.childs">
<q-item active-class="nav-active" :active="x.id == activeMenu" @click="checkMenuHandler(x.id)" class="q-ml-md rounded-borders q-mr-md q-pl-md sunzi" clickable v-ripple v-for="(x, i) in menu.childs" :key="i">
<q-item active-class="nav-active" :to="x.url" :active="x.id == activeMenu" @click="checkMenuHandler(x.id)" class="q-ml-md rounded-borders q-mr-md q-pl-md sunzi" clickable v-ripple v-for="(x, i) in menu.childs" :key="i">
<q-item-section>
<div class="row items-center nav-item">
<svg-icon icon="Design/Circle.svg" :size="8" color="nav"></svg-icon>
......@@ -39,6 +39,7 @@ export default defineComponent({
const activeMenu = inject(MENU_KEYS) as any
const data = reactive({
activeParent: computed(() => {
if(!activeMenu) return false
if (props.menu.childs) {
let temp = props.menu.childs.find(x => x.id == activeMenu.value)
return temp ? true : false
......
......@@ -7,4 +7,10 @@ const userDictionmary = {
sendCodeTimeSpan:'scts'
}
export { userDictionmary }
class DirtionmaryHelper {
/**
* 子頁面傳遞給主界面的標題KEY
*/
static readonly PAGE_TITLE_KEY = 'page_title_key'
}
export { userDictionmary,DirtionmaryHelper }
......@@ -9,6 +9,16 @@ export default {
lanuage:"系統語言",
loginout:'登錄信息失效,請重新登錄',
timeout:'當前網絡環境異常,請求超時',
syslog:'系統升級告示',
sysmsg:'系統通知',
daterange:'請選擇檢索日期',
morequery:'更多篩選項',
query:'檢索',
hotel:{
pageTitle:"酒店檢索",
area:"檢索區域",
searchName:'酒店名稱'
},
userMenu:{
mypro:'個人檔案',
myfinace:'請求書',
......
......@@ -2,12 +2,19 @@
<q-layout view="lHh lpr lFf" style="background: #f5f8fa">
<q-header reveal class="bg-white text-white q-px-md q-py-sm">
<q-toolbar>
<q-toolbar-title class="row">
<q-toolbar-title class="row items-center">
<div class="col row items-center">
<q-btn dense flat round @click="toggleLeftDrawer" class="mobile-only">
<svg-icon icon="Text/Menu.svg" :size="32"></svg-icon>
</q-btn>
<div class="mobile-only q-ml-md text-dark text-h6 text-weight-bold">JVS</div>
<div class="mls text-h6 text-dark desktop-only">{{childPageTitle}}</div>
</div>
<div class="rounded-borders header-item q-mr-lg">
<svg-icon color="grey" icon="design/component.svg" :size="25" :tips="$t('syslog')"></svg-icon>
</div>
<div class="rounded-borders header-item q-mr-lg">
<svg-icon color="grey" icon="Communication/Chat6.svg" :size="25" :tips="$t('sysmsg')"></svg-icon>
</div>
<q-avatar size="40px" rounded class="bg-blue-2 cursor-pointer">
<img :src="userInfo.photo" v-if="userInfo.photo" />
......@@ -30,8 +37,10 @@
</q-scroll-area>
</q-drawer>
<q-page-container class="q-pa-md">
<router-view />
<q-page-container class="window-height">
<q-scroll-area :thumb-style="scrollStyle.thumbStyle" :bar-style="scrollStyle.barStyle" class="full-height q-pa-md">
<router-view />
</q-scroll-area>
</q-page-container>
<q-footer class="bg-white text-dark">
......@@ -45,13 +54,14 @@
</template>
<script lang="ts">
import { reactive, ref, toRefs } from 'vue'
import { inject, provide, reactive, ref, toRefs } from 'vue'
import { getStoreGetter } from '../store/utils'
import { UserGetter } from '../store/modules/user/getters'
import svgIcon from '../components/global/svg-icon.vue'
import useScrollModule from '../module/scrollbar/scrollModule'
import Navs from '../components/layout/navs.vue'
import userInfo from "../components/layout/userInfo.vue";
import { DirtionmaryHelper } from '../config/dictionary'
export default {
components: { svgIcon, Navs,userInfo },
setup() {
......@@ -61,6 +71,8 @@ export default {
leftDrawerOpen: false,
scrollStyle: {} as any
})
const childPageTitle = ref('')
provide(DirtionmaryHelper.PAGE_TITLE_KEY ,childPageTitle)
data.userInfo = getStoreGetter<UserGetter>('user', 'getUser')
data.scrollStyle = useScrollModule().scrollStyle
const methods = {
......@@ -70,9 +82,30 @@ export default {
}
return {
...toRefs(data),
...methods
...methods,
childPageTitle
}
}
}
</script>
<style>
.header-item{
cursor: pointer;
display: flex;
height: 40px;
width: 40px;
align-items: center;
justify-content: center;
}
.header-item svg g [fill]{
fill: rgb(161,165,183) !important;
cursor: pointer;
padding: 4px;
}
.header-item:hover{
background: rgba(0,0,0,.05);
}
.header-item:hover svg g [fill]{
fill:var(--q-primary) !important;
}
</style>
......@@ -7,7 +7,8 @@
<script lang="ts">
import { Todo, Meta } from '../components/models'
import ExampleComponent from 'components/CompositionComponent.vue'
import { defineComponent, ref } from 'vue'
import { defineComponent, provide, ref } from 'vue'
import { DirtionmaryHelper } from '../config/dictionary'
export default defineComponent({
name: 'PageIndex',
......@@ -38,6 +39,7 @@ export default defineComponent({
const meta = ref<Meta>({
totalCount: 1200
})
provide(DirtionmaryHelper.PAGE_TITLE_KEY,ref(''))
return { todos, meta }
}
})
......
......@@ -131,9 +131,9 @@ export default defineComponent({
window.history.go(-1)
},
// 切换语言
getLanguage(val) {
locale.value = val.langLocale;
localStorage.setItem('lanuage', val.langLocale)
getLanguage(val:SitLang) {
locale.value = val.langLocale??'';
localStorage.setItem('lanuage', val.langLocale??'')
}
}
......
<template>
<div class="rounded-borders bg-white row items-center q-pa-md">
<n-cascader v-if="$q.platform.is.desktop" class="col-2 no-border" @update:value="changearea"
v-model:value="cascader.addressValue" size="large" :placeholder="$t('hotel.area')" clearable
check-strategy="all" :options="provinces" value-field="ID" label-field="Name" remote :on-load="loadChilds"
cascade />
<q-field v-if="$q.platform.is.desktop" stack-label :label="$t('daterange')" standout class="q-ml-lg col-2"
style="min-width: 190px" dense>
<div class="self-center full-width no-outline" tabindex="0">{{ dateRangeFormat }}</div>
<q-popup-proxy :offset="[0, 10]" ref="qDateProxy">
<q-date v-model="dateRange" :options="optionsFn" range mask="YYYY/MM/DD" landscape
@range-end="dateRangeHandler"></q-date>
</q-popup-proxy>
</q-field>
<q-input @compositionstart="onCompositionStart" @compositionend="onCompositionEnd" class="q-ml-lg col-2"
v-model="hotelName" @update:model-value="changeHotelNameHnadler" type="text" :label="$t('酒店名稱')" dense
standout style="min-width: 190px">
<q-popup-proxy class="no-shadow" ref="qNameProxy" v-if="cacheHotels.length > 0">
<q-card class="q-pa-sm" flat dark>
<q-list>
<q-item class="rounded-borders" clickable v-ripple v-for="(x, i) in cacheHotels">
<q-item-section>
<div class="row">
<div class="f12 dark col">{{ x.langName }}</div>
</div>
</q-item-section>
</q-item>
</q-list>
</q-card>
</q-popup-proxy>
<template v-slot:append>
<q-spinner-tail color="grey" v-if="loading" />
</template>
</q-input>
<div class="col"></div>
<q-btn unelevated class="bg-grey-3 hover q-mr-md" :title="$t('morequery')">
<svg-icon color="dark" icon="Text/Filter.svg" :tips="$t('morequery')" :size="20"></svg-icon>
<q-tooltip>{{ $t('morequery') }}</q-tooltip>
<q-popup-proxy class="no-shadow" style="box-shadow:0 0 50px #ddd !important" :offset="[0, 20]">
<q-card class="q-pa-md rounded-borders" style="width:300px">
<div class="q-mb-md text-subtitle2">{{ $t('morequery') }}</div>
<div>
<n-cascader v-if="$q.platform.is.mobile" @update:value="changearea"
v-model:value="cascader.addressValue" size="large" :placeholder="$t('hotel.area')" clearable
check-strategy="all" :options="provinces" value-field="ID" label-field="Name" remote
:on-load="loadChilds" cascade />
</div>
<div class="q-my-md">
<q-field v-if="$q.platform.is.mobile" stack-label :label="$t('daterange')" outlined
style="min-width: 190px" dense>
<div class="self-center full-width no-outline" tabindex="0">{{ dateRangeFormat }}</div>
<q-popup-proxy :offset="[0, 10]" ref="qDateProxy">
<q-date v-model="dateRange" :options="optionsFn" range mask="YYYY/MM/DD" landscape
@range-end="dateRangeHandler"></q-date>
</q-popup-proxy>
</q-field>
</div>
</q-card>
</q-popup-proxy>
</q-btn>
<q-btn color="primary" unelevated :label="$t('query')" />
</div>
</template>
<script lang="ts">
import useMetaModule from '../../module/meta/metaModule'
import { DateTimeFormatResult, useI18n } from 'vue-i18n'
import svgIcon from '../../components/global/svg-icon.vue'
import { inject, provide, reactive, ref, toRefs } from 'vue'
import { DirtionmaryHelper } from '../../config/dictionary'
import HotelService from '../../api/hotel'
import message from '../../utils/message'
import { ApiResult } from '../../@types/enumHelper'
import { CascaderOption } from 'naive-ui'
import { date } from 'quasar'
export default {
components: { svgIcon },
setup() {
const qDateProxy = ref(null) as any
const qNameProxy = ref(null) as any
const data = reactive({
addressParams: {
Id: '651'
},
provinces: [],
search: {
HotelChooseArray: [],
StartDate: '',
EndDate: '',
Country: '651',
Province: 0,
City: 0,
OutBranchId: -1,
Star: 0,
PriceLevel: 0,
Supplier: 0
},
cascader: {
addressValue: null
} as any,
dateRange: {} as any,
dateRangeFormat: '',
hotelName: '',
loading: false,
cacheHotels: [] as Array<any>,
lockInput: false
})
let { setTitle } = useMetaModule()
const { locale, t } = useI18n()
const pageTitle = inject(DirtionmaryHelper.PAGE_TITLE_KEY) as any
pageTitle.value = t('hotel.pageTitle')
setTitle(pageTitle.value)
data.dateRange.to = date.formatDate(date.addToDate(new Date(), { days: 37 }), 'YYYY/MM/DD')
data.dateRange.from = date.formatDate(date.addToDate(new Date(), { days: 7 }), 'YYYY/MM/DD')
data.dateRangeFormat = `${data.dateRange.from} - ${data.dateRange.to}`
data.search.StartDate = data.dateRange.from
data.search.EndDate = data.dateRange.to
let timer = null as any
const methods = {
initAddress() {
HotelService.GetDestination(data.addressParams)
.then(r => {
if (r.data.resultCode == ApiResult.SUCCESS) {
r.data.data.forEach((x: any) => {
x.isLeaf = false
x.depth = 1
})
data.provinces = r.data.data
} else {
message.errorMsg(r.data.message)
}
})
.catch(e => {
message.errorMsg(e.message)
})
},
loadChilds(option: CascaderOption) {
return new Promise<void>(resolve => {
console.log('innnnnnn', option)
HotelService.GetDestination({ Id: option.ID })
.then(r => {
if (r.data.resultCode == ApiResult.SUCCESS) {
r.data.data.forEach((x: any) => {
x.isLeaf = true
x.depth = 2
})
option.children = r.data.data
resolve()
} else {
message.errorMsg(r.data.message)
resolve()
}
})
.catch(e => {
message.errorMsg(e.message)
resolve()
})
})
},
dateRangeHandler(e: any) {
data.search.StartDate = `${e.from.year}/${e.from.month}/${e.from.day}`
data.search.EndDate = `${e.to.year}/${e.to.month}/${e.to.day} `
data.dateRangeFormat = `${data.search.StartDate} - ${data.search.EndDate} `
if (qDateProxy.value) qDateProxy.value.hide()
},
optionsFn(cd: any) {
return cd >= date.formatDate(date.addToDate(new Date(), { days: 7 }), 'YYYY/MM/DD')
},
changearea(e: number, option: any, pathValues: Array<any>) {
data.search.Province = 0
data.search.City = 0
if (pathValues.length > 0) {
data.search.Province = pathValues[0].ID
} else if (pathValues.length > 1) {
data.search.City = pathValues[1].ID
}
},
changeHotelNameHnadler(val: any) {
if(!data.lockInput){
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
console.log(data.hotelName)
}, 1000);
}
},
onCompositionStart() {
data.lockInput = true;
},
onCompositionEnd(e: any) {
console.log('.......')
// 输入中文触发
data.lockInput = false;
// 在调用
this.changeHotelNameHnadler(e);
},
}
methods.initAddress()
return {
...toRefs(data),
...methods,
qDateProxy,
qNameProxy
}
}
}
</script>
<style>
</style>
......@@ -4,7 +4,7 @@ const routes: RouteRecordRaw[] = [
{
path: '/index',
component: () => import('../layouts/MainLayout.vue'),
children: [{ path: '', component: () => import('../pages/Index.vue') }]
children: [{ path: '', component: () => import('../pages/Index.vue') },{ path: '/hotel', component: () => import('../pages/hotel/HotelList.vue') }]
},
{
path:'/auth/login',
......
......@@ -20,7 +20,7 @@ const useMenus={
childs:[
{
name:t('menu.hotel.second'),
url:'',
url:'/hotel',
id:2,
parentId:1,
},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment