Browse Source

feat: 初始化魔兽世界金币价格查询小程序项目

添加基础项目结构,包括页面、组件和配置文件
实现金币价格展示和价格走势图功能
添加筛选功能支持按区服和阵营筛选
master
Boom 1 month ago
parent
commit
5f8f6287f8
  1. 3
      .gitignore
  2. 27
      src/App.vue
  3. 11
      src/main.js
  4. 63
      src/manifest.json
  5. 34
      src/pages.json
  6. 215
      src/pages/gold-price/index.vue
  7. 23
      weixin/.gitignore
  8. 19
      weixin/README.md
  9. 81
      weixin/babel.config.js
  10. 37369
      weixin/package-lock.json
  11. 107
      weixin/package.json
  12. 27
      weixin/postcss.config.js
  13. 25
      weixin/public/index.html
  14. 11
      weixin/shims-uni.d.ts
  15. 4
      weixin/shims-vue.d.ts
  16. 17
      weixin/src/App.vue
  17. 12
      weixin/src/main.js
  18. 75
      weixin/src/manifest.json
  19. 38
      weixin/src/pages.json
  20. 623
      weixin/src/pages/chart/chart.vue
  21. 587
      weixin/src/pages/index/index.vue
  22. BIN
      weixin/src/static/logo.png
  23. 13
      weixin/src/uni.promisify.adaptor.js
  24. 76
      weixin/src/uni.scss

3
.gitignore vendored

@ -19,7 +19,8 @@ dmypy.json
.pyre/
.pytype/
*.so
node_modules/
weixin/node_modules
# Editor directories and files
.vscode/
.idea/

27
src/App.vue

@ -0,0 +1,27 @@
<template>
<div>
<router-view />
</div>
</template>
<script>
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style>
/* 全局样式 */
page {
background-color: #f5f5f5;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
}
</style>

11
src/main.js

@ -0,0 +1,11 @@
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()

63
src/manifest.json

@ -0,0 +1,63 @@
{
"name": "魔兽世界金币价格查询",
"appid": "",
"description": "魔兽世界各区金币价格查询小程序",
"versionName": "1.0.0",
"versionCode": 1,
"transformPx": true,
"mp-weixin": {
"appid": "",
"setting": {
"urlCheck": false,
"es6": true,
"enhance": true,
"postcss": true,
"preloadBackgroundData": false,
"minified": true,
"newFeature": false,
"coverView": true,
"nodeModules": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"scopeDataCheck": false,
"uglifyFileName": true,
"checkInvalidKey": true,
"checkSiteMap": true,
"uploadWithSourceMap": true,
"compileHotReLoad": false,
"lazyloadPlaceholderEnable": false,
"useMultiFrameRuntime": true,
"useApiHook": true,
"useApiHostProcess": true,
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"enableEngineNative": false,
"packNpmManually": false,
"packNpmRelationList": [],
"minifyWXSS": true,
"minifyWXML": true,
"showES6CompileOption": false,
"useIsolateContext": true,
"useCompilerV2": true,
"userConfirmedUseCompilerV2": true
},
"usingComponents": true,
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将用于获取附近的金币价格"
}
}
},
"quickapp": {},
"h5": {
"devServer": {
"port": 8080,
"disableHostCheck": true
},
"title": "魔兽世界金币价格查询",
"domain": ""
}
}

34
src/pages.json

@ -0,0 +1,34 @@
{
"pages": [
{
"path": "pages/gold-price/index",
"style": {
"navigationBarTitleText": "魔兽世界金币价格查询",
"navigationBarBackgroundColor": "#1989fa",
"navigationBarTextStyle": "white",
"enablePullDownRefresh": true
}
}
],
"globalStyle": {
"navigationBarBackgroundColor": "#1989fa",
"navigationBarTextStyle": "white",
"navigationBarTitleText": "魔兽世界金币价格查询",
"backgroundColor": "#F8F8F8"
},
"uniIdRouter": {},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/gold-price/index",
"iconPath": "static/icon_home.png",
"selectedIconPath": "static/icon_home_selected.png",
"text": "金币价格"
}
]
}
}

215
src/pages/gold-price/index.vue

@ -0,0 +1,215 @@
<template>
<view class="container">
<view class="header">
<text class="title">魔兽世界金币价格查询</text>
</view>
<view class="content">
<!-- 铁血1区 -->
<view class="server-section">
<view class="server-title">
<text>铁血1区</text>
</view>
<view class="faction-section">
<view class="faction-title">
<text>联盟</text>
</view>
<view class="price-table">
<view class="table-header">
<view class="table-cell">排名</view>
<view class="table-cell">价格</view>
<view class="table-cell">数量</view>
</view>
<view class="table-row" v-for="(price, index) in alliancePrices1" :key="index">
<view class="table-cell">{{ index + 1 }}</view>
<view class="table-cell">{{ price.price }}</view>
<view class="table-cell">{{ price.amount }}</view>
</view>
</view>
</view>
<view class="faction-section">
<view class="faction-title">
<text>部落</text>
</view>
<view class="price-table">
<view class="table-header">
<view class="table-cell">排名</view>
<view class="table-cell">价格</view>
<view class="table-cell">数量</view>
</view>
<view class="table-row" v-for="(price, index) in hordePrices1" :key="index">
<view class="table-cell">{{ index + 1 }}</view>
<view class="table-cell">{{ price.price }}</view>
<view class="table-cell">{{ price.amount }}</view>
</view>
</view>
</view>
</view>
<!-- 铁血2区 -->
<view class="server-section">
<view class="server-title">
<text>铁血2区</text>
</view>
<view class="faction-section">
<view class="faction-title">
<text>联盟</text>
</view>
<view class="price-table">
<view class="table-header">
<view class="table-cell">排名</view>
<view class="table-cell">价格</view>
<view class="table-cell">数量</view>
</view>
<view class="table-row" v-for="(price, index) in alliancePrices2" :key="index">
<view class="table-cell">{{ index + 1 }}</view>
<view class="table-cell">{{ price.price }}</view>
<view class="table-cell">{{ price.amount }}</view>
</view>
</view>
</view>
<view class="faction-section">
<view class="faction-title">
<text>部落</text>
</view>
<view class="price-table">
<view class="table-header">
<view class="table-cell">排名</view>
<view class="table-cell">价格</view>
<view class="table-cell">数量</view>
</view>
<view class="table-row" v-for="(price, index) in hordePrices2" :key="index">
<view class="table-cell">{{ index + 1 }}</view>
<view class="table-cell">{{ price.price }}</view>
<view class="table-cell">{{ price.amount }}</view>
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
//
alliancePrices1: [
{ price: '0.012元/金', amount: '100,000' },
{ price: '0.013元/金', amount: '50,000' },
{ price: '0.014元/金', amount: '20,000' }
],
hordePrices1: [
{ price: '0.011元/金', amount: '150,000' },
{ price: '0.012元/金', amount: '80,000' },
{ price: '0.013元/金', amount: '30,000' }
],
alliancePrices2: [
{ price: '0.015元/金', amount: '70,000' },
{ price: '0.016元/金', amount: '40,000' },
{ price: '0.017元/金', amount: '15,000' }
],
hordePrices2: [
{ price: '0.014元/金', amount: '90,000' },
{ price: '0.015元/金', amount: '50,000' },
{ price: '0.016元/金', amount: '25,000' }
]
}
},
onLoad() {
//
this.loadPriceData()
},
methods: {
loadPriceData() {
//
console.log('加载价格数据...')
// axiosuni.request
}
}
}
</script>
<style scoped>
.container {
min-height: 100vh;
background-color: #f5f5f5;
}
.header {
background-color: #1989fa;
color: white;
padding: 20rpx;
text-align: center;
}
.title {
font-size: 36rpx;
font-weight: bold;
}
.content {
padding: 20rpx;
}
.server-section {
background-color: white;
border-radius: 10rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
.server-title {
font-size: 32rpx;
font-weight: bold;
margin-bottom: 20rpx;
color: #333;
border-bottom: 2rpx solid #eee;
padding-bottom: 10rpx;
}
.faction-section {
margin-bottom: 20rpx;
}
.faction-title {
font-size: 28rpx;
font-weight: bold;
margin-bottom: 10rpx;
color: #666;
}
.price-table {
border-radius: 5rpx;
overflow: hidden;
}
.table-header {
display: flex;
background-color: #f0f0f0;
font-weight: bold;
border-bottom: 2rpx solid #eee;
}
.table-row {
display: flex;
border-bottom: 1rpx solid #f0f0f0;
}
.table-cell {
flex: 1;
padding: 15rpx;
text-align: center;
font-size: 24rpx;
}
.table-row:last-child {
border-bottom: none;
}
</style>

23
weixin/.gitignore vendored

@ -0,0 +1,23 @@
.DS_Store
node_modules/
unpackage/
dist/
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Editor directories and files
.project
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw*

19
weixin/README.md

@ -0,0 +1,19 @@
# weixin
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

81
weixin/babel.config.js

@ -0,0 +1,81 @@
const webpack = require('webpack')
const plugins = []
if (process.env.UNI_OPT_TREESHAKINGNG) {
plugins.push(require('@dcloudio/vue-cli-plugin-uni-optimize/packages/babel-plugin-uni-api/index.js'))
}
if (
(
process.env.UNI_PLATFORM === 'app-plus' &&
process.env.UNI_USING_V8
) ||
(
process.env.UNI_PLATFORM === 'h5' &&
process.env.UNI_H5_BROWSER === 'builtin'
)
) {
const path = require('path')
const isWin = /^win/.test(process.platform)
const normalizePath = path => (isWin ? path.replace(/\\/g, '/') : path)
const input = normalizePath(process.env.UNI_INPUT_DIR)
try {
plugins.push([
require('@dcloudio/vue-cli-plugin-hbuilderx/packages/babel-plugin-console'),
{
file (file) {
file = normalizePath(file)
if (file.indexOf(input) === 0) {
return path.relative(input, file)
}
return false
}
}
])
} catch (e) { }
}
process.UNI_LIBRARIES = process.UNI_LIBRARIES || ['@dcloudio/uni-ui']
process.UNI_LIBRARIES.forEach(libraryName => {
plugins.push([
'import',
{
'libraryName': libraryName,
'customName': (name) => {
return `${libraryName}/lib/${name}/${name}`
}
}
])
})
if (process.env.UNI_PLATFORM !== 'h5') {
plugins.push('@babel/plugin-transform-runtime')
}
const config = {
presets: [
[
'@vue/app',
{
modules: webpack.version[0] > 4 ? 'auto' : 'commonjs',
useBuiltIns: process.env.UNI_PLATFORM === 'h5' ? 'usage' : 'entry'
}
]
],
plugins
}
const UNI_H5_TEST = '**/@dcloudio/uni-h5/dist/index.umd.min.js'
if (process.env.NODE_ENV === 'production') {
config.overrides = [{
test: UNI_H5_TEST,
compact: true,
}]
} else {
config.ignore = [UNI_H5_TEST]
}
module.exports = config

37369
weixin/package-lock.json generated

File diff suppressed because it is too large Load Diff

107
weixin/package.json

@ -0,0 +1,107 @@
{
"name": "weixin",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "npm run dev:h5",
"build": "npm run build:h5",
"build:app-plus": "cross-env NODE_ENV=production UNI_PLATFORM=app-plus vue-cli-service uni-build",
"build:custom": "cross-env NODE_ENV=production uniapp-cli custom",
"build:h5": "cross-env NODE_ENV=production UNI_PLATFORM=h5 vue-cli-service uni-build",
"build:mp-360": "cross-env NODE_ENV=production UNI_PLATFORM=mp-360 vue-cli-service uni-build",
"build:mp-alipay": "cross-env NODE_ENV=production UNI_PLATFORM=mp-alipay vue-cli-service uni-build",
"build:mp-baidu": "cross-env NODE_ENV=production UNI_PLATFORM=mp-baidu vue-cli-service uni-build",
"build:mp-harmony": "cross-env NODE_ENV=production UNI_PLATFORM=mp-harmony vue-cli-service uni-build",
"build:mp-jd": "cross-env NODE_ENV=production UNI_PLATFORM=mp-jd vue-cli-service uni-build",
"build:mp-kuaishou": "cross-env NODE_ENV=production UNI_PLATFORM=mp-kuaishou vue-cli-service uni-build",
"build:mp-lark": "cross-env NODE_ENV=production UNI_PLATFORM=mp-lark vue-cli-service uni-build",
"build:mp-qq": "cross-env NODE_ENV=production UNI_PLATFORM=mp-qq vue-cli-service uni-build",
"build:mp-toutiao": "cross-env NODE_ENV=production UNI_PLATFORM=mp-toutiao vue-cli-service uni-build",
"build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",
"build:mp-xhs": "cross-env NODE_ENV=production UNI_PLATFORM=mp-xhs vue-cli-service uni-build",
"build:quickapp-native": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-native vue-cli-service uni-build",
"build:quickapp-webview": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview vue-cli-service uni-build",
"build:quickapp-webview-huawei": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build",
"build:quickapp-webview-union": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build",
"dev:app-plus": "cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch",
"dev:custom": "cross-env NODE_ENV=development uniapp-cli custom",
"dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve",
"dev:mp-360": "cross-env NODE_ENV=development UNI_PLATFORM=mp-360 vue-cli-service uni-build --watch",
"dev:mp-alipay": "cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch",
"dev:mp-baidu": "cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch",
"dev:mp-harmony": "cross-env NODE_ENV=development UNI_PLATFORM=mp-harmony vue-cli-service uni-build --watch",
"dev:mp-jd": "cross-env NODE_ENV=development UNI_PLATFORM=mp-jd vue-cli-service uni-build --watch",
"dev:mp-kuaishou": "cross-env NODE_ENV=development UNI_PLATFORM=mp-kuaishou vue-cli-service uni-build --watch",
"dev:mp-lark": "cross-env NODE_ENV=development UNI_PLATFORM=mp-lark vue-cli-service uni-build --watch",
"dev:mp-qq": "cross-env NODE_ENV=development UNI_PLATFORM=mp-qq vue-cli-service uni-build --watch",
"dev:mp-toutiao": "cross-env NODE_ENV=development UNI_PLATFORM=mp-toutiao vue-cli-service uni-build --watch",
"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch",
"dev:mp-xhs": "cross-env NODE_ENV=development UNI_PLATFORM=mp-xhs vue-cli-service uni-build --watch",
"dev:quickapp-native": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-native vue-cli-service uni-build --watch",
"dev:quickapp-webview": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview vue-cli-service uni-build --watch",
"dev:quickapp-webview-huawei": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build --watch",
"dev:quickapp-webview-union": "cross-env NODE_ENV=development UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build --watch",
"info": "node node_modules/@dcloudio/vue-cli-plugin-uni/commands/info.js",
"serve:quickapp-native": "node node_modules/@dcloudio/uni-quickapp-native/bin/serve.js",
"test:android": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=android jest -i",
"test:h5": "cross-env UNI_PLATFORM=h5 jest -i",
"test:ios": "cross-env UNI_PLATFORM=app-plus UNI_OS_NAME=ios jest -i",
"test:mp-baidu": "cross-env UNI_PLATFORM=mp-baidu jest -i",
"test:mp-weixin": "cross-env UNI_PLATFORM=mp-weixin jest -i"
},
"dependencies": {
"@dcloudio/uni-app": "^2.0.2-4080720251210002",
"@dcloudio/uni-app-plus": "^2.0.2-4080720251210002",
"@dcloudio/uni-h5": "^2.0.2-4080720251210002",
"@dcloudio/uni-i18n": "^2.0.2-4080720251210002",
"@dcloudio/uni-mp-360": "^2.0.2-4080720251210002",
"@dcloudio/uni-mp-alipay": "^2.0.2-4080720251210002",
"@dcloudio/uni-mp-baidu": "^2.0.2-4080720251210002",
"@dcloudio/uni-mp-harmony": "^2.0.2-4080720251210002",
"@dcloudio/uni-mp-jd": "^2.0.2-4080720251210002",
"@dcloudio/uni-mp-kuaishou": "^2.0.2-4080720251210002",
"@dcloudio/uni-mp-lark": "^2.0.2-4080720251210002",
"@dcloudio/uni-mp-qq": "^2.0.2-4080720251210002",
"@dcloudio/uni-mp-toutiao": "^2.0.2-4080720251210002",
"@dcloudio/uni-mp-vue": "^2.0.2-4080720251210002",
"@dcloudio/uni-mp-weixin": "^2.0.2-4080720251210002",
"@dcloudio/uni-mp-xhs": "^2.0.2-4080720251210002",
"@dcloudio/uni-quickapp-native": "^2.0.2-4080720251210002",
"@dcloudio/uni-quickapp-webview": "^2.0.2-4080720251210002",
"@dcloudio/uni-stacktracey": "^2.0.2-4080720251210002",
"@dcloudio/uni-stat": "^2.0.2-4080720251210002",
"@vue/shared": "^3.0.0",
"core-js": "^3.8.3",
"flyio": "^0.6.2",
"vue": ">= 2.6.14 < 2.7",
"vuex": "^3.2.0"
},
"devDependencies": {
"@dcloudio/types": "^3.3.2",
"@dcloudio/uni-automator": "^2.0.2-4080720251210002",
"@dcloudio/uni-cli-i18n": "^2.0.2-4080720251210002",
"@dcloudio/uni-cli-shared": "^2.0.2-4080720251210002",
"@dcloudio/uni-helper-json": "*",
"@dcloudio/uni-migration": "^2.0.2-4080720251210002",
"@dcloudio/uni-template-compiler": "^2.0.2-4080720251210002",
"@dcloudio/vue-cli-plugin-hbuilderx": "^2.0.2-4080720251210002",
"@dcloudio/vue-cli-plugin-uni": "^2.0.2-4080720251210002",
"@dcloudio/vue-cli-plugin-uni-optimize": "^2.0.2-4080720251210002",
"@dcloudio/webpack-uni-mp-loader": "^2.0.2-4080720251210002",
"@dcloudio/webpack-uni-pages-loader": "^2.0.2-4080720251210002",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"babel-plugin-import": "^1.11.0",
"cross-env": "^7.0.2",
"jest": "^25.4.0",
"postcss-comment": "^2.0.0",
"vue-template-compiler": ">= 2.6.14 < 2.7"
},
"browserslist": [
"Android >= 4.4",
"ios >= 9"
],
"uni-app": {
"scripts": {}
}
}

27
weixin/postcss.config.js

@ -0,0 +1,27 @@
const path = require('path')
const webpack = require('webpack')
const config = {
parser: require('postcss-comment'),
plugins: [
require('postcss-import')({
resolve (id, basedir, importOptions) {
if (id.startsWith('~@/')) {
return path.resolve(process.env.UNI_INPUT_DIR, id.substr(3))
} else if (id.startsWith('@/')) {
return path.resolve(process.env.UNI_INPUT_DIR, id.substr(2))
} else if (id.startsWith('/') && !id.startsWith('//')) {
return path.resolve(process.env.UNI_INPUT_DIR, id.substr(1))
}
return id
}
}),
require('autoprefixer')({
remove: process.env.UNI_PLATFORM !== 'h5'
}),
require('@dcloudio/vue-cli-plugin-uni/packages/postcss')
]
}
if (webpack.version[0] > 4) {
delete config.parser
}
module.exports = config

25
weixin/public/index.html

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>
<%= htmlWebpackPlugin.options.title %>
</title>
<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>
<link rel="stylesheet" href="<%= BASE_URL %>static/index.<%= VUE_APP_INDEX_CSS_HASH %>.css" />
</head>
<body>
<noscript>
<strong>Please enable JavaScript to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

11
weixin/shims-uni.d.ts vendored

@ -0,0 +1,11 @@
/// <reference types='@dcloudio/types' />
import Vue from 'vue'
declare module "vue/types/options" {
type Hooks = App.AppInstance & Page.PageInstance;
interface ComponentOptions<V extends Vue> extends Hooks {
/**
*
*/
mpType?: string;
}
}

4
weixin/shims-vue.d.ts vendored

@ -0,0 +1,4 @@
declare module "*.vue" {
import Vue from 'vue'
export default Vue
}

17
weixin/src/App.vue

@ -0,0 +1,17 @@
<script>
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style>
/*每个页面公共css */
</style>

12
weixin/src/main.js

@ -0,0 +1,12 @@
import Vue from 'vue'
import App from './App'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()

75
weixin/src/manifest.json

@ -0,0 +1,75 @@
{
"name": "魔兽世界金币价格查询",
"appid": "",
"description": "魔兽世界金币价格查询小程序",
"versionName": "1.0.0",
"versionCode": "100",
"transformPx": false,
"app-plus": { /* 5+App */
"usingComponents": true,
"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.READ_CONTACTS\"/>",
"<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.WRITE_CONTACTS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
"<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.CALL_PHONE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
"ios": { /* ios */
},
"sdkConfigs": { /* SDK */
}
}
},
"quickapp": { /* */
},
"mp-weixin": { /* */
"appid": "",
"setting": {
"urlCheck": false
},
"usingComponents": true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"mp-qq" : {
"usingComponents" : true
}
}

38
weixin/src/pages.json

@ -0,0 +1,38 @@
{
"pages": [ //pageshttps://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "当前金价"
}
},
{
"path": "pages/chart/chart",
"style": {
"navigationBarTitleText": "价格走势图"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "魔兽世界金币价格查询",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"tabBar": {
"color": "#666666",
"selectedColor": "#1989fa",
"backgroundColor": "#ffffff",
"borderStyle": "black",
"list": [
{
"pagePath": "pages/index/index",
"text": "当前金价"
},
{
"pagePath": "pages/chart/chart",
"text": "价格走势图"
}
]
}
}

623
weixin/src/pages/chart/chart.vue

@ -0,0 +1,623 @@
<template>
<view class="chart-container">
<text class="title">价格走势图</text>
<!-- 悬浮筛选按钮 -->
<view class="floating-filter-btn" @click="showFilter = true">
<text>筛选</text>
</view>
<!-- 筛选面板 -->
<view class="filter-panel" v-if="showFilter">
<view class="filter-header">
<text class="filter-title">选择关注的区服和阵营</text>
<view class="close-btn" @click="showFilter = false">关闭</view>
</view>
<view class="filter-content">
<checkbox-group @change="handleCheckboxChange">
<view class="server-group" v-for="server in allServers" :key="server.id">
<view class="server-title">{{ server.name }}</view>
<view class="faction-items">
<view class="filter-item" v-for="faction in server.factions" :key="faction.id">
<checkbox :value="faction.id" :checked="selectedFactions.includes(faction.id)">
{{ faction.name }}
</checkbox>
</view>
</view>
</view>
</checkbox-group>
</view>
<view class="filter-footer">
<view class="cancel-btn" @click="showFilter = false">取消</view>
<view class="save-btn" @click="saveFilter">保存</view>
</view>
</view>
<view class="chart-header">
<!-- 时间筛选 -->
<view class="time-filter">
<view class="filter-item" :class="{ active: timeFilter === 'day' }" @click="timeFilter = 'day'">
<text></text>
</view>
<view class="filter-item" :class="{ active: timeFilter === 'hour' }" @click="timeFilter = 'hour'">
<text></text>
</view>
<view class="filter-item" :class="{ active: timeFilter === 'week' }" @click="timeFilter = 'week'">
<text></text>
</view>
</view>
</view>
<view class="chart-content">
<!-- 价格走势图区域 -->
<!-- 铁血1区 -->
<view v-if="isServerSelected('tx1')">
<view class="chart-item" v-if="isFactionSelected('tx1-alliance')">
<text class="chart-title">铁血1区 - 联盟</text>
<canvas canvas-id="tx1AllianceChart" class="chart-canvas"></canvas>
</view>
<view class="chart-item" v-if="isFactionSelected('tx1-horde')">
<text class="chart-title">铁血1区 - 部落</text>
<canvas canvas-id="tx1HordeChart" class="chart-canvas"></canvas>
</view>
</view>
<!-- 铁血2区 -->
<view v-if="isServerSelected('tx2')">
<view class="chart-item" v-if="isFactionSelected('tx2-alliance')">
<text class="chart-title">铁血2区 - 联盟</text>
<canvas canvas-id="tx2AllianceChart" class="chart-canvas"></canvas>
</view>
<view class="chart-item" v-if="isFactionSelected('tx2-horde')">
<text class="chart-title">铁血2区 - 部落</text>
<canvas canvas-id="tx2HordeChart" class="chart-canvas"></canvas>
</view>
</view>
<!-- 时光1区 -->
<view v-if="isServerSelected('sg1')">
<view class="chart-item" v-if="isFactionSelected('sg1-alliance')">
<text class="chart-title">时光1区 - 联盟</text>
<canvas canvas-id="sg1AllianceChart" class="chart-canvas"></canvas>
</view>
<view class="chart-item" v-if="isFactionSelected('sg1-horde')">
<text class="chart-title">时光1区 - 部落</text>
<canvas canvas-id="sg1HordeChart" class="chart-canvas"></canvas>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
timeFilter: 'day', // day, hour, week
showFilter: false,
//
allServers: [
{
id: 'tx1',
name: '铁血1区',
factions: [
{ id: 'tx1-alliance', name: '联盟', serverId: 'tx1' },
{ id: 'tx1-horde', name: '部落', serverId: 'tx1' }
]
},
{
id: 'tx2',
name: '铁血2区',
factions: [
{ id: 'tx2-alliance', name: '联盟', serverId: 'tx2' },
{ id: 'tx2-horde', name: '部落', serverId: 'tx2' }
]
},
{
id: 'sg1',
name: '时光1区',
factions: [
{ id: 'sg1-alliance', name: '联盟', serverId: 'sg1' },
{ id: 'sg1-horde', name: '部落', serverId: 'sg1' }
]
}
],
selectedFactions: [],
// /1000
chartData: {
tx1Alliance: [],
tx1Horde: [],
tx2Alliance: [],
tx2Horde: [],
sg1Alliance: [],
sg1Horde: []
}
};
},
onLoad() {
//
this.loadSelectedFactions();
//
this.generateMockData();
//
// DOMcanvas
},
onReady() {
// DOM
this.$nextTick(() => {
this.drawCharts();
});
},
watch: {
//
timeFilter: function() {
this.generateMockData();
this.$nextTick(() => {
this.drawCharts();
});
}
},
methods: {
//
loadSelectedFactions() {
const selected = uni.getStorageSync('selectedFactions');
if (selected && selected.length > 0) {
this.selectedFactions = selected;
} else {
//
this.selectedFactions = [];
this.allServers.forEach(server => {
server.factions.forEach(faction => {
this.selectedFactions.push(faction.id);
});
});
//
uni.setStorageSync('selectedFactions', this.selectedFactions);
}
},
// checkbox
handleCheckboxChange(e) {
this.selectedFactions = e.detail.value;
},
//
saveFilter() {
//
if (this.selectedFactions.length === 0) {
uni.showToast({
title: '请至少选择一个阵营',
icon: 'none'
});
return;
}
//
uni.setStorageSync('selectedFactions', this.selectedFactions);
uni.showToast({
title: '保存成功',
icon: 'success'
});
this.showFilter = false;
//
this.drawCharts();
},
//
isFactionSelected(factionId) {
return this.selectedFactions.includes(factionId);
},
//
isServerSelected(serverId) {
return this.allServers.some(server =>
server.id === serverId &&
server.factions.some(faction =>
this.selectedFactions.includes(faction.id)
)
);
},
//
generateMockData() {
const basePrice = 10;
const fluctuation = 2;
let dataCount = 24; //
let timeStep = 1; //
if (this.timeFilter === 'day') {
dataCount = 30; // 30
timeStep = 24; //
} else if (this.timeFilter === 'hour') {
dataCount = 24; // 24
timeStep = 1; //
} else if (this.timeFilter === 'week') {
dataCount = 12; // 12
timeStep = 168; //
}
//
this.chartData = {
tx1Alliance: this.generatePriceData(basePrice + 1, fluctuation, dataCount, timeStep),
tx1Horde: this.generatePriceData(basePrice + 0.5, fluctuation, dataCount, timeStep),
tx2Alliance: this.generatePriceData(basePrice + 2, fluctuation, dataCount, timeStep),
tx2Horde: this.generatePriceData(basePrice + 1.5, fluctuation, dataCount, timeStep),
sg1Alliance: this.generatePriceData(basePrice + 3, fluctuation, dataCount, timeStep),
sg1Horde: this.generatePriceData(basePrice + 2.5, fluctuation, dataCount, timeStep)
};
console.log('Generated mock data:', this.chartData);
},
//
generatePriceData(base, fluctuation, count, timeStep) {
const data = [];
const now = new Date();
for (let i = count - 1; i >= 0; i--) {
const time = new Date(now.getTime() - i * timeStep * 60 * 60 * 1000);
//
const price = base + (Math.random() - 0.5) * fluctuation;
data.push({
time: time,
price: parseFloat(price.toFixed(2))
});
}
return data;
},
//
drawCharts() {
//
if (this.isFactionSelected('tx1-alliance')) {
this.drawChart('tx1AllianceChart', this.chartData.tx1Alliance);
}
if (this.isFactionSelected('tx1-horde')) {
this.drawChart('tx1HordeChart', this.chartData.tx1Horde);
}
if (this.isFactionSelected('tx2-alliance')) {
this.drawChart('tx2AllianceChart', this.chartData.tx2Alliance);
}
if (this.isFactionSelected('tx2-horde')) {
this.drawChart('tx2HordeChart', this.chartData.tx2Horde);
}
if (this.isFactionSelected('sg1-alliance')) {
this.drawChart('sg1AllianceChart', this.chartData.sg1Alliance);
}
if (this.isFactionSelected('sg1-horde')) {
this.drawChart('sg1HordeChart', this.chartData.sg1Horde);
}
},
//
drawChart(canvasId, data) {
if (!data || data.length === 0) return;
const ctx = uni.createCanvasContext(canvasId, this);
// 使rpx
const canvasWidth = 350; //
const canvasHeight = 150; //
const padding = 25; //
//
const chartWidth = canvasWidth - 2 * padding;
const chartHeight = canvasHeight - 2 * padding;
//
const prices = data.map(item => item.price);
const minPrice = Math.min(...prices) - 0.5;
const maxPrice = Math.max(...prices) + 0.5;
const priceRange = maxPrice - minPrice;
//
const times = data.map(item => item.time);
const minTime = times[0];
const maxTime = times[times.length - 1];
const timeRange = maxTime - minTime;
//
this.drawAxes(ctx, padding, chartWidth, chartHeight, minPrice, maxPrice, data);
// 线
this.drawPriceLine(ctx, padding, chartWidth, chartHeight, data, minPrice, maxPrice, minTime, maxTime);
//
this.drawPricePoints(ctx, padding, chartWidth, chartHeight, data, minPrice, maxPrice, minTime, maxTime);
//
ctx.draw();
},
//
drawAxes(ctx, padding, chartWidth, chartHeight, minPrice, maxPrice, data) {
ctx.setStrokeStyle('#ccc');
ctx.setLineWidth(1);
// X
ctx.beginPath();
ctx.moveTo(padding, padding + chartHeight);
ctx.lineTo(padding + chartWidth, padding + chartHeight);
ctx.stroke();
// Y
ctx.beginPath();
ctx.moveTo(padding, padding);
ctx.lineTo(padding, padding + chartHeight);
ctx.stroke();
// Y
const yTicks = 5;
for (let i = 0; i <= yTicks; i++) {
const y = padding + (chartHeight / yTicks) * i;
const price = maxPrice - (maxPrice - minPrice) * (i / yTicks);
// 线
ctx.beginPath();
ctx.moveTo(padding - 3, y);
ctx.lineTo(padding, y);
ctx.stroke();
//
ctx.setFontSize(10);
ctx.setFillStyle('#666');
ctx.setTextAlign('right');
ctx.fillText(price.toFixed(1), padding - 5, y + 3);
}
// X
const xTicks = this.timeFilter === 'day' ? 6 : 5;
for (let i = 0; i <= xTicks; i++) {
const x = padding + (chartWidth / xTicks) * i;
const index = Math.round((data.length - 1) * (i / xTicks));
const time = data[index].time;
// 线
ctx.beginPath();
ctx.moveTo(x, padding + chartHeight);
ctx.lineTo(x, padding + chartHeight + 3);
ctx.stroke();
//
let timeLabel = '';
if (this.timeFilter === 'day') {
timeLabel = time.getDate() + '日';
} else if (this.timeFilter === 'hour') {
timeLabel = time.getHours() + '时';
} else if (this.timeFilter === 'week') {
timeLabel = '第' + Math.ceil((time.getDate() + time.getDay()) / 7) + '周';
}
//
ctx.setFontSize(10);
ctx.setFillStyle('#666');
ctx.setTextAlign('center');
ctx.fillText(timeLabel, x, padding + chartHeight + 15);
}
//
ctx.setFontSize(12);
ctx.setFillStyle('#333');
ctx.setTextAlign('center');
ctx.fillText('时间', padding + chartWidth / 2, padding + chartHeight + 30);
ctx.setTextAlign('right');
ctx.fillText('价格 (元/1000金)', padding - 20, padding + chartHeight / 2);
},
// 线
drawPriceLine(ctx, padding, chartWidth, chartHeight, data, minPrice, maxPrice, minTime, maxTime) {
ctx.setStrokeStyle('#1989fa');
ctx.setLineWidth(2);
ctx.beginPath();
data.forEach((item, index) => {
//
const x = padding + (chartWidth * (item.time - minTime)) / (maxTime - minTime);
const y = padding + chartHeight - (chartHeight * (item.price - minPrice)) / (maxPrice - minPrice);
if (index === 0) {
ctx.moveTo(x, y);
} else {
ctx.lineTo(x, y);
}
});
ctx.stroke();
},
//
drawPricePoints(ctx, padding, chartWidth, chartHeight, data, minPrice, maxPrice, minTime, maxTime) {
ctx.setFillStyle('#1989fa');
data.forEach(item => {
//
const x = padding + (chartWidth * (item.time - minTime)) / (maxTime - minTime);
const y = padding + chartHeight - (chartHeight * (item.price - minPrice)) / (maxPrice - minPrice);
//
ctx.beginPath();
ctx.arc(x, y, 3, 0, 2 * Math.PI);
ctx.fill();
});
}
}
};
</script>
<style scoped>
.chart-container {
min-height: 100vh;
background-color: #f5f5f5;
padding: 20rpx;
}
.chart-header {
text-align: center;
padding: 20rpx 0;
}
.title {
font-size: 36rpx;
font-weight: bold;
color: #333;
text-align: center;
margin-bottom: 20rpx;
display: block;
}
/* 悬浮筛选按钮样式 */
.floating-filter-btn {
position: fixed;
right: 30rpx;
top: 30rpx;
width: 80rpx;
height: 80rpx;
background-color: #1989fa;
color: #fff;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 24rpx;
box-shadow: 0 4rpx 10rpx rgba(25, 137, 250, 0.3);
z-index: 998;
}
/* 筛选面板样式 */
.filter-panel {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 999;
display: flex;
flex-direction: column;
}
.filter-header {
background-color: #fff;
padding: 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1rpx solid #eee;
}
.filter-title {
font-size: 32rpx;
font-weight: bold;
}
.close-btn {
background-color: #f0f0f0;
color: #333;
font-size: 24rpx;
padding: 10rpx 20rpx;
border-radius: 20rpx;
}
.filter-content {
background-color: #fff;
flex: 1;
padding: 20rpx;
overflow-y: auto;
}
.server-group {
margin-bottom: 30rpx;
}
.server-title {
font-weight: bold;
font-size: 30rpx;
margin-bottom: 15rpx;
padding-left: 20rpx;
}
.faction-items {
padding-left: 40rpx;
}
.filter-item {
margin-bottom: 15rpx;
font-size: 28rpx;
}
.filter-footer {
background-color: #fff;
padding: 20rpx;
display: flex;
justify-content: space-around;
border-top: 1rpx solid #eee;
}
.cancel-btn {
background-color: #f0f0f0;
color: #333;
font-size: 24rpx;
padding: 10rpx 40rpx;
border-radius: 20rpx;
}
.save-btn {
background-color: #1989fa;
color: #fff;
font-size: 24rpx;
padding: 10rpx 40rpx;
border-radius: 20rpx;
}
/* 时间筛选样式 */
.time-filter {
display: flex;
justify-content: center;
margin: 20rpx 0;
gap: 20rpx;
}
.filter-item {
padding: 10rpx 30rpx;
border-radius: 20rpx;
background-color: #f5f5f5;
font-size: 28rpx;
color: #666;
}
.filter-item.active {
background-color: #1989fa;
color: #fff;
}
.chart-content {
display: flex;
flex-direction: column;
gap: 30rpx;
}
.chart-item {
background-color: #fff;
border-radius: 10rpx;
padding: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
.chart-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
display: block;
}
/* 图表画布样式 */
.chart-canvas {
width: 700rpx;
height: 300rpx;
background-color: #fafafa;
border-radius: 8rpx;
}
</style>

587
weixin/src/pages/index/index.vue

@ -0,0 +1,587 @@
<template>
<view class="container">
<text class="title">魔兽世界金币价格查询</text>
<!-- 悬浮筛选按钮 -->
<view class="floating-filter-btn" @click="showFilter = true">
<text>筛选</text>
</view>
<!-- 筛选面板 -->
<view class="filter-panel" v-if="showFilter">
<view class="filter-header">
<text class="filter-title">选择关注的区服和阵营</text>
<button class="close-btn" @click="showFilter = false">关闭</button>
</view>
<view class="filter-content">
<checkbox-group @change="handleCheckboxChange">
<view class="server-group" v-for="server in allServers" :key="server.id">
<view class="server-title">{{ server.name }}</view>
<view class="faction-items">
<view class="filter-item" v-for="faction in server.factions" :key="faction.id">
<checkbox :value="faction.id" :checked="selectedFactions.includes(faction.id)">
{{ faction.name }}
</checkbox>
</view>
</view>
</view>
</checkbox-group>
</view>
<view class="filter-footer">
<button class="cancel-btn" @click="showFilter = false">取消</button>
<button class="save-btn" @click="saveFilter">保存</button>
</view>
</view>
<view class="content">
<!-- 铁血1区 -->
<view class="server-section" v-if="isServerSelected('tx1')">
<view class="server-title">
<text>铁血1区</text>
</view>
<view class="faction-section" v-if="isFactionSelected('tx1-alliance')">
<view class="faction-title">
<text>联盟</text>
</view>
<view class="price-table">
<view class="table-header">
<view class="table-cell">排名</view>
<view class="table-cell">价格</view>
<view class="table-cell">数量</view>
</view>
<view class="table-row" v-for="(price, index) in getDisplayPrices(alliancePrices1, 'tx1')" :key="index">
<view class="table-cell">{{ index + 1 }}</view>
<view class="table-cell">{{ price.price }}</view>
<view class="table-cell">{{ price.amount }}</view>
</view>
</view>
<view class="expand-btn" v-if="alliancePrices1.length > 3" @click="toggleExpand('tx1')">
{{ expandedServers['tx1'] ? '收起' : '展开更多' }}
</view>
</view>
<view class="faction-section" v-if="isFactionSelected('tx1-horde')">
<view class="faction-title">
<text>部落</text>
</view>
<view class="price-table">
<view class="table-header">
<view class="table-cell">排名</view>
<view class="table-cell">价格</view>
<view class="table-cell">数量</view>
</view>
<view class="table-row" v-for="(price, index) in getDisplayPrices(hordePrices1, 'tx1')" :key="index">
<view class="table-cell">{{ index + 1 }}</view>
<view class="table-cell">{{ price.price }}</view>
<view class="table-cell">{{ price.amount }}</view>
</view>
</view>
<view class="expand-btn" v-if="hordePrices1.length > 3" @click="toggleExpand('tx1')">
{{ expandedServers['tx1'] ? '收起' : '展开更多' }}
</view>
</view>
</view>
<!-- 铁血2区 -->
<view class="server-section" v-if="isServerSelected('tx2')">
<view class="server-title">
<text>铁血2区</text>
</view>
<view class="faction-section" v-if="isFactionSelected('tx2-alliance')">
<view class="faction-title">
<text>联盟</text>
</view>
<view class="price-table">
<view class="table-header">
<view class="table-cell">排名</view>
<view class="table-cell">价格</view>
<view class="table-cell">数量</view>
</view>
<view class="table-row" v-for="(price, index) in getDisplayPrices(alliancePrices2, 'tx2')" :key="index">
<view class="table-cell">{{ index + 1 }}</view>
<view class="table-cell">{{ price.price }}</view>
<view class="table-cell">{{ price.amount }}</view>
</view>
</view>
<view class="expand-btn" v-if="alliancePrices2.length > 3" @click="toggleExpand('tx2')">
{{ expandedServers['tx2'] ? '收起' : '展开更多' }}
</view>
</view>
<view class="faction-section" v-if="isFactionSelected('tx2-horde')">
<view class="faction-title">
<text>部落</text>
</view>
<view class="price-table">
<view class="table-header">
<view class="table-cell">排名</view>
<view class="table-cell">价格</view>
<view class="table-cell">数量</view>
</view>
<view class="table-row" v-for="(price, index) in getDisplayPrices(hordePrices2, 'tx2')" :key="index">
<view class="table-cell">{{ index + 1 }}</view>
<view class="table-cell">{{ price.price }}</view>
<view class="table-cell">{{ price.amount }}</view>
</view>
</view>
<view class="expand-btn" v-if="hordePrices2.length > 3" @click="toggleExpand('tx2')">
{{ expandedServers['tx2'] ? '收起' : '展开更多' }}
</view>
</view>
</view>
<!-- 时光1区 -->
<view class="server-section" v-if="isServerSelected('sg1')">
<view class="server-title">
<text>时光1区</text>
</view>
<view class="faction-section" v-if="isFactionSelected('sg1-alliance')">
<view class="faction-title">
<text>联盟</text>
</view>
<view class="price-table">
<view class="table-header">
<view class="table-cell">排名</view>
<view class="table-cell">价格</view>
<view class="table-cell">数量</view>
</view>
<view class="table-row" v-for="(price, index) in getDisplayPrices(alliancePricesSg, 'sg1')" :key="index">
<view class="table-cell">{{ index + 1 }}</view>
<view class="table-cell">{{ price.price }}</view>
<view class="table-cell">{{ price.amount }}</view>
</view>
</view>
<view class="expand-btn" v-if="alliancePricesSg.length > 3" @click="toggleExpand('sg1')">
{{ expandedServers['sg1'] ? '收起' : '展开更多' }}
</view>
</view>
<view class="faction-section" v-if="isFactionSelected('sg1-horde')">
<view class="faction-title">
<text>部落</text>
</view>
<view class="price-table">
<view class="table-header">
<view class="table-cell">排名</view>
<view class="table-cell">价格</view>
<view class="table-cell">数量</view>
</view>
<view class="table-row" v-for="(price, index) in getDisplayPrices(hordePricesSg, 'sg1')" :key="index">
<view class="table-cell">{{ index + 1 }}</view>
<view class="table-cell">{{ price.price }}</view>
<view class="table-cell">{{ price.amount }}</view>
</view>
</view>
<view class="expand-btn" v-if="hordePricesSg.length > 3" @click="toggleExpand('sg1')">
{{ expandedServers['sg1'] ? '收起' : '展开更多' }}
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
showFilter: false,
//
allServers: [
{
id: 'tx1',
name: '铁血1区',
factions: [
{ id: 'tx1-alliance', name: '联盟', serverId: 'tx1' },
{ id: 'tx1-horde', name: '部落', serverId: 'tx1' }
]
},
{
id: 'tx2',
name: '铁血2区',
factions: [
{ id: 'tx2-alliance', name: '联盟', serverId: 'tx2' },
{ id: 'tx2-horde', name: '部落', serverId: 'tx2' }
]
},
{
id: 'sg1',
name: '时光1区',
factions: [
{ id: 'sg1-alliance', name: '联盟', serverId: 'sg1' },
{ id: 'sg1-horde', name: '部落', serverId: 'sg1' }
]
}
],
selectedFactions: [],
expandedServers: {}, //
//
alliancePrices1: [
{ price: '0.022', amount: '1000000' },
{ price: '0.022', amount: '500000' },
{ price: '0.023', amount: '300000' },
{ price: '0.023', amount: '200000' },
{ price: '0.023', amount: '100000' },
{ price: '0.024', amount: '50000' },
{ price: '0.024', amount: '50000' },
{ price: '0.025', amount: '20000' },
{ price: '0.025', amount: '20000' },
{ price: '0.025', amount: '20000' }
],
hordePrices1: [
{ price: '0.021', amount: '2000000' },
{ price: '0.021', amount: '1000000' },
{ price: '0.021', amount: '500000' },
{ price: '0.022', amount: '300000' },
{ price: '0.022', amount: '200000' },
{ price: '0.022', amount: '100000' },
{ price: '0.023', amount: '50000' },
{ price: '0.023', amount: '50000' },
{ price: '0.023', amount: '50000' },
{ price: '0.024', amount: '20000' }
],
alliancePrices2: [
{ price: '0.020', amount: '1500000' },
{ price: '0.020', amount: '800000' },
{ price: '0.021', amount: '500000' },
{ price: '0.021', amount: '300000' },
{ price: '0.021', amount: '200000' },
{ price: '0.022', amount: '100000' },
{ price: '0.022', amount: '100000' },
{ price: '0.023', amount: '50000' },
{ price: '0.023', amount: '50000' },
{ price: '0.023', amount: '30000' }
],
hordePrices2: [
{ price: '0.019', amount: '2000000' },
{ price: '0.019', amount: '1000000' },
{ price: '0.020', amount: '500000' },
{ price: '0.020', amount: '300000' },
{ price: '0.020', amount: '200000' },
{ price: '0.021', amount: '100000' },
{ price: '0.021', amount: '80000' },
{ price: '0.021', amount: '50000' },
{ price: '0.022', amount: '50000' },
{ price: '0.022', amount: '30000' }
],
// 1
alliancePricesSg: [
{ price: '0.025', amount: '1200000' },
{ price: '0.025', amount: '600000' },
{ price: '0.026', amount: '400000' },
{ price: '0.026', amount: '300000' },
{ price: '0.026', amount: '200000' },
{ price: '0.027', amount: '150000' },
{ price: '0.027', amount: '100000' },
{ price: '0.027', amount: '80000' },
{ price: '0.028', amount: '50000' },
{ price: '0.028', amount: '50000' }
],
hordePricesSg: [
{ price: '0.023', amount: '1500000' },
{ price: '0.023', amount: '800000' },
{ price: '0.024', amount: '500000' },
{ price: '0.024', amount: '400000' },
{ price: '0.024', amount: '300000' },
{ price: '0.025', amount: '200000' },
{ price: '0.025', amount: '150000' },
{ price: '0.025', amount: '100000' },
{ price: '0.026', amount: '80000' },
{ price: '0.026', amount: '50000' }
]
}
},
onLoad() {
//
this.loadSelectedFactions()
//
this.loadPriceData()
},
methods: {
loadPriceData() {
//
console.log('加载价格数据...')
// axiosuni.request
},
//
loadSelectedFactions() {
const selected = uni.getStorageSync('selectedFactions')
if (selected && selected.length > 0) {
this.selectedFactions = selected
} else {
//
this.selectedFactions = []
this.allServers.forEach(server => {
server.factions.forEach(faction => {
this.selectedFactions.push(faction.id)
})
})
//
uni.setStorageSync('selectedFactions', this.selectedFactions)
}
},
// checkbox
handleCheckboxChange(e) {
this.selectedFactions = e.detail.value
},
//
saveFilter() {
//
if (this.selectedFactions.length === 0) {
uni.showToast({
title: '请至少选择一个阵营',
icon: 'none'
})
return
}
//
uni.setStorageSync('selectedFactions', this.selectedFactions)
// 5
this.selectedFactions.forEach(factionId => {
// ID
const serverId = factionId.split('-')[0]
// 使$setVue
this.$set(this.expandedServers, serverId, true)
})
uni.showToast({
title: '保存成功',
icon: 'success'
})
this.showFilter = false
},
//
toggleExpand(serverId) {
// 使$setVue
this.$set(this.expandedServers, serverId, !this.expandedServers[serverId])
},
//
getDisplayPrices(prices, serverId) {
const isExpanded = this.expandedServers[serverId] || false
return isExpanded ? prices.slice(0, 5) : prices.slice(0, 3)
},
//
isFactionSelected(factionId) {
return this.selectedFactions.includes(factionId)
},
//
isServerSelected(serverId) {
return this.allServers.some(server =>
server.id === serverId &&
server.factions.some(faction =>
this.selectedFactions.includes(faction.id)
)
)
}
}
}
</script>
<style scoped>
.container {
min-height: 100vh;
background-color: #f5f5f5;
padding: 20rpx;
}
.title {
font-size: 36rpx;
font-weight: bold;
color: #333;
text-align: center;
margin-bottom: 20rpx;
display: block;
}
/* 悬浮筛选按钮样式 */
.floating-filter-btn {
position: fixed;
right: 30rpx;
top: 30rpx;
width: 80rpx;
height: 80rpx;
background-color: #1989fa;
color: #fff;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
font-size: 24rpx;
box-shadow: 0 4rpx 10rpx rgba(25, 137, 250, 0.3);
z-index: 998;
}
/* 筛选面板样式 */
.filter-panel {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 999;
display: flex;
flex-direction: column;
}
.filter-header {
background-color: #fff;
padding: 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1rpx solid #eee;
}
.filter-title {
font-size: 32rpx;
font-weight: bold;
}
.close-btn {
background-color: #f0f0f0;
color: #333;
font-size: 24rpx;
padding: 10rpx 20rpx;
border-radius: 20rpx;
}
.filter-content {
background-color: #fff;
flex: 1;
padding: 20rpx;
overflow-y: auto;
}
.server-group {
margin-bottom: 30rpx;
}
.server-title {
font-weight: bold;
font-size: 30rpx;
margin-bottom: 15rpx;
padding-left: 20rpx;
}
.faction-items {
padding-left: 40rpx;
}
.filter-item {
margin-bottom: 15rpx;
font-size: 28rpx;
}
.filter-footer {
background-color: #fff;
padding: 20rpx;
display: flex;
justify-content: space-around;
border-top: 1rpx solid #eee;
}
.cancel-btn {
background-color: #f0f0f0;
color: #333;
font-size: 24rpx;
padding: 10rpx 40rpx;
border-radius: 20rpx;
}
.save-btn {
background-color: #1989fa;
color: #fff;
font-size: 24rpx;
padding: 10rpx 40rpx;
border-radius: 20rpx;
}
.title {
font-size: 36rpx;
font-weight: bold;
}
.content {
padding: 20rpx;
}
.server-section {
background-color: white;
border-radius: 10rpx;
padding: 20rpx;
margin-bottom: 20rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.1);
}
.server-title {
font-size: 32rpx;
font-weight: bold;
margin-bottom: 20rpx;
color: #333;
border-bottom: 2rpx solid #eee;
padding-bottom: 10rpx;
}
.faction-section {
margin-bottom: 20rpx;
}
.faction-title {
font-size: 28rpx;
font-weight: bold;
margin-bottom: 10rpx;
color: #666;
}
.price-table {
border-radius: 5rpx;
overflow: hidden;
}
.table-header {
display: flex;
background-color: #f0f0f0;
font-weight: bold;
border-bottom: 2rpx solid #eee;
}
.table-row {
display: flex;
border-bottom: 1rpx solid #f0f0f0;
}
.table-cell {
flex: 1;
padding: 15rpx;
text-align: center;
font-size: 24rpx;
}
.table-row:last-child {
border-bottom: none;
}
/* 展开按钮样式 */
.expand-btn {
text-align: center;
color: #1989fa;
font-size: 24rpx;
padding: 10rpx;
margin-top: 10rpx;
cursor: pointer;
}
</style>

BIN
weixin/src/static/logo.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

13
weixin/src/uni.promisify.adaptor.js

@ -0,0 +1,13 @@
uni.addInterceptor({
returnValue (res) {
if (!(!!res && (typeof res === "object" || typeof res === "function") && typeof res.then === "function")) {
return res;
}
return new Promise((resolve, reject) => {
if (!res) {
return resolve(res)
}
res.then((res) => res[0] ? reject(res[0]) : resolve(res[1]));
});
},
});

76
weixin/src/uni.scss

@ -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: #fff;
$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: 12px;
$uni-font-size-base: 14px;
$uni-font-size-lg: 16px;
/* 图片尺寸 */
$uni-img-size-sm: 20px;
$uni-img-size-base: 26px;
$uni-img-size-lg: 40px;
/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2c405a; // 文章标题颜色
$uni-font-size-title: 20px;
$uni-color-subtitle: #555; // 二级标题颜色
$uni-font-size-subtitle: 18px;
$uni-color-paragraph: #3f536e; // 文章段落颜色
$uni-font-size-paragraph: 15px;
Loading…
Cancel
Save