This commit is contained in:
faiz 2024-10-21 09:05:15 +08:00
commit 67c21995dd
72 changed files with 14149 additions and 0 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
VITE_BASE_XXX=XXX

1
.env.development Normal file
View File

@ -0,0 +1 @@
VITE_SERVICE_ENV=dev

1
.env.production Normal file
View File

@ -0,0 +1 @@
VITE_SERVICE_ENV=prod

1
.env.test Normal file
View File

@ -0,0 +1 @@
VITE_SERVICE_ENV=test

18
.eslintrc Normal file
View File

@ -0,0 +1,18 @@
{
"extends": "@antfu",
"rules": {
// if else try catch 风格
// ```
// try { try {
// loading() loading()
// } ==> } catch (e) {
// catch (e) { hideLoading()
// hideLoading() }
// }
// ```
"@typescript-eslint/brace-style": ["error", "1tbs"],
// if else 必须添加{} if()do() => if(){ do() }
"curly":["error", "multi-line"]
}
}

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
dist

16
.hbuilderx/launch.json Normal file
View File

@ -0,0 +1,16 @@
{ // launch.json configurations app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtypelocalremote, localremote
"version": "0.0",
"configurations": [{
"default" :
{
"launchtype" : "local"
},
"mp-weixin" :
{
"launchtype" : "local"
},
"type" : "uniCloud"
}
]
}

2
.npmrc Normal file
View File

@ -0,0 +1,2 @@
shamefully-hoist=true
strict-peer-dependencies=false

398
.vscode/css.code-snippets vendored Normal file
View File

@ -0,0 +1,398 @@
{
"#ifdef": {
"body": [
"/* #ifdef ${1|APP-PLUS,MP,MP-ALIPAY,MP-BAIDU,MP-WEIXIN,MP-QQ,H5|} */",
"$0",
"/* #endif */"
],
"prefix": "ifdef",
"project": "uni-app",
"scope": "css"
},
"#ifndef": {
"body": [
"/* #ifndef ${1|APP-PLUS,MP,MP-ALIPAY,MP-BAIDU,MP-WEIXIN,MP-QQ,H5|} */",
"$0",
"/* #endif */"
],
"prefix": "ifndef",
"project": "uni-app",
"scope": "css"
},
"-moz-": {
"body": [
"-moz-"
],
"prefix": "moz",
"scope": "css",
"triggerAssist": true
},
"-ms-": {
"body": [
"-ms-"
],
"prefix": "ms",
"scope": "css",
"triggerAssist": true
},
"-webkit-": {
"body": [
"-webkit-"
],
"prefix": "webkit",
"scope": "css",
"triggerAssist": true
},
"@-moz-keyframes": {
"body": [
"@-moz-keyframes ${1:name}{",
"\tfrom{$2}",
"\tto{$3}",
"}"
],
"prefix": "@keyframes",
"scope": "CSS_OUTRULE"
},
"@-ms-keyframes": {
"body": [
"@-ms-keyframes ${1:name}{",
"\tfrom{$2}",
"\tto{$3}",
"}"
],
"prefix": "@keyframes",
"scope": "CSS_OUTRULE"
},
"@-webkit-keyframes": {
"body": [
"@-webkit-keyframes ${1:name}{",
"\tfrom{$2}",
"\tto{$3}",
"}"
],
"prefix": "@keyframes",
"scope": "CSS_OUTRULE"
},
"@charset": {
"body": [
"@charset \"${1:utf-8}\";"
],
"prefix": "@charset",
"scope": "CSS_OUTRULE"
},
"@document": {
"body": [
"@document ${1:url}(\"$2\") {",
"\t$3",
"}"
],
"prefix": "@document",
"scope": "CSS_OUTRULE"
},
"@font-face": {
"body": [
"@font-face {",
"\tfont-family:$1;",
"\tsrc: url($2);",
"}"
],
"prefix": "@fontface",
"scope": "CSS_OUTRULE"
},
"@import": {
"body": [
"@import url(\"$1\");"
],
"prefix": "@import",
"scope": "CSS_OUTRULE",
"triggerAssist": true
},
"@keyframes": {
"body": [
"@keyframes ${1:name}{",
"\tfrom{$2}",
"\tto{$3}",
"}"
],
"prefix": "@keyframes",
"scope": "CSS_OUTRULE"
},
"@media": {
"body": [
"@media $1 {",
"\t$2",
"}"
],
"prefix": "@media",
"scope": "CSS_OUTRULE"
},
"@namespace": {
"body": [
"@namespace ${1:prefix} \"$2\";"
],
"prefix": "@namespace",
"scope": "CSS_OUTRULE"
},
"@page": {
"body": [
"@page:${1:first}{",
"\t",
"}"
],
"prefix": "@page",
"scope": "CSS_OUTRULE"
},
"@supports": {
"body": [
"@supports(${1:prop}:${2:value}) {",
"\t$3",
"}"
],
"prefix": "@supports",
"scope": "CSS_OUTRULE"
},
"background-color": {
"body": [
"background-color: $1"
],
"prefix": "bc",
"scope": "css",
"triggerAssist": true
},
"background-color: #": {
"body": [
"background-color: #$1"
],
"prefix": "bch",
"scope": "css",
"triggerAssist": true
},
"background-color: rgb": {
"body": [
"background-color: rgb(${1:255},${2:255},${3:255})"
],
"prefix": "bcr",
"scope": "css"
},
"background-image": {
"body": [
"background-image: $1"
],
"prefix": "bi",
"scope": "css",
"triggerAssist": true
},
"background-image: url": {
"body": [
"background-image: url($1)"
],
"prefix": "biu",
"scope": "css",
"triggerAssist": true
},
"background-position": {
"body": [
"background-position: $1"
],
"prefix": "bp",
"scope": "css",
"triggerAssist": true
},
"background: image repeat attachment position": {
"body": [
"background: url($1) ${2:repeat} ${3:fixed} ${4:center};$0"
],
"prefix": "bg",
"scope": "css",
"triggerAssist": true
},
"border-color": {
"body": [
"border-color: $1"
],
"prefix": "boc",
"scope": "css",
"triggerAssist": true
},
"border-style": {
"body": [
"border-style: $1"
],
"prefix": "bs",
"scope": "css",
"triggerAssist": true
},
"border-width": {
"body": [
"border-width: $1"
],
"prefix": "bw",
"scope": "css",
"triggerAssist": true
},
"display: block": {
"body": [
"display: block;"
],
"prefix": "db",
"scope": "css"
},
"display: flex": {
"body": [
"display: flex;"
],
"prefix": "df",
"scope": "css"
},
"display: none": {
"body": [
"display: none;"
],
"prefix": "dn",
"scope": "css"
},
"flex-direction: row": {
"body": [
"flex-direction: row;"
],
"prefix": "fdr",
"scope": "css"
},
"font-family: family": {
"body": [
"font-family: $1"
],
"prefix": "ff",
"scope": "css",
"triggerAssist": true
},
"font-size: size": {
"body": [
"font-size: $1"
],
"prefix": "fsize",
"scope": "css",
"triggerAssist": true
},
"height --status-bar-height": {
"body": [
"height: var(--status-bar-height);"
],
"prefix": "heightstatusbar",
"project": "uni-app",
"scope": "css"
},
"height --window-bottom": {
"body": [
"height: var(--window-bottom);"
],
"prefix": "heightwindowbottom",
"project": "uni-app",
"scope": "css"
},
"height --window-top": {
"body": [
"height: var(--window-top);"
],
"prefix": "heightwindowtop",
"project": "uni-app",
"scope": "css"
},
"height px": {
"body": [
"height: ${1}px;$0"
],
"prefix": "hpx",
"scope": "css"
},
"justify-content: center": {
"body": [
"justify-content: center;"
],
"prefix": "jcc",
"scope": "css"
},
"list-style-image: url": {
"body": [
"list-style-image: url($1);"
],
"prefix": "lsi",
"scope": "css",
"triggerAssist": true
},
"scrollbar": {
"body": [
"scrollbar-base-color: ${1:#CCCCCC};",
"scrollbar-arrow-color: ${2:#000000};",
"scrollbar-track-color: ${3:#999999};",
"scrollbar-3dlight-color: ${4:#EEEEEE};",
"scrollbar-highlight-color: ${5:#FFFFFF};",
"scrollbar-face-color: ${6:#CCCCCC};",
"scrollbar-shadow-color: ${7:#999999};",
"scrollbar-darkshadow-color: ${8:#666666};"
],
"prefix": "scrollbarr",
"scope": "css"
},
"text-align: center": {
"body": [
"text-align: center;"
],
"prefix": "tac",
"scope": "css"
},
"text-align: left": {
"body": [
"text-align: left;"
],
"prefix": "tal",
"scope": "css"
},
"text-align: right": {
"body": [
"text-align: right;"
],
"prefix": "tar",
"scope": "css"
},
"text-transform": {
"body": [
"text-transform: $1"
],
"prefix": "tt",
"scope": "css",
"triggerAssist": true
},
"userselect:none": {
"body": [
"-webkit-user-select: none;",
"-moz-user-select: none;",
"-ms-user-select: none;",
"user-select: none;"
],
"prefix": "usn",
"scope": "css"
},
"width length": {
"body": [
"width: ${1}px;$0"
],
"prefix": "widthlength",
"scope": "css"
},
"width upx": {
"body": [
"width: ${1}upx;$0"
],
"prefix": "wupx",
"project": "uni-app",
"scope": "css"
},
"width_length": {
"body": [
"width: ${1}px;$0"
],
"prefix": "wlength",
"scope": "css"
}
}

8
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,8 @@
{
"recommendations": [
"dbaeumer.vscode-eslint",
"antfu.unocss",
"vue.volar",
"Vue.vscode-typescript-vue-plugin"
]
}

1669
.vscode/js.code-snippets vendored Normal file

File diff suppressed because it is too large Load Diff

668
.vscode/vue-html.code-snippets vendored Normal file
View File

@ -0,0 +1,668 @@
{
"#ifdef": {
"body": [
"<!-- #ifdef ${1|APP-PLUS,MP,MP-ALIPAY,MP-BAIDU,MP-WEIXIN,MP-QQ,H5|} -->",
"$0",
"<!-- #endif -->"
],
"prefix": "ifdef",
"project": "uni-app",
"scope": "vue-html"
},
"#ifndef": {
"body": [
"<!-- #ifndef ${1|APP-PLUS,MP,MP-ALIPAY,MP-BAIDU,MP-WEIXIN,MP-QQ,H5|} -->",
"$0",
"<!-- #endif -->"
],
"prefix": "ifndef",
"project": "uni-app",
"scope": "vue-html"
},
"Vue Base": {
"body": [
"<template>",
"\t<${1:div}>",
"",
"\t</${1:div}>",
"</template>",
"",
"<script>",
"\texport default {",
"\t\t${0}",
"\t}",
"</script>",
"",
"<style scoped>",
"",
"</style>"
],
"description": "Base for Vue File",
"prefix": "vbase",
"scope": "vue-html"
},
"Vue Class Binding": {
"body": ["<${1|div|} :class=\"{ ${2:className}: ${3:data} }\"><,${1:div}>"],
"description": "vue class binding",
"prefix": "vclass",
"scope": "vue-html"
},
"Vue Class Binding Object": {
"body": [
"<${1|div|} :class=\"[${2:classNameA}, ${3:classNameB}]\"><,${1:div}>"
],
"description": "vue class binding",
"prefix": "vclass-obj",
"scope": "vue-html"
},
"Vue Component with Props Binding": {
"body": ["<${1|component|} :${1:propName}=\"${0}\"><,${1:component}>"],
"description": "component element with props",
"prefix": "vel-props",
"scope": "vue-html"
},
"Vue Image Source Binding": {
"body": [
"<img :src=\"'/path/to/images/' + ${1:fileName}\" alt=\"${2:altText}\"/>"
],
"description": "image source binding",
"prefix": "vsrc",
"scope": "vue-html"
},
"Vue Multiple Conditional Class Bindings": {
"body": [
"<${1|div|} :class=\"[${2:classNameA}, {${3:classNameB} : ${4:condition}}]\"><,${1:div}>"
],
"description": "vue multiple conditional class bindings",
"prefix": "vclass-obj-mult",
"scope": "vue-html"
},
"Vue Nuxt Routing Link": {
"body": ["<nuxt-link to=\"/${1:page}\">${1:page}</nuxt-link>"],
"description": "nuxt routing link",
"prefix": "vnuxtl",
"scope": "vue-html"
},
"Vue Style Binding": {
"body": [
"<${1|div|} :style=\"{ fontSize: ${2:data} + 'px' }\"><,${1:div}>"
],
"description": "vue inline style binding",
"prefix": "vstyle",
"scope": "vue-html"
},
"Vue Style Binding Object": {
"body": [
"<${1|div|} :style=\"[${2:styleObjectA}, ${3:styleObjectB]}\"><,${1:div}>"
],
"description": "vue inline style binding, objects",
"prefix": "vstyle-obj",
"scope": "vue-html"
},
"Vue Transition Component with JavaScript Hooks": {
"body": [
"<transition",
"\tmode=\"out-in\"",
"\t@before-enter=\"beforeEnter\"",
"\t@enter=\"enter\"",
"",
"\t@before-leave=\"beforeLeave\"",
"\t@leave=\"leave\"",
"\t:css=\"false\">",
"",
"</transition>"
],
"description": "transition component js hooks",
"prefix": "vanim",
"scope": "vue-html"
},
"Vue v-for": {
"body": [
"<${1:div} v-for=\"${2:item} in ${2:item}s\" :key=\"${2:item}.id\">",
"\t{{ ${2:item} }}",
"</${1:div}>"
],
"description": "vfor statement",
"prefix": "vfor",
"scope": "vue-html"
},
"Vue v-model Directive": {
"body": ["<input v-model=\"${1:data}\" type=\"text\" />"],
"description": "v-model directive",
"prefix": "vmodel",
"scope": "vue-html"
},
"Vue v-model Number Directive": {
"body": [
"<input v-model.number=\"${1:numData}\" type=\"number\" step=\"1\" />"
],
"description": "v-model directive number input",
"prefix": "vmodel-num",
"scope": "vue-html"
},
"Vue v-on Shortcut Directive": {
"body": ["@click=\"${1:handler}(${2:arg}, $event)\""],
"description": "v-on click handler with arguments",
"prefix": "von",
"scope": "vue-html"
},
"uAccordion": {
"body": [
"<view class=\"uni-list\">",
"\t<view class=\"uni-list-cell uni-collapse\" v-for=\"(item,index) in list$1\" :key=\"index\">",
"\t\t<view class=\"uni-list-cell-navigate uni-navigate-bottom\" :class=\"item.show ? 'uni-active' : ''\" @click=\"trigerCollapse$0(index)\">",
"\t\t\t折叠面板{{index}}",
"\t\t</view>",
"\t\t<view class=\"uni-collapse-content\" :class=\"item.show ? 'uni-active' : ''\">",
"\t\t\t<view class=\"page-pd\">",
"\t\t\t\t<view class=\"uni-h1\">hello uni-app</view>",
"\t\t\t\t<view class=\"uni-h2\">hello uni-app</view>",
"\t\t\t\t<view class=\"uni-h3\">hello uni-app</view>",
"\t\t\t</view>",
"\t\t</view>",
"\t</view>",
"</view>"
],
"prefix": "uaccordion",
"project": "uni-app",
"scope": "vue-html"
},
"uAudio": {
"body": [
"<audio :src=\"$1\" :poster=\"$0\" :name=\"$2\" :author=\"$3\" :action=\"$4\" controls></audio>"
],
"prefix": "uaudio",
"project": "uni-app",
"scope": "vue-html"
},
"uBadge": {
"body": ["<uni-badge text=\"$1\" type=\"$2\"></uni-badge>"],
"prefix": "ubadge",
"project": "uni-app",
"scope": "vue-html"
},
"uButton": {
"body": ["<button type=\"primary\">$1</button>"],
"prefix": "ubutton",
"project": "uni-app",
"scope": "vue-html"
},
"uCalendar": {
"body": [
"<uni-calendar lunar=\"\" @change=\"$1\" @to-click=\"$2\"></uni-calendar>"
],
"prefix": "ucalendar",
"project": "uni-app",
"scope": "vue-html"
},
"uCard": {
"body": [
"<uni-card title=\"标题文字\" thumbnail=\"$1\" extra=\"额外信息$2\" note=\"Tips$3\">",
"\t内容主体可自定义内容及样式$4",
"</uni-card>"
],
"prefix": "ucard",
"project": "uni-app",
"scope": "vue-html"
},
"uCheckbox": {
"body": [
"<label class=\"checkbox\">",
"\t<checkbox value=\"$1\" checked= />$0",
"</label>"
],
"prefix": "ucheckbox",
"project": "uni-app",
"scope": "vue-html"
},
"uCollapse": {
"body": [
"<uni-collapse @change=\"$1\">",
"\t<uni-collapse-item title=\"$2\">",
"\t\t内容$3",
"\t</uni-collapse-item>",
"</uni-collapse>"
],
"prefix": "uCollapse",
"project": "uni-app",
"scope": "vue-html"
},
"uCountDown": {
"body": [
"<uni-countdown font-color=\"$1\" bgr-color=\"$2\" timer=\"$3\"></uni-countdown>"
],
"prefix": "ucountdown",
"project": "uni-app",
"scope": "vue-html"
},
"uDrawer": {
"body": [
"<uni-drawer :visible=\"$1\">",
"\t<view style=\"padding:30upx;\">",
"\t\t$2",
"\t</view>",
"</uni-drawer>"
],
"prefix": "uDrawer",
"project": "uni-app",
"scope": "vue-html"
},
"uEditor": {
"body": ["<editor placeholder=\"$1\"></editor>"],
"prefix": "uEditor",
"project": "uni-app",
"scope": "vue-html"
},
"uForm": {
"body": [
"<form @submit=\"formSubmit\" @reset=\"formReset\">",
"\t<view class=\"section section_gap\">",
"\t\t<view class=\"section__title\">switch$1</view>",
"\t\t<switch name=\"switch\" />",
"\t</view>",
"\t<view class=\"section section_gap\">",
"\t\t<view class=\"section__title\">slider</view>",
"\t\t<slider name=\"slider\" show-value></slider>",
"\t</view>",
"\t<view class=\"section\">",
"\t\t<view class=\"section__title\">input</view>",
"\t\t<input name=\"input\" placeholder=\"please input here\" />",
"\t</view>",
"\t<view class=\"section section_gap\">",
"\t\t<view class=\"section__title\">radio</view>",
"\t\t<radio-group name=\"radio-group\">",
"\t\t<label>",
"\t\t\t<radio value=\"radio1\" />radio1</label>",
"\t\t<label>",
"\t\t\t<radio value=\"radio2\" />radio2</label>",
"\t\t</radio-group>",
"\t</view>",
"\t<view class=\"section section_gap\">",
"\t\t<view class=\"section__title\">checkbox</view>",
"\t\t<checkbox-group name=\"checkbox\">",
"\t\t\t<label>",
"\t\t\t\t<checkbox value=\"checkbox1\" />checkbox1</label>",
"\t\t\t<label>",
"\t\t\t\t<checkbox value=\"checkbox2\" />checkbox2</label>",
"\t\t</checkbox-group>",
"\t</view>",
"\t<view class=\"btn-area\">",
"\t\t<button formType=\"submit\">Submit</button>",
"\t\t<button formType=\"reset\">Reset</button>",
"\t</view>",
"</form>"
],
"prefix": "uform",
"project": "uni-app",
"scope": "vue-html"
},
"uGrid": {
"body": ["<uni-grid :data=\"$1\"></uni-grid>"],
"prefix": "ugrid",
"project": "uni-app",
"scope": "vue-html"
},
"uIcon": {
"body": ["<uni-icon type=\"$1\"></uni-icon>"],
"prefix": "uicon",
"project": "uni-app",
"scope": "vue-html"
},
"uImage": {
"body": ["<image src=\"$1\" mode=\"$2\">$0</image>"],
"prefix": "uimage",
"project": "uni-app",
"scope": "vue-html"
},
"uInput": {
"body": ["<input type=\"text$1\" value=\"$0\" />"],
"prefix": "uinput",
"project": "uni-app",
"scope": "vue-html"
},
"uList": {
"body": [
"<uni-list>",
"\t<uni-list-item title=\"$1\" note=\"$2\"></uni-list-item>",
"\t<uni-list-item title=\"$3\" note=\"$4\"></uni-list-item>",
"</uni-list>"
],
"prefix": "ulist",
"project": "uni-app",
"scope": "vue-html"
},
"uListMedia": {
"body": [
"<view class=\"uni-list\">",
"\t<view class=\"uni-list-cell\" hover-class=\"uni-list-cell-hover\" v-for=\"(item,index) in list$1\" :key=\"index\">",
"\t\t<view class=\"uni-media-list\">",
"\t\t\t<image class=\"uni-media-list-logo\" :src=\"item.img$2\"></image>",
"\t\t\t<view class=\"uni-media-list-body\">",
"\t\t\t\t<view class=\"uni-media-list-text-top\">{{item.title$3}}</view>",
"\t\t\t\t<view class=\"uni-media-list-text-bottom uni-ellipsis\">{{item.content$4}}</view>",
"\t\t\t</view>",
"\t\t</view>",
"\t</view>",
"</view>"
],
"prefix": "ulistmedia",
"project": "uni-app",
"scope": "vue-html"
},
"uLoadMore": {
"body": [
"<uni-load-more :loadingType=\"$1\" :contentText=\"$2\"></uni-load-more>"
],
"prefix": "uloadmore",
"project": "uni-app",
"scope": "vue-html"
},
"uMap": {
"body": ["<map :latitude=\"$1\" :longitude=\"$0\"></map>"],
"prefix": "umap",
"project": "uni-app",
"scope": "vue-html"
},
"uNavBar": {
"body": [
"<uni-nav-bar left-icon=\"back\" left-text=\"返回\" right-text=\"菜单\" title=\"标题$1\"></uni-nav-bar>"
],
"prefix": "unavbar",
"project": "uni-app",
"scope": "vue-html"
},
"uNavigator": {
"body": ["<navigator url=\"$1\">$0</navigator>"],
"prefix": "unavigator",
"project": "uni-app",
"scope": "vue-html"
},
"uNoticeBar": {
"body": ["<uni-notice-bar single=\"$1\" text=\"$2\"></uni-notice-bar>"],
"prefix": "uNoticeBar",
"project": "uni-app",
"scope": "vue-html"
},
"uNumberBox": {
"body": ["<uni-number-box @change=\"$1\"></uni-number-box>"],
"prefix": "unumberbox",
"project": "uni-app",
"scope": "vue-html"
},
"uPagination": {
"body": [
"<uni-pagination title=\"$1\" show-icon=\"$2\" total=\"$3\" current=\"$4\"></uni-pagination>"
],
"prefix": "uPagination",
"project": "uni-app",
"scope": "vue-html"
},
"uPicker": {
"body": [
"<picker mode=\"$1\" :range=\"$2\" @change=\"$3\">",
"\t<view>picker组件</view>",
"</picker>"
],
"prefix": "upicker",
"project": "uni-app",
"scope": "vue-html"
},
"uPickerView": {
"body": [
"<picker-view indicator-style=\"height: 50px;\" :value=\"value$1\" @change=\"bindChange\">",
"\t<picker-view-column>",
"\t\t$0",
"\t</picker-view-column>",
"\t<picker-view-column>",
"\t\t$2",
"\t</picker-view-column>",
"\t<picker-view-column>",
"\t\t",
"\t</picker-view-column>",
"</picker-view>"
],
"prefix": "upickerview",
"project": "uni-app",
"scope": "vue-html"
},
"uPopup": {
"body": [
"<uni-popup msg=\"$1\" :show=\"true$2\" type=\"middle$3\"></uni-popup>"
],
"prefix": "upopup",
"project": "uni-app",
"scope": "vue-html"
},
"uProductList": {
"body": [
"<view class=\"uni-product-list\">",
"\t<view class=\"uni-product\" v-for=\"(product,index) in productList$1\" :key=\"index\">",
"\t\t<view class=\"image-view\">",
"\t\t\t<image v-if=\"renderImage\" class=\"uni-product-image\" :src=\"product.image\"></image>",
"\t\t</view>",
"\t\t<view class=\"uni-product-title\">{{product.title}}</view>",
"\t\t<view class=\"uni-product-price\">",
"\t\t\t<text class=\"uni-product-price-favour\">¥{{product.originalPrice}}</text>",
"\t\t\t<text class=\"uni-product-price-original\">¥{{product.favourPrice}}</text>",
"\t\t\t<text class=\"uni-product-tip\">{{product.tip}}</text>",
"\t\t</view>",
"\t</view>",
"</view>"
],
"prefix": "uproductlist",
"project": "uni-app",
"scope": "vue-html"
},
"uProgress": {
"body": [" <progress percent=\"$1\" show-info$0 />"],
"prefix": "uprogress",
"project": "uni-app",
"scope": "vue-html"
},
"uRadio": {
"body": [
"<label class=\"radio\">",
"\t<radio value=\"$1\" checked= />$0",
"</label>"
],
"prefix": "uradio",
"project": "uni-app",
"scope": "vue-html"
},
"uRate": {
"body": ["<uni-rate value=\"$1\"></uni-rate>"],
"prefix": "uRate",
"project": "uni-app",
"scope": "vue-html"
},
"uRichText": {
"body": ["<rich-text :nodes=\"$1\"></rich-text>"],
"prefix": "urichtext",
"project": "uni-app",
"scope": "vue-html"
},
"uScrollView": {
"body": [
"<scroll-view scroll-y$1>",
"\t<view>$0</view>",
"\t<view></view>",
"\t<view></view>",
"\t<view></view>",
"</scroll-view>"
],
"prefix": "uscrollview",
"project": "uni-app",
"scope": "vue-html"
},
"uSegmentedControl": {
"body": [
"<uni-segmented-control :current=\"current$1\" :values=\"$0\" @clickItem=\"$2\"></uni-segmented-control>",
"<view class=\"content\">",
"\t<view v-show=\"current === 0\">",
"\t\t选项卡1的内容",
"\t</view>",
"\t<view v-show=\"current === 1\">",
"\t\t选项卡2的内容",
"\t</view>",
"\t<view v-show=\"current === 2\">",
"\t\t选项卡3的内容",
"\t</view>",
"</view>"
],
"prefix": "usegmentedcontrol",
"project": "uni-app",
"scope": "vue-html"
},
"uSlider": {
"body": ["<slider @change=\"$1\" show-value$0/>"],
"prefix": "uslider",
"project": "uni-app",
"scope": "vue-html"
},
"uSteps": {
"body": ["<uni-steps :options=\"$1\" :active=\"0$2\"></uni-steps>"],
"prefix": "usteps",
"project": "uni-app",
"scope": "vue-html"
},
"uSwipeAction": {
"body": [
"<uni-swipe-action :options=\"$1\">",
"\t$2",
"</uni-swipe-action>"
],
"prefix": "uSwipeAction",
"project": "uni-app",
"scope": "vue-html"
},
"uSwiper": {
"body": [
"<swiper :indicator-dots=\"true\" :autoplay=\"true\" :interval=\"3000\" :duration=\"1000\">",
"\t<swiper-item>",
"\t\t<view class=\"swiper-item\">$1</view>",
"\t</swiper-item>",
"\t<swiper-item>",
"\t\t<view class=\"swiper-item\">$2</view>",
"\t</swiper-item>",
"\t<swiper-item>",
"\t\t<view class=\"swiper-item\">$0</view>",
"\t</swiper-item>",
"</swiper>"
],
"prefix": "uswiper",
"project": "uni-app",
"scope": "vue-html"
},
"uSwipermsg": {
"body": [
"<view class=\"uni-swiper-msg\">",
"\t<view class=\"uni-swiper-msg-icon\">",
"\t\t<image src=\"$1\" mode=\"widthFix\"></image>",
"\t</view>",
"\t<swiper vertical=\"true\" autoplay=\"true\" circular=\"true\" interval=\"3000\">",
"\t\t<swiper-item>",
"\t\t\t<navigator>消息1</navigator>",
"\t\t</swiper-item>",
"\t\t<swiper-item>",
"\t\t\t<navigator>消息2</navigator>",
"\t\t</swiper-item>",
"\t\t<swiper-item>",
"\t\t\t<navigator>消息3</navigator>",
"\t\t</swiper-item>",
"\t</swiper>",
"</view>"
],
"prefix": "uswipermsg",
"project": "uni-app",
"scope": "vue-html"
},
"uSwitch": {
"body": ["<switch checked @change=\"$1\" />"],
"prefix": "uswitch",
"project": "uni-app",
"scope": "vue-html"
},
"uTag": {
"body": ["<uni-tag text=\"$1\" type=\"$2\"></uni-tag>"],
"prefix": "utag",
"project": "uni-app",
"scope": "vue-html"
},
"uTemplate": {
"body": ["<template>", "\t<view>$0</view>", "</template>"],
"prefix": "utemplate",
"project": "uni-app",
"scope": "vue-html"
},
"uText": {
"body": ["<text>$0</text>"],
"prefix": "utext",
"project": "uni-app",
"scope": "vue-html"
},
"uTextarea": {
"body": ["<textarea value=\"$1\" placeholder=\"$0\" />"],
"prefix": "utextarea",
"project": "uni-app",
"scope": "vue-html"
},
"uTimeline": {
"body": [
"<view class=\"uni-timeline\">",
"\t<view class=\"uni-timeline-item uni-timeline-first-item\">",
"\t\t<view class=\"uni-timeline-item-keynode\">日期1$1</view>",
"\t\t<view class=\"uni-timeline-item-divider\"></view>",
"\t\t<view class=\"uni-timeline-item-content\">事件1</view>",
"\t</view>",
"\t<view class=\"uni-timeline-item\">",
"\t\t<view class=\"uni-timeline-item-keynode\">日期2</view>",
"\t\t<view class=\"uni-timeline-item-divider\"></view>",
"\t\t<view class=\"uni-timeline-item-content\">事件2</view>",
"\t</view>",
"\t<view class=\"uni-timeline-item uni-timeline-last-item\">",
"\t\t<view class=\"uni-timeline-item-keynode\">日期3</view>",
"\t\t<view class=\"uni-timeline-item-divider\"></view>",
"\t\t<view class=\"uni-timeline-item-content\">事件3</view>",
"\t</view>",
"</view>"
],
"prefix": "utimeline",
"project": "uni-app",
"scope": "vue-html"
},
"uVideo": {
"body": ["<video src=\"$1\" controls></video>"],
"prefix": "uvideo",
"project": "uni-app",
"scope": "vue-html"
},
"uView": {
"body": ["<view class=\"$1\">$0</view>"],
"prefix": "uview",
"project": "uni-app",
"scope": "vue-html"
},
"uWebView": {
"body": ["<web-view src=\"$1\"></web-view>"],
"prefix": "uwebview",
"project": "uni-app",
"scope": "vue-html"
},
"view for": {
"body": [
"<view v-for=\"(item,index) in ${1:dataList}\" :key=\"index\">",
"\t$0",
"</view>"
],
"description": "view带for循环",
"prefix": "viewfor",
"project": "uni-app",
"scope": "vue-html"
},
"view_class": {
"body": ["<view class=\"$1\">", "\t$0", "</view>"],
"prefix": "viewclass",
"scope": "vue-html",
"triggerAssist": true
}
}

66
README.md Normal file
View File

@ -0,0 +1,66 @@
# uniapp-vue3-starter
## 插件
* [Vue 3](https://github.com/vuejs/core), [Vite 3](https://github.com/vitejs/vite), [pnpm](https://pnpm.io/)
* [UnoCSS](https://github.com/unocss/unocss) - 高性能且极具灵活性的即时原子化 css 引擎
* [unocss-preset-weapp](https://github.com/MellowCo/unocss-preset-weapp) - unocss 小程序预设
* [unplugin-auto-import](https://github.com/antfu/unplugin-auto-import) - API 自动加载,直接使用 Composition API 无需引入
* TypeScript
* [UniApp 代码片段](https://github.com/zhetengbiji/uniapp-snippets-vscode)
* [ESLint](https://eslint.org/) with [@antfu/eslint-config](https://github.com/antfu/eslint-config)
* [@meoc/utils](https://github.com/MellowCo/utils) - 个人小工具集
## 使用
```shell
npx degit MellowCo/uni-vue3-starter my-app
cd my-app
pnpm i
```
## 使用 unocss
vite.config.ts
```ts
import { defineConfig } from 'vite'
import Unocss from 'unocss/vite'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
// https://github.com/antfu/unocss
Unocss(),
],
})
```
unocss.config.ts
```ts
import presetWeapp from 'unocss-preset-weapp'
import { transformerAttributify, transformerClass } from 'unocss-preset-weapp/transformer'
import { defineConfig } from 'unocss'
export default defineConfig({
presets: [
// https://github.com/MellowCo/unocss-preset-weapp
presetWeapp(),
],
shortcuts: [
{
'border-base': 'border border-[#eee]',
'flex-center': 'flex justify-center items-center',
'text-c1': 'text-[#181818]',
'text-c2': 'text-[#333333]',
'text-c3': 'text-[#B2B2B2]',
'text-c4': 'text-[#CCCCCC]',
'bg': 'bg-[#f6f7fb]',
},
],
transformers: [
// https://github.com/MellowCo/unocss-preset-weapp/tree/main/src/transformer/transformerAttributify
transformerAttributify(),
// https://github.com/MellowCo/unocss-preset-weapp/tree/main/src/transformer/transformerClass
transformerClass(),
],
})
```

286
auto-imports.d.ts vendored Normal file
View File

@ -0,0 +1,286 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// Generated by unplugin-auto-import
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate']
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const createPinia: typeof import('pinia')['createPinia']
const customRef: typeof import('vue')['customRef']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const defineStore: typeof import('pinia')['defineStore']
const effectScope: typeof import('vue')['effectScope']
const getActivePinia: typeof import('pinia')['getActivePinia']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const inject: typeof import('vue')['inject']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const mapActions: typeof import('pinia')['mapActions']
const mapGetters: typeof import('pinia')['mapGetters']
const mapState: typeof import('pinia')['mapState']
const mapStores: typeof import('pinia')['mapStores']
const mapWritableState: typeof import('pinia')['mapWritableState']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onAddToFavorites: typeof import('@dcloudio/uni-app')['onAddToFavorites']
const onBackPress: typeof import('@dcloudio/uni-app')['onBackPress']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onDeactivated: typeof import('vue')['onDeactivated']
const onError: typeof import('@dcloudio/uni-app')['onError']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onHide: typeof import('@dcloudio/uni-app')['onHide']
const onLaunch: typeof import('@dcloudio/uni-app')['onLaunch']
const onLoad: typeof import('@dcloudio/uni-app')['onLoad']
const onMounted: typeof import('vue')['onMounted']
const onNavigationBarButtonTap: typeof import('@dcloudio/uni-app')['onNavigationBarButtonTap']
const onNavigationBarSearchInputChanged: typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputChanged']
const onNavigationBarSearchInputClicked: typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputClicked']
const onNavigationBarSearchInputConfirmed: typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputConfirmed']
const onNavigationBarSearchInputFocusChanged: typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputFocusChanged']
const onPageNotFound: typeof import('@dcloudio/uni-app')['onPageNotFound']
const onPageScroll: typeof import('@dcloudio/uni-app')['onPageScroll']
const onPullDownRefresh: typeof import('@dcloudio/uni-app')['onPullDownRefresh']
const onReachBottom: typeof import('@dcloudio/uni-app')['onReachBottom']
const onReady: typeof import('@dcloudio/uni-app')['onReady']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onResize: typeof import('@dcloudio/uni-app')['onResize']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onShareAppMessage: typeof import('@dcloudio/uni-app')['onShareAppMessage']
const onShareTimeline: typeof import('@dcloudio/uni-app')['onShareTimeline']
const onShow: typeof import('@dcloudio/uni-app')['onShow']
const onTabItemTap: typeof import('@dcloudio/uni-app')['onTabItemTap']
const onThemeChange: typeof import('@dcloudio/uni-app')['onThemeChange']
const onUnhandledRejection: typeof import('@dcloudio/uni-app')['onUnhandledRejection']
const onUnload: typeof import('@dcloudio/uni-app')['onUnload']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const resolveComponent: typeof import('vue')['resolveComponent']
const setActivePinia: typeof import('pinia')['setActivePinia']
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const storeToRefs: typeof import('pinia')['storeToRefs']
const toRaw: typeof import('vue')['toRaw']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const toValue: typeof import('vue')['toValue']
const triggerRef: typeof import('vue')['triggerRef']
const unref: typeof import('vue')['unref']
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useSlots: typeof import('vue')['useSlots']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
}
// for type re-export
declare global {
// @ts-ignore
export type { Component, ComponentPublicInstance, ComputedRef, InjectionKey, PropType, Ref, VNode } from 'vue'
}
// for vue template auto import
import { UnwrapRef } from 'vue'
declare module 'vue' {
interface ComponentCustomProperties {
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
readonly computed: UnwrapRef<typeof import('vue')['computed']>
readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
readonly createPinia: UnwrapRef<typeof import('pinia')['createPinia']>
readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
readonly defineStore: UnwrapRef<typeof import('pinia')['defineStore']>
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
readonly h: UnwrapRef<typeof import('vue')['h']>
readonly inject: UnwrapRef<typeof import('vue')['inject']>
readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
readonly mapActions: UnwrapRef<typeof import('pinia')['mapActions']>
readonly mapGetters: UnwrapRef<typeof import('pinia')['mapGetters']>
readonly mapState: UnwrapRef<typeof import('pinia')['mapState']>
readonly mapStores: UnwrapRef<typeof import('pinia')['mapStores']>
readonly mapWritableState: UnwrapRef<typeof import('pinia')['mapWritableState']>
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
readonly onAddToFavorites: UnwrapRef<typeof import('@dcloudio/uni-app')['onAddToFavorites']>
readonly onBackPress: UnwrapRef<typeof import('@dcloudio/uni-app')['onBackPress']>
readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
readonly onError: UnwrapRef<typeof import('@dcloudio/uni-app')['onError']>
readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
readonly onHide: UnwrapRef<typeof import('@dcloudio/uni-app')['onHide']>
readonly onLaunch: UnwrapRef<typeof import('@dcloudio/uni-app')['onLaunch']>
readonly onLoad: UnwrapRef<typeof import('@dcloudio/uni-app')['onLoad']>
readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
readonly onNavigationBarButtonTap: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarButtonTap']>
readonly onNavigationBarSearchInputChanged: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputChanged']>
readonly onNavigationBarSearchInputClicked: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputClicked']>
readonly onNavigationBarSearchInputConfirmed: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputConfirmed']>
readonly onNavigationBarSearchInputFocusChanged: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputFocusChanged']>
readonly onPageNotFound: UnwrapRef<typeof import('@dcloudio/uni-app')['onPageNotFound']>
readonly onPageScroll: UnwrapRef<typeof import('@dcloudio/uni-app')['onPageScroll']>
readonly onPullDownRefresh: UnwrapRef<typeof import('@dcloudio/uni-app')['onPullDownRefresh']>
readonly onReachBottom: UnwrapRef<typeof import('@dcloudio/uni-app')['onReachBottom']>
readonly onReady: UnwrapRef<typeof import('@dcloudio/uni-app')['onReady']>
readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
readonly onResize: UnwrapRef<typeof import('@dcloudio/uni-app')['onResize']>
readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
readonly onShareAppMessage: UnwrapRef<typeof import('@dcloudio/uni-app')['onShareAppMessage']>
readonly onShareTimeline: UnwrapRef<typeof import('@dcloudio/uni-app')['onShareTimeline']>
readonly onShow: UnwrapRef<typeof import('@dcloudio/uni-app')['onShow']>
readonly onTabItemTap: UnwrapRef<typeof import('@dcloudio/uni-app')['onTabItemTap']>
readonly onThemeChange: UnwrapRef<typeof import('@dcloudio/uni-app')['onThemeChange']>
readonly onUnhandledRejection: UnwrapRef<typeof import('@dcloudio/uni-app')['onUnhandledRejection']>
readonly onUnload: UnwrapRef<typeof import('@dcloudio/uni-app')['onUnload']>
readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
readonly provide: UnwrapRef<typeof import('vue')['provide']>
readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
readonly ref: UnwrapRef<typeof import('vue')['ref']>
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
readonly setActivePinia: UnwrapRef<typeof import('pinia')['setActivePinia']>
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
readonly storeToRefs: UnwrapRef<typeof import('pinia')['storeToRefs']>
readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
readonly unref: UnwrapRef<typeof import('vue')['unref']>
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
readonly watch: UnwrapRef<typeof import('vue')['watch']>
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
}
}
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
readonly computed: UnwrapRef<typeof import('vue')['computed']>
readonly createApp: UnwrapRef<typeof import('vue')['createApp']>
readonly createPinia: UnwrapRef<typeof import('pinia')['createPinia']>
readonly customRef: UnwrapRef<typeof import('vue')['customRef']>
readonly defineAsyncComponent: UnwrapRef<typeof import('vue')['defineAsyncComponent']>
readonly defineComponent: UnwrapRef<typeof import('vue')['defineComponent']>
readonly defineStore: UnwrapRef<typeof import('pinia')['defineStore']>
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>
readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
readonly h: UnwrapRef<typeof import('vue')['h']>
readonly inject: UnwrapRef<typeof import('vue')['inject']>
readonly isProxy: UnwrapRef<typeof import('vue')['isProxy']>
readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
readonly mapActions: UnwrapRef<typeof import('pinia')['mapActions']>
readonly mapGetters: UnwrapRef<typeof import('pinia')['mapGetters']>
readonly mapState: UnwrapRef<typeof import('pinia')['mapState']>
readonly mapStores: UnwrapRef<typeof import('pinia')['mapStores']>
readonly mapWritableState: UnwrapRef<typeof import('pinia')['mapWritableState']>
readonly markRaw: UnwrapRef<typeof import('vue')['markRaw']>
readonly nextTick: UnwrapRef<typeof import('vue')['nextTick']>
readonly onActivated: UnwrapRef<typeof import('vue')['onActivated']>
readonly onAddToFavorites: UnwrapRef<typeof import('@dcloudio/uni-app')['onAddToFavorites']>
readonly onBackPress: UnwrapRef<typeof import('@dcloudio/uni-app')['onBackPress']>
readonly onBeforeMount: UnwrapRef<typeof import('vue')['onBeforeMount']>
readonly onBeforeUnmount: UnwrapRef<typeof import('vue')['onBeforeUnmount']>
readonly onBeforeUpdate: UnwrapRef<typeof import('vue')['onBeforeUpdate']>
readonly onDeactivated: UnwrapRef<typeof import('vue')['onDeactivated']>
readonly onError: UnwrapRef<typeof import('@dcloudio/uni-app')['onError']>
readonly onErrorCaptured: UnwrapRef<typeof import('vue')['onErrorCaptured']>
readonly onHide: UnwrapRef<typeof import('@dcloudio/uni-app')['onHide']>
readonly onLaunch: UnwrapRef<typeof import('@dcloudio/uni-app')['onLaunch']>
readonly onLoad: UnwrapRef<typeof import('@dcloudio/uni-app')['onLoad']>
readonly onMounted: UnwrapRef<typeof import('vue')['onMounted']>
readonly onNavigationBarButtonTap: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarButtonTap']>
readonly onNavigationBarSearchInputChanged: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputChanged']>
readonly onNavigationBarSearchInputClicked: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputClicked']>
readonly onNavigationBarSearchInputConfirmed: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputConfirmed']>
readonly onNavigationBarSearchInputFocusChanged: UnwrapRef<typeof import('@dcloudio/uni-app')['onNavigationBarSearchInputFocusChanged']>
readonly onPageNotFound: UnwrapRef<typeof import('@dcloudio/uni-app')['onPageNotFound']>
readonly onPageScroll: UnwrapRef<typeof import('@dcloudio/uni-app')['onPageScroll']>
readonly onPullDownRefresh: UnwrapRef<typeof import('@dcloudio/uni-app')['onPullDownRefresh']>
readonly onReachBottom: UnwrapRef<typeof import('@dcloudio/uni-app')['onReachBottom']>
readonly onReady: UnwrapRef<typeof import('@dcloudio/uni-app')['onReady']>
readonly onRenderTracked: UnwrapRef<typeof import('vue')['onRenderTracked']>
readonly onRenderTriggered: UnwrapRef<typeof import('vue')['onRenderTriggered']>
readonly onResize: UnwrapRef<typeof import('@dcloudio/uni-app')['onResize']>
readonly onScopeDispose: UnwrapRef<typeof import('vue')['onScopeDispose']>
readonly onServerPrefetch: UnwrapRef<typeof import('vue')['onServerPrefetch']>
readonly onShareAppMessage: UnwrapRef<typeof import('@dcloudio/uni-app')['onShareAppMessage']>
readonly onShareTimeline: UnwrapRef<typeof import('@dcloudio/uni-app')['onShareTimeline']>
readonly onShow: UnwrapRef<typeof import('@dcloudio/uni-app')['onShow']>
readonly onTabItemTap: UnwrapRef<typeof import('@dcloudio/uni-app')['onTabItemTap']>
readonly onThemeChange: UnwrapRef<typeof import('@dcloudio/uni-app')['onThemeChange']>
readonly onUnhandledRejection: UnwrapRef<typeof import('@dcloudio/uni-app')['onUnhandledRejection']>
readonly onUnload: UnwrapRef<typeof import('@dcloudio/uni-app')['onUnload']>
readonly onUnmounted: UnwrapRef<typeof import('vue')['onUnmounted']>
readonly onUpdated: UnwrapRef<typeof import('vue')['onUpdated']>
readonly provide: UnwrapRef<typeof import('vue')['provide']>
readonly reactive: UnwrapRef<typeof import('vue')['reactive']>
readonly readonly: UnwrapRef<typeof import('vue')['readonly']>
readonly ref: UnwrapRef<typeof import('vue')['ref']>
readonly resolveComponent: UnwrapRef<typeof import('vue')['resolveComponent']>
readonly setActivePinia: UnwrapRef<typeof import('pinia')['setActivePinia']>
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
readonly storeToRefs: UnwrapRef<typeof import('pinia')['storeToRefs']>
readonly toRaw: UnwrapRef<typeof import('vue')['toRaw']>
readonly toRef: UnwrapRef<typeof import('vue')['toRef']>
readonly toRefs: UnwrapRef<typeof import('vue')['toRefs']>
readonly toValue: UnwrapRef<typeof import('vue')['toValue']>
readonly triggerRef: UnwrapRef<typeof import('vue')['triggerRef']>
readonly unref: UnwrapRef<typeof import('vue')['unref']>
readonly useAttrs: UnwrapRef<typeof import('vue')['useAttrs']>
readonly useCssModule: UnwrapRef<typeof import('vue')['useCssModule']>
readonly useCssVars: UnwrapRef<typeof import('vue')['useCssVars']>
readonly useSlots: UnwrapRef<typeof import('vue')['useSlots']>
readonly watch: UnwrapRef<typeof import('vue')['watch']>
readonly watchEffect: UnwrapRef<typeof import('vue')['watchEffect']>
readonly watchPostEffect: UnwrapRef<typeof import('vue')['watchPostEffect']>
readonly watchSyncEffect: UnwrapRef<typeof import('vue')['watchSyncEffect']>
}
}

20
index.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

71
package.json Normal file
View File

@ -0,0 +1,71 @@
{
"name": "uni-vue3-starter",
"version": "0.0.0",
"scripts": {
"dev:app": "uni -p app",
"dev:custom": "uni -p",
"dev:h5": "uni",
"dev:h5:ssr": "uni --ssr",
"dev:mp-alipay": "uni -p mp-alipay",
"dev:mp-baidu": "uni -p mp-baidu",
"dev:mp-kuaishou": "uni -p mp-kuaishou",
"dev:mp-lark": "uni -p mp-lark",
"dev:mp-qq": "uni -p mp-qq",
"dev:mp-toutiao": "uni -p mp-toutiao",
"dev:mp-weixin": "uni -p mp-weixin",
"dev:quickapp-webview": "uni -p quickapp-webview",
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
"build:app": "uni build -p app",
"build:custom": "uni build -p",
"build:h5": "uni build",
"build:h5:ssr": "uni build --ssr",
"build:mp-alipay": "uni build -p mp-alipay",
"build:mp-baidu": "uni build -p mp-baidu",
"build:mp-kuaishou": "uni build -p mp-kuaishou",
"build:mp-lark": "uni build -p mp-lark",
"build:mp-qq": "uni build -p mp-qq",
"build:mp-toutiao": "uni build -p mp-toutiao",
"build:mp-weixin": "uni build -p mp-weixin",
"build:quickapp-webview": "uni build -p quickapp-webview",
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
"build:quickapp-webview-union": "uni build -p quickapp-webview-union",
"lint": "eslint ."
},
"dependencies": {
"@dcloudio/uni-app": "3.0.0-3080420230531001",
"@dcloudio/uni-app-plus": "3.0.0-3080420230531001",
"@dcloudio/uni-components": "3.0.0-3080420230531001",
"@dcloudio/uni-h5": "3.0.0-3080420230531001",
"@dcloudio/uni-mp-alipay": "3.0.0-3080420230531001",
"@dcloudio/uni-mp-baidu": "3.0.0-3080420230531001",
"@dcloudio/uni-mp-jd": "3.0.0-3080420230531001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-3080420230531001",
"@dcloudio/uni-mp-lark": "3.0.0-3080420230531001",
"@dcloudio/uni-mp-qq": "3.0.0-3080420230531001",
"@dcloudio/uni-mp-toutiao": "3.0.0-3080420230531001",
"@dcloudio/uni-mp-weixin": "3.0.0-3080420230531001",
"@dcloudio/uni-quickapp-webview": "3.0.0-3080420230531001",
"@meoc/utils": "^0.2.5",
"pinia": "^2.0.24",
"vue": "^3.2.45",
"vue-i18n": "^9.2.2",
"wot-design-uni": "^1.3.12"
},
"devDependencies": {
"@antfu/eslint-config": "^0.39.5",
"@dcloudio/types": "^3.3.3",
"@dcloudio/uni-automator": "3.0.0-3080420230531001",
"@dcloudio/uni-cli-shared": "3.0.0-3080420230531001",
"@dcloudio/uni-stacktracey": "3.0.0-3080420230531001",
"@dcloudio/vite-plugin-uni": "3.0.0-3080420230531001",
"@types/node": "^20.3.1",
"eslint": "^8.42.0",
"sass": "^1.78.0",
"typescript": "^5.1.3",
"unocss": "^0.53.1",
"unocss-preset-weapp": "^0.52.1",
"unplugin-auto-import": "^0.16.4",
"vite": "^4.1.4"
}
}

8791
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

17
src/App.vue Normal file
View File

@ -0,0 +1,17 @@
<script setup lang="ts">
onLaunch(() => {
console.log('App Launch')
})
onShow(() => {
console.log('App Show')
})
onHide(() => {
console.log('App Hide')
})
</script>
<style>
page{
background-color: #f6f7fb;
}
</style>

29
src/config/env.ts Normal file
View File

@ -0,0 +1,29 @@
/** 请求服务的环境配置 */
type ServiceEnv = Record<ServiceEnvType, ServiceEnvConfig>
const serviceEnv: ServiceEnv = {
dev: {
url: 'http://localhost:8080',
json: 'http://localhost:8080',
},
test: {
url: 'http://localhost:8080',
json: 'http://localhost:8080',
},
prod: {
url: 'http://localhost:8080',
json: 'http://localhost:8080',
},
}
/**
*
* @param env
*/
export function getServiceEnvConfig(env: ImportMetaEnv) {
const { VITE_SERVICE_ENV = 'dev' } = env
const config = serviceEnv[VITE_SERVICE_ENV]
return config
}

2
src/config/index.ts Normal file
View File

@ -0,0 +1,2 @@
export * from './service'
export * from './env'

47
src/config/service.ts Normal file
View File

@ -0,0 +1,47 @@
/** 请求超时时间 */
export const REQUEST_TIMEOUT = 60 * 1000
/** 错误信息的显示时间 */
export const ERROR_MSG_DURATION = 3 * 1000
/** 默认的请求错误code */
export const DEFAULT_REQUEST_ERROR_CODE = 'DEFAULT'
/** 默认的请求错误文本 */
export const DEFAULT_REQUEST_ERROR_MSG = '请求错误~'
/** 请求超时的错误code(为固定值ECONNABORTED) */
export const REQUEST_TIMEOUT_CODE = 'ECONNABORTED'
/** 请求超时的错误文本 */
export const REQUEST_TIMEOUT_MSG = '请求超时~'
/** 网络不可用的code */
export const NETWORK_ERROR_CODE = 'NETWORK_ERROR'
/** 网络不可用的错误文本 */
export const NETWORK_ERROR_MSG = '网络不可用~'
/** 请求不成功各种状态的错误 */
/** 请求不成功各种状态的错误 */
export const ERROR_STATUS: Record<number | string, string> = {
400: '400: 请求出现语法错误~',
401: '401: 用户未授权~',
403: '403: 服务器拒绝访问~',
404: '404: 请求的资源不存在~',
405: '405: 请求方法未允许~',
408: '408: 网络请求超时~',
500: '500: 服务器内部错误~',
501: '501: 服务器未实现请求功能~',
502: '502: 错误网关~',
503: '503: 服务不可用~',
504: '504: 网关超时~',
505: '505: http版本不支持该请求~',
[DEFAULT_REQUEST_ERROR_CODE]: DEFAULT_REQUEST_ERROR_MSG,
}
/** 不弹出错误信息的code */
export const NO_ERROR_MSG_CODE: (string | number)[] = []
/** token失效需要刷新token的code */
export const REFRESH_TOKEN_CODE: (string | number)[] = []

View File

@ -0,0 +1 @@
export * from './storage'

View File

@ -0,0 +1,5 @@
export enum ContentType {
JSON = 'application/json;charset=UTF-8',
TEXT = 'text/plain;charset=UTF-8',
FORM_DATA = 'multipart/form-data;charset=UTF-8',
}

View File

@ -0,0 +1,8 @@
export enum StorageKey {
/** 用户token */
token = '__TOKEN__',
/** 用户刷新token */
refreshToken = '__REFRESH_TOKEN__',
/** 用户信息 */
userInfo = '__USER_INFO__',
}

1
src/enums/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './common'

8
src/env.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
/// <reference types="vite/client" />
declare module '*.vue' {
import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}

14
src/main.ts Normal file
View File

@ -0,0 +1,14 @@
import { createSSRApp } from 'vue'
import App from './App.vue'
import { setupStore } from './store'
import 'uno.css'
export function createApp() {
const app = createSSRApp(App)
setupStore(app)
return {
app,
}
}

72
src/manifest.json Normal file
View File

@ -0,0 +1,72 @@
{
"name" : "452",
"appid" : "__UNI__FAB99D9",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* */
"modules" : {},
/* */
"distribute" : {
/* android */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios" : {},
/* SDK */
"sdkConfigs" : {}
}
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "wx56a1f8716a60996d",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "3"
}

112
src/pages.json Normal file
View File

@ -0,0 +1,112 @@
{
"globalStyle": {
"navigationStyle": "default",
"navigationBarTitleText": "unibest",
"navigationBarBackgroundColor": "#f8f8f8",
"navigationBarTextStyle": "black",
"backgroundColor": "#FFFFFF",
"h5": {
"navigationStyle": "custom"
}
},
"easycom": {
"autoscan": true,
"custom": {
"^wd-(.*)": "wot-design-uni/components/wd-$1/wd-$1.vue",
"^layout-(.*)-uni": "@/layouts/$1.vue"
}
},
"tabBar": {
"color": "#999999",
"selectedColor": "#018d71",
"backgroundColor": "#F8F8F8",
"borderStyle": "black",
"height": "50px",
"fontSize": "10px",
"iconWidth": "24px",
"spacing": "3px",
"custom": true,
"list": [
{
"iconPath": "static/tabbar/home.png",
"selectedIconPath": "static/tabbar/homeHL.png",
"pagePath": "pages/index/index",
"text": "首页"
},
{
"iconPath": "static/tabbar/example.png",
"selectedIconPath": "static/tabbar/exampleHL.png",
"pagePath": "pages/index/about",
"text": "关于"
}
]
},
"pages": [
{
"path": "pages/index/index",
"type": "home",
"style": {
"navigationStyle": "custom",
"navigationBarTitleText": "首页"
}
},
{
"path": "pages/appointment-form/index",
"type": "page",
// "layout": "default",
"style": {
"navigationBarTitleText": "预约表单",
"navigationStyle": "custom"
}
},
{
"path": "pages/appointment-quan/index",
"type": "page",
// "layout": "default",
"style": {
"navigationBarTitleText": "预约表单",
"navigationStyle": "custom"
}
},
{
"path": "pages/appointment-time/index",
"type": "page",
// "layout": "default",
"style": {
"navigationBarTitleText": "日期",
"navigationStyle": "custom"
}
},
{
"path": "pages/index/about",
"type": "page",
// "layout": "default",
"style": {
"navigationBarTitleText": "关于"
}
},
{
"path": "pages/user-info/index",
"type": "page",
// "layout": "default",
"style": {
"navigationBarTitleText": "旅游",
"navigationStyle": "custom"
}
}
]
// "subPackages": [
// {
// "root": "pages-sub",
// "pages": [
// {
// "path": "demo",
// "type": "page",
// "style": {
// "navigationBarTitleText": "分包页面 标题"
// }
// }
// ]
// }
// ]
}

View File

@ -0,0 +1,348 @@
<template>
<view class="home-head" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
<view class="nav">
<wd-icon @click='onBack' name="thin-arrow-left" size="35rpx"></wd-icon>
<text class='nav_title'>旅游度假 预约出行系统</text>
</view>
<view class="main" v-if="status">
<view class="list flex">
<view class="lable">出游日期 </view>
<view class="">2024年09月2日-2024年09月13日</view>
</view>
<wd-form ref="form" :model="model">
<wd-cell-group>
<wd-picker prop='num' :rules="[{ required: true, message: '请选择出游人数' }]" :columns="columns" label="出游人数" v-model="model.num" @confirm="handleConfirm" />
<!-- <wd-icon name="camera" size="22px"></wd-icon> -->
<view class="mist" v-for="(item, index) in model.num">
<wd-input
:key="index"
:label="'出游券码截图' + (index+1)"
:prop="'voucher.' + index + '.value'"
label-width='34%'
clearable
disabled
no-border
suffixIcon='camera'
v-model="model.code_pic[index]"
placeholder="出游券码截图"
:rules="[{ required: true, message: '请填写出游券码截图' + (index+1) }]"
/>
<view class='tip flex' @click="handleVoucherCode">
<view class="tip-bor flex items-center">
<image src="../../static/home/tip.png" mode=""></image>
</view>
<view style="color: #2A8AFF;font-size: 22rpx;">如何查看券码</view>
</view>
</view>
<wd-input
label="出游人姓名"
label-width="200rpx"
prop="name"
clearable
no-border
v-model="model.name"
placeholder="请输入用户名"
:rules="[{ required: true, message: '请填写用户名' }]"
/>
<wd-input
label="出游人电话"
label-width="200rpx"
prop="mobile"
no-border
clearable
v-model="model.mobile"
placeholder="请输入出游人电话"
:rules="[{ required: true, message: '请填写出游人电话' }]"
/>
<wd-textarea no-border size="large" label-width="100rpx" label="备注" v-model="model.note" placeholder="请填写备注" />
</wd-cell-group>
<view class="footer">
<view class="btn" @click="handleSubmit">立刻预约</view>
</view>
</wd-form>
</view>
<view class="main" v-else>
<view class="status-icon">
<image src="../../static/home/scuss.png" mode=""></image>
<view style="margin-top: 28rpx;">
预约成功
</view>
</view>
</view>
<view class="main" v-if="showQuan">
<image class="quan" src="../../static/home/quan.png"></image>
</view>
<wd-popup v-model="show" position='center' custom-style='border-radius: 25rpx;width:525rpx' @close="handleClose">
<view class="pop">
<view class="pop-title">确认预约</view>
<view class="pop-tip">预约成功后取消或修改需联系商家</view>
<view class="pop-list flex items-center">
<view class="pop-icon flex items-center justify-center">
<wd-icon color='#1096FD' name="check" size="22rpx"></wd-icon>
</view>
<view class="pop-desc overflow"> 欧洲13国12天9晚双飞游</view>
</view>
<view class="pop-list flex items-center">
<view class="pop-icon flex items-center justify-center">
<wd-icon color='#1096FD' name="check" size="22rpx"></wd-icon>
</view>
<view class="pop-desc overflow"> 2024.09.02(周一)-2024.09.13(周五)</view>
</view>
<view class="pop-list flex items-center">
<view class="pop-icon flex items-center justify-center">
<wd-icon color='#1096FD' name="check" size="22rpx"></wd-icon>
</view>
<view class="pop-desc overflow"> 1</view>
</view>
<view class="pop-list flex items-center">
<view class="pop-icon flex items-center justify-center">
<wd-icon color='#1096FD' name="check" size="22rpx"></wd-icon>
</view>
<view class="pop-desc overflow"> 吴生</view>
</view>
<view class="pop-list flex items-center">
<view class="pop-icon flex items-center justify-center">
<wd-icon color='#1096FD' name="check" size="22rpx"></wd-icon>
</view>
<view class="pop-desc overflow"> 13588779988</view>
</view>
</view>
<view class="bottom flex items-center">
<view class="bottom-btn-left" @click="handleClose">取消</view>
<view class="bottom-btn-right" @click="handleSave">确定</view>
</view>
</wd-popup>
</view>
</template>
<script lang="ts" setup>
//
const { safeAreaInsets } = uni.getSystemInfoSync()
// const { success: showSuccess } = useToast()
const status = ref(1)
const showQuan = ref(false)
const show = ref(false)
const handleVoucherCode = ()=>{
// status.value = 0
// showQuan.value = true
uni.navigateTo({
url:'/pages/appointment-quan/index'
})
}
const handleClose = ()=>{
show.value = false
}
const handleSave = ()=>{
form.value
.validate()
.then(({ valid, errors }) => {
if (valid) {
// showSuccess({
// msg: ''
// })
show.value = false
}
})
.catch((error) => {
console.log(error, 'error')
})
}
onLoad(() => {
console.log(safeAreaInsets)
})
const model = reactive<{
num: number,
code_pic: Array,
name:string,
mobile:string,
note:string
}>({
num: 1,
code_pic: [],
name:'',
mobile:'',
note:''
})
const form = ref()
const columns = ref([1, 2, 3, 4, 5, 6, 7])
function handleConfirm({ value }) {
model.num = value
}
const handleSubmit = ()=> {
show.value = true
// form.value
// .validate()
// .then(({ valid, errors }) => {
// if (valid) {
// // showSuccess({
// // msg: ''
// // })
// }
// })
// .catch((error) => {
// console.log(error, 'error')
// })
}
const handleAppointment = ()=>{
uni.navigateTo({
url:'/pages/appointment-time/index'
})
}
const onBack = ()=>{
uni.navigateBack({ delta: 1 })
}
</script>
<style lang="scss" scoped>
.txt{
font-size: 30rpx;
font-weight: bold;
color: #181818;
}
.pdf{
color: #0095FF;
font-size: 24rpx;
font-weight: bold;
}
.overflow {
white-space: nowrap; /* 文本不换行 */
overflow: hidden; /* 隐藏超出的内容 */
text-overflow: ellipsis; /* 当文本溢出时显示省略号 */
}
.footer{
margin-top: 222rpx;
}
.btn{
// margin-top: 160rpx;
background: #1170FF;
border-radius: 50rpx;
padding: 20rpx 230rpx;
text-align: center;
color: #fff;
font-size: 32rpx;
}
.pop{
padding: 40rpx 30rpx 0 30rpx;
.pop-title{
font-size: 32rpx;
font-weight: bold;
color: #181818;
text-align: center;
}
.pop-icon{
border-radius: 50%;
background: #E7F4FE;
width: 36rpx;
height: 36rpx;
}
.pop-tip{
font-size: 24rpx;
color: #878585;
margin-top: 14rpx;
text-align: center;
}
.pop-list{
margin-top: 25rpx;
& + .pop-list{
margin-top: 10rpx;
}
}
.pop-desc{
margin-left: 10rpx;
font-size: 26rpx;
color: #181818;
}
}
.bottom{
width: 100%;
margin-top: 45rpx;
border-top: 1px solid #D8D8D8;
justify-content: space-between;
.bottom-btn-left,.bottom-btn-right{
padding: 25rpx 0;
width: 50%;
text-align: center;
}
.bottom-btn-right{
border-left: 1px solid #D8D8D8;
}
}
.status-icon{
padding-top: 90rpx;
margin: 0 270rpx;
text-align: center;
image{
width: 160rpx;
height: 160rpx;
}
}
.mist{
.tip{
margin-left: 28rpx;
.tip-bor{
margin-right: 10rpx;
image{
width: 18rpx;
height: 18rpx;
}
}
}
}
.home-head {
width: 100%;
height: 574rpx;
background: linear-gradient(180deg, #92deeb 0%, rgba(216, 216, 216, 0) 100%);
border-radius: 0px 0px 0px 0px;
.nav{
padding: 16rpx 0 16rpx 20rpx;
.nav_title{
font-size: 36rpx;
color: #181818;
font-weight: bold;
margin-left: 75rpx;
}
}
.main{
margin: 54rpx 26rpx 0 26rpx;
background: #fff;
border-radius: 20rpx;
min-height: 894rpx;
// padding: 40rpx 30rpx;
.quan{
height: 3502rpx;
}
.list{
padding: 40rpx 30rpx;
padding-bottom: 10rpx;
color: #181818;
font-size: 28rpx;
.lable{
font-weight: bold;
}
.box{
font-weight: 400;
margin-left: 20rpx;
}
}
::v-deep.wd-textarea__inner{
border: 1px solid #444444;
}
::v-deep.wd-input__icon{
color: #1170FF;
}
// ::v-deep.wd-picker__cell{
// padding: 0;
// }
}
}
</style>

View File

@ -0,0 +1,173 @@
<template>
<view class="home-head" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
<view class="nav">
<wd-icon @click='onBack' name="thin-arrow-left" size="35rpx"></wd-icon>
<text class='nav_title'>查看券码</text>
</view>
<view class="main">
<image class="quan" src="../../static/home/quan.png"></image>
</view>
</view>
</template>
<script lang="ts" setup>
//
const { safeAreaInsets } = uni.getSystemInfoSync()
// const { success: showSuccess } = useToast()
const showQuan = ref(false)
onLoad(() => {
console.log(safeAreaInsets)
})
const onBack = ()=>{
uni.navigateBack({ delta: 1 })
}
</script>
<style lang="scss" scoped>
.txt{
font-size: 30rpx;
font-weight: bold;
color: #181818;
}
.pdf{
color: #0095FF;
font-size: 24rpx;
font-weight: bold;
}
.overflow {
white-space: nowrap; /* 文本不换行 */
overflow: hidden; /* 隐藏超出的内容 */
text-overflow: ellipsis; /* 当文本溢出时显示省略号 */
}
.footer{
margin-top: 222rpx;
}
.btn{
// margin-top: 160rpx;
background: #1170FF;
border-radius: 50rpx;
padding: 20rpx 230rpx;
text-align: center;
color: #fff;
font-size: 32rpx;
}
.pop{
padding: 40rpx 30rpx 0 30rpx;
.pop-title{
font-size: 32rpx;
font-weight: bold;
color: #181818;
text-align: center;
}
.pop-icon{
border-radius: 50%;
background: #E7F4FE;
width: 36rpx;
height: 36rpx;
}
.pop-tip{
font-size: 24rpx;
color: #878585;
margin-top: 14rpx;
text-align: center;
}
.pop-list{
margin-top: 25rpx;
& + .pop-list{
margin-top: 10rpx;
}
}
.pop-desc{
margin-left: 10rpx;
font-size: 26rpx;
color: #181818;
}
}
.bottom{
width: 100%;
margin-top: 45rpx;
border-top: 1px solid #D8D8D8;
justify-content: space-between;
.bottom-btn-left,.bottom-btn-right{
padding: 25rpx 0;
width: 50%;
text-align: center;
}
.bottom-btn-right{
border-left: 1px solid #D8D8D8;
}
}
.status-icon{
padding-top: 90rpx;
margin: 0 270rpx;
text-align: center;
image{
width: 160rpx;
height: 160rpx;
}
}
.mist{
.tip{
margin-left: 28rpx;
.tip-bor{
margin-right: 10rpx;
image{
width: 18rpx;
height: 18rpx;
}
}
}
}
.home-head {
width: 100%;
height: 574rpx;
background: linear-gradient(180deg, #92deeb 0%, rgba(216, 216, 216, 0) 100%);
border-radius: 0px 0px 0px 0px;
.nav{
padding: 16rpx 0 16rpx 20rpx;
.nav_title{
font-size: 36rpx;
color: #181818;
font-weight: bold;
margin-left: 75rpx;
}
}
.main{
margin: 54rpx 26rpx 0 26rpx;
background: #fff;
border-radius: 20rpx;
min-height: 894rpx;
// padding: 40rpx 30rpx;
.quan{
height: 3502rpx;
}
.list{
padding: 40rpx 30rpx;
padding-bottom: 10rpx;
color: #181818;
font-size: 28rpx;
.lable{
font-weight: bold;
}
.box{
font-weight: 400;
margin-left: 20rpx;
}
}
::v-deep.wd-textarea__inner{
border: 1px solid #444444;
}
::v-deep.wd-input__icon{
color: #1170FF;
}
// ::v-deep.wd-picker__cell{
// padding: 0;
// }
}
}
</style>

View File

@ -0,0 +1,167 @@
<template>
<view class="home-head" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
<view class="nav">
<wd-icon @click='onBack' name="thin-arrow-left" size="35rpx"></wd-icon>
<text class='nav_title'>旅游度假 预约出行系统</text>
</view>
<view class="main">
<view class="head-title">
<text class="txt">选择出行日期</text>
<text class="data">可选</text>
<text class="rde">12天9晚</text>
<text class="desc">·所选日期为北京时间</text>
</view>
<wd-calendar-view custom-class='data' :panel-height='500' :formatter="formatter" :max-range="7" type="daterange" :show-panel-title='false' v-model="dataTime" @change="handleChange" />
</view>
<view class="bottom">
<view class="desc">09.02-09.13 共12天9晚</view>
<view class="btn" @click="handleMise">
下一步
</view>
</view>
</view>
</template>
<script lang="ts" setup>
//
const { safeAreaInsets } = uni.getSystemInfoSync()
const dataTime = ref([])
const dataDesc = ref('')
//
const formatter = (day) => {
const date = new Date(day.date)
const now = new Date()
const year = date.getFullYear()
const month = date.getMonth()
const da = date.getDate()
const nowYear = now.getFullYear()
const nowMonth = now.getMonth()
const nowDa = now.getDate()
day.bottomInfo = '可约'
// if (year === nowYear && month === nowMonth && da === nowDa) {
// day.topInfo = ''
// }
if (month === 5 && da === 18) {
day.topInfo = '618大促'
}
if (month === 10 && da === 11) {
day.topInfo = '京东双11'
}
if (day.type === 'start') {
day.topInfo = '出发'
day.bottomInfo = ''
}
if(day.type ==='middle'){
day.bottomInfo = ''
}
if (day.type === 'end') {
day.topInfo = '结束'
day.bottomInfo = ''
}
if (day.type === 'same') {
day.bottomInfo = '开始/结束'
}
return day
}
const onBack = ()=>{
uni.navigateBack({ delta: 1 })
}
const handleMise = ()=>{
uni.navigateTo({
url:'/pages/appointment-form/index'
})
}
const handleChange = ({ value })=>{
const date = new Date(value[0])
const now = new Date(value[1])
// const year = date.getFullYear()
const month = date.getMonth()
const da = date.getDate()
// const nowYear = now.getFullYear()
const nowMonth = now.getMonth()
const nowDa = now.getDate()
// console.log(nowDa-da);
dataDesc.value = `${month}.${da}-${nowMonth}.${nowDa}`
console.log(dataDesc.value)
}
</script>
<style lang="scss" scoped>
.txt{
color: #181818;
font-size: 32rpx;
font-weight: bold;
}
.head-title{
padding: 30rpx 20rpx;
font-size: 24rpx;
.data{
color: #787878;
margin-left: 8rpx;
}
.rde{
color: #F70C47;
}
.desc{
color: #787878;
}
}
.home-head {
width: 100%;
height: 574rpx;
background: linear-gradient(180deg, #92deeb 0%, rgba(216, 216, 216, 0) 100%);
border-radius: 0px 0px 0px 0px;
.nav{
padding: 16rpx 0 16rpx 20rpx;
.nav_title{
font-size: 36rpx;
color: #181818;
font-weight: bold;
margin-left: 75rpx;
}
}
}
.main{
background: #fff;
margin: 54rpx 26rpx 0 26rpx;
border-radius: 20rpx;
}
::v-deep.wd-month__day.is-start .wd-month__day-container,::v-deep.wd-month__day.is-end .wd-month__day-container{
background: #FB3158 !important;
}
::v-deep.wd-month__day.is-middle .wd-month__day-container{
background: #FFD4DC !important;
}
.bottom{
.desc{
margin-left: 38rpx;
margin-top: 20rpx;
color: #181818;
font-size: 24rpx;
}
.btn{
// margin-top: 160rpx;
margin: 44rpx 80rpx 0 80rpx;
background: #1170FF;
border-radius: 50rpx;
padding: 20rpx 230rpx;
text-align: center;
color: #fff;
font-size: 32rpx;
}
}
</style>

19
src/pages/index/about.vue Normal file
View File

@ -0,0 +1,19 @@
<template>
<view
class="bg-white overflow-hidden pt-2 px-4"
:style="{ marginTop: safeAreaInsets?.top + 'px' }"
>
</view>
</template>
<script lang="ts" setup>
//
const { safeAreaInsets } = uni.getSystemInfoSync()
</script>
<style lang="scss" scoped>
.desc {
width: 700rpx;
}
</style>

215
src/pages/index/index.vue Normal file
View File

@ -0,0 +1,215 @@
<template>
<view class="home-head">
<view :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
<view class="home-head-logo flex items-center justify-center">
<image src="../../static/home/meituan.png" mode=""></image>
<image src="../../static/home/shipinhao.png" mode=""></image>
</view>
<view class="home-head-text flex items-center justify-center">旅游度假预约出行系统</view>
<view class="home-input">
<view class="lable">输入您的下单手机号查询订单</view>
<view class="phone_input">
<wd-input no-border use-suffix-slot type="text" v-model="phone" center>
<template #suffix>
<view class="phone_btn">查询</view>
</template >
</wd-input>
</view>
</view>
<view class="home-list">
<view class="list_title">查询结果:</view>
<view class="list_main">
<view class="list_item">
<view class="order flex items-center">
<view class="id">订单编号4566888888</view>
<!-- <view class="btn">去预约</view> -->
</view>
<view class="stroke">
<text class="stroke_lable">行程</text>
<text class="stroke_desc">欧洲12天纯玩</text>
</view>
<view class="content flex items-center">
<view class="content_item">
<view class="title">订单金额</view>
<view class="desc">6800</view>
</view>
<view class="content_item">
<view class="title">状态</view>
<wd-text size="24rpx" type="success" text="已使用"></wd-text>
<!-- <wd-text type="error" text="错误"></wd-text>
<wd-text text="默认"></wd-text>
<view class="desc">已使用</view> -->
</view>
<view class="content_item">
<view class="title">下单平台</view>
<view class="desc">美团官方视频号直播</view>
</view>
</view>
</view>
<view class="list_item">
<view class="order flex items-center">
<view class="id">订单编号4566888888</view>
<view class="btn" @click="handleAppointment">去预约</view>
</view>
<view class="stroke">
<text class="stroke_lable">行程</text>
<text class="stroke_desc">欧洲12天纯玩</text>
</view>
<view class="content flex items-center">
<view class="content_item">
<view class="title">订单金额</view>
<view class="desc">6800</view>
</view>
<view class="content_item">
<view class="title">状态</view>
<wd-text type="error" size="24rpx" text="未预约"></wd-text>
<!-- <view class="desc">未预约</view> -->
</view>
<view class="content_item">
<view class="title">下单平台</view>
<view class="desc">美团官方视频号直播</view>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script lang="ts" setup>
//
const { safeAreaInsets } = uni.getSystemInfoSync()
onLoad(() => {
console.log()
uni.hideTabBar();
})
const phone = ref('')
const handleAppointment = ()=>{
uni.navigateTo({
url:'/pages/user-info/index'
})
}
</script>
<style lang="scss" scoped>
.main-title-color {
color: #d14328;
}
.home-head-logo{
padding-top: 132rpx;
image{
width: 140rpx;
height: 140rpx;
&:nth-child(1){
margin-right: 100rpx;
}
}
}
.home-head {
width: 100%;
height: 574rpx;
background: linear-gradient(180deg, #92deeb 0%, rgba(216, 216, 216, 0) 100%);
border-radius: 0px 0px 0px 0px;
}
.home-head-text {
color: #009fd4;
margin-top: 48rpx;
font-size: 40rpx;
font-weight: bold;
}
.home-input{
padding: 48rpx 30rpx 0 30rpx;
font-size: 32rpx;
color: #181818;
}
.phone_input{
margin-top: 32rpx;
.phone_btn{
background: #1170FF;
border-radius: 10rpx;
margin-right: 20rpx;
padding: 14rpx 35rpx;
color: #fff;
font-size: 28rpx;
font-weight: bold;
}
::v-deep.wd-input__value{
background: #EDEDED;
border-radius: 10rpx;
}
::v-deep.wd-input.is-no-border .wd-input__inner{
height: 100rpx;
}
}
.home-list{
margin-top: 76rpx;
padding: 0 30rpx;
.list_title{
font-size: 32rpx;
color: #181818;
font-weight: bold;
}
.list_main{
margin-top: 24rpx;
.list_item{
// width: 689px;
// height: 260px;
padding: 18rpx 23rpx;
background: #EEF4F5;
box-shadow: 0px 4rpx 20rpx 0px #D0D0D0;
border-radius: 10rpx 10rpx 10rpx 10rpx;
border: 1px solid #D5ECF0;
& + .list_item {
margin-top: 40rpx;
}
.order{
justify-content: space-between;
}
.btn{
background: #1170FF;
border-radius: 10rpx;
padding: 8rpx 27rpx;
font-size: 24rpx;
color: #fff;
}
.id{
font-size: 30rpx;
color: #181818;
font-weight: bold;
}
.stroke{
margin-top: 20rpx;
.stroke_lable{
font-size: 30rpx;
color: #181818;
font-weight: bold;
}
.stroke_desc{
font-size: 30rpx;
color: #181818;
}
}
}
}
.content{
margin-top: 24rpx;
justify-content: space-between;
.content_item{
.title{
font-size: 30rpx;
color: #181818;
font-weight: bold;
}
.desc{
margin-top: 14rpx;
font-size: 24rpx;
}
}
}
}
</style>

View File

@ -0,0 +1,176 @@
<template>
<view class="home-head" :style="{ paddingTop: safeAreaInsets?.top + 'px' }">
<view class="nav">
<wd-icon @click='onBack' name="thin-arrow-left" size="35rpx"></wd-icon>
<text class='nav_title'>旅游度假 预约出行系统</text>
</view>
<view class="main">
<view class="main-item txt">
<view class="main-title">下单行程</view>
<view class="main-desc">欧洲12天纯玩</view>
</view>
<view class="main-item">
<view class="main-title txt">查看详细行程</view>
<view class="flex items-center main_pdf flex-wrap">
<view class="main-desc pdf overflow">出境旅游合同.pdf</view>
</view>
</view>
<view class="main-item">
<view class="main-title txt">查看旅游合同</view>
<view class="flex items-center main_pdf flex-wrap">
<view class="main-desc pdf overflow">出境旅游合同.pdf</view>
<view class="main-desc pdf overflow">出境旅游合同.pdf</view>
<view class="main-desc pdf overflow">出境旅游合同.pdf</view>
<view class="main-desc pdf overflow">出境旅游合同.pdf</view>
</view>
</view>
<view class="main-item">
<view class="main-title txt">专属客服管家</view>
<view class="main_content flex">
<view class="main_content_left">
<view class="list">
<text class="lable">姓名:</text>
<text class="box">李达</text>
</view>
<view class="list">
<text class="lable">手机号:</text>
<text class="box">13355558888</text>
</view>
<view class="list">
<text class="lable">微信号:</text>
<text class="box">13355558888</text>
</view>
<view class="list">
<text class="lable">职位:</text>
<text class="box">金牌管家</text>
</view>
<view class="list">
<text class="lable">服务承诺:</text>
<text class="box">顾客是上帝</text>
</view>
</view>
<view class="main_content_right">
<image src="../../static/home/user.png" mode=""></image>
</view>
</view>
<view class="btn" @click="handleAppointment"> 预约出行 </view>
</view>
</view>
</view>
</template>
<script lang="ts" setup>
//
const { safeAreaInsets } = uni.getSystemInfoSync()
onLoad(() => {
console.log(safeAreaInsets)
})
const handleAppointment = ()=>{
uni.navigateTo({
url:'/pages/appointment-time/index'
})
}
const onBack = ()=>{
uni.navigateBack({ delta: 1 })
}
</script>
<style lang="scss" scoped>
.txt{
font-size: 30rpx;
font-weight: bold;
color: #181818;
}
.pdf{
color: #0095FF;
font-size: 24rpx;
font-weight: bold;
}
.overflow {
white-space: nowrap; /* 文本不换行 */
overflow: hidden; /* 隐藏超出的内容 */
text-overflow: ellipsis; /* 当文本溢出时显示省略号 */
}
.home-head {
width: 100%;
height: 574rpx;
background: linear-gradient(180deg, #92deeb 0%, rgba(216, 216, 216, 0) 100%);
border-radius: 0px 0px 0px 0px;
.nav{
padding: 16rpx 0 16rpx 20rpx;
.nav_title{
font-size: 36rpx;
color: #181818;
font-weight: bold;
margin-left: 75rpx;
}
}
.main{
margin: 54rpx 26rpx 0 26rpx;
background: #fff;
border-radius: 20rpx;
padding: 40rpx 30rpx;
.main_pdf{
.pdf{
flex:1;
flex-basis:24%;
margin-right: 58rpx;
margin-bottom: 20rpx;
}
}
}
.main-item {
& + .main-item {
margin-top: 40rpx;
}
.main-title{
margin-bottom: 24rpx;
}
.btn{
margin-top: 160rpx;
background: #1170FF;
border-radius: 50rpx;
padding: 20rpx 230rpx;
text-align: center;
color: #fff;
font-size: 32rpx;
}
}
.main_content{
background: #FFFAED;
border: 5rpx solid #F6E4B7;
padding: 20rpx 40rpx;
// margin-top: 12rpx;
.main_content_left{
.list{
width: 330rpx;
border-bottom: 1px solid #F6E4B7;
padding-bottom: 10rpx;
color: #181818;
font-size: 28rpx;
.lable{
font-weight: bold;
}
.box{
font-weight: 400;
margin-left: 20rpx;
}
}
}
.main_content_right{
margin-left: 75rpx;
image{
width: 156rpx;
height: 180rpx;
}
}
}
}
</style>

1
src/service/api/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './user'

View File

@ -0,0 +1,16 @@
import { jsonRequest } from '@/service/request'
interface IData {
b: string
a: string
}
export function fetchUpdateConfig() {
return jsonRequest.get<IData>({
url: 'xxxxxxxxxxxx/json',
})
}
// async () => {
// const { a, b } = await fetchUpdateConfig()
// }

View File

@ -0,0 +1,16 @@
import { apiResquest } from '@/service/request'
interface IUser {
name: string
age: number
}
export function fetchUserInfo() {
return apiResquest.post<IUser>({
url: 'xxxxxxxxxxxx/user',
})
}
// async () => {
// const { age, name } = await fetchUserInfo()
// }

1
src/service/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './api'

View File

@ -0,0 +1,25 @@
import { createRequest } from './request'
import { resultResponseInterceptor, statusResponseInterceptor, tokenRequestInterceptor } from './interceptors'
import { getServiceEnvConfig } from '@/config'
const { url, json } = getServiceEnvConfig(import.meta.env)
export const apiResquest = createRequest(
{
baseURL: url,
returnData(val) {
return val.data
},
},
{
requestInterceptors: [tokenRequestInterceptor],
responseInterceptors: [statusResponseInterceptor, resultResponseInterceptor],
})
export const jsonRequest = createRequest(
{
baseURL: json,
},
{
responseInterceptors: [statusResponseInterceptor],
})

View File

@ -0,0 +1,40 @@
import { ERROR_STATUS } from '@/config'
import { createError } from '@/utils'
/**
* token
*/
export const tokenRequestInterceptor: requestInterceptor = (requestConfig: RequestConfig) => {
requestConfig.header = {
...requestConfig.header,
token: 'xxxxxxxxxxxxx',
}
return requestConfig
}
/**
*
*/
export const statusResponseInterceptor: responseInterceptor = (result) => {
const { statusCode } = result
if (statusCode !== 200) {
throw createError(ERROR_STATUS[statusCode])
}
return result
}
/**
*
*/
export const resultResponseInterceptor: responseInterceptor = (result) => {
const resultData = result.data as Result<string>
if (resultData.success === 'false') {
throw createError(resultData.msg)
}
return result
}

View File

@ -0,0 +1,98 @@
import { invokeArrayFns } from '@meoc/utils'
import { DEFAULT_REQUEST_ERROR_MSG, REQUEST_TIMEOUT } from '@/config'
import { getErrorMsg, hideLoading, showErrorModal, showLoading, showToast } from '@/utils'
let loadingCount = 0
/**
*
* @param baseRequestConfig -
* @param interceptorConfig -
*/
export function createRequest(baseRequestConfig: RequestConfig, interceptorConfig?: InterceptorConfig) {
const { requestInterceptors, responseInterceptors } = interceptorConfig || {}
function request<T>(requestConfig: RequestConfig) {
// 合并请求配置
requestConfig = {
...baseRequestConfig,
...requestConfig,
}
// 请求拦截器
if (requestInterceptors) {
requestConfig = invokeArrayFns(requestInterceptors, requestConfig)
}
// 设置默认值
const { baseURL = '', loading = true, method = 'POST', showErr = true, errMsg = '', successMsg, url, data, timeout = REQUEST_TIMEOUT, header, returnData = val => val } = requestConfig
// 显示loading
if (loading) {
loadingCount++
showLoading()
}
return new Promise<T>((resolve, reject) => {
uni.request({
url: `${baseURL}${url}`,
method,
header,
timeout,
data,
success(result) {
try {
// 响应拦截器
result = invokeArrayFns(responseInterceptors as Function[], result)
} catch (error) {
// 自定义错误优先
const msg = errMsg || getErrorMsg(error)
if (showErr) {
showErrorModal(msg)
}
reject(msg)
return
}
// 自定义返回数据
resolve(returnData(result.data) as T)
// 显示成功toast
if (successMsg) {
showToast({
icon: 'success',
title: successMsg,
})
}
},
fail(err) {
// 失败弹窗
const msg = `${DEFAULT_REQUEST_ERROR_MSG}-${getErrorMsg(err)}`
showErrorModal(msg)
reject(msg)
},
complete() {
if (loadingCount !== 0) {
--loadingCount === 0 && hideLoading()
}
},
})
})
}
function post<T>(requestConfig: RequestConfig) {
return request<T>({ ...requestConfig, method: 'POST' })
}
function get<T>(requestConfig: RequestConfig) {
return request<T>({ ...requestConfig, method: 'GET' })
}
return {
request,
post,
get,
}
}

BIN
src/static/home/meituan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
src/static/home/quan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

BIN
src/static/home/scuss.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
src/static/home/tip.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 955 B

BIN
src/static/home/user.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

BIN
src/static/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

33
src/static/logo.svg Normal file
View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="_图层_2" data-name="图层 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 113.39 113.39">
<defs>
<style>
.cls-1 {
fill: none;
}
.cls-2 {
fill: #d14328;
}
.cls-3 {
fill: #2c8d3a;
}
</style>
</defs>
<g id="_图层_1-2" data-name="图层 1">
<g>
<rect class="cls-1" width="113.39" height="113.39" />
<g>
<path class="cls-3"
d="M86.31,11.34H25.08c-8.14,0-14.74,6.6-14.74,14.74v61.23c0,8.14,6.6,14.74,14.74,14.74h61.23c.12,0,.24-.02,.37-.02-9.76-.2-17.64-8.18-17.64-17.99,0-.56,.03-1.12,.08-1.67H34.1c-1.57,0-2.83-1.27-2.83-2.83V32.43c0-.78,.63-1.42,1.42-1.42h9.17c.78,0,1.42,.63,1.42,1.42v36.52c0,.78,.63,1.42,1.42,1.42h22.02c.78,0,1.42-.63,1.42-1.42V32.43c0-.78,.63-1.42,1.42-1.42h9.17c.78,0,1.42,.63,1.42,1.42v34.99c2.13-.89,4.47-1.39,6.92-1.39,5.66,0,10.7,2.63,14.01,6.72V26.08c0-8.14-6.6-14.74-14.74-14.74Z" />
<g>
<path class="cls-2"
d="M87.04,68.03c-8.83,0-16.01,7.18-16.01,16.01s7.18,16.01,16.01,16.01,16.01-7.18,16.01-16.01-7.18-16.01-16.01-16.01Zm-.27,24.84h-7.2v-3h1.18v-10.48h4.58v2.81h1.42c.84,0,1.46-.16,1.88-.48s.62-.87,.62-1.64c0-.69-.25-1.17-.74-1.45s-1.19-.42-2.09-.42h-6.84v-3h7.2c2.38,0,4.15,.38,5.31,1.15,1.16,.77,1.74,1.93,1.74,3.48,0,1.71-.83,2.93-2.5,3.64,1.07,.4,1.87,.95,2.39,1.65s.79,1.56,.79,2.58c0,3.44-2.58,5.16-7.73,5.16Z" />
<path class="cls-2"
d="M86.49,85.17h-1.16v4.7h1.8c.81,0,1.46-.18,1.94-.55s.72-.95,.72-1.73c0-.86-.25-1.48-.74-1.85s-1.35-.56-2.56-.56Z" />
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/static/tabbar/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

9
src/store/index.ts Normal file
View File

@ -0,0 +1,9 @@
import type { App } from 'vue'
import { createPinia } from 'pinia'
export function setupStore(app: App) {
const store = createPinia()
app.use(store)
}
export * from './modules'

View File

@ -0,0 +1,10 @@
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
actions: {
increment() {
this.count++
},
},
})

View File

@ -0,0 +1 @@
export * from './count'

17
src/typings/env.d.ts vendored Normal file
View File

@ -0,0 +1,17 @@
/**
*
* - dev: 开发环境
* - test: 测试环境
* - prod: 生产环境
*/
type ServiceEnvType = 'dev' | 'test' | 'prod'
/** 后台服务的环境配置 */
interface ServiceEnvConfig {
url: string
[key: string]: any
}
interface ImportMetaEnv {
readonly VITE_SERVICE_ENV?: ServiceEnvType;
}

11
src/typings/error.ts Normal file
View File

@ -0,0 +1,11 @@
/**
* (errMsg)
*/
export class IError extends Error {
errMsg: string
constructor(errMsg: string) {
super(errMsg)
this.errMsg = errMsg
}
}

66
src/typings/request.d.ts vendored Normal file
View File

@ -0,0 +1,66 @@
interface RequestConfig extends Partial<UniApp.RequestOptions>{
/**
* url前缀
*/
baseURL?: string
/**
* loading
* @default true
*/
loading?: boolean
/**
*
*/
successMsg?: string
/**
*
* @default true
*/
showErr?: boolean
/**
*
*/
errMsg?: string
/**
*
*/
returnData?: (val:any) => any
}
/**
*
*/
type responseInterceptor = (result: UniApp.RequestSuccessCallbackResult) => UniApp.RequestSuccessCallbackResult
/**
*
*/
type requestInterceptor = (config: RequestConfig) => RequestConfig
/**
*
*/
interface InterceptorConfig {
/**
*
*/
requestInterceptors?: requestInterceptor[]
/**
*
*/
responseInterceptors?: responseInterceptor[]
}
interface Result<T> {
success: 'true' | 'false'
data: T
msg: string
}

76
src/uni.scss Normal file
View File

@ -0,0 +1,76 @@
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场https://ext.dcloud.net.cn上很多三方插件均使用了这些样式变量
* 如果你是插件开发者建议你使用scss预处理并在插件代码中直接使用这些变量无需 import 这个文件方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者插件使用者你可以通过修改这些变量来定制自己的插件主题实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理你也可以直接在你的 scss 代码中使用如下变量同时无需 import 这个文件
*/
/* 颜色变量 */
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
/* 边框颜色 */
$uni-border-color:#c8c7cc;
/* 尺寸变量 */
/* 文字尺寸 */
$uni-font-size-sm:24rpx;
$uni-font-size-base:28rpx;
$uni-font-size-lg:32rpx;
/* 图片尺寸 */
$uni-img-size-sm:40rpx;
$uni-img-size-base:52rpx;
$uni-img-size-lg:80rpx;
/* Border Radius */
$uni-border-radius-sm: 4rpx;
$uni-border-radius-base: 6rpx;
$uni-border-radius-lg: 12rpx;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 10px;
$uni-spacing-row-base: 20rpx;
$uni-spacing-row-lg: 30rpx;
/* 垂直间距 */
$uni-spacing-col-sm: 8rpx;
$uni-spacing-col-base: 16rpx;
$uni-spacing-col-lg: 24rpx;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:40rpx;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:36rpx;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:30rpx;

22
src/utils/common/error.ts Normal file
View File

@ -0,0 +1,22 @@
import { isObject } from '@meoc/utils'
import { IError } from '@/typings/error'
/**
*
* @param errMsg -
*/
export function createError(errMsg: string) {
return new IError(errMsg)
}
/**
*
* @param err -
*/
export function getErrorMsg(err: Error | IError | UniApp.GeneralCallbackResult | unknown) {
if (isObject(err)) {
return 'errMsg' in err ? err.errMsg : err.message
}
return ''
}

View File

@ -0,0 +1,4 @@
export * from './error'
export * from './modal'
export * from './route'
export * from './storage'

61
src/utils/common/modal.ts Normal file
View File

@ -0,0 +1,61 @@
/**
* loading
* @param mask -
* @param title -
*/
export function showLoading(title = '加载中...', mask = true) {
uni.showLoading({
mask,
title,
})
}
export function showToast(options?: UniApp.ShowToastOptions) {
const { icon = 'none', mask = true } = options || {}
uni.showToast({
icon,
mask,
...options,
})
}
/**
* loading
*/
export function hideLoading() {
uni.hideLoading()
}
/**
*
*/
export function showModal(options: UniApp.ShowModalOptions) {
const { title = '提示', showCancel = true } = options
return new Promise((resolve, reject) => {
uni.showModal({
title,
showCancel,
success(res) {
if (res.confirm) {
resolve(res)
} else if (res.cancel) {
reject(res)
}
},
fail(err) {
reject(err)
},
...options,
})
})
}
/**
*
* @param errMsg -
*/
export function showErrorModal(errMsg: string) {
return showModal({ content: errMsg, showCancel: false })
}

105
src/utils/common/route.ts Normal file
View File

@ -0,0 +1,105 @@
import { params2Url } from '@meoc/utils'
interface IRoute {
/**
*
*/
type: ENUM_ROUTE_TYPE
/**
*
*/
url: string
/**
*
*/
params?: Record<string, any>
/**
* 退 uni.navigateBack
* @default 1
*/
delta?: number
}
/**
*
*/
enum ENUM_ROUTE_TYPE {
TO = 'navigateTo',
REDIRECT = 'redirectTo',
TAB = 'switchTab',
RELAUNCH = 'reLaunch',
BACK = 'navigateBack',
}
/**
*
*/
export function route({ type, url, params, delta = 1 }: IRoute) {
if (type !== ENUM_ROUTE_TYPE.BACK && params) {
url = `${url}?${params2Url(params)}`
}
switch (type) {
case ENUM_ROUTE_TYPE.TO:
uni.navigateTo({
url,
})
break
case ENUM_ROUTE_TYPE.REDIRECT:
uni.redirectTo({
url,
})
break
case ENUM_ROUTE_TYPE.TAB:
uni.switchTab({
url,
})
break
case ENUM_ROUTE_TYPE.RELAUNCH:
uni.reLaunch({
url,
})
break
case ENUM_ROUTE_TYPE.BACK:
uni.navigateBack({
delta,
})
break
default:
break
}
}
export function to(url: string, params?: Record<string, any>) {
route({
type: ENUM_ROUTE_TYPE.TO, url, params,
})
}
export function redirect(url: string, params?: Record<string, any>) {
route({
type: ENUM_ROUTE_TYPE.REDIRECT, url, params,
})
}
export function tabbar(url: string, params?: Record<string, any>) {
route({
type: ENUM_ROUTE_TYPE.TAB, url, params,
})
}
export function relaunch(url: string, params?: Record<string, any>) {
route({
type: ENUM_ROUTE_TYPE.RELAUNCH, url, params,
})
}
export function back(delta?: number) {
route({
type: ENUM_ROUTE_TYPE.BACK, delta, url: '',
})
}

View File

@ -0,0 +1,7 @@
export function setStorage(key: string, value: any) {
uni.setStorageSync(key, value)
}
export function getStorage(key: string) {
return uni.getStorageSync(key)
}

1
src/utils/index.ts Normal file
View File

@ -0,0 +1 @@
export * from './common'

29
tsconfig.json Normal file
View File

@ -0,0 +1,29 @@
{
"compilerOptions": {
"baseUrl": ".",
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"strict": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"types": [
"@dcloudio/types"
],
"paths": {
"@/*": ["src/*"]
}
},
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue",
"./auto-imports.d.ts"
],
"exclude": ["dist", "node_modules"]
}

28
unocss.config.ts Normal file
View File

@ -0,0 +1,28 @@
import presetWeapp from 'unocss-preset-weapp'
import { transformerAttributify, transformerClass } from 'unocss-preset-weapp/transformer'
import { defineConfig } from 'unocss'
export default defineConfig({
presets: [
// https://github.com/MellowCo/unocss-preset-weapp
presetWeapp(),
],
shortcuts: [
{
'border-base': 'border border-[#eee]',
'flex-center': 'flex justify-center items-center',
'text-c1': 'text-[#181818]',
'text-c2': 'text-[#333333]',
'text-c3': 'text-[#B2B2B2]',
'text-c4': 'text-[#CCCCCC]',
'bg': 'bg-[#f6f7fb]',
},
],
transformers: [
// https://github.com/MellowCo/unocss-preset-weapp/tree/main/src/transformer/transformerAttributify
transformerAttributify(),
// https://github.com/MellowCo/unocss-preset-weapp/tree/main/src/transformer/transformerClass
transformerClass(),
],
})

39
vite.config.ts Normal file
View File

@ -0,0 +1,39 @@
import path from 'path'
import { defineConfig } from 'vite'
import uni from '@dcloudio/vite-plugin-uni'
import Unocss from 'unocss/vite'
import AutoImport from 'unplugin-auto-import/vite'
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
alias: {
'@/': `${path.resolve(__dirname, 'src')}/`,
},
},
plugins: [
uni(),
// https://github.com/antfu/unocss
Unocss(),
// https://github.com/antfu/unplugin-auto-import
AutoImport({
imports: [
'vue',
'uni-app',
'pinia',
],
dts: true,
vueTemplate: true,
}),
],
css: {
preprocessorOptions: {
scss: {
api: "modern-compiler" // or 'modern'
}
}
},
})