Merge remote-tracking branch 'origin/master'

# Conflicts:
#	package-lock.json
This commit is contained in:
Lihx 2024-09-24 21:23:35 +08:00
commit e3cad75481
187 changed files with 14641 additions and 14155 deletions

2
.gitignore vendored
View File

@ -1 +1,3 @@
/unpackage/
unpackage/*
unpackage

View File

@ -18,6 +18,14 @@ export function login(username, password, code, uuid) {
})
}
// 微信登录
export function wechatLogin(data) {
return request({
'url': '/weChat/wechatLogin',
'method': 'post',
'data':data
})
}
// 获取用户详细信息
export function getInfo() {
return request({
@ -50,7 +58,18 @@ export function getCodeImg() {
// 获取验证码
export function loginApp(data) {
return request({
'url': '/rescue/loginApp',
'url': '/rescue/loginQx',
headers: {
isToken: false
},
method: 'post',
timeout: 20000,
data
})
}
export function loginAppuserName(data) {
return request({
'url': '/userClient/weChat/login',
headers: {
isToken: false
},

View File

@ -2,7 +2,8 @@
<view class="orderInfo">
<view class="header">
<text class="orderTitle">{{ orderInfo.title }}</text>
<text class="orderStatus" :class="['status_' + orderInfo.status]">
<!-- <text class="orderStatus" :class="['status_' + orderInfo.status]">-->
<text class="orderStatus" :class="['status_' + '01']">
{{ getOrderStatusTxt() }}
</text>
</view>
@ -60,16 +61,22 @@
},
methods: {
getOrderStatusTxt() {
switch (this.orderInfo.status) {
case '1':
return '等待维修'
default:
return ''
}
// console.log(this.orderInfo.status)
switch (this.orderInfo.status) {
case '01':
this.isDetail = true
return '等待维修'
case '02':
return '维修中'
case '03':
return '已完成'
default:
return ''
}
},
showOrderDetail() {
uni.navigateTo({
url: '/pages/orderDetail/orderDetail'
url: '/pages/orderDetail/orderDetail?info=' + encodeURIComponent(JSON.stringify(this.orderInfo))
})
}
}
@ -101,9 +108,9 @@
font-weight: 500;
font-size: 24rpx;
&.status_1 {
color: #0174F6;
}
&.status_01 {
color: #0174F6;
}
}
}
@ -140,7 +147,7 @@
font-weight: 500;
font-size: 28rpx;
color: #0174F6;
display: flex;
align-items: center;
justify-content: center;
@ -161,7 +168,7 @@
color: #fff;
border: none;
}
.btnIcon {
width: 32rpx;
height: 32rpx;
@ -169,4 +176,4 @@
}
}
}
</style>
</style>

View File

@ -1,6 +1,6 @@
<template>
<view class="bottoms">
<view class="box" :class="{active: aindex == 1}" @click="getgogo(1)" v-if="identity == 'user' ">
<view class="box" :class="{active: aindex == 1}" @click="getgogo(1)">
<view class="imgs">
<image mode="aspectFit" src="@/static/icons/tabbar/home.png" v-show="aindex != 1"></image>
<image mode="aspectFit" src="@/static/icons/tabbar/home-checked.png" v-show="aindex == 1"></image>
@ -65,7 +65,7 @@
this.identity = uni.getStorageSync('identity');
// #endif
this.aindex = this.msg
this.getbottom()
},
methods: {
async getbottom() {

View File

@ -0,0 +1,78 @@
<template>
<view>
<view class="i_title">
{{itemTitle}}
</view>
<view>
<table class="i_table">
<thead>
<tr>
<th>名称</th>
<th>单价</th>
<th>数量</th>
<th>合计</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr v-for="item in list">
<td>{{item[title].name}}</td>
<td>{{item.itemPrice}}</td>
<td>{{item.itemCount}}</td>
<td>{{item.itemMoney}}</td>
<td>{{item.remark}}</td>
</tr>
</tbody>
</table>
</view>
</view>
</template>
<script>
export default {
name: "ticketsItem",
props:{
list: {
type: Array,
default: () => {return []}
},
title: {
type: String,
defalut: ""
}
},
data:{
itemTitle: null
},
created(){
this.getTitle()
},
methods:{
getTitle(){
switch (this.title){
case "project":
this.itemTitle = "项目"
break
case "wares":
this.itemTitle = "配件"
break
case "others":
this.itemTitle = "其他"
break
default:
return ""
}
}
}
}
</script>
<style scoped lang="less">
.i_table{
width: 100%;
text-align: center;
}
.i_title{
font-size: 1.2rem;
}
</style>

View File

@ -1,9 +1,11 @@
// 应用全局配置
module.exports = {
//baseUrl: 'https://www.nuoyunr.com/admin-api',
baseUrl: 'http://192.168.1.4:48080/admin-api',
// baseUrl: 'https://3w823u8516.vicp.fun',
// baseUrl: 'http://192.168.1.4:48080',
baseUrl: 'http://localhost:48080',
imagesUrl: 'http://shequ.0315e.com/static/images/pages/',
baseImageUrl: 'https://www.nuoyunr.com/minio',
baseImageUrl: 'http://122.51.230.86:9000/',
//wsUrl: 'wss://www.nuoyunr.com/admin-api',
wsUrl: 'ws://192.168.1.4:48080/admin-api',
// 应用信息

View File

@ -69,5 +69,15 @@
"uniStatistics" : {
"enable" : false
},
"h5" : {
"router" : {
"base" : "/lanan-repair"
},
"devServer" : {
"port" : 8080,
"disableHostCheck" : true,
"https" : false
}
},
"vueVersion" : "2"
}

20
node_modules/extend/.editorconfig generated vendored Normal file
View File

@ -0,0 +1,20 @@
root = true
[*]
indent_style = tab
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 150
[CHANGELOG.md]
indent_style = space
indent_size = 2
[*.json]
max_line_length = off
[Makefile]
max_line_length = off

17
node_modules/extend/.eslintrc generated vendored Normal file
View File

@ -0,0 +1,17 @@
{
"root": true,
"extends": "@ljharb",
"rules": {
"complexity": [2, 20],
"eqeqeq": [2, "allow-null"],
"func-name-matching": [1],
"max-depth": [1, 4],
"max-statements": [2, 26],
"no-extra-parens": [1],
"no-magic-numbers": [0],
"no-restricted-syntax": [2, "BreakStatement", "ContinueStatement", "DebuggerStatement", "LabeledStatement", "WithStatement"],
"sort-keys": [0],
}
}

175
node_modules/extend/.jscs.json generated vendored Normal file
View File

@ -0,0 +1,175 @@
{
"es3": true,
"additionalRules": [],
"requireSemicolons": true,
"disallowMultipleSpaces": true,
"disallowIdentifierNames": [],
"requireCurlyBraces": {
"allExcept": [],
"keywords": ["if", "else", "for", "while", "do", "try", "catch"]
},
"requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch", "function"],
"disallowSpaceAfterKeywords": [],
"disallowSpaceBeforeComma": true,
"disallowSpaceAfterComma": false,
"disallowSpaceBeforeSemicolon": true,
"disallowNodeTypes": [
"DebuggerStatement",
"LabeledStatement",
"SwitchCase",
"SwitchStatement",
"WithStatement"
],
"requireObjectKeysOnNewLine": { "allExcept": ["sameLine"] },
"requireSpacesInAnonymousFunctionExpression": { "beforeOpeningRoundBrace": true, "beforeOpeningCurlyBrace": true },
"requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true },
"disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true },
"requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true },
"disallowSpacesInFunctionDeclaration": { "beforeOpeningRoundBrace": true },
"requireSpaceBetweenArguments": true,
"disallowSpacesInsideParentheses": true,
"disallowSpacesInsideArrayBrackets": true,
"disallowQuotedKeysInObjects": { "allExcept": ["reserved"] },
"disallowSpaceAfterObjectKeys": true,
"requireCommaBeforeLineBreak": true,
"disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"],
"requireSpaceAfterPrefixUnaryOperators": [],
"disallowSpaceBeforePostfixUnaryOperators": ["++", "--"],
"requireSpaceBeforePostfixUnaryOperators": [],
"disallowSpaceBeforeBinaryOperators": [],
"requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
"requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="],
"disallowSpaceAfterBinaryOperators": [],
"disallowImplicitTypeConversion": ["binary", "string"],
"disallowKeywords": ["with", "eval"],
"requireKeywordsOnNewLine": [],
"disallowKeywordsOnNewLine": ["else"],
"requireLineFeedAtFileEnd": true,
"disallowTrailingWhitespace": true,
"disallowTrailingComma": true,
"excludeFiles": ["node_modules/**", "vendor/**"],
"disallowMultipleLineStrings": true,
"requireDotNotation": { "allExcept": ["keywords"] },
"requireParenthesesAroundIIFE": true,
"validateLineBreaks": "LF",
"validateQuoteMarks": {
"escape": true,
"mark": "'"
},
"disallowOperatorBeforeLineBreak": [],
"requireSpaceBeforeKeywords": [
"do",
"for",
"if",
"else",
"switch",
"case",
"try",
"catch",
"finally",
"while",
"with",
"return"
],
"validateAlignedFunctionParameters": {
"lineBreakAfterOpeningBraces": true,
"lineBreakBeforeClosingBraces": true
},
"requirePaddingNewLinesBeforeExport": true,
"validateNewlineAfterArrayElements": {
"maximum": 6
},
"requirePaddingNewLinesAfterUseStrict": true,
"disallowArrowFunctions": true,
"disallowMultiLineTernary": true,
"validateOrderInObjectKeys": false,
"disallowIdenticalDestructuringNames": true,
"disallowNestedTernaries": { "maxLevel": 1 },
"requireSpaceAfterComma": { "allExcept": ["trailing"] },
"requireAlignedMultilineParams": false,
"requireSpacesInGenerator": {
"afterStar": true
},
"disallowSpacesInGenerator": {
"beforeStar": true
},
"disallowVar": false,
"requireArrayDestructuring": false,
"requireEnhancedObjectLiterals": false,
"requireObjectDestructuring": false,
"requireEarlyReturn": false,
"requireCapitalizedConstructorsNew": {
"allExcept": ["Function", "String", "Object", "Symbol", "Number", "Date", "RegExp", "Error", "Boolean", "Array"]
},
"requireImportAlphabetized": false,
"requireSpaceBeforeObjectValues": true,
"requireSpaceBeforeDestructuredValues": true,
"disallowSpacesInsideTemplateStringPlaceholders": true,
"disallowArrayDestructuringReturn": false,
"requireNewlineBeforeSingleStatementsInIf": false,
"disallowUnusedVariables": true,
"requireSpacesInsideImportedObjectBraces": true,
"requireUseStrict": true
}

230
node_modules/extend/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,230 @@
language: node_js
os:
- linux
node_js:
- "10.7"
- "9.11"
- "8.11"
- "7.10"
- "6.14"
- "5.12"
- "4.9"
- "iojs-v3.3"
- "iojs-v2.5"
- "iojs-v1.8"
- "0.12"
- "0.10"
- "0.8"
before_install:
- 'case "${TRAVIS_NODE_VERSION}" in 0.*) export NPM_CONFIG_STRICT_SSL=false ;; esac'
- 'nvm install-latest-npm'
install:
- 'if [ "${TRAVIS_NODE_VERSION}" = "0.6" ] || [ "${TRAVIS_NODE_VERSION}" = "0.9" ]; then nvm install --latest-npm 0.8 && npm install && nvm use "${TRAVIS_NODE_VERSION}"; else npm install; fi;'
script:
- 'if [ -n "${PRETEST-}" ]; then npm run pretest ; fi'
- 'if [ -n "${POSTTEST-}" ]; then npm run posttest ; fi'
- 'if [ -n "${COVERAGE-}" ]; then npm run coverage ; fi'
- 'if [ -n "${TEST-}" ]; then npm run tests-only ; fi'
sudo: false
env:
- TEST=true
matrix:
fast_finish: true
include:
- node_js: "lts/*"
env: PRETEST=true
- node_js: "lts/*"
env: POSTTEST=true
- node_js: "4"
env: COVERAGE=true
- node_js: "10.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "10.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "10.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "10.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "10.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "10.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "10.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "9.10"
env: TEST=true ALLOW_FAILURE=true
- node_js: "9.9"
env: TEST=true ALLOW_FAILURE=true
- node_js: "9.8"
env: TEST=true ALLOW_FAILURE=true
- node_js: "9.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "9.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "9.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "9.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "9.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "9.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "9.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "9.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.10"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.9"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.8"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "8.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.9"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.8"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "7.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.13"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.12"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.11"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.10"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.9"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.8"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "6.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.11"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.10"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.9"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.8"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "5.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.8"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "4.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v3.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v3.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v3.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v2.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.7"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.5"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.4"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.3"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.2"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.1"
env: TEST=true ALLOW_FAILURE=true
- node_js: "iojs-v1.0"
env: TEST=true ALLOW_FAILURE=true
- node_js: "0.11"
env: TEST=true ALLOW_FAILURE=true
- node_js: "0.9"
env: TEST=true ALLOW_FAILURE=true
- node_js: "0.6"
env: TEST=true ALLOW_FAILURE=true
- node_js: "0.4"
env: TEST=true ALLOW_FAILURE=true
allow_failures:
- os: osx
- env: TEST=true ALLOW_FAILURE=true

83
node_modules/extend/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,83 @@
3.0.2 / 2018-07-19
==================
* [Fix] Prevent merging `__proto__` property (#48)
* [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape`
* [Tests] up to `node` `v10.7`, `v9.11`, `v8.11`, `v7.10`, `v6.14`, `v4.9`; use `nvm install-latest-npm`
3.0.1 / 2017-04-27
==================
* [Fix] deep extending should work with a non-object (#46)
* [Dev Deps] update `tape`, `eslint`, `@ljharb/eslint-config`
* [Tests] up to `node` `v7.9`, `v6.10`, `v4.8`; improve matrix
* [Docs] Switch from vb.teelaun.ch to versionbadg.es for the npm version badge SVG.
* [Docs] Add example to readme (#34)
3.0.0 / 2015-07-01
==================
* [Possible breaking change] Use global "strict" directive (#32)
* [Tests] `int` is an ES3 reserved word
* [Tests] Test up to `io.js` `v2.3`
* [Tests] Add `npm run eslint`
* [Dev Deps] Update `covert`, `jscs`
2.0.1 / 2015-04-25
==================
* Use an inline `isArray` check, for ES3 browsers. (#27)
* Some old browsers fail when an identifier is `toString`
* Test latest `node` and `io.js` versions on `travis-ci`; speed up builds
* Add license info to package.json (#25)
* Update `tape`, `jscs`
* Adding a CHANGELOG
2.0.0 / 2014-10-01
==================
* Increase code coverage to 100%; run code coverage as part of tests
* Add `npm run lint`; Run linter as part of tests
* Remove nodeType and setInterval checks in isPlainObject
* Updating `tape`, `jscs`, `covert`
* General style and README cleanup
1.3.0 / 2014-06-20
==================
* Add component.json for browser support (#18)
* Use SVG for badges in README (#16)
* Updating `tape`, `covert`
* Updating travis-ci to work with multiple node versions
* Fix `deep === false` bug (returning target as {}) (#14)
* Fixing constructor checks in isPlainObject
* Adding additional test coverage
* Adding `npm run coverage`
* Add LICENSE (#13)
* Adding a warning about `false`, per #11
* General style and whitespace cleanup
1.2.1 / 2013-09-14
==================
* Fixing hasOwnProperty bugs that would only have shown up in specific browsers. Fixes #8
* Updating `tape`
1.2.0 / 2013-09-02
==================
* Updating the README: add badges
* Adding a missing variable reference.
* Using `tape` instead of `buster` for tests; add more tests (#7)
* Adding node 0.10 to Travis CI (#6)
* Enabling "npm test" and cleaning up package.json (#5)
* Add Travis CI.
1.1.3 / 2012-12-06
==================
* Added unit tests.
* Ensure extend function is named. (Looks nicer in a stack trace.)
* README cleanup.
1.1.1 / 2012-11-07
==================
* README cleanup.
* Added installation instructions.
* Added a missing semicolon
1.0.0 / 2012-04-08
==================
* Initial commit

23
node_modules/extend/LICENSE generated vendored Normal file
View File

@ -0,0 +1,23 @@
The MIT License (MIT)
Copyright (c) 2014 Stefan Thomas
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

81
node_modules/extend/README.md generated vendored Normal file
View File

@ -0,0 +1,81 @@
[![Build Status][travis-svg]][travis-url]
[![dependency status][deps-svg]][deps-url]
[![dev dependency status][dev-deps-svg]][dev-deps-url]
# extend() for Node.js <sup>[![Version Badge][npm-version-png]][npm-url]</sup>
`node-extend` is a port of the classic extend() method from jQuery. It behaves as you expect. It is simple, tried and true.
Notes:
* Since Node.js >= 4,
[`Object.assign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)
now offers the same functionality natively (but without the "deep copy" option).
See [ECMAScript 2015 (ES6) in Node.js](https://nodejs.org/en/docs/es6).
* Some native implementations of `Object.assign` in both Node.js and many
browsers (since NPM modules are for the browser too) may not be fully
spec-compliant.
Check [`object.assign`](https://www.npmjs.com/package/object.assign) module for
a compliant candidate.
## Installation
This package is available on [npm][npm-url] as: `extend`
``` sh
npm install extend
```
## Usage
**Syntax:** extend **(** [`deep`], `target`, `object1`, [`objectN`] **)**
*Extend one object with one or more others, returning the modified object.*
**Example:**
``` js
var extend = require('extend');
extend(targetObject, object1, object2);
```
Keep in mind that the target object will be modified, and will be returned from extend().
If a boolean true is specified as the first argument, extend performs a deep copy, recursively copying any objects it finds. Otherwise, the copy will share structure with the original object(s).
Undefined properties are not copied. However, properties inherited from the object's prototype will be copied over.
Warning: passing `false` as the first argument is not supported.
### Arguments
* `deep` *Boolean* (optional)
If set, the merge becomes recursive (i.e. deep copy).
* `target` *Object*
The object to extend.
* `object1` *Object*
The object that will be merged into the first.
* `objectN` *Object* (Optional)
More objects to merge into the first.
## License
`node-extend` is licensed under the [MIT License][mit-license-url].
## Acknowledgements
All credit to the jQuery authors for perfecting this amazing utility.
Ported to Node.js by [Stefan Thomas][github-justmoon] with contributions by [Jonathan Buchanan][github-insin] and [Jordan Harband][github-ljharb].
[travis-svg]: https://travis-ci.org/justmoon/node-extend.svg
[travis-url]: https://travis-ci.org/justmoon/node-extend
[npm-url]: https://npmjs.org/package/extend
[mit-license-url]: http://opensource.org/licenses/MIT
[github-justmoon]: https://github.com/justmoon
[github-insin]: https://github.com/insin
[github-ljharb]: https://github.com/ljharb
[npm-version-png]: http://versionbadg.es/justmoon/node-extend.svg
[deps-svg]: https://david-dm.org/justmoon/node-extend.svg
[deps-url]: https://david-dm.org/justmoon/node-extend
[dev-deps-svg]: https://david-dm.org/justmoon/node-extend/dev-status.svg
[dev-deps-url]: https://david-dm.org/justmoon/node-extend#info=devDependencies

32
node_modules/extend/component.json generated vendored Normal file
View File

@ -0,0 +1,32 @@
{
"name": "extend",
"author": "Stefan Thomas <justmoon@members.fsf.org> (http://www.justmoon.net)",
"version": "3.0.0",
"description": "Port of jQuery.extend for node.js and the browser.",
"scripts": [
"index.js"
],
"contributors": [
{
"name": "Jordan Harband",
"url": "https://github.com/ljharb"
}
],
"keywords": [
"extend",
"clone",
"merge"
],
"repository" : {
"type": "git",
"url": "https://github.com/justmoon/node-extend.git"
},
"dependencies": {
},
"devDependencies": {
"tape" : "~3.0.0",
"covert": "~0.4.0",
"jscs": "~1.6.2"
}
}

117
node_modules/extend/index.js generated vendored Normal file
View File

@ -0,0 +1,117 @@
'use strict';
var hasOwn = Object.prototype.hasOwnProperty;
var toStr = Object.prototype.toString;
var defineProperty = Object.defineProperty;
var gOPD = Object.getOwnPropertyDescriptor;
var isArray = function isArray(arr) {
if (typeof Array.isArray === 'function') {
return Array.isArray(arr);
}
return toStr.call(arr) === '[object Array]';
};
var isPlainObject = function isPlainObject(obj) {
if (!obj || toStr.call(obj) !== '[object Object]') {
return false;
}
var hasOwnConstructor = hasOwn.call(obj, 'constructor');
var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');
// Not own constructor property must be Object
if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {
return false;
}
// Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own.
var key;
for (key in obj) { /**/ }
return typeof key === 'undefined' || hasOwn.call(obj, key);
};
// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target
var setProperty = function setProperty(target, options) {
if (defineProperty && options.name === '__proto__') {
defineProperty(target, options.name, {
enumerable: true,
configurable: true,
value: options.newValue,
writable: true
});
} else {
target[options.name] = options.newValue;
}
};
// Return undefined instead of __proto__ if '__proto__' is not an own property
var getProperty = function getProperty(obj, name) {
if (name === '__proto__') {
if (!hasOwn.call(obj, name)) {
return void 0;
} else if (gOPD) {
// In early versions of node, obj['__proto__'] is buggy when obj has
// __proto__ as an own property. Object.getOwnPropertyDescriptor() works.
return gOPD(obj, name).value;
}
}
return obj[name];
};
module.exports = function extend() {
var options, name, src, copy, copyIsArray, clone;
var target = arguments[0];
var i = 1;
var length = arguments.length;
var deep = false;
// Handle a deep copy situation
if (typeof target === 'boolean') {
deep = target;
target = arguments[1] || {};
// skip the boolean and the target
i = 2;
}
if (target == null || (typeof target !== 'object' && typeof target !== 'function')) {
target = {};
}
for (; i < length; ++i) {
options = arguments[i];
// Only deal with non-null/undefined values
if (options != null) {
// Extend the base object
for (name in options) {
src = getProperty(target, name);
copy = getProperty(options, name);
// Prevent never-ending loop
if (target !== copy) {
// Recurse if we're merging plain objects or arrays
if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
if (copyIsArray) {
copyIsArray = false;
clone = src && isArray(src) ? src : [];
} else {
clone = src && isPlainObject(src) ? src : {};
}
// Never move original objects, clone them
setProperty(target, { name: name, newValue: extend(deep, clone, copy) });
// Don't bring in undefined values
} else if (typeof copy !== 'undefined') {
setProperty(target, { name: name, newValue: copy });
}
}
}
}
}
// Return the modified object
return target;
};

75
node_modules/extend/package.json generated vendored Normal file
View File

@ -0,0 +1,75 @@
{
"_from": "extend@^3.0.2",
"_id": "extend@3.0.2",
"_inBundle": false,
"_integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"_location": "/extend",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "extend@^3.0.2",
"name": "extend",
"escapedName": "extend",
"rawSpec": "^3.0.2",
"saveSpec": null,
"fetchSpec": "^3.0.2"
},
"_requiredBy": [
"/weapp-qrcode"
],
"_resolved": "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz",
"_shasum": "f8b1136b4071fbd8eb140aff858b1019ec2915fa",
"_spec": "extend@^3.0.2",
"_where": "D:\\lananWork\\lanan-repair\\node_modules\\weapp-qrcode",
"author": {
"name": "Stefan Thomas",
"email": "justmoon@members.fsf.org",
"url": "http://www.justmoon.net"
},
"bugs": {
"url": "https://github.com/justmoon/node-extend/issues"
},
"bundleDependencies": false,
"contributors": [
{
"name": "Jordan Harband",
"url": "https://github.com/ljharb"
}
],
"dependencies": {},
"deprecated": false,
"description": "Port of jQuery.extend for node.js and the browser",
"devDependencies": {
"@ljharb/eslint-config": "^12.2.1",
"covert": "^1.1.0",
"eslint": "^4.19.1",
"jscs": "^3.0.7",
"tape": "^4.9.1"
},
"homepage": "https://github.com/justmoon/node-extend#readme",
"keywords": [
"extend",
"clone",
"merge"
],
"license": "MIT",
"main": "index",
"name": "extend",
"repository": {
"type": "git",
"url": "git+https://github.com/justmoon/node-extend.git"
},
"scripts": {
"coverage": "covert test/index.js",
"coverage-quiet": "covert test/index.js --quiet",
"eslint": "eslint *.js */*.js",
"jscs": "jscs *.js */*.js",
"lint": "npm run jscs && npm run eslint",
"posttest": "npm run coverage-quiet",
"pretest": "npm run lint",
"test": "npm run tests-only",
"tests-only": "node test"
},
"version": "3.0.2"
}

9
node_modules/weapp-qrcode/.editorconfig generated vendored Normal file
View File

@ -0,0 +1,9 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

2
node_modules/weapp-qrcode/.eslintignore generated vendored Normal file
View File

@ -0,0 +1,2 @@
build/*.js
src/qrcode.js

26
node_modules/weapp-qrcode/.eslintrc.js generated vendored Normal file
View File

@ -0,0 +1,26 @@
module.exports = {
root: true,
parser: 'babel-eslint',
parserOptions: {
sourceType: 'module'
},
env: {
browser: true,
},
// https://github.com/feross/standard/blob/master/RULES.md#javascript-standard-style
extends: 'standard',
"globals": {
__VERSION__: false,
ENV: false,
wx: false
},
// add your custom rules here
'rules': {
// allow paren-less arrow functions
'arrow-parens': 0,
// allow async-await
'generator-star-spacing': 0,
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
}
}

37
node_modules/weapp-qrcode/.github/ISSUE_TEMPLATE.md generated vendored Normal file
View File

@ -0,0 +1,37 @@
# Description
[问题简单描述]
# Environment
* Platform: [开发者工具/iOS/Andriod/Web]
* Platform version: [对应工具或者iOS或者Andriod的版本号]
* Wechat version: [微信版本号]
* weapp-qrcode version: [在package.json里]
* other version: [如果在某一设备下出现该问题,请填写设备号]
# Reproduce
**问题复现步骤:**
1. [第一步]
2. [第二步]
3. [其他步骤...]
**期望的表现:**
[在这里描述期望的表现]
**观察到的表现:**
[在这里描述观察到的表现]
**屏幕截图和动态 GIF 图**
![复现步骤的屏幕截图和动态 GIF 图](图片的 url)
# Relevant Code / Logs
```
// TODO(you): code or logs here to reproduce the problem
```

23
node_modules/weapp-qrcode/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,23 @@
language: node_js
sudo: required
node_js:
- 10.0.0
cache:
directories:
- node_modules
before_install:
- export TZ='Asia/Shanghai'
install:
- npm install
script:
- npm run publish
after_script:
- git init
- git config user.name "${USER_NAME}"
- git config user.email "${USER_EMAIL}"
- git add .
- git commit -m "publish"
- git push -f https://${access_token}@github.com/yingye/weapp-qrcode HEAD:master
branch: master

40
node_modules/weapp-qrcode/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,40 @@
# Change Log
Change log for weapp-qrcode. [Details at Github](https://github.com/yingye/weapp-qrcode)
## [1.0.0] - 2018-12-25
- 支持传入绘图上下文(CanvasContext).
## [1.0.0-beta] - 2018-12-13
- 支持二维码在 canvas 上绘制的起始位置.
- 支持在二维码上绘制图片及绘制位置.
## [0.9.0] - 2018-05-31
- 支持绘制带中文的二维码.
## [0.8.0] - 2018-05-15
- 绘制二维码后添加回调函数.
## [0.7.0] - 2018-05-11
- 支持在小程序组件中绘制二维码.
## [0.6.0] - 2018-04-16
- Add multi-output.
## [0.5.0] - 2018-03-11
- Add version in weapp.qrcode.js.
## [0.4.0] - 2018-03-10
- Fix options.
## [0.3.0] - 2018-02-03
- Initial release.

21
node_modules/weapp-qrcode/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 yingye
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

96
node_modules/weapp-qrcode/README.md generated vendored Normal file
View File

@ -0,0 +1,96 @@
# weapp-qrcode
[![npm version](https://badge.fury.io/js/weapp-qrcode.svg)](https://badge.fury.io/js/weapp-qrcode)
[![change-log](https://img.shields.io/badge/changelog-md-blue.svg)](https://github.com/yingye/weapp-qrcode/blob/master/CHANGELOG.md)
weapp.qrcode.js 在 微信小程序 中,快速生成二维码
## Usage
先在 wxml 文件中,创建绘制的 `canvas`,并定义好 `width`, `height`, `canvasId`
```html
<canvas style="width: 200px; height: 200px;" canvas-id="myQrcode"></canvas>
```
直接引入 js 文件,使用 `drawQrcode()` 绘制二维码。!!!在 调用 `drawQrcode()` 方法之前,一定要确保可以获取到 `canvas context`
在 v0.6.0 版本构建出多个文件,详情移步[Build Files说明](https://github.com/yingye/weapp-qrcode/blob/master/dist/README.md)。
```js
// 将 dist 目录下weapp.qrcode.esm.js 复制到项目目录中
import drawQrcode from '../../utils/weapp.qrcode.esm.js'
drawQrcode({
width: 200,
height: 200,
canvasId: 'myQrcode',
// ctx: wx.createCanvasContext('myQrcode'),
text: 'https://github.com/yingye',
// v1.0.0+版本支持在二维码上绘制图片
image: {
imageResource: '../../images/icon.png',
dx: 70,
dy: 70,
dWidth: 60,
dHeight: 60
}
})
```
如果项目使用了 wepy 框架,可直接安装 `weapp-qrcode` npm包。
```
npm install weapp-qrcode --save
```
```js
import drawQrcode from 'weapp-qrcode'
drawQrcode({
width: 200,
height: 200,
canvasId: 'myQrcode',
text: 'https://github.com/yingye'
})
```
## DEMO
<img src="./examples/demo.jpg" width=300 >
更多 demo 可以参考 [examples目录](https://github.com/yingye/weapp-qrcode/tree/master/examples)示例包含原生语法及WePY、mpvue、Taro框架。
## API
### drawQrcode([options])
#### options
Type: Object
| 参数 | 说明 | 示例|
| ------ | ------ | ------ |
| width | 必须,二维码宽度,与`canvas`的`width`保持一致 | 200 |
| height | 必须,二维码高度,与`canvas`的`height`保持一致 | 200 |
| canvasId | 非必须,绘制的`canvasId` | `'myQrcode'` |
| ctx | 非必须,绘图上下文,可通过 `wx.createCanvasContext('canvasId')` 获取v1.0.0+版本支持 | `'wx.createCanvasContext('canvasId')'` |
| text | 必须,二维码内容 | 'https://github.com/yingye' |
| typeNumber | 非必须,二维码的计算模式,默认值-1 | 8 |
| correctLevel | 非必须,二维码纠错级别,默认值为高级,取值:`{ L: 1, M: 0, Q: 3, H: 2 }` | 1 |
| background | 非必须,二维码背景颜色,默认值白色 | `'#ffffff'` |
| foreground | 非必须,二维码前景色,默认值黑色 | `'#000000'` |
| _this | 非必须若在组件中使用需要传入v0.7.0+版本支持 | this |
| callback | 非必须绘制完成后的回调函数v0.8.0+版本支持。安卓手机兼容性问题,可通过自行设置计时器来解决,更多可以参考 [issue #18](https://github.com/yingye/weapp-qrcode/issues/18) | `function (e) { console.log('e', e) }` |
| x | 非必须,二维码绘制的 x 轴起始位置默认值0v1.0.0+版本支持 | 100 |
| y | 非必须,二维码绘制的 y 轴起始位置默认值0v1.0.0+版本支持 | 100 |
| image | 非必须,在 canvas 上绘制图片,**层级高于二维码**v1.0.0+版本支持,更多可参考[drawImage](https://developers.weixin.qq.com/miniprogram/dev/api/CanvasContext.drawImage.html) | `{ imageResource: '', dx: 0, dy: 0, dWidth: 100, dHeight: 100 }` |
**位置信息可以参见下图:**
<image src="./examples/api.png" width=500 height=500>
## TIPS
weapp.qrcode.js 二维码生成部分借鉴了 jquery-qrcode 源码,可以参考 [jquery-qrcode](https://github.com/jeromeetienne/jquery-qrcode)。

39
node_modules/weapp-qrcode/build/rollup.dev.config.js generated vendored Normal file
View File

@ -0,0 +1,39 @@
var babel = require('rollup-plugin-babel')
var resolve = require('rollup-plugin-node-resolve')
var commonjs = require('rollup-plugin-commonjs')
var eslint = require('rollup-plugin-eslint')
var license = require('rollup-plugin-license')
var path = require('path')
var pkg = require('../package.json')
module.exports = {
input: path.resolve(__dirname, '../src/index.js'),
output: [
{
file: path.resolve(__dirname, '../dist/weapp.qrcode.js'),
format: 'umd'
},
{
file: path.resolve(__dirname, '../examples/wechat-app/utils/weapp.qrcode.js'),
format: 'umd'
}
],
moduleName: 'drawQrcode',
plugins: [
eslint(),
resolve({
jsnext: true,
main: true,
browser: true
}),
commonjs(),
babel({
exclude: 'node_modules/**'
}),
license({
banner: 'weapp.qrcode.js v' + pkg.version + ' (' + pkg.homepage + ')'
})
]
}

49
node_modules/weapp-qrcode/build/rollup.prod.config.js generated vendored Normal file
View File

@ -0,0 +1,49 @@
var babel = require('rollup-plugin-babel')
var babel = require('rollup-plugin-babel')
var resolve = require('rollup-plugin-node-resolve')
var commonjs = require('rollup-plugin-commonjs')
var eslint = require('rollup-plugin-eslint')
var license = require('rollup-plugin-license')
var uglify = require('rollup-plugin-uglify')
var path = require('path')
var pkg = require('../package.json')
module.exports = {
input: path.resolve(__dirname, '../src/index.js'),
output: [
{
file: path.resolve(__dirname, '../dist/weapp.qrcode.min.js'),
format: 'umd'
},
{
file: path.resolve(__dirname, '../dist/weapp.qrcode.common.js'),
format: 'cjs'
},
{
file: path.resolve(__dirname, '../dist/weapp.qrcode.esm.js'),
format: 'es'
}
],
moduleName: 'drawQrcode',
plugins: [
eslint(),
resolve({
jsnext: true,
main: true,
browser: true
}),
commonjs(),
babel({
exclude: 'node_modules/**'
}),
uglify({
compress: {
// 'drop_console': true
}
}),
license({
banner: 'weapp.qrcode.js v' + pkg.version + ' (' + pkg.homepage + ')'
})
]
}

6
node_modules/weapp-qrcode/dist/README.md generated vendored Normal file
View File

@ -0,0 +1,6 @@
## Explanation of Build Files
| | UMD | CommonJS | ES Module |
| --- | --- | --- | --- |
| **Develpment** | weapp.qrcode.js | weapp.qrcode.common.js | weapp.qrcode.esm.js |
| **Production** | weapp.qrcode.min.js | | |

File diff suppressed because one or more lines are too long

5
node_modules/weapp-qrcode/dist/weapp.qrcode.esm.js generated vendored Normal file

File diff suppressed because one or more lines are too long

1281
node_modules/weapp-qrcode/dist/weapp.qrcode.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

5
node_modules/weapp-qrcode/dist/weapp.qrcode.min.js generated vendored Normal file

File diff suppressed because one or more lines are too long

78
node_modules/weapp-qrcode/package.json generated vendored Normal file
View File

@ -0,0 +1,78 @@
{
"_from": "weapp-qrcode",
"_id": "weapp-qrcode@1.0.0",
"_inBundle": false,
"_integrity": "sha512-4sa3W0rGDVJ9QaeZpAKlAuUxVyjhDwiUqHyGK/jJMsRMXnhb4yO8qWU/pZruMo+iT5J6CraS67lDMFb1VY+RaA==",
"_location": "/weapp-qrcode",
"_phantomChildren": {},
"_requested": {
"type": "tag",
"registry": true,
"raw": "weapp-qrcode",
"name": "weapp-qrcode",
"escapedName": "weapp-qrcode",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmmirror.com/weapp-qrcode/-/weapp-qrcode-1.0.0.tgz",
"_shasum": "4f3b4b4e7d37710c513439166734587859aebbfc",
"_spec": "weapp-qrcode",
"_where": "D:\\lananWork\\lanan-repair",
"author": {
"name": "yingye"
},
"bugs": {
"url": "https://github.com/yingye/weapp-qrcode/issues"
},
"bundleDependencies": false,
"dependencies": {
"extend": "^3.0.2"
},
"deprecated": false,
"description": "generate qrcode in weapp",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-eslint": "^8.2.1",
"eslint": "^4.16.0",
"eslint-config-standard": "^11.0.0-beta.0",
"eslint-plugin-import": "^2.8.0",
"eslint-plugin-node": "^5.2.1",
"eslint-plugin-promise": "^3.6.0",
"eslint-plugin-standard": "^3.0.1",
"rollup": "^0.55.1",
"rollup-plugin-babel": "^3.0.3",
"rollup-plugin-commonjs": "^8.3.0",
"rollup-plugin-eslint": "^4.0.0",
"rollup-plugin-license": "^0.6.0",
"rollup-plugin-node-resolve": "^3.0.2",
"rollup-plugin-replace": "^2.0.0",
"rollup-plugin-uglify": "^3.0.0"
},
"homepage": "https://github.com/yingye/weapp-qrcode#readme",
"keywords": [
"wechat",
"weapp",
"qrcode",
"canvas"
],
"license": "MIT",
"main": "dist/weapp.qrcode.common.js",
"module": "dist/weapp.qrcode.esm.js",
"name": "weapp-qrcode",
"repository": {
"type": "git",
"url": "git+https://github.com/yingye/weapp-qrcode.git"
},
"scripts": {
"build": "rollup --config build/rollup.prod.config.js",
"dev": "rollup --config build/rollup.dev.config.js -w",
"publish": "rollup --config build/rollup.dev.config.js & npm run build",
"test": "echo \"Error: no test specified\" && exit 1"
},
"version": "1.0.0"
}

94
node_modules/weapp-qrcode/src/index.js generated vendored Normal file
View File

@ -0,0 +1,94 @@
import extend from 'extend'
import {
QRCode,
QRErrorCorrectLevel
} from './qrcode'
// support Chinese
function utf16to8 (str) {
var out, i, len, c
out = ''
len = str.length
for (i = 0; i < len; i++) {
c = str.charCodeAt(i)
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i)
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F))
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F))
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F))
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F))
}
}
return out
}
function drawQrcode (options) {
options = options || {}
options = extend(true, {
width: 256,
height: 256,
x: 0,
y: 0,
typeNumber: -1,
correctLevel: QRErrorCorrectLevel.H,
background: '#ffffff',
foreground: '#000000',
image: {
imageResource: '',
dx: 0,
dy: 0,
dWidth: 100,
dHeight: 100
}
}, options)
if (!options.canvasId && !options.ctx) {
console.warn('please set canvasId or ctx!')
return
}
createCanvas()
function createCanvas () {
// create the qrcode itself
var qrcode = new QRCode(options.typeNumber, options.correctLevel)
qrcode.addData(utf16to8(options.text))
qrcode.make()
// get canvas context
var ctx
if (options.ctx) {
ctx = options.ctx
} else {
ctx = options._this ? wx.createCanvasContext && wx.createCanvasContext(options.canvasId, options._this) : wx.createCanvasContext && wx.createCanvasContext(options.canvasId)
}
// compute tileW/tileH based on options.width/options.height
var tileW = options.width / qrcode.getModuleCount()
var tileH = options.height / qrcode.getModuleCount()
// draw in the canvas
for (var row = 0; row < qrcode.getModuleCount(); row++) {
for (var col = 0; col < qrcode.getModuleCount(); col++) {
var style = qrcode.isDark(row, col) ? options.foreground : options.background
ctx.setFillStyle(style)
var w = (Math.ceil((col + 1) * tileW) - Math.floor(col * tileW))
var h = (Math.ceil((row + 1) * tileW) - Math.floor(row * tileW))
ctx.fillRect(Math.round(col * tileW) + options.x, Math.round(row * tileH) + options.y, w, h)
}
}
if (options.image.imageResource) {
ctx.drawImage(options.image.imageResource, options.image.dx, options.image.dy, options.image.dWidth, options.image.dHeight)
}
ctx.draw(false, function (e) {
options.callback && options.callback(e)
})
}
}
export default drawQrcode

1242
node_modules/weapp-qrcode/src/qrcode.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

1729
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
{
"dependencies": {
"uview-ui": "^2.0.36"
"uview-ui": "^2.0.36",
"weapp-qrcode": "^1.0.0"
},
"devDependencies": {
"sass": "^1.69.5",

View File

@ -1,11 +1,11 @@
{
"pages": [ //pageshttps://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "uni-app"
}
},
// {
// "path": "pages/index/index",
// "style": {
// "navigationBarTitleText": "uni-app"
// }
// },
{
"path": "pages/login/login",
"style": {
@ -144,6 +144,13 @@
{
"navigationBarTitleText" : ""
}
},
{
"path" : "pages/login/bindPhoe",
"style" :
{
"navigationBarTitleText" : ""
}
}
],
"globalStyle": {

View File

@ -27,7 +27,7 @@
<view v-for="(item, index) in shopList" :key="index" class="shopItem" @click="gotoShopDetail(item)">
<image class="shopImg" :src="item.image" mode="aspectFill"></image>
<view class="shopInfo">
<view class="shopTitle">{{item.title}}</view>
<view class="shopTitle">{{item.corpName}}</view>
<view class="shopDetail">
<view class="shopAddress">{{item.address}}</view>
<view class="line"></view>
@ -45,6 +45,7 @@
<script>
import tabBarVue from '@/components/tabBar/tabBar.vue'
import VNavigationBar from '@/components/VNavigationBar.vue'
import request from "@/utils/request";
export default {
components: {
tabBarVue,
@ -82,42 +83,60 @@
title: '车辆机件“焕新上岗”,武汉公交修旧创效出实招'
},
],
shopList: [{
id: 1,
title: '顺捷汽车维修搭电救援补胎中心',
address: '济南市历下区福瑞达历下护理院东南门旁',
distance: '1.9km',
image: ''
},
{
id: 2,
title: '顺捷汽车维修搭电救援补胎中心',
address: '济南市历下区福瑞达历下护理院东南门旁',
distance: '1.9km',
image: ''
},
{
id: 3,
title: '顺捷汽车维修搭电救援补胎中心',
address: '济南市历下区福瑞达历下护理院东南门旁',
distance: '1.9km',
image: ''
},
]
// shopList: [{
// id: 1,
// title: '',
// address: '',
// distance: '1.9km',
// image: ''
// },
// {
// id: 2,
// title: '',
// address: '',
// distance: '1.9km',
// image: ''
// },
// {
// id: 3,
// title: '',
// address: '',
// distance: '1.9km',
// image: ''
// },
// ]
shopList: []
}
},
onShow(){
this.getCompanyPage()
},
methods: {
gotoShopDetail() {
gotoShopDetail(row) {
//
uni.navigateTo({
url: '/pages/shopDetail/shopDetail'
url: '/pages/shopDetail/shopDetail?info=' + encodeURIComponent(JSON.stringify(row))
})
},
gotoPage(menu) {
uni.navigateTo({
url: menu.path
})
}
},
//
async getCompanyPage(){
const res = await request({
url: "/userClient/base/company/page",
method: "get",
params:{
serviceCodes: "weixiu"
}
})
this.shopList = res.data.records
this.shopList.forEach(item => {
item['image'] = require("@/static/images/outImage.jpg")
})
}
}
}
</script>
@ -292,4 +311,4 @@
}
}
}
</style>
</style>

217
pages/login/bindPhoe.vue Normal file
View File

@ -0,0 +1,217 @@
<template>
<view class="container">
<view class="title">绑定手机号</view>
<view class="phone formItem">
<image style="width: 28rpx;height: 28rpx;" src="../../static/icons/order-icon2.png" mode="aspectFit">
</image>
<input v-model="phone" placeholder="请输入手机号" class="formItemInput" type="text" />
</view>
<view class="validaCode formItem">
<uni-icons type="locked"></uni-icons>
<input v-model="validaCode" class="formItemInput" placeholder="请输入验证码" type="text" />
<view :class="{ 'disabled': isButtonDisabled }" class="validaCodeBtn" @click="sendVerificationCode">{{buttonText}}</view>
</view>
<view class="submit" @click="bindPhone">
绑定
</view>
</view>
</template>
<script>
import { setToken } from '../../utils/auth';
import request from '../../utils/request';
export default {
data() {
return {
phone: '15254781016',
validaCode: '',
countdownTime: 60,
isButtonDisabled: false,
}
},
computed: {
buttonText() {
if (this.isButtonDisabled) {
return `${this.countdownTime}s 后重新发送`;
} else {
return "获取验证码";
}
},
},
methods: {
sendVerificationCode() {
if (this.isButtonDisabled) {
return
}
let reg = /^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\d{8}$/;
if (!reg.test(this.phone)) {
uni.showToast({
icon: 'none',
title: '请输入正确的11位手机号'
})
this.phone = '';
return false;
}
if (this.isButtonDisabled) {
return; //
}
const data = {
phone: this.phone,
}
request({
url: '/rescue/sendSmsQx',
method: 'get',
params: data,
headers: {
isToken: false,
},
header: {
Authorization: 'Bearer ' + uni.getStorageSync('validaCodeToken')
}
}).then((res) => {
console.log('验证码', res);
if (res.code == 200) {
uni.showToast({
title: '验证码已发送 请注意查收',
icon: 'none'
})
} else {
uni.showToast({
title: '网络不佳请稍后再试',
icon: 'none'
})
}
})
this.disableButton(); //
this.startCountdown(); //
},
disableButton() {
this.isButtonDisabled = true;
},
enableButton() {
this.isButtonDisabled = false;
},
startCountdown() {
let countdown = setInterval(() => {
this.countdownTime--;
if (this.countdownTime === 0) {
clearInterval(countdown);
this.enableButton(); //
}
}, 1000);
},
bindPhone() {
let reg = /^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\d{8}$/;
if (!reg.test(this.phone)) {
uni.showToast({
icon: 'none',
title: '请输入正确的11位手机号'
})
this.phone = '';
return false;
}
if (!this.validaCode) {
uni.showToast({
icon: 'none',
title: '请输入验证码'
})
return false;
}
request({
url: '/rescue/updateUserQx',
method: 'post',
data: {
phone: this.phone,
code: this.validaCode
},
headers: {
isToken: false,
},
header: {
Authorization: 'Bearer ' + uni.getStorageSync('validaCodeToken')
}
}).then(res => {
console.log('updateUserQx: ',res);
if (res.code == 200) {
setToken(uni.getStorageSync('validaCodeToken'))
uni.reLaunch({
url: '/pages/home/home'
})
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
})
}
}
}
</script>
<style lang="less" scoped>
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
row-gap: 40rpx;
background-color: #F5F5F5;
.title {
font-size: 40rpx;
font-weight: bold;
margin-bottom: 20rpx;
}
.formItem {
box-sizing: border-box;
width: 680rpx;
height: 100rpx;
border-radius: 50rpx;
background-color: #fff;
padding: 0 30rpx;
display: flex;
align-items: center;
column-gap: 16rpx;
.formItemInput {
flex: 1;
width: 0;
}
.validaCodeBtn {
background-color: #1890ff;
color: #fff;
height: 60rpx;
border-radius: 30rpx;
padding: 0 30rpx;
font-size: 28rpx;
display: flex;
align-items: center;
justify-content: center;
&.disabled {
background-color: #1890ff99;
}
}
}
.submit {
height: 100rpx;
border-radius: 50rpx;
width: 600rpx;
background-color: #1890ff;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>

View File

@ -1,52 +1,82 @@
<template>
<view class="content">
<view class="top">
<view class="inputs" >
<view class="touxiang">
<image src="../../static/xinlogo.png" mode=""></image>
</view>
<view class="inputs">
<input type="text" v-model="userName" placeholder="请输入用户名">
</view>
<view class="inputs">
<input type="password" v-model="wrod" placeholder="请输入密码">
<input type="password" v-model="wrod" placeholder="请输入密码">
</view>
<view class="wjworb" @click="goforgot()">
<view class="">忘记密码</view>
</view>
</view>
<view class="dl" @click="getlogin()">
<text> </text>
</view>
<!-- <view class="hging">
<text>没有账号</text>
<text style="color: #0078FF;" @click="goregister()">立即注册</text>
</view> -->
<view class="dbottom">
<view class="quanzi" v-if="qindex == false " @click="qindex =! qindex"></view>
<view class="lanquanzi" v-if="qindex == true" @click="qindex =! qindex">
<uni-icons type="checkmarkempty" color="#ffffff" size="14"></uni-icons>
</view>
<text>请仔细阅读</text>
<text class="lan">用户协议</text>
<text></text>
<text class="lan">隐私政策</text>
</view>
</view>
</template>
<script>
import request from '../../utils/request';
import {setToken, setTenantId} from '../../utils/auth.js'
import {
loginAppuserName,
} from '@/api/login.js';
import {
setToken,
getToken,
setTenantId,
removeToken
} from '@/utils/auth.js'
import {
login,
getInfo,
getTenantIdByWebsite
} from '@/api/login.js'
export default{
data(){
return{
import drawQrcode from "weapp-qrcode";
export default {
data() {
return {
//openId
openId: "",
phoneNumber: "",
baseUrl: this.$baseUrl,
isButtonDisabled: false,
countdownTime: 60,
qh:[
{text:'密码登录'},
{text:'验证码登录'}
],
userName:'',
yzm:'',
wrod:'',
activeid:0,
qindex: false,
sfindex: 'user',
userName: '',
yzm: '',
wrod: '',
activeid: 0,
tenantCode: 'lanan'
}
},
created() {
// getTenantIdByWebsite(this.tenantCode).then(res => {
// const tenantId = res.data;
// if (tenantId && tenantId >= 0) {
// setTenantId(tenantId)
// }
// })
},
computed: {
groupChange(n) {
console.log('groupChange', n);
},
radioChange(n) {
console.log('radioChange', n);
},
buttonText() {
if (this.isButtonDisabled) {
return `${this.countdownTime}s 后重新发送`;
@ -55,76 +85,286 @@ export default{
}
},
},
methods:{
//
getlogin(){
if(this.userName == ''){
uni.showToast({
title:'输入框不能为空!',
icon:'none'
mounted() {
},
created(){
this.checkIfLogin()
},
onShow() {
},
methods: {
checkIfLogin(){
if(getToken()){
//
uni.reLaunch({
url: '/pages/home/home'
})
return
}else{
//
// this.checkIfCode()
}
let data ={
username:this.userName,
password:this.wrod,
type:0
},
/**
*判断是否有code
* */
checkIfCode(){
let code = this.getUrlCode('code')
if (code !== null && code !== "") {
//
this.getOpenidAndUserinfo(code)
} else {
uni.showToast({
title: '未获取到授权信息,请重新进入!!',
icon: 'none'
})
}
console.log('密码请求',data);
request({
url: '/rescue/loginQx',
method: 'post',
data: data
}).then((res)=>{
console.log('密码请求',res);
if(res.code == 200){
setToken(res.data.accessToken)
uni.reLaunch({
url: '/pages/index/index'
},
/**
* 微信自动登录
* @param {Object} code 用户code
*/
async getOpenidAndUserinfo(code) {
await request({
url: '/userClient/weChat/wechatLogin',
method: 'get',
params: {code:code}
}).then((res) => {
if (res.code==200) {
if(res.data.hasOwnProperty("accessToken")){
setToken(res.data.accessToken)
uni.reLaunch({
url: '/pages/home/home'
})
}else{
//
this.openId = res.data
//
this.goregister()
}
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
})
},
/**
* 获取路径中的参数
* @param {Object} name
*/
getUrlCode(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ''])[1].replace(/\+/g, '%20')) || null
},
setidentity(text) {
this.sfindex = text
},
//
getlogin() {
if (this.qindex != true) {
uni.showToast({
icon: "none",
title: "请阅读并勾选用户协议",
duration: 2000
})
return;
}
if (this.userName == '') {
uni.showToast({
title: '输入框不能为空!',
icon: 'none'
})
return
}
uni.setStorageSync('identity', this.sfindex);
const loginFun = () => {
const data = {
username: this.userName,
password: this.wrod,
type: 0
}
loginAppuserName(data).then(res => {
if (res.code==200) {
if(res.data.hasOwnProperty("accessToken")){
setToken(res.data.accessToken)
uni.reLaunch({
url: '/pages/home/home'
})
}else{
uni.showToast({
title: '登录失败',
icon: 'none'
})
}
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
// if (res.data.needMobile === "1") {
// uni.navigateTo({
// url: '/pages/login/bindPhoe'
// })
// uni.setStorageSync('validaCodeToken', res.data.accessToken)
// } else {
// setToken(res.data.accessToken)
// uni.reLaunch({
// url: '/pages/home/home'
// })
// }
})
}
getTenantIdByWebsite(this.tenantCode).then(res => {
if (res.code === 200 && res.data && res.data.length > 0) {
uni.showActionSheet({
itemList: res.data.map(m => m.name),
success: ({
tapIndex
}) => {
setTenantId(res.data[tapIndex].id)
loginFun()
}
})
} else {
setTenantId('')
loginFun()
}
})
},
getxz(index) {
this.activeid = index
},
goregister() {
uni.navigateTo({
url: '/pages/my/register?openId='+this.openId
})
},
goforgot() {
uni.navigateTo({
url: '/pages/login/forgot'
})
},
goselect() {
console.log('执行去救援', this.sfindex);
// pages/rescue/trafficPolice
if (this.sfindex == 'police') {
uni.reLaunch({
url: '/pages/rescue/trafficPolice'
})
} else {
uni.reLaunch({
url: '/pages/rescue/rescue'
})
}
},
//
sendVerificationCode() {
let reg = /^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))\d{8}$/;
if (!reg.test(this.userName)) {
uni.showToast({
icon: 'none',
title: '请输入正确的11位手机号'
})
this.userName = '';
return false;
}
if (this.isButtonDisabled) {
return; //
}
const data = {
phone: this.userName,
}
request({
url: '/loginSmsCode',
method: 'post',
params: data
}).then((res) => {
console.log('验证码', res);
if (res.code == 200) {
uni.showToast({
title: '验证码已发送 请注意查收',
icon: 'none'
})
} else {
uni.showToast({
title: '网络不佳请稍后再试',
icon: 'none'
})
}
})
this.disableButton(); //
this.startCountdown(); //
},
disableButton() {
this.isButtonDisabled = true;
},
enableButton() {
this.isButtonDisabled = false;
},
startCountdown() {
let countdown = setInterval(() => {
this.countdownTime--;
if (this.countdownTime === 0) {
clearInterval(countdown);
this.enableButton(); //
}
}, 1000);
},
}
}
</script>
<style scoped lang="scss">
.jsq{
.jsq {
border: none !important;
font-size: 14px;
font-weight: 400;
color: #0078FF;
}
button {
border: none !important;
background: none !important;
margin: 0px;
display: block;
}
button:focus {
color: #0078FF;
outline: none;
box-shadow: none;
}
.content{
.content {
box-sizing: border-box;
}
.top{
.top {
box-sizing: border-box;
padding: 0px 27px;
padding-top: 100px;
background-image: url('../../static/loginbj.png');
// background-color:lightseagreen;
//background-image: url('../../static/loginbj.png');
// background-image: url('../../static/loginbj.png');
background-size: cover;
background-position: center;
width: 100%;
// height: 385px;
}
.touxiang{
.touxiang {
width: 88px;
height: 88px;
border-radius: 10px;
@ -132,16 +372,19 @@ button:focus {
margin: 0 auto;
margin-bottom: 40px;
overflow: hidden;
image{
image {
width: 100%;
height: 100%;
}
}
.twotap{
.twotap {
width: 100%;
display: flex;
align-items: center;
view{
view {
font-size: 15px;
font-family: Microsoft YaHei;
font-weight: 400;
@ -149,19 +392,22 @@ button:focus {
margin-right: 38.5px;
}
}
.blck{
.blck {
color: #333333 !important;
font-weight: bold !important;
}
.inputs{
.inputs {
box-sizing: border-box;
padding: 16px 0px;
display: flex;
align-items: center;
border-bottom: 2px solid #E8E8E8 ;
border-bottom: 2px solid #E8E8E8;
margin-top: 20px;
}
.wjworb{
.wjworb {
margin-top: 5px;
width: 100%;
display: flex;
@ -171,7 +417,8 @@ button:focus {
align-items: center;
}
.dl{
.dl {
width: 90%;
height: 44px;
background: linear-gradient(-46deg, #0853C4 0%, #4282D8 80%);
@ -184,7 +431,8 @@ button:focus {
align-items: center;
margin-top: 22px;
}
.hging{
.hging {
width: 100%;
text-align: center;
font-size: 14px;
@ -192,26 +440,30 @@ button:focus {
color: #636363;
margin-top: 20px;
}
.wx{
.wx {
width: 38px;
height: 38px;
overflow: hidden;
box-sizing: border-box;
margin: 0px auto;
margin-top: 20px;
image{
image {
width: 100%;
height: 100%;
}
}
.hui{
.hui {
font-size: 10px;
width: 100%;
text-align: center;
font-weight: 400;
color: #666666;
}
.dbottom{
.dbottom {
width: 100%;
text-align: center;
font-size: 12px;
@ -219,8 +471,74 @@ button:focus {
margin-top: 40px;
position: fixed;
bottom: 25px;
display: flex;
align-items: center;
justify-content: center;
}
.lan{
.quanzi {
width: 14px;
height: 14px;
border: 1px solid #666666;
border-radius: 50%;
margin-right: 10px;
}
.lanquanzi {
width: 14px;
height: 14px;
border: 1px solid #0078FF;
border-radius: 50%;
margin-right: 10px;
background: #0078FF;
color: white;
}
.lan {
color: #0078FF;
}
.jiuzhong {
width: 90%;
margin: 10px auto;
display: flex;
align-items: center;
}
.dist {
display: flex;
align-items: center;
margin: 0px 10px;
}
.d-zi {
font-size: 14px;
}
.d-qian {
width: 14px;
height: 14px;
margin-right: 5px;
overflow: hidden;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
border: 1px solid #666666;
color: white;
}
.d-qian-lan {
width: 14px;
height: 14px;
margin-right: 5px;
overflow: hidden;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
background: #0078FF;
border: 1px solid #0078FF;
color: white;
}
</style>

View File

@ -1,6 +1,40 @@
<template>
<view>
<view class="container">
<v-navigation-bar title-color="#333" background-color="#fff" title="卡卷包">
</v-navigation-bar>
<view class="tabbar">
<view v-for="item in tabList" :key="item.value" class="tabItem" :class="{active: activeKey === item.value}">
{{item.title}}
<view v-if="activeKey === item.value" class="activeLine">
</view>
</view>
</view>
<view class="body">
<view class="cardItem">
<view class="cardItemTop">
<!-- <image class="cardImg" src="" mode="aspectFill"></image> -->
<view class="cardImg">
<view class="cardImgText">车辆保养卡</view>
<image class="cardImgBg" src="../../static/images/cardRollBg.png" mode="aspectFit"></image>
</view>
<view class="cardInfo">
<view class="cardName">车辆保养卡</view>
<view class="cardEndDate">2024-09-20</view>
</view>
<view class="cardInfoRight">
<view class="cardNum">
<text class="cardNumValue">4</text>
</view>
<view class="cardLabel">可用次数</view>
</view>
</view>
<view class="cardItemBottom">
<view class="useSm">使用说明</view>
<view class="useBtn">去使用</view>
</view>
</view>
</view>
</view>
</template>
@ -13,12 +47,174 @@
},
data() {
return {
tabList: [{
value: 0,
title: '优惠卷'
},
{
value: 1,
title: '卡包'
}
],
activeKey: 0
};
}
}
</script>
<style lang="less">
<style lang="less" scoped>
.container {
height: 100%;
background-color: #F0F1F5;
</style>
display: flex;
flex-direction: column;
.body {
flex: 1;
height: 0;
box-sizing: border-box;
padding: 30rpx 0;
margin: 0 32rpx;
display: flex;
flex-direction: column;
row-gap: 20rpx;
overflow: auto;
.cardItem {
background: #FFFFFF;
border-radius: 16rpx 16rpx 16rpx 16rpx;
padding: 30rpx;
}
.cardItemTop {
display: flex;
align-items: center;
column-gap: 16rpx;
padding-bottom: 32rpx;
border-bottom: 1px solid #ddd;
}
.cardImg {
width: 136rpx;
height: 100rpx;
background-color: #efefef;
display: flex;
align-items: center;
justify-content: center;
position: relative;
.cardImgText {
color: #fff;
font-size: 24rpx;
position: relative;
z-index: 2;
}
.cardImgBg {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 1;
}
}
.cardInfo {
flex: 1;
width: 0;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 6rpx 0;
.cardName {
font-size: 32rpx;
color: #333333;
}
.cardEndDate {
font-size: 24rpx;
color: #999999;
}
}
.cardInfoRight {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: 24rpx;
color: #FC4D4A;
.cardNumValue {
font-size: 64rpx;
}
.cardLabel {
color: #999999;
}
}
}
.cardItemBottom {
display: flex;
align-items: center;
justify-content: space-between;
padding: 30rpx 0 0;
.useSm {
font-size: 24rpx;
color: #999999;
}
.useBtn {
width: 144rpx;
height: 60rpx;
border-radius: 30rpx 30rpx 30rpx 30rpx;
border: 1rpx solid #FC4D4A;
font-size: 28rpx;
color: #FC4D4A;
display: flex;
align-items: center;
justify-content: center;
}
}
}
.tabbar {
background-color: #fff;
display: flex;
align-items: center;
.tabItem {
flex: 1;
width: 0;
display: flex;
justify-content: center;
padding: 30rpx 0;
position: relative;
}
.activeLine {
width: 52rpx;
height: 8rpx;
background: #009EDA;
border-radius: 4rpx 4rpx 4rpx 4rpx;
position: absolute;
left: 50%;
bottom: 2rpx;
transform: translate(-50%, 0);
}
}
</style>

View File

@ -5,17 +5,19 @@
<view v-for="(item, index) in evaluateList" :key="index" class="item">
<view class="date">07-06</view>
<view class="message">
这家修理厂的喷漆工艺非常不错特别均匀师傅也很细心如果您需要做喷漆或者维修服务不要错过这里
<!-- 这家修理厂的喷漆工艺非常不错特别均匀师傅也很细心如果您需要做喷漆或者维修服务不要错过这里-->
{{item.commentDesc}}
</view>
<view class="rate">
<!-- 设置尺寸大小 -->
<uni-rate allow-half :value="3.5"/>
<uni-rate allow-half :value="item.commentStar"/>
</view>
<view class="shopInfo">
<image class="shopImg" src="" mode="aspectFill"></image>
<image class="shopImg" :src="item.image" mode="aspectFill"></image>
<view class="shopInfo_content">
<view class="shopName">顺捷汽车维修搭电救援补胎中心</view>
<view class="shopAddress">济南市历下区福瑞达历下护理院东南门旁</view>
<!-- <view class="shopName">顺捷汽车维修搭电救援补胎中心</view>-->
<view class="shopName">{{ item.tenantName }}</view>
<!-- <view class="shopAddress">济南市历下区福瑞达历下护理院东南门旁</view>-->
</view>
</view>
</view>
@ -25,6 +27,7 @@
<script>
import VNavigationBar from '@/components/VNavigationBar.vue'
import request from "@/utils/request";
export default {
components: {
@ -32,9 +35,33 @@
},
data() {
return {
evaluateList: [{}, {}, {}]
// evaluateList: [{}, {}, {}],
queryParams:{
pageNum: 1,
pageSize: 10
},
evaluateList: [],
};
}
},
onShow(){
this.getAppraisePage()
},
methods:{
async getAppraisePage(){
const res = await request({
url: "/userClient/repair/order/getAppraise",
method: "get",
params:{
...this.queryParams,
pageNo: this.queryParams.pageNum
}
})
this.evaluateList = res.data.records
this.evaluateList.forEach(item => {
item.image = require("@/static/images/inImage.jpg")
})
}
}
}
</script>
@ -56,44 +83,44 @@
flex-direction: column;
row-gap: 10rpx;
}
.item {
background-color: #fff;
padding: 30rpx;
display: flex;
flex-direction: column;
row-gap: 20rpx;
}
.date {
font-weight: bold;
font-size: 36rpx;
color: #333333;
}
.shopInfo {
display: flex;
align-items: stretch;
column-gap: 20rpx;
.shopImg {
width: 160rpx;
height: 100rpx;
border-radius: 8rpx 8rpx 8rpx 8rpx;
background-color: #efefef;
}
.shopInfo_content {
flex: 1;
width: 0;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 6rpx 0;
}
.shopName {
font-size: 28rpx;
color: #333333;
@ -104,4 +131,4 @@
}
}
}
</style>
</style>

View File

@ -48,7 +48,7 @@
<image class="menu-item-more" src="../../static/icons/homeInfoMore.png" mode="widthFix"></image>
</view>
</view>
<view class="menuCard">
<view @click="goToPage(item.path)" v-for="(item, index) in menuCard2" :key="item.title" class="menu-item">
<image class="menu-item-icon" :src="item.icon" mode="aspectFit"></image>
@ -74,10 +74,11 @@
return {
menuCard1: [
{ title: '我的资料', icon: require('@/static/icons/my-menu-icon1.png'), path: '/pages/my/myInfo' },
{ title: '消息中心', icon: require('@/static/icons/my-menu-icon2.png'), path: '/pages/my/message' },
{ title: '我的卡券', icon: require('@/static/icons/my-menu-icon5.png'), path: "/pages/my/cardRoll" },
{ title: '我的评价', icon: require('@/static/icons/my-menu-icon3.png'), path: '/pages/my/evaluate' },
],
menuCard2: [
{ title: '消息中心', icon: require('@/static/icons/my-menu-icon2.png'), path: '/pages/my/message' },
{ title: '客服中心', icon: require('@/static/icons/my-menu-icon4.png') },
{ title: '操作指南', icon: require('@/static/icons/my-menu-icon5.png'), path: "/pages/guideList/guideList" },
]
@ -240,7 +241,7 @@
height: 32rpx;
}
}
.menuCard {
width: 686rpx;
margin: 30rpx auto 0;
@ -275,11 +276,11 @@
display: flex;
align-items: center;
justify-content: center;
font-weight: bold;
font-size: 20rpx;
color: #FFFFFF;
}
}
}
</style>
</style>

View File

@ -1,189 +1,305 @@
<template>
<view class="container">
<VNavigationBar title-color="#333" background-color="#fff" title="信息填写"></VNavigationBar>
<view class="body">
<view class="formItem">
<view class="formLabel">姓名</view>
<view class="formContainer">
<input placeholder="请填写你的真实姓名" type="text" />
</view>
</view>
<view class="formItem">
<view class="formLabel">性别</view>
<view class="formContainer">
<radio-group class="radioGroup">
<label class="radio">
<radio activeBackgroundColor="#009EDA" value="r1" checked="true" />
</label>
<label class="radio">
<radio activeBackgroundColor="#009EDA" value="r2" />
</label>
</radio-group>
</view>
</view>
<view class="formItem">
<view class="formLabel">省份</view>
<view class="formContainer">
<picker :range="addressRange" mode="multiSelector" @columnchange="addressColumnChangeFun">
<view class="formPicker">
<input class="formPickerInput" type="text" disabled="true" placeholder="请选择所在省份/城市/区" />
<image class="formPickerBtn" src="../../static/icons/homeInfoMore.png" mode="aspectFit">
</image>
</view>
</picker>
</view>
</view>
<view class="formItem">
<view class="formLabel">详细地址</view>
<view class="formContainer">
<picker :range="detailAddress" mode="multiSelector" @columnchange="detailColumnChangeFun">
<view class="formPicker">
<input class="formPickerInput" type="text" disabled="true" placeholder="请选择所在街道/小区" />
<image class="formPickerBtn" src="../../static/icons/homeInfoMore.png" mode="aspectFit">
</image>
</view>
</picker>
</view>
</view>
<view class="formItem">
<view class="formLabel">上传图片</view>
<view class="formContainer">
<view class="">
<uni-file-picker :image-styles="{width: 80, height: 80}" v-model="imageValue"
fileMediatype="image" limit="1" mode="grid" @select="select" @progress="progress"
@success="success" @fail="fail">
<image style="width: 160rpx;height: 160rpx;" src="../../static/icons/addImageIcon.png"
mode="aspectFit"></image>
</uni-file-picker>
</view>
</view>
</view>
</view>
</view>
<view class="container">
<VNavigationBar title-color="#333" background-color="#fff" title="信息填写"></VNavigationBar>
<view class="body">
<view class="formItem">
<view class="formLabel">姓名</view>
<view class="formContainer">
<input placeholder="请填写你的真实姓名" v-model="formData.cusName" type="text"/>
</view>
</view>
<view class="formItem">
<view class="formLabel">性别</view>
<view class="formContainer">
<radio-group name="group1" class="radioGroup" :bindchange="radioChange">
<label class="radio" v-for="(item, index) in radioSexItems" :key="item.value">
<radio activeBackgroundColor="#009EDA" :value="item.value" :checked="item.checked"/>
{{item.name}}
</label>
</radio-group>
</view>
</view>
<view class="formItem">
<view class="formLabel">身份证号</view>
<view class="formContainer">
<input placeholder="请填写你的身份证号" v-model="formData.idCard" type="text"/>
</view>
</view>
<!-- <view class="formItem">-->
<!-- <view class="formLabel">生日</view>-->
<!-- <view class="formContainer">-->
<!-- <picker mode="date" :value="formData.birthday" start="1900-01-01" end="2050-12-12" :bindchange="bindDateChange">-->
<!-- </picker>-->
<!-- </view>-->
<!-- </view>-->
<view class="formItem">
<view class="formLabel">手机号</view>
<view class="formContainer">
<input placeholder="请填写你的手机号" v-model="formData.phoneNumber" type="text"/>
</view>
</view>
<view class="formItem">
<view class="formLabel">联系地址</view>
<view class="formContainer">
<textarea placeholder="请填写你的联系地址" v-model="formData.address" maxlength="300"/>
</view>
</view>
<view class="dl" @click="getlogin()">
<text>注册</text>
</view>
</view>
</view>
</template>
<script>
import VNavigationBar from '@/components/VNavigationBar.vue'
import VNavigationBar from '@/components/VNavigationBar.vue'
import request from "../../utils/request";
import {
setToken,
} from '@/utils/auth.js'
export default {
components: {
VNavigationBar
},
data() {
return {
detailAddress: [
['a', 'b'],
['b', 'a']
],
addressRange: [
['山东'],
['济南'],
['历下区']
]
};
},
methods: {
detailColumnChangeFun({
detail
}) {
if (detail.column === 0) {
//
this.$set(this.detailAddress, 1, ['m', 'n'])
}
},
addressColumnChangeFun({
detail
}) {
if (detail.column === 0) {
//
this.$set(this.detailAddress, 1, ['济宁'])
//
this.$set(this.detailAddress, 2, ['任城'])
} else if (detail.column === 1) {
//
this.$set(this.detailAddress, 2, ['任城'])
}
},
//
select(e) {
console.log('选择文件:', e)
},
//
progress(e) {
console.log('上传进度:', e)
},
export default {
components: {
VNavigationBar
},
data() {
return {
formData: {
openId: "",
cusName: "",
sex: "",
idCard:"",
phoneNumber:"",
address:"",
},
//
radioSexItems: [
{ name: '男', value: '0', checked: true },
{ name: '女', value: '1', checked: false },
],
detailAddress: [
['a', 'b'],
['b', 'a']
],
addressRange: [
['山东'],
['济南'],
['历下区']
]
};
},
onLoad(e) {
this.formData.openId = e.openId
},
methods: {
/**
* 注册
*/
async getlogin(){
//
if(this.checkForm()){
//
this.formData.sex = this.radioSexItems.filter(item => item.checked ===true)[0].value;
await request({
url: '/base/custom-app/register',
method: 'post',
data: this.formData
}).then((res) => {
if (res.code==200) {
if(res.data.hasOwnProperty("accessToken")){
setToken(res.data.accessToken)
uni.reLaunch({
url: '/pages/home/home'
})
}
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
})
}
},
checkForm(){
if(""==this.formData.cusName){
uni.showToast({
title: '请填写姓名',
icon: 'none'
})
return false
}
if(""==this.formData.idCard || !this.isValidID(this.formData.idCard)){
uni.showToast({
title: '请填写正确的身份证号',
icon: 'none'
})
return false
}
if(""==this.formData.phoneNumber || !this.isValidPhoneNumber(this.formData.phoneNumber)){
uni.showToast({
title: '请填写手机号',
icon: 'none'
})
return false
}
if(""==this.formData.address){
uni.showToast({
title: '请填写联系地址',
icon: 'none'
})
return false
}
return true;
},
/**
* 校验身份证号是否合法
* @param id
* @returns {boolean}
*/
isValidID(id) {
const regex = /^[1-9]\d{5}(18|19|20|21|22)?\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}(\d|[Xx])$/;
return regex.test(id);
},
/**
* 校验手机号
* @param phoneNumber
* @returns {boolean}
*/
isValidPhoneNumber(phoneNumber) {
const regex = /^1[3-9]\d{9}$/;
return regex.test(phoneNumber);
},
bindDateChange(e) {
this.formData.birthday = e.detail.value;
},
radioChange: function(e) {
let radioItems = this.radioSexItems;
for (let i = 0, len = radioItems.length; i < len; ++i) {
radioItems[i].checked = radioItems[i].value === e.detail.value;
}
this.radioSexItems = radioItems;
},
submit() {
this.$refs.form.validate().then(res => {
console.log('表单数据信息:', res);
}).catch(err => {
console.log('表单错误信息:', err);
})
},
detailColumnChangeFun({
detail
}) {
if (detail.column === 0) {
//
this.$set(this.detailAddress, 1, ['m', 'n'])
}
},
addressColumnChangeFun({
detail
}) {
if (detail.column === 0) {
//
this.$set(this.detailAddress, 1, ['济宁'])
//
this.$set(this.detailAddress, 2, ['任城'])
} else if (detail.column === 1) {
//
this.$set(this.detailAddress, 2, ['任城'])
}
},
//
select(e) {
console.log('选择文件:', e)
},
//
progress(e) {
console.log('上传进度:', e)
},
//
success(e) {
console.log('上传成功')
},
//
success(e) {
console.log('上传成功')
},
//
fail(e) {
console.log('上传失败:', e)
}
}
}
//
fail(e) {
console.log('上传失败:', e)
}
}
}
</script>
<style lang="less" scoped>
.container {
height: 100%;
display: flex;
flex-direction: column;
.container {
height: 100%;
display: flex;
flex-direction: column;
.body {
flex: 1;
height: 0;
overflow: auto;
padding: 20rpx 0;
}
.body {
flex: 1;
height: 0;
overflow: auto;
padding: 20rpx 0;
}
.formItem {
padding: 40rpx 0;
margin: 0 32rpx;
border-bottom: 1rpx solid #EEEEEE;
}
.formItem {
padding: 40rpx 0;
margin: 0 32rpx;
border-bottom: 1rpx solid #EEEEEE;
}
.formLabel {
font-weight: 500;
font-size: 28rpx;
color: #333333;
padding-bottom: 20rpx;
}
.formLabel {
font-weight: 500;
font-size: 28rpx;
color: #333333;
padding-bottom: 20rpx;
}
.radioGroup {
display: flex;
align-items: center;
column-gap: 100rpx;
}
.radioGroup {
display: flex;
align-items: center;
column-gap: 100rpx;
}
.radio {
display: flex;
align-items: center;
column-gap: 20rpx;
}
.radio {
display: flex;
align-items: center;
column-gap: 20rpx;
}
/* #ifdef MP-WEIXIN */
radio {
filter: hue-rotate(90deg);
}
/* #ifdef MP-WEIXIN */
radio {
filter: hue-rotate(90deg);
}
/* #endif */
.formPicker {
display: flex;
align-items: center;
column-gap: 20rpx;
}
/* #endif */
.formPicker {
display: flex;
align-items: center;
column-gap: 20rpx;
}
.formPickerInput {
flex: 1;
width: 0;
}
.formPickerInput {
flex: 1;
width: 0;
}
.formPickerBtn {
width: 28rpx;
height: 28rpx;
}
}
</style>
.formPickerBtn {
width: 28rpx;
height: 28rpx;
}
}
.dl {
width: 90%;
height: 44px;
background: linear-gradient(-46deg, #0853C4 0%, #4282D8 80%);
border-radius: 5px;
margin: 0 auto;
font-size: 16px;
color: #FFFFFF;
display: flex;
justify-content: center;
align-items: center;
margin-top: 22px;
}
</style>

View File

@ -1,186 +1,419 @@
<template>
<view class="container">
<VNavigationBar title="车辆详情" background-color="#fff" title-color="#333"></VNavigationBar>
<view class="body">
<view class="card">
<view class="formItem">
<text class="formLabel">车辆照片</text>
<image class="carImg" src="" mode="aspectFill"></image>
</view>
<view class="formItem">
<text class="formLabel">车牌号</text>
<text class="formValue">鲁A 781NB</text>
</view>
<view class="formItem">
<text class="formLabel">车辆持有人</text>
<text class="formValue">魏书豪</text>
</view>
<view class="formItem">
<text class="formLabel">持有人电话</text>
<text class="formValue">15726576890</text>
</view>
</view>
<view class="card">
<view class="formItem1">
<view class="labelVal">
<text class="formLabel">车辆年检时间</text>
<text class="formValue">2024</text>
</view>
<image class="formImg" src="" mode="aspectFill"></image>
</view>
<view class="formItem1">
<view class="labelVal">
<text class="formLabel">车辆保险时间</text>
<text class="formValue">2024</text>
</view>
<image class="formImg" src="" mode="aspectFill"></image>
</view>
</view>
</view>
<view class="footer">
<view class="btnItem delete">
<uni-icons type="trash" color="#F92C2C"></uni-icons>
删除
</view>
<view class="line"></view>
<view class="btnItem edit">
<uni-icons type="compose" color="#0174F6"></uni-icons>
编辑
</view>
</view>
</view>
<view class="container">
<VNavigationBar title="车辆详情" background-color="#fff" title-color="#333"></VNavigationBar>
<view class="body">
<view class="card">
<view class="formItem">
<text class="formLabel">车牌号</text>
<input type="text" placeholder="请输入文本" v-model="car.licenseNumber"/>
</view>
<view class="formItem">
<text class="formLabel">品牌</text>
<picker @change="brandChange" :value="brandIndex" :range="brandNamesComputed">
<view class="uni-input">{{ brandNamesComputed[brandIndex] }}</view>
</picker>
</view>
<view class="formItem">
<text class="formLabel">型号</text>
<input type="text" placeholder="请输入文本" v-model="car.carModelInput"/>
</view>
<view class="formItem">
<text class="formLabel">车辆类别</text>
<picker @change="categoryChange" :value="categoryIndex" :range="categoryNamesComputed">
<view class="uni-input">{{ categoryNamesComputed[categoryIndex] }}</view>
</picker>
</view>
<view class="formItem">
<text class="formLabel">车辆性质</text>
<picker @change="natureChange" :value="natureIndex" :range="natureNamesComputed">
<view class="uni-input">{{ natureNamesComputed[natureIndex] }}</view>
</picker>
</view>
<view class="formItem">
<text class="formLabel">注册日期</text>
<picker
mode="date"
:value="car.carRegisterDate"
start="2020-01-01"
end="2030-12-31"
@change="bindDateChange1">
<view style="margin-left: 10rpx">
{{ car.carRegisterDate}}
</view>
</picker>
</view>
<!-- <view class="formItem">-->
<!-- <text class="formLabel">车辆图片</text>-->
<!-- <u-upload-->
<!-- :action="uploadUrl"-->
<!-- :headers="headers"-->
<!-- :file-list="fileList"-->
<!-- :max-count="3"-->
<!-- :show-upload-btn="true"-->
<!-- @after-read="afterRead"-->
<!-- @delete="deleteFile"-->
<!-- @success="uploadSuccess"-->
<!-- @fail="uploadFail"-->
<!-- ></u-upload>-->
<!-- </view>-->
</view>
</view>
<view class="footer">
<view class="btnItem edit" @click="submit" v-if="bo2">
确定
</view>
<view class="btnItem delete" v-if="bo1" @click="del">
<uni-icons type="trash" color="#F92C2C"></uni-icons>
删除
</view>
<view class="line" v-if="bo1"></view>
<view class="btnItem edit" v-if="bo1" @click="update">
<uni-icons type="compose" color="#0174F6"></uni-icons>
保存
</view>
</view>
</view>
</template>
<script>
import VNavigationBar from '@/components/VNavigationBar.vue'
export default {
components: {
VNavigationBar,
},
data() {
return {
import VNavigationBar from '@/components/VNavigationBar.vue';
import request from "../../utils/request";
}
},
methods: {
export default {
components: {
VNavigationBar
},
data() {
return {
}
}
// uploadUrl: 'https://your-server.com/upload',
// headers: {},
// fileList: [],
car: {
//
licenseNumber: '',
//
carModelInput: '',
// id
carBrand:'',
//
carCategory:'',
//
carNature:'',
//
carRegisterDate:'2024-09-24',
},
bo1: false,
bo2: true,
categoryIndex: 0,
natureIndex: 0,
brandIndex: 0,
categoryList: [],
natureList: [],
brandList: []
};
},
//
computed: {
// picker range
brandNamesComputed() {
return this.brandList.map(item => item.brandName);
},
natureNamesComputed() {
return this.natureList.map(item => item.label);
},
categoryNamesComputed() {
return this.categoryList.map(item => item.label);
}
},
onLoad(options) {
//
if (options.car) {
//
this.car = JSON.parse(decodeURIComponent(options.car));
console.log('初始化页面数据', this.car)
this.bo1 = true;
this.bo2 = false;
} else {
//
this.bo1 = false;
this.bo2 = true;
}
//
this.getCategoryList();
this.getNatureList();
this.getBrandList();
},
methods: {
// afterRead(file) {
// console.log('');
// },
// deleteFile(file, index) {
// console.log('');
// this.fileList.splice(index, 1);
// },
// uploadSuccess(res, file) {
// console.log('', res);
// },
// uploadFail(error, file) {
// console.log('', error);
// },
//
brandChange(event) {
//
const newIndex = event.detail.value;
this.brandIndex = newIndex;
//
this.car.carBrand = this.brandList[newIndex].id;
},
//
categoryChange(event) {
const newIndex = event.detail.value;
this.categoryIndex = newIndex;
//
this.car.carCategory = this.categoryList[newIndex].value;
},
//
natureChange(event) {
const newIndex = event.detail.value;
this.natureIndex = newIndex;
//
this.car.carNature = this.natureList[newIndex].value;
},
//
bindDateChange1(e) {
this.car.carRegisterDate = e.target.value; // datadate
},
//
async getCategoryList() {
let res = await request({
url: '/admin-api/system/dict-data/type?type=car_category',
method: 'get',
noTenantId: false
})
if (res.code == 200) {
console.log('车辆类别', res.data)
this.categoryList = res.data;
if (this.bo2 == true){
this.car.carCategory = res.data[0].value;
}
else {
// index
this.categoryList.forEach((item, index) => {
if (item.value == this.car.carCategory) {
this.categoryIndex = index;
}
})
}
}
},
//
async getNatureList() {
let res = await request({
url: '/admin-api/system/dict-data/type?type=car_nature',
method: 'get',
noTenantId: false
})
if (res.code == 200) {
console.log('车辆性质', res.data)
this.natureList = res.data;
if (this.bo2 == true){
this.car.carNature = res.data[0].value;
}
else {
// index
this.natureList.forEach((item, index) => {
if (item.value == this.car.carNature) {
this.natureIndex = index;
}
})
}
}
},
//
async getBrandList() {
let res = await request({
url: '/userClient/base/carBrand/list',
method: 'get',
})
if (res.code == 200) {
console.log('车辆品牌', res.data)
this.brandList = res.data;
if (this.bo2 == true){
this.car.carBrand= res.data[0].id;
}else {
// index
this.brandList.forEach((item, index) => {
if (item.id == this.car.carBrand) {
this.brandIndex = index;
}
})
}
}
},
//
async submit() {
let res = await request({
url: '/userClient/base/myCar/create',
method: 'POST',
data: this.car,
})
if (res.code == 200) {
//
uni.navigateBack();
}
},
//
async del() {
let res = await request({
url: `/userClient/base/myCar/delete?id=${this.car.id}`,
method: 'Delete',
})
if (res.code == 200) {
//
uni.navigateBack();
}
},
//
async update() {
let res = await request({
url: `/userClient/base/myCar/update`,
data: this.car,
method: 'Put',
})
if (res.code == 200) {
}
}
}
}
</script>
<style lang="less" scoped>
.container {
box-sizing: border-box;
height: 100%;
background-color: #F3F5F7;
display: flex;
flex-direction: column;
.body {
flex: 1;
height: 0;
overflow: auto;
.card {
margin: 20rpx 0;
padding: 0 32rpx;
background-color: #fff;
.container {
box-sizing: border-box;
height: 100%;
background-color: #f3f5f7;
display: flex;
flex-direction: column;
.formItem {
box-sizing: border-box;
width: 686rpx;
margin: 0 auto;
padding: 40rpx;
.body {
flex: 1;
height: 0;
overflow: auto;
display: flex;
align-items: center;
justify-content: space-between;
column-gap: 20rpx;
.card {
margin: 20rpx 0;
padding: 0 32rpx;
background-color: #fff;
border-bottom: 1rpx solid #DDDDDD;
&:last-child {
border: none;
}
}
.labelVal {
display: flex;
align-items: center;
justify-content: space-between;
column-gap: 20rpx;
}
.formItem1 {
box-sizing: border-box;
width: 686rpx;
margin: 0 auto;
padding: 40rpx;
border-bottom: 1rpx solid #DDDDDD;
&:last-child {
border: none;
}
}
.formItem {
box-sizing: border-box;
width: 686rpx;
margin: 0 auto;
padding: 40rpx;
.formLabel {
font-size: 32rpx;
color: #333333;
}
display: flex;
align-items: center;
justify-content: space-between;
column-gap: 20rpx;
.formValue {
flex: 1;
width: 0;
text-align: right;
font-size: 32rpx;
color: #999999;
}
.carImg {
width: 240rpx;
height: 150rpx;
border-radius: 8rpx 8rpx 8rpx 8rpx;
background-color: #efefef;
}
.formImg {
margin-top: 30rpx;
width: 240rpx;
height: 150rpx;
border-radius: 12rpx 12rpx 12rpx 12rpx;
background-color: #efefef;
}
}
border-bottom: 1rpx solid #dddddd;
}
&:last-child {
border: none;
}
}
.footer {
background: #FFFFFF;
display: flex;
align-items: center;
.labelVal {
display: flex;
align-items: center;
justify-content: space-between;
column-gap: 20rpx;
}
.line {
width: 2rpx;
background-color: #DDDDDD;
}
.btnItem {
flex: 1;
width: 0;
padding: 34rpx 0;
.formLabel {
font-size: 32rpx;
color: #333333;
}
display: flex;
align-items: center;
justify-content: center;
.formValue {
flex: 1;
width: 0;
text-align: right;
font-size: 32rpx;
color: #999999;
}
font-size: 32rpx;
.carImg {
width: 240rpx;
height: 150rpx;
border-radius: 8rpx 8rpx 8rpx 8rpx;
background-color: #efefef;
}
&.delete {
color: #F92C2C;
}
.formImg {
margin-top: 30rpx;
width: 240rpx;
height: 150rpx;
border-radius: 12rpx 12rpx 12rpx 12rpx;
background-color: #efefef;
}
}
}
&.edit {
color: #0174F6;
}
}
}
}
</style>
.footer {
background: #ffffff;
display: flex;
align-items: center;
.line {
width: 2rpx;
background-color: #dddddd;
}
.btnItem {
flex: 1;
width: 0;
padding: 34rpx 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
&.delete {
color: #f92c2c;
}
&.edit {
color: #0174f6;
}
}
}
}
</style>

View File

@ -1,118 +1,157 @@
<template>
<view class="container">
<VNavigationBar titleColor="rgba(0,0,0,0.9)" backgroundColor="#fff" title="我的车辆">
</VNavigationBar>
<view class="body">
<scroll-view style="height: 100%;" scroll-y="true">
<view class="carList">
<view v-for="(item, index) in carList" :key="index" class="carItem" @click="gotoDetail(item)">
<image class="carImage" src="" mode="aspectFit"></image>
<view class="carInfo">
<view class="carNum">{{ item.carNum }}</view>
<view class="name">车辆持有人{{ item.name }}</view>
<view class="phone">持有人电话{{ item.phone }}</view>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="addCarBtn">
<uni-icons color="#0174F6" type="plusempty"></uni-icons>
添加车辆
</view>
</view>
<view class="container">
<VNavigationBar titleColor="rgba(0,0,0,0.9)" backgroundColor="#fff" title="我的车辆"></VNavigationBar>
<view class="body">
<scroll-view style="height: 100%" scroll-y="true">
<view class="carList">
<view v-for="(item, index) in carList" :key="index" class="carItem" @click="gotoDetail(item)">
<image class="carImage" :src="config.baseImageUrl+item.logoImg" mode="aspectFit"></image>
<view class="carInfo">
<view class="carNum">{{ item.licenseNumber}}</view>
<view class="name">品牌{{ item.brandName }}</view>
<view class="phone">型号{{ item.carModelInput }}</view>
</view>
</view>
</view>
</scroll-view>
</view>
<view class="addCarBtn" @click="gotoDetail()">
<uni-icons color="#0174F6" type="plusempty"></uni-icons>
添加车辆
</view>
</view>
</template>
<script>
import VNavigationBar from '@/components/VNavigationBar.vue'
export default {
components: {
VNavigationBar
},
data() {
return {
carList: [{
carNum: '鲁A 781NB',
name: '魏书豪',
phone: '15726786903',
image: ''
}]
}
},
methods: {
gotoDetail() {
uni.navigateTo({
url: '/pages/myCar/carDetail'
})
}
}
}
import VNavigationBar from '@/components/VNavigationBar.vue';
import request from "../../utils/request";
import config from "config";
export default {
computed: {
config() {
return config
}
},
components: {
VNavigationBar
},
data() {
return {
carList: [
{
carNum: '鲁A 781NB',
name: '魏书豪',
phone: '15726786903',
image: ''
}
]
};
},
onLoad() {
//
this.getList();
},
onShow() {
//
this.getList();
},
methods: {
getList(){
request({
url: '/userClient/base/myCar/get',
method: 'GET',
}).then(res => {
console.log(res);
this.carList = res.data;
console.log('图片路径', config.baseImageUrl+this.carList[0].logoImg)
})
},
gotoDetail(item) {
if (item){
uni.navigateTo({
url: `/pages/myCar/carDetail?car=${encodeURIComponent(JSON.stringify(item))}`
});
}
else {
uni.navigateTo({
url: '/pages/myCar/carDetail'
});
}
}
}
};
</script>
<style scoped lang="less">
.container {
height: 100%;
display: flex;
flex-direction: column;
padding-bottom: env(safe-area-inset-bottom);
.container {
height: 100%;
display: flex;
flex-direction: column;
padding-bottom: env(safe-area-inset-bottom);
.body {
flex: 1;
height: 0;
background-color: #F3F5F7;
}
.body {
flex: 1;
height: 0;
background-color: #f3f5f7;
}
.carList {
display: flex;
flex-direction: column;
}
.carList {
display: flex;
flex-direction: column;
}
.carItem {
box-sizing: border-box;
width: 686rpx;
margin: 20rpx auto;
display: flex;
align-items: center;
padding: 30rpx;
background: #FFFFFF;
border-radius: 12rpx 12rpx 12rpx 12rpx;
column-gap: 20rpx;
}
.carItem {
box-sizing: border-box;
width: 686rpx;
margin: 20rpx auto;
display: flex;
align-items: center;
padding: 30rpx;
background: #ffffff;
border-radius: 12rpx 12rpx 12rpx 12rpx;
column-gap: 20rpx;
}
.carImage {
background-color: #eee;
width: 240rpx;
height: 150rpx;
border-radius: 8rpx 8rpx 8rpx 8rpx;
}
.carImage {
background-color: #eee;
width: 240rpx;
height: 150rpx;
border-radius: 8rpx 8rpx 8rpx 8rpx;
}
.carNum {
font-weight: bold;
font-size: 36rpx;
color: #333333;
margin-bottom: 20rpx;
}
.carNum {
font-weight: bold;
font-size: 36rpx;
color: #333333;
margin-bottom: 20rpx;
}
.name,
.phone {
font-weight: 500;
font-size: 28rpx;
color: #858BA0;
}
.name,
.phone {
font-weight: 500;
font-size: 28rpx;
color: #858ba0;
}
.addCarBtn {
padding: 34rpx 0;
background: #FFFFFF;
border-radius: 0rpx 0rpx 0rpx 0rpx;
.addCarBtn {
padding: 34rpx 0;
background: #ffffff;
border-radius: 0rpx 0rpx 0rpx 0rpx;
display: flex;
align-items: center;
justify-content: center;
column-gap: 12rpx;
display: flex;
align-items: center;
justify-content: center;
column-gap: 12rpx;
font-weight: 500;
font-size: 32rpx;
color: #0174F6;
}
}
</style>
font-weight: 500;
font-size: 32rpx;
color: #0174f6;
}
}
</style>

View File

@ -17,6 +17,7 @@
import VNavigationBar from '@/components/VNavigationBar.vue'
import tabBarVue from '@/components/tabBar/tabBar.vue'
import reservationOrderVue from '../../components/reservationOrder/reservationOrder.vue'
import request from "@/utils/request";
export default {
components: {
@ -26,25 +27,55 @@
},
data() {
return {
orderList: [{
title: '顺捷汽车维修搭电救援补胎中心',
status: '1',
address: '济南市历下区福瑞达历下护理院东南门旁',
phone: '15726506879',
busiTypeStr: '汽车维修'
},
{
title: '顺捷汽车维修搭电救援补胎中心',
status: '1',
address: '济南市历下区福瑞达历下护理院东南门旁',
phone: '15726506879',
busiTypeStr: '汽车维修'
}
]
// orderList: [{
// title: '',
// status: '1',
// address: '',
// phone: '15726506879',
// busiTypeStr: ''
// },
// {
// title: '',
// status: '1',
// address: '',
// phone: '15726506879',
// busiTypeStr: ''
// }
// ]
orderList:[]
}
},
onShow() {
this.getBookingPage()
},
methods: {
async getBookingPage(){
const res = await request({
url: "/userClient/repair/booking/page",
method: "get",
params:{
pageNo: 1,
pageSize: 10
}
})
const data = res.data.records
const ids = data.map(item => item.id)
const response = await request({
url: "/userClient/repair/booking/map?ids=" + ids,
method: "get",
})
const list = response.data
this.orderList = list.map(item => {
return {
...item,
title: item.company.corpName,
address: item.company.address,
phone: item.company.mobilePhone,
busiTypeStr: item.servicePackage.name,
status: item.bookingStatus
}
})
}
}
}
</script>
@ -75,4 +106,4 @@
row-gap: 20rpx;
}
}
</style>
</style>

View File

@ -4,17 +4,18 @@
<view class="body">
<view style="padding: 0 32rpx;">
<view class="shopInfo">
<image class="shopImg" src="" mode="aspectFill"></image>
<image class="shopImg" :src="info.image" mode="aspectFill"></image>
<view class="shopInfo_content">
<view class="shopName">顺捷汽车维修搭电救援补胎中心</view>
<view class="shopAdress">济南市历下区福瑞达历下护理院东南门旁</view>
<!-- <view class="shopName">顺捷汽车维修搭电救援补胎中心</view>-->
<view class="shopName">{{ info.tenantName }}</view>
<!-- <view class="shopAdress">济南市历下区福瑞达历下护理院东南门旁</view>-->
</view>
</view>
<view class="rate">
<text>服务评价</text>
<uni-rate allow-half="true" value=""></uni-rate>
<uni-rate allow-half="true" v-model="formData.commentStar"></uni-rate>
</view>
<textarea class="message" value="" placeholder="可在此输入当前维修厂的服务评价" />
<textarea class="message" v-model="formData.commentDesc" placeholder="可在此输入当前维修厂的服务评价" />
<view class="submit" @click="submit">提交评价</view>
</view>
</view>
@ -23,6 +24,7 @@
<script>
import VNavigationBar from '@/components/VNavigationBar.vue'
import request from "../../utils/request";
export default {
components: {
@ -30,12 +32,28 @@
},
data() {
return {
info: {},
formData:{
id: null,
commentDesc: null,
commentStar: null,
}
};
},
onLoad(data){
this.info = JSON.parse(decodeURIComponent(data.info))
this.info['image'] = require("@/static/images/inImage.jpg")
},
methods: {
submit() {
uni.navigateBack()
this.formData['id'] = this.info.id
request({
url: "/userClient/repair/order/appraise",
method: "post",
data: this.formData
}).then(res => {
uni.navigateBack()
}).catch(()=>{})
}
}
}
@ -59,7 +77,7 @@
align-items: stretch;
column-gap: 20rpx;
margin: 30rpx 0;
.shopImg {
width: 160rpx;
height: 100rpx;
@ -86,10 +104,10 @@
.rate {
padding: 30rpx 0;
border-bottom: 1rpx solid #DDDDDD;
display: flex;
align-items: center;
column-gap: 28rpx;
}
.message {
@ -99,18 +117,18 @@
.submit {
width: 510rpx;
height: 76rpx;
margin: 0 auto;
background: #0174F6;
border-radius: 38rpx 38rpx 38rpx 38rpx;
font-size: 32rpx;
color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
}
}
</style>
</style>

View File

@ -2,7 +2,7 @@
<view class="container">
<view class="containerBody">
<VNavigationBar title="订单详情" background-color="rgba(0,0,0,0)" title-color="#333"></VNavigationBar>
<view class="body">
<view class="body" v-if="orderInfo.id">
<view class="orderStatus card">
<template v-if="orderInfo.status === '1'">
<image class="statusIcon" src="@/static/icons/order-icon8.png" mode="aspectFit"></image>
@ -18,7 +18,7 @@
</reservationOrder>
</view>
<view v-if="orderInfo.status !== '0'" class="progress card">
<view v-if="orderInfo.status !== '0' && !ticketsInfo" class="progress card">
<view v-for="(item, index) in processList" :key="index" class="processItem">
<view class="row1">
<view v-if="item.status !== '3'" class="processIndex">{{ index + 1 }}</view>
@ -42,25 +42,38 @@
</view>
</view>
<view v-else class="progress card">
<TicketsItem v-if="projects && projects.length > 0" :list="projects" :title='"project"' />
<TicketsItem v-if="wares && wares.length > 0" :list="wares" :title='"wares"' />
<TicketsItem v-if="others && others.length > 0" :list="others" :title='"other"' />
</view>
<view class="reservationInfo card">
<view class="row">
<text class="col1">姓名</text>
<text class="col2">{{'魏书豪'}}</text>
<text class="col2">{{orderInfo.userName}}</text>
</view>
<view class="row">
<text class="col1">联系电话</text>
<text class="col2">{{'15728586970'}}</text>
<text class="col2">{{orderInfo.userMobile}}</text>
</view>
<view class="row">
<text class="col1">预约项目</text>
<text class="col2">{{'车辆维修'}}</text>
<text class="col2">{{orderInfo.servicePackage.name}}</text>
</view>
<view class="row">
<text class="col1">预约时间</text>
<text class="col2">{{'2024-06-05 13:00'}}</text>
<text class="col2">{{orderInfo.bookingTime}}</text>
</view>
</view>
</view>
<view class="body" v-else-if="ticketsId">
<view class="progress card">
<TicketsItem v-if="projects && projects.length > 0" :list="projects" :title='"project"' />
<TicketsItem v-if="wares && wares.length > 0" :list="wares" :title='"wares"' />
<TicketsItem v-if="others && others.length > 0" :list="others" :title='"other"' />
</view>
</view>
<view class="footer" v-if="['0', '2'].includes(orderInfo.status)">
<view v-if="orderInfo.status === '2'" class="footerBtn" @click="gotoEvaluate">服务评价</view>
<template v-else-if="orderInfo.status === '0'">
@ -80,20 +93,24 @@
<script>
import VNavigationBar from '@/components/VNavigationBar.vue'
import reservationOrder from '@/components/reservationOrder/reservationOrder.vue'
import TicketsItem from "@/components/ticketsItem/ticketsItem.vue";
import request from "../../utils/request";
export default {
components: {
VNavigationBar,
reservationOrder
reservationOrder,
TicketsItem
},
data() {
return {
orderInfo: {
title: '顺捷汽车维修搭电救援补胎中心',
address: '济南市历下区福瑞达历下护理院东南门旁',
phone: '15726506879',
busiTypeStr: '15726506879',
status: '1'
},
// orderInfo: {
// title: '',
// address: '',
// phone: '15726506879',
// busiTypeStr: '15726506879',
// status: '1'
// },
orderInfo: {},
processList: [{
title: '接收车辆',
desc: '车辆已到维修厂,工作人员正准备开始维修',
@ -112,15 +129,42 @@
imageList: [],
status: '3'
}
]
],
ticketsInfo: {},
projects: [],
wares: [],
others: [],
ticketsId: null
};
},
onLoad(data){
if (data.info){
this.orderInfo = JSON.parse(decodeURIComponent(data.info))
this.ticketsId = this.orderInfo?.ticketsId
}
if (data.ticketsId){
this.ticketsId = data.ticketsId
}
if (this.ticketsId){
this.getTicketsInfo(this.ticketsId)
}
},
methods: {
gotoEvaluate() {
uni.navigateTo({
url: '/pages/orderDetail/evaluate'
})
}
},
async getTicketsInfo(id){
const res = await request({
url: "/userClient/repair/tickets/get?id=" + id,
method: "get"
})
this.ticketsInfo = res.data
this.projects = this.ticketsInfo.items.filter(item => item.project)
this.wares = this.ticketsInfo.items.filter(item => item.ware)
this.others = this.ticketsInfo.items.filter(item => item.other)
}
}
}
</script>
@ -299,21 +343,21 @@
font-size: 32rpx;
color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
column-gap: 8rpx;
line-height: 1.5;
&.phone {
background: #E8A321;
}
&.address {
}
.footerBtnIcon {
width: 32rpx;
height: 32rpx;
@ -321,4 +365,4 @@
}
}
}
</style>
</style>

View File

@ -1,251 +1,380 @@
<template>
<view class="container">
<VNavigationBar titleColor="rgba(0,0,0,0.9)" leftTitle="true" backgroundColor="transparent" title="我的订单">
</VNavigationBar>
<view class="body">
<view class="tabList">
<view @click="changeTabFun(item.id)" v-for="(item, index) in tabList" :key="index" class="tabItem"
:class="{actived: item.id === activeKey}">
{{ item.title }}
<view v-if="activeKey === item.id" class="activeLine"></view>
</view>
</view>
<view class="orderList">
<view v-for="(item, index) in orderList" :key="index" class="orderItem">
<view class="line1">
<view class="orderNo">
订单编号{{item.orderNo}}
</view>
<text class="orderStatus" :class="['status_' + item.status]">
{{ getStatus(item.status) }}
</text>
</view>
<view class="orderInfo">
<image class="orderInfoIcon" src="" mode="aspectFit"></image>
<text class="orderInfoText">{{ item.busiTypeStr }}</text>
</view>
<view class="orderInfo">
<image class="orderInfoIcon" src="" mode="aspectFit"></image>
<text class="orderInfoText">{{ item.address }}</text>
</view>
<view class="line2">
<view>
共计
<text class="orderAmountUnit"></text>
<text class="orderAmount">781</text>
</view>
<text>{{ item.date }}</text>
</view>
<view class="line3">
<view @click="gotoDetail(item)" class="showOrder" v-if="item.status === '1'">查看订单</view>
<view @click="gotoEvaluate(item)" class="evaluate" v-if="item.status === '2'">评价订单</view>
</view>
</view>
</view>
</view>
<tabBarVue msg="2"></tabBarVue>
</view>
<view class="container">
<VNavigationBar titleColor="rgba(0,0,0,0.9)" leftTitle="true" backgroundColor="transparent" title="我的订单">
</VNavigationBar>
<view class="body">
<view class="tabList">
<view @click="changeTabFun(item.id)" v-for="(item, index) in tabList" :key="index" class="tabItem"
:class="{actived: item.id === activeKey}">
{{ item.title }}
<view v-if="activeKey === item.id" class="activeLine"></view>
</view>
</view>
<view class="orderList">
<view v-for="(item, index) in orderList" :key="index" class="orderItem">
<view class="line1">
<view class="orderNo">
订单编号{{ item.orderNo }}
</view>
<text class="orderStatus" :class="['status_' + item.status]">
{{ getStatus(item.orderStatus) }}
</text>
</view>
<view class="orderInfo">
<image class="orderInfoIcon" src="" mode="aspectFit"></image>
<text class="orderInfoText">{{ item.goodsTitle }}</text>
</view>
<view class="orderInfo">
<image class="orderInfoIcon" src="" mode="aspectFit"></image>
<text class="orderInfoText">{{ item.tenantName | 蓝安-中鑫之宝 }}</text>
</view>
<view class="line2">
<view>
共计
<text class="orderAmountUnit"></text>
<text class="orderAmount">{{ item.payMoney }}</text>
</view>
<text>{{ formatTimestamp(item.createTime) }}</text>
</view>
<view class="line3">
<view @click="goPay(item)" class="showOrder">支付</view>
<view @click="gotoDetail(item)" class="showOrder">查看订单</view>
<view @click="gotoEvaluate(item)" class="evaluate" v-if="item.orderStatus === '1' && !item.commentDesc">评价订单</view>
</view>
</view>
</view>
<uni-popup ref="popup" type="center" border-radius="10px 10px 0 0" @change="popupChange">
<view
style="position: relative;padding: 30rpx;border-radius:20rpx;width: 600rpx;background-color: #fff;display: flex;align-items: center;row-gap: 10rpx;flex-direction: column;">
<canvas style="width:200px; height: 200px;"
canvas-id="myQrcode"></canvas>
<img id="dl-pay-img" style="width: 200px; height: 200px;position: absolute;top: 30rpx;" :key="imageUrl"
:src="imageUrl"/>
<view class="popup-title">长按识别图中二维码支付</view>
</view>
</uni-popup>
</view>
<tabBarVue msg="2"></tabBarVue>
</view>
</template>
<script>
import VNavigationBar from '@/components/VNavigationBar.vue'
import tabBarVue from '@/components/tabBar/tabBar.vue'
import request from '../../utils/request';
import VNavigationBar from '@/components/VNavigationBar.vue'
import tabBarVue from '@/components/tabBar/tabBar.vue'
import drawQrcode from 'weapp-qrcode';
export default {
components: {
tabBarVue,
VNavigationBar
},
data() {
return {
activeKey: 0,
tabList: [{
id: 0,
title: '全部订单'
},
{
id: 1,
title: '维修中'
},
{
id: 2,
title: '待评价'
},
],
orderList: [{
orderNo: '20198104817050157810',
status: '1',
busiTypeStr: '维修轮胎',
address: '顺捷汽车维修搭电救援补胎中心',
amount: '781',
date: '2024-07-02 12:00'
},
{
orderNo: '20198104817050157810',
status: '2',
busiTypeStr: '维修轮胎',
address: '顺捷汽车维修搭电救援补胎中心',
amount: '781',
date: '2024-07-02 12:00'
}
]
}
},
methods: {
changeTabFun(id) {
this.activeKey = id
},
getStatus(status) {
switch (status) {
case '1':
return '维修中'
case '2':
return '待评价'
default:
break;
}
},
gotoDetail() {
uni.navigateTo({
url: '/pages/orderDetail/orderDetail'
})
},
gotoEvaluate() {
uni.navigateTo({
url: '/pages/orderDetail/evaluate'
})
}
}
}
export default {
components: {
tabBarVue,
VNavigationBar
},
data() {
return {
payShow: false,
activeKey: 0,
pageNum: 1,
totalPages: 0,
imageUrl: '',
tabList: [{
id: 0,
title: '全部订单'
},
{
id: 1,
title: '维修中'
},
{
id: 2,
title: '待评价'
},
],
orderList: [],
changeActive: false
}
},
onShow() {
this.orderList = []
this.getList()
},
onReachBottom() {
if (this.pageNum >= this.totalPages) {
uni.showToast({
title: '没有下一页数据',
icon: 'none'
})
} else {
this.pageNum++
this.getList()
}
},
methods: {
formatTimestamp(timestamp) {
// Date
const date = new Date(timestamp);
//
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0');
const day = date.getDate().toString().padStart(2, '0');
const hours = date.getHours().toString().padStart(2, '0');
const minutes = date.getMinutes().toString().padStart(2, '0');
const seconds = date.getSeconds().toString().padStart(2, '0');
//
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
async getList() {
let data = {
pageSize: 20,
pageNo: this.pageNum
}
switch (this.activeKey) {
case 0:
break;
case 1:
data.status = "06"
break;
case 2:
data.status = '00'
break
default:
break
}
if (this.changeActive){
this.orderList = []
}
this.changeActive = false
await request({
url: '/userClient/order/page',
method: 'get',
params: data
}).then((res) => {
if (res.code === 200) {
this.orderList = this.orderList.concat(res.rows)
let total = res.total
this.totalPages = Math.ceil(total / this.pageSize);
}
})
},
changeTabFun(id) {
this.activeKey = id
this.changeActive = true
this.getList()
},
getStatus(status) {
switch (status) {
case '0':
return '待支付'
case '1':
return '已支付'
default:
break;
}
},
async goPay(data) {
let that = this
await request({
url: '/pay/toPay',
method: 'get',
params: {orderId: data.id}
}).then((res) => {
this.$refs.popup.open()
setTimeout(() => {
drawQrcode({
width: 200,
height: 200,
canvasId: 'myQrcode',
text: res.data.code_url
})
that.convertToImage()
}, 60)
})
},
convertToImage() {
uni.canvasToTempFilePath({
canvasId: 'myQrcode',
success: function (res) {
// H5tempFilePath base64
// this.imageUrl = res.tempFilePath.replace(/[\r\n]/g, "")
document.getElementById("dl-pay-img").setAttribute("src", res.tempFilePath.replace(/[\r\n]/g, ""))
this.$forceUpdate()
console.log(this.imageUrl, 200);
}
})
},
popupChange({show}) {
if (show) {
}
},
gotoDetail(row) {
if (row.goodsType === '2'){
uni.navigateTo({
url: '/pages/orderDetail/orderDetail?ticketsId=' + row.goodsId
})
}else {
uni.navigateTo({
url: '/pages/orderDetail/orderDetail'
})
}
},
gotoEvaluate(row) {
uni.navigateTo({
url: '/pages/orderDetail/evaluate?info=' + encodeURIComponent(JSON.stringify(row))
})
}
}
}
</script>
<style scoped lang="less">
.container {
height: 100%;
background: #F3F5F7;
display: flex;
flex-direction: column;
color: #333333;
.container {
height: 100%;
background: #F3F5F7;
display: flex;
flex-direction: column;
color: #333333;
.body {
flex: 1;
height: 0;
padding: 24rpx 32rpx;
}
.body {
flex: 1;
height: 0;
padding: 24rpx 32rpx;
overflow: auto;
}
.tabList {
background: #FFFFFF;
border-radius: 12rpx 12rpx 12rpx 12rpx;
display: flex;
align-items: center;
padding: 0 40rpx;
.tabList {
background: #FFFFFF;
border-radius: 12rpx 12rpx 12rpx 12rpx;
display: flex;
align-items: center;
padding: 0 40rpx;
.tabItem {
padding: 30rpx;
flex: 1;
text-align: center;
position: relative;
font-size: 24rpx;
.tabItem {
padding: 30rpx;
flex: 1;
text-align: center;
position: relative;
font-size: 24rpx;
&.actived {
color: #0174F6;
}
&.actived {
color: #0174F6;
}
.activeLine {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 96rpx;
height: 6rpx;
background: #0174F6;
border-radius: 4rpx 4rpx 0rpx 0rpx;
}
}
}
.activeLine {
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 96rpx;
height: 6rpx;
background: #0174F6;
border-radius: 4rpx 4rpx 0rpx 0rpx;
}
}
}
.orderList {
padding: 30rpx 0;
display: flex;
flex-direction: column;
row-gap: 20rpx;
.orderList {
padding: 30rpx 0;
display: flex;
flex-direction: column;
row-gap: 20rpx;
.orderItem {
padding: 30rpx;
background: #FFFFFF;
border-radius: 12rpx 12rpx 12rpx 12rpx;
}
.line1 {
margin-bottom: 30rpx;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 24rpx;
.orderNo {
flex: 1;
width: 0;
font-weight: 500;
color: #858BA0;
}
.status_1 {
color: #0174F6;
}
.status_2 {
color: #999999;
}
}
.orderInfo {
margin-bottom: 20rpx;
display: flex;
align-items: center;
column-gap: 10rpx;
.orderInfoIcon {
width: 28rpx;
height: 28rpx;
background: #ddd;
}
.orderInfoText {
font-weight: bold;
font-size: 28rpx;
color: #333333;
}
}
.line2 {
margin: 30rpx 0;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 12px;
color: #858BA0;
.orderAmountUnit {
color: #F92C2C;
}
.orderAmount {
color: #F92C2C;
font-weight: bold;
font-size: 40rpx;
}
}
.line3 {
display: flex;
align-items: center;
justify-content: flex-end;
.showOrder, .evaluate {
width: 172rpx;
height: 60rpx;
border-radius: 30rpx 30rpx 30rpx 30rpx;
border: 2rpx solid #0174F6;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #0174F6;
}
.evaluate {
border: 1rpx solid #EEEEEE;
color: #333333;
}
}
}
}
</style>
.orderItem {
padding: 30rpx;
background: #FFFFFF;
border-radius: 12rpx 12rpx 12rpx 12rpx;
}
.line1 {
margin-bottom: 30rpx;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 24rpx;
.orderNo {
flex: 1;
width: 0;
font-weight: 500;
color: #858BA0;
}
.status_1 {
color: #0174F6;
}
.status_2 {
color: #999999;
}
}
.orderInfo {
margin-bottom: 20rpx;
display: flex;
align-items: center;
column-gap: 10rpx;
.orderInfoIcon {
width: 28rpx;
height: 28rpx;
background: #ddd;
}
.orderInfoText {
font-weight: bold;
font-size: 28rpx;
color: #333333;
}
}
.line2 {
margin: 30rpx 0;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 12px;
color: #858BA0;
.orderAmountUnit {
color: #F92C2C;
}
.orderAmount {
color: #F92C2C;
font-weight: bold;
font-size: 40rpx;
}
}
.line3 {
display: flex;
align-items: center;
justify-content: flex-end;
.showOrder, .evaluate {
width: 172rpx;
height: 60rpx;
border-radius: 30rpx 30rpx 30rpx 30rpx;
border: 2rpx solid #0174F6;
display: flex;
align-items: center;
justify-content: center;
font-size: 28rpx;
color: #0174F6;
}
.evaluate {
border: 1rpx solid #EEEEEE;
color: #333333;
}
}
}
}
</style>

View File

@ -14,7 +14,8 @@
</view>
<view class="shopBody">
<view class="shopDetail">
<view class="shopTitle">顺捷汽车维修搭电救援补胎中心</view>
<!-- <view class="shopTitle">顺捷汽车维修搭电救援补胎中心</view>-->
<view class="shopTitle">{{ info.corpName }}</view>
<view class="rate">
<view class="rateNumBox">
<text>4.5</text>
@ -24,10 +25,13 @@
<text>强烈推荐</text>
</view>
<view class="shopDetailText">
<mote-lines-divide :line="3" expandText="全部" foldHint="收起">
<mote-lines-divide :line="3" expandText="全部" foldHint="收起" v-if="info && info.corpContent">
<text class="shopDetailTextLabel">厂家介绍</text>
<!-- <text class="shopDetailTextValue">-->
<!-- 正安汽车维修服务有限公司成立于1993年10月25日属东莞市成立最早规模最大的民营汽修企业之一现在莞城区及桥头镇开设有二家连锁经营分厂及直属汽车销售部主要从事汽车销售售后-->
<!-- </text>-->
<text class="shopDetailTextValue">
正安汽车维修服务有限公司成立于1993年10月25日属东莞市成立最早规模最大的民营汽修企业之一现在莞城区及桥头镇开设有二家连锁经营分厂及直属汽车销售部主要从事汽车销售售后
{{ info.corpContent }}
</text>
</mote-lines-divide>
</view>
@ -35,7 +39,8 @@
<view class="shopAddress">
<image style="width: 32rpx;height: 32rpx;" src="../../static/icons/order-icon1.png"
mode="aspectFit"></image>
<text>济南市历下区福瑞达历下护理院东南门旁</text>
<!-- <text>济南市历下区福瑞达历下护理院东南门旁</text>-->
<text>{{ info.address }}</text>
</view>
<view class="shopPhone">
<image style="width: 32rpx;height: 32rpx;" src="../../static/icons/order-icon2.png"
@ -45,15 +50,16 @@
</view>
</view>
<view class="busiDetail">
<view class="busiDetailTitle">顺捷汽车维修搭电救援补胎中心</view>
<!-- <view class="busiDetailTitle">顺捷汽车维修搭电救援补胎中心</view>-->
<view class="busiDetailTitle">{{info.corpName}}</view>
<view class="busiList">
<view v-for="(item, index) in busiList" :key="index" class="busiItem">
<image class="busiTypeImg" :src="item.image" mode="aspectFill"></image>
<view class="busiItemInfo">
<view class="busiItemTitle">{{ item.title }}</view>
<view class="busiItemTitle">{{ item.name }}</view>
<view class="busiItemDesc">{{ item.desc }}</view>
</view>
<view class="busiItemBtn">查看</view>
<!-- <view class="busiItemBtn">查看</view>-->
</view>
</view>
</view>
@ -67,37 +73,61 @@
<script>
import VNavigationBar from '@/components/VNavigationBar.vue'
import request from "../../utils/request";
export default {
components: {
VNavigationBar
},
data() {
return {
busiList: [{
title: '钣金喷漆维修',
desc: '钣金喷漆维修是一个汽车修理的技术手段,此方面汽车钣金等于汽车钣金修理,指汽车发生碰撞后要对车身进行修复,也即除对车身进行防腐和装饰的喷涂工作外其余的所有工作。如汽车车身损伤的分析,汽车车身的测量,汽车车身钣金的整形,拉伸矫正,去应力焊接,以及汽车车身附件装配,调整等工作。',
image: ''
}, {
title: '钣金喷漆维修',
desc: '钣金喷漆维修是一个汽车修理的技术手段,此方面汽车钣金等于汽车钣金修理,指汽车发生碰撞后要对车身进行修复,也即除对车身进行防腐和装饰的喷涂工作外其余的所有工作。如汽车车身损伤的分析,汽车车身的测量,汽车车身钣金的整形,拉伸矫正,去应力焊接,以及汽车车身附件装配,调整等工作。',
image: ''
}, {
title: '钣金喷漆维修',
desc: '钣金喷漆维修是一个汽车修理的技术手段,此方面汽车钣金等于汽车钣金修理,指汽车发生碰撞后要对车身进行修复,也即除对车身进行防腐和装饰的喷涂工作外其余的所有工作。如汽车车身损伤的分析,汽车车身的测量,汽车车身钣金的整形,拉伸矫正,去应力焊接,以及汽车车身附件装配,调整等工作。',
image: ''
}, {
title: '钣金喷漆维修',
desc: '钣金喷漆维修是一个汽车修理的技术手段,此方面汽车钣金等于汽车钣金修理,指汽车发生碰撞后要对车身进行修复,也即除对车身进行防腐和装饰的喷涂工作外其余的所有工作。如汽车车身损伤的分析,汽车车身的测量,汽车车身钣金的整形,拉伸矫正,去应力焊接,以及汽车车身附件装配,调整等工作。',
image: ''
}, ]
// busiList: [{
// title: '',
// desc: '',
// image: ''
// }, {
// title: '',
// desc: '',
// image: ''
// }, {
// title: '',
// desc: '',
// image: ''
// }, {
// title: '',
// desc: '',
// image: ''
// }, ]
busiList: [],
info: {}
};
},
onLoad(data) {
this.info = JSON.parse(decodeURIComponent(data.info))
},
onShow() {
this.getServer()
},
methods: {
//
gotoReservation() {
uni.navigateTo({
url: '/pages/myReservation/addReservation'
})
},
//
async getServer() {
const res = await request({
url: "/userClient/base/company/get",
method: 'get',
params: {
id: this.info.id
}
})
this.busiList = res.data.servicePackages
this.busiList.forEach(item => {
item['image'] = require("@/static/images/inImage.jpg")
item['desc'] = this.info.business
})
}
}
}
@ -290,7 +320,7 @@
font-size: 28rpx;
color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
@ -321,4 +351,4 @@
}
}
}
</style>
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
static/images/inImage.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 MiB

BIN
static/images/outImage.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

BIN
static/images/pay.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
static/loginbj.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

BIN
static/xinlogo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -0,0 +1,86 @@
## 1.9.22024-09-21
- 修复 uni-popup在android上的重复点击弹出位置不正确的bug
## 1.9.12024-04-02
- 修复 uni-popup-dialog vue3下使用value无法进行绑定的bug(双向绑定兼容旧写法)
## 1.9.02024-03-28
- 修复 uni-popup-dialog 双向绑定时初始化逻辑修正
## 1.8.92024-03-20
- 修复 uni-popup-dialog 数据输入时修正为双向绑定
## 1.8.82024-02-20
- 修复 uni-popup 在微信小程序下出现文字向上闪动的bug
## 1.8.72024-02-02
- 新增 uni-popup-dialog 新增属性focusinput模式下是否自动自动聚焦
## 1.8.62024-01-30
- 新增 uni-popup-dialog 新增属性maxLength:限制输入框字数
## 1.8.52024-01-26
- 新增 uni-popup-dialog 新增属性showClose:控制关闭按钮的显示
## 1.8.42023-11-15
- 新增 uni-popup 支持uni-app-x 注意暂时仅支持 `maskClick` `@open` `@close`
## 1.8.32023-04-17
- 修复 uni-popup 重复打开时的 bug
## 1.8.22023-02-02
- uni-popup-dialog 组件新增 inputType 属性
## 1.8.12022-12-01
- 修复 nvue 下 v-show 报错
## 1.8.02022-11-29
- 优化 主题样式
## 1.7.92022-04-02
- 修复 弹出层内部无法滚动的bug
## 1.7.82022-03-28
- 修复 小程序中高度错误的bug
## 1.7.72022-03-17
- 修复 快速调用open出现问题的Bug
## 1.7.62022-02-14
- 修复 safeArea 属性不能设置为false的bug
## 1.7.52022-01-19
- 修复 isMaskClick 失效的bug
## 1.7.42022-01-19
- 新增 cancelText \ confirmText 属性 ,可自定义文本
- 新增 maskBackgroundColor 属性 ,可以修改蒙版颜色
- 优化 maskClick属性 更新为 isMaskClick ,解决微信小程序警告的问题
## 1.7.32022-01-13
- 修复 设置 safeArea 属性不生效的bug
## 1.7.22021-11-26
- 优化 组件示例
## 1.7.12021-11-26
- 修复 vuedoc 文字错误
## 1.7.02021-11-19
- 优化 组件UI并提供设计资源详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-popup](https://uniapp.dcloud.io/component/uniui/uni-popup)
## 1.6.22021-08-24
- 新增 支持国际化
## 1.6.12021-07-30
- 优化 vue3下事件警告的问题
## 1.6.02021-07-13
- 组件兼容 vue3如何创建vue3项目详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.5.02021-06-23
- 新增 mask-click 遮罩层点击事件
## 1.4.52021-06-22
- 修复 nvue 平台中间弹出后点击内容再点击遮罩无法关闭的Bug
## 1.4.42021-06-18
- 修复 H5平台中间弹出后点击内容再点击遮罩无法关闭的Bug
## 1.4.32021-06-08
- 修复 错误的 watch 字段
- 修复 safeArea 属性不生效的问题
- 修复 点击内容再点击遮罩无法关闭的Bug
## 1.4.22021-05-12
- 新增 组件示例地址
## 1.4.12021-04-29
- 修复 组件内放置 input 、textarea 组件,无法聚焦的问题
## 1.4.0 2021-04-29
- 新增 type 属性的 left\right 值,支持左右弹出
- 新增 open(String:type) 方法参数 ,可以省略 type 属性 ,直接传入类型打开指定弹窗
- 新增 backgroundColor 属性,可定义主窗口背景色,默认不显示背景色
- 新增 safeArea 属性,是否适配底部安全区
- 修复 App\h5\微信小程序底部安全区占位不对的Bug
- 修复 App 端弹出等待的Bug
- 优化 提升低配设备性能,优化动画卡顿问题
- 优化 更简单的组件自定义方式
## 1.2.92021-02-05
- 优化 组件引用关系通过uni_modules引用组件
## 1.2.82021-02-05
- 调整为uni_modules目录规范
## 1.2.72021-02-05
- 调整为uni_modules目录规范
- 新增 支持 PC 端
- 新增 uni-popup-message 、uni-popup-dialog扩展组件支持 PC 端

View File

@ -0,0 +1,45 @@
// #ifdef H5
export default {
name: 'Keypress',
props: {
disable: {
type: Boolean,
default: false
}
},
mounted () {
const keyNames = {
esc: ['Esc', 'Escape'],
tab: 'Tab',
enter: 'Enter',
space: [' ', 'Spacebar'],
up: ['Up', 'ArrowUp'],
left: ['Left', 'ArrowLeft'],
right: ['Right', 'ArrowRight'],
down: ['Down', 'ArrowDown'],
delete: ['Backspace', 'Delete', 'Del']
}
const listener = ($event) => {
if (this.disable) {
return
}
const keyName = Object.keys(keyNames).find(key => {
const keyName = $event.key
const value = keyNames[key]
return value === keyName || (Array.isArray(value) && value.includes(keyName))
})
if (keyName) {
// 避免和其他按键事件冲突
setTimeout(() => {
this.$emit(keyName, {})
}, 0)
}
}
document.addEventListener('keyup', listener)
this.$once('hook:beforeDestroy', () => {
document.removeEventListener('keyup', listener)
})
},
render: () => {}
}
// #endif

View File

@ -0,0 +1,316 @@
<template>
<view class="uni-popup-dialog">
<view class="uni-dialog-title">
<text class="uni-dialog-title-text" :class="['uni-popup__'+dialogType]">{{titleText}}</text>
</view>
<view v-if="mode === 'base'" class="uni-dialog-content">
<slot>
<text class="uni-dialog-content-text">{{content}}</text>
</slot>
</view>
<view v-else class="uni-dialog-content">
<slot>
<input class="uni-dialog-input" :maxlength="maxlength" v-model="val" :type="inputType"
:placeholder="placeholderText" :focus="focus">
</slot>
</view>
<view class="uni-dialog-button-group">
<view class="uni-dialog-button" v-if="showClose" @click="closeDialog">
<text class="uni-dialog-button-text">{{closeText}}</text>
</view>
<view class="uni-dialog-button" :class="showClose?'uni-border-left':''" @click="onOk">
<text class="uni-dialog-button-text uni-button-color">{{okText}}</text>
</view>
</view>
</view>
</template>
<script>
import popup from '../uni-popup/popup.js'
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import messages from '../uni-popup/i18n/index.js'
const {
t
} = initVueI18n(messages)
/**
* PopUp 弹出层-对话框样式
* @description 弹出层-对话框样式
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} value input 模式下的默认值
* @property {String} placeholder input 模式下输入提示
* @property {Boolean} focus input模式下是否自动聚焦默认为true
* @property {String} type = [success|warning|info|error] 主题样式
* @value success 成功
* @value warning 提示
* @value info 消息
* @value error 错误
* @property {String} mode = [base|input] 模式
* @value base 基础对话框
* @value input 可输入对话框
* @showClose {Boolean} 是否显示关闭按钮
* @property {String} content 对话框内容
* @property {Boolean} beforeClose 是否拦截取消事件
* @property {Number} maxlength 输入
* @event {Function} confirm 点击确认按钮触发
* @event {Function} close 点击取消按钮触发
*/
export default {
name: "uniPopupDialog",
mixins: [popup],
emits: ['confirm', 'close', 'update:modelValue', 'input'],
props: {
inputType: {
type: String,
default: 'text'
},
showClose: {
type: Boolean,
default: true
},
// #ifdef VUE2
value: {
type: [String, Number],
default: ''
},
// #endif
// #ifdef VUE3
modelValue: {
type: [Number, String],
default: ''
},
// #endif
placeholder: {
type: [String, Number],
default: ''
},
type: {
type: String,
default: 'error'
},
mode: {
type: String,
default: 'base'
},
title: {
type: String,
default: ''
},
content: {
type: String,
default: ''
},
beforeClose: {
type: Boolean,
default: false
},
cancelText: {
type: String,
default: ''
},
confirmText: {
type: String,
default: ''
},
maxlength: {
type: Number,
default: -1,
},
focus: {
type: Boolean,
default: true,
}
},
data() {
return {
dialogType: 'error',
val: ""
}
},
computed: {
okText() {
return this.confirmText || t("uni-popup.ok")
},
closeText() {
return this.cancelText || t("uni-popup.cancel")
},
placeholderText() {
return this.placeholder || t("uni-popup.placeholder")
},
titleText() {
return this.title || t("uni-popup.title")
}
},
watch: {
type(val) {
this.dialogType = val
},
mode(val) {
if (val === 'input') {
this.dialogType = 'info'
}
},
value(val) {
if (this.maxlength != -1 && this.mode === 'input') {
this.val = val.slice(0, this.maxlength);
} else {
this.val = val
}
},
val(val) {
// #ifdef VUE2
// TODO vue2
this.$emit('input', val);
// #endif
// #ifdef VUE3
// TODO  vue3
this.$emit('update:modelValue', val);
// #endif
}
},
created() {
//
this.popup.disableMask()
// this.popup.closeMask()
if (this.mode === 'input') {
this.dialogType = 'info'
this.val = this.value;
// #ifdef VUE3
this.val = this.modelValue;
// #endif
} else {
this.dialogType = this.type
}
},
methods: {
/**
* 点击确认按钮
*/
onOk() {
if (this.mode === 'input') {
this.$emit('confirm', this.val)
} else {
this.$emit('confirm')
}
if (this.beforeClose) return
this.popup.close()
},
/**
* 点击取消按钮
*/
closeDialog() {
this.$emit('close')
if (this.beforeClose) return
this.popup.close()
},
close() {
this.popup.close()
}
}
}
</script>
<style lang="scss">
.uni-popup-dialog {
width: 300px;
border-radius: 11px;
background-color: #fff;
}
.uni-dialog-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
padding-top: 25px;
}
.uni-dialog-title-text {
font-size: 16px;
font-weight: 500;
}
.uni-dialog-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
align-items: center;
padding: 20px;
}
.uni-dialog-content-text {
font-size: 14px;
color: #6C6C6C;
}
.uni-dialog-button-group {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
border-top-color: #f5f5f5;
border-top-style: solid;
border-top-width: 1px;
}
.uni-dialog-button {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex: 1;
flex-direction: row;
justify-content: center;
align-items: center;
height: 45px;
}
.uni-border-left {
border-left-color: #f0f0f0;
border-left-style: solid;
border-left-width: 1px;
}
.uni-dialog-button-text {
font-size: 16px;
color: #333;
}
.uni-button-color {
color: #007aff;
}
.uni-dialog-input {
flex: 1;
font-size: 14px;
border: 1px #eee solid;
height: 40px;
padding: 0 10px;
border-radius: 5px;
color: #555;
}
.uni-popup__success {
color: #4cd964;
}
.uni-popup__warn {
color: #f0ad4e;
}
.uni-popup__error {
color: #dd524d;
}
.uni-popup__info {
color: #909399;
}
</style>

View File

@ -0,0 +1,143 @@
<template>
<view class="uni-popup-message">
<view class="uni-popup-message__box fixforpc-width" :class="'uni-popup__'+type">
<slot>
<text class="uni-popup-message-text" :class="'uni-popup__'+type+'-text'">{{message}}</text>
</slot>
</view>
</view>
</template>
<script>
import popup from '../uni-popup/popup.js'
/**
* PopUp 弹出层-消息提示
* @description 弹出层-消息提示
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} type = [success|warning|info|error] 主题样式
* @value success 成功
* @value warning 提示
* @value info 消息
* @value error 错误
* @property {String} message 消息提示文字
* @property {String} duration 显示时间设置为 0 则不会自动关闭
*/
export default {
name: 'uniPopupMessage',
mixins:[popup],
props: {
/**
* 主题 success/warning/info/error 默认 success
*/
type: {
type: String,
default: 'success'
},
/**
* 消息文字
*/
message: {
type: String,
default: ''
},
/**
* 显示时间设置为 0 则不会自动关闭
*/
duration: {
type: Number,
default: 3000
},
maskShow:{
type:Boolean,
default:false
}
},
data() {
return {}
},
created() {
this.popup.maskShow = this.maskShow
this.popup.messageChild = this
},
methods: {
timerClose(){
if(this.duration === 0) return
clearTimeout(this.timer)
this.timer = setTimeout(()=>{
this.popup.close()
},this.duration)
}
}
}
</script>
<style lang="scss" >
.uni-popup-message {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
}
.uni-popup-message__box {
background-color: #e1f3d8;
padding: 10px 15px;
border-color: #eee;
border-style: solid;
border-width: 1px;
flex: 1;
}
@media screen and (min-width: 500px) {
.fixforpc-width {
margin-top: 20px;
border-radius: 4px;
flex: none;
min-width: 380px;
/* #ifndef APP-NVUE */
max-width: 50%;
/* #endif */
/* #ifdef APP-NVUE */
max-width: 500px;
/* #endif */
}
}
.uni-popup-message-text {
font-size: 14px;
padding: 0;
}
.uni-popup__success {
background-color: #e1f3d8;
}
.uni-popup__success-text {
color: #67C23A;
}
.uni-popup__warn {
background-color: #faecd8;
}
.uni-popup__warn-text {
color: #E6A23C;
}
.uni-popup__error {
background-color: #fde2e2;
}
.uni-popup__error-text {
color: #F56C6C;
}
.uni-popup__info {
background-color: #F2F6FC;
}
.uni-popup__info-text {
color: #909399;
}
</style>

View File

@ -0,0 +1,187 @@
<template>
<view class="uni-popup-share">
<view class="uni-share-title"><text class="uni-share-title-text">{{shareTitleText}}</text></view>
<view class="uni-share-content">
<view class="uni-share-content-box">
<view class="uni-share-content-item" v-for="(item,index) in bottomData" :key="index" @click.stop="select(item,index)">
<image class="uni-share-image" :src="item.icon" mode="aspectFill"></image>
<text class="uni-share-text">{{item.text}}</text>
</view>
</view>
</view>
<view class="uni-share-button-box">
<button class="uni-share-button" @click="close">{{cancelText}}</button>
</view>
</view>
</template>
<script>
import popup from '../uni-popup/popup.js'
import {
initVueI18n
} from '@dcloudio/uni-i18n'
import messages from '../uni-popup/i18n/index.js'
const { t } = initVueI18n(messages)
export default {
name: 'UniPopupShare',
mixins:[popup],
emits:['select'],
props: {
title: {
type: String,
default: ''
},
beforeClose: {
type: Boolean,
default: false
}
},
data() {
return {
bottomData: [{
text: '微信',
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/c2b17470-50be-11eb-b680-7980c8a877b8.png',
name: 'wx'
},
{
text: '支付宝',
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/d684ae40-50be-11eb-8ff1-d5dcf8779628.png',
name: 'ali'
},
{
text: 'QQ',
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/e7a79520-50be-11eb-b997-9918a5dda011.png',
name: 'qq'
},
{
text: '新浪',
icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/0dacdbe0-50bf-11eb-8ff1-d5dcf8779628.png',
name: 'sina'
},
// {
// text: '',
// icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/1ec6e920-50bf-11eb-8a36-ebb87efcf8c0.png',
// name: 'copy'
// },
// {
// text: '',
// icon: 'https://vkceyugu.cdn.bspapp.com/VKCEYUGU-dc-site/2e0fdfe0-50bf-11eb-b997-9918a5dda011.png',
// name: 'more'
// }
]
}
},
created() {},
computed: {
cancelText() {
return t("uni-popup.cancel")
},
shareTitleText() {
return this.title || t("uni-popup.shareTitle")
}
},
methods: {
/**
* 选择内容
*/
select(item, index) {
this.$emit('select', {
item,
index
})
this.close()
},
/**
* 关闭窗口
*/
close() {
if(this.beforeClose) return
this.popup.close()
}
}
}
</script>
<style lang="scss" >
.uni-popup-share {
background-color: #fff;
border-top-left-radius: 11px;
border-top-right-radius: 11px;
}
.uni-share-title {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
height: 40px;
}
.uni-share-title-text {
font-size: 14px;
color: #666;
}
.uni-share-content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
justify-content: center;
padding-top: 10px;
}
.uni-share-content-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
flex-wrap: wrap;
width: 360px;
}
.uni-share-content-item {
width: 90px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
padding: 10px 0;
align-items: center;
}
.uni-share-content-item:active {
background-color: #f5f5f5;
}
.uni-share-image {
width: 30px;
height: 30px;
}
.uni-share-text {
margin-top: 10px;
font-size: 14px;
color: #3B4144;
}
.uni-share-button-box {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
padding: 10px 15px;
}
.uni-share-button {
flex: 1;
border-radius: 50px;
color: #666;
font-size: 16px;
}
.uni-share-button::after {
border-radius: 50px;
}
</style>

View File

@ -0,0 +1,7 @@
{
"uni-popup.cancel": "cancel",
"uni-popup.ok": "ok",
"uni-popup.placeholder": "pleace enter",
"uni-popup.title": "Hint",
"uni-popup.shareTitle": "Share to"
}

View File

@ -0,0 +1,8 @@
import en from './en.json'
import zhHans from './zh-Hans.json'
import zhHant from './zh-Hant.json'
export default {
en,
'zh-Hans': zhHans,
'zh-Hant': zhHant
}

View File

@ -0,0 +1,7 @@
{
"uni-popup.cancel": "取消",
"uni-popup.ok": "确定",
"uni-popup.placeholder": "请输入",
"uni-popup.title": "提示",
"uni-popup.shareTitle": "分享到"
}

View File

@ -0,0 +1,7 @@
{
"uni-popup.cancel": "取消",
"uni-popup.ok": "確定",
"uni-popup.placeholder": "請輸入",
"uni-popup.title": "提示",
"uni-popup.shareTitle": "分享到"
}

View File

@ -0,0 +1,45 @@
// #ifdef H5
export default {
name: 'Keypress',
props: {
disable: {
type: Boolean,
default: false
}
},
mounted () {
const keyNames = {
esc: ['Esc', 'Escape'],
tab: 'Tab',
enter: 'Enter',
space: [' ', 'Spacebar'],
up: ['Up', 'ArrowUp'],
left: ['Left', 'ArrowLeft'],
right: ['Right', 'ArrowRight'],
down: ['Down', 'ArrowDown'],
delete: ['Backspace', 'Delete', 'Del']
}
const listener = ($event) => {
if (this.disable) {
return
}
const keyName = Object.keys(keyNames).find(key => {
const keyName = $event.key
const value = keyNames[key]
return value === keyName || (Array.isArray(value) && value.includes(keyName))
})
if (keyName) {
// 避免和其他按键事件冲突
setTimeout(() => {
this.$emit(keyName, {})
}, 0)
}
}
document.addEventListener('keyup', listener)
// this.$once('hook:beforeDestroy', () => {
// document.removeEventListener('keyup', listener)
// })
},
render: () => {}
}
// #endif

View File

@ -0,0 +1,26 @@
export default {
data() {
return {
}
},
created(){
this.popup = this.getParent()
},
methods:{
/**
* 获取父元素实例
*/
getParent(name = 'uniPopup') {
let parent = this.$parent;
let parentName = parent.$options.name;
while (parentName !== name) {
parent = parent.$parent;
if (!parent) return false
parentName = parent.$options.name;
}
return parent;
},
}
}

View File

@ -0,0 +1,90 @@
<template>
<view class="popup-root" v-if="isOpen" v-show="isShow" @click="clickMask">
<view @click.stop>
<slot></slot>
</view>
</view>
</template>
<script>
type CloseCallBack = ()=> void;
let closeCallBack:CloseCallBack = () :void => {};
export default {
emits:["close","clickMask"],
data() {
return {
isShow:false,
isOpen:false
}
},
props: {
maskClick: {
type: Boolean,
default: true
},
},
watch: {
// 设置show = true 时,如果没有 open 需要设置为 open
isShow:{
handler(isShow) {
// console.log("isShow",isShow)
if(isShow && this.isOpen == false){
this.isOpen = true
}
},
immediate:true
},
// 设置isOpen = true 时,如果没有 isShow 需要设置为 isShow
isOpen:{
handler(isOpen) {
// console.log("isOpen",isOpen)
if(isOpen && this.isShow == false){
this.isShow = true
}
},
immediate:true
}
},
methods:{
open(){
// ...funs : CloseCallBack[]
// if(funs.length > 0){
// closeCallBack = funs[0]
// }
this.isOpen = true;
},
clickMask(){
if(this.maskClick == true){
this.$emit('clickMask')
this.close()
}
},
close(): void{
this.isOpen = false;
this.$emit('close')
closeCallBack()
},
hiden(){
this.isShow = false
},
show(){
this.isShow = true
}
}
}
</script>
<style>
.popup-root {
position: fixed;
top: 0;
left: 0;
width: 750rpx;
height: 100%;
flex: 1;
background-color: rgba(0, 0, 0, 0.3);
justify-content: center;
align-items: center;
z-index: 99;
}
</style>

View File

@ -0,0 +1,506 @@
<template>
<view v-if="showPopup" class="uni-popup" :class="[popupstyle, isDesktop ? 'fixforpc-z-index' : '']">
<view @touchstart="touchstart">
<uni-transition key="1" v-if="maskShow" name="mask" mode-class="fade" :styles="maskClass"
:duration="duration" :show="showTrans" @click="onTap" />
<uni-transition key="2" :mode-class="ani" name="content" :styles="transClass" :duration="duration"
:show="showTrans" @click="onTap">
<view class="uni-popup__wrapper" :style="getStyles" :class="[popupstyle]" @click="clear">
<slot />
</view>
</uni-transition>
</view>
<!-- #ifdef H5 -->
<keypress v-if="maskShow" @esc="onTap" />
<!-- #endif -->
</view>
</template>
<script>
// #ifdef H5
import keypress from './keypress.js'
// #endif
/**
* PopUp 弹出层
* @description 弹出层组件为了解决遮罩弹层的问题
* @tutorial https://ext.dcloud.net.cn/plugin?id=329
* @property {String} type = [top|center|bottom|left|right|message|dialog|share] 弹出方式
* @value top 顶部弹出
* @value center 中间弹出
* @value bottom 底部弹出
* @value left 左侧弹出
* @value right 右侧弹出
* @value message 消息提示
* @value dialog 对话框
* @value share 底部分享示例
* @property {Boolean} animation = [true|false] 是否开启动画
* @property {Boolean} maskClick = [true|false] 蒙版点击是否关闭弹窗(废弃)
* @property {Boolean} isMaskClick = [true|false] 蒙版点击是否关闭弹窗
* @property {String} backgroundColor 主窗口背景色
* @property {String} maskBackgroundColor 蒙版颜色
* @property {String} borderRadius 设置圆角(左上右上右下和左下) 示例:"10px 10px 10px 10px"
* @property {Boolean} safeArea 是否适配底部安全区
* @event {Function} change 打开关闭弹窗触发e={show: false}
* @event {Function} maskClick 点击遮罩触发
*/
export default {
name: 'uniPopup',
components: {
// #ifdef H5
keypress
// #endif
},
emits: ['change', 'maskClick'],
props: {
//
animation: {
type: Boolean,
default: true
},
// top: bottomcenter
// message: ; dialog :
type: {
type: String,
default: 'center'
},
// maskClick
isMaskClick: {
type: Boolean,
default: null
},
// TODO 2 使 isMaskClick
maskClick: {
type: Boolean,
default: null
},
backgroundColor: {
type: String,
default: 'none'
},
safeArea: {
type: Boolean,
default: true
},
maskBackgroundColor: {
type: String,
default: 'rgba(0, 0, 0, 0.4)'
},
borderRadius:{
type: String,
}
},
watch: {
/**
* 监听type类型
*/
type: {
handler: function(type) {
if (!this.config[type]) return
this[this.config[type]](true)
},
immediate: true
},
isDesktop: {
handler: function(newVal) {
if (!this.config[newVal]) return
this[this.config[this.type]](true)
},
immediate: true
},
/**
* 监听遮罩是否可点击
* @param {Object} val
*/
maskClick: {
handler: function(val) {
this.mkclick = val
},
immediate: true
},
isMaskClick: {
handler: function(val) {
this.mkclick = val
},
immediate: true
},
// H5
showPopup(show) {
// #ifdef H5
// fix by mehaotian h5 穿
document.getElementsByTagName('body')[0].style.overflow = show ? 'hidden' : 'visible'
// #endif
}
},
data() {
return {
duration: 300,
ani: [],
showPopup: false,
showTrans: false,
popupWidth: 0,
popupHeight: 0,
config: {
top: 'top',
bottom: 'bottom',
center: 'center',
left: 'left',
right: 'right',
message: 'top',
dialog: 'center',
share: 'bottom'
},
maskClass: {
position: 'fixed',
bottom: 0,
top: 0,
left: 0,
right: 0,
backgroundColor: 'rgba(0, 0, 0, 0.4)'
},
transClass: {
backgroundColor: 'transparent',
borderRadius: this.borderRadius || "0",
position: 'fixed',
left: 0,
right: 0
},
maskShow: true,
mkclick: true,
popupstyle: 'top'
}
},
computed: {
getStyles() {
let res = { backgroundColor: this.bg };
if (this.borderRadius || "0") {
res = Object.assign(res, { borderRadius: this.borderRadius })
}
return res;
},
isDesktop() {
return this.popupWidth >= 500 && this.popupHeight >= 500
},
bg() {
if (this.backgroundColor === '' || this.backgroundColor === 'none') {
return 'transparent'
}
return this.backgroundColor
}
},
mounted() {
const fixSize = () => {
const {
windowWidth,
windowHeight,
windowTop,
safeArea,
screenHeight,
safeAreaInsets
} = uni.getSystemInfoSync()
this.popupWidth = windowWidth
this.popupHeight = windowHeight + (windowTop || 0)
// TODO fix by mehaotian ,ios app ios
if (safeArea && this.safeArea) {
// #ifdef MP-WEIXIN
this.safeAreaInsets = screenHeight - safeArea.bottom
// #endif
// #ifndef MP-WEIXIN
this.safeAreaInsets = safeAreaInsets.bottom
// #endif
} else {
this.safeAreaInsets = 0
}
}
fixSize()
// #ifdef H5
// window.addEventListener('resize', fixSize)
// this.$once('hook:beforeDestroy', () => {
// window.removeEventListener('resize', fixSize)
// })
// #endif
},
// #ifndef VUE3
// TODO vue2
destroyed() {
this.setH5Visible()
},
// #endif
// #ifdef VUE3
// TODO vue3
unmounted() {
this.setH5Visible()
},
// #endif
activated() {
this.setH5Visible(!this.showPopup);
},
deactivated() {
this.setH5Visible(true);
},
created() {
// this.mkclick = this.isMaskClick || this.maskClick
if (this.isMaskClick === null && this.maskClick === null) {
this.mkclick = true
} else {
this.mkclick = this.isMaskClick !== null ? this.isMaskClick : this.maskClick
}
if (this.animation) {
this.duration = 300
} else {
this.duration = 0
}
// TODO message
this.messageChild = null
// TODO
this.clearPropagation = false
this.maskClass.backgroundColor = this.maskBackgroundColor
},
methods: {
setH5Visible(visible = true) {
// #ifdef H5
// fix by mehaotian h5 穿
document.getElementsByTagName('body')[0].style.overflow = visible ? "visible" : "hidden";
// #endif
},
/**
* 公用方法不显示遮罩层
*/
closeMask() {
this.maskShow = false
},
/**
* 公用方法遮罩层禁止点击
*/
disableMask() {
this.mkclick = false
},
// TODO nvue
clear(e) {
// #ifndef APP-NVUE
e.stopPropagation()
// #endif
this.clearPropagation = true
},
open(direction) {
// fix by mehaotian
if (this.showPopup) {
return
}
let innerType = ['top', 'center', 'bottom', 'left', 'right', 'message', 'dialog', 'share']
if (!(direction && innerType.indexOf(direction) !== -1)) {
direction = this.type
}
if (!this.config[direction]) {
console.error('缺少类型:', direction)
return
}
this[this.config[direction]]()
this.$emit('change', {
show: true,
type: direction
})
},
close(type) {
this.showTrans = false
this.$emit('change', {
show: false,
type: this.type
})
clearTimeout(this.timer)
// //
// this.customOpen && this.customClose()
this.timer = setTimeout(() => {
this.showPopup = false
}, 300)
},
// TODO
touchstart() {
this.clearPropagation = false
},
onTap() {
if (this.clearPropagation) {
// fix by mehaotian nvue
this.clearPropagation = false
return
}
this.$emit('maskClick')
if (!this.mkclick) return
this.close()
},
/**
* 顶部弹出样式处理
*/
top(type) {
this.popupstyle = this.isDesktop ? 'fixforpc-top' : 'top'
this.ani = ['slide-top']
this.transClass = {
position: 'fixed',
left: 0,
right: 0,
backgroundColor: this.bg,
borderRadius:this.borderRadius || "0"
}
// TODO type
if (type) return
this.showPopup = true
this.showTrans = true
this.$nextTick(() => {
this.showPoptrans()
if (this.messageChild && this.type === 'message') {
this.messageChild.timerClose()
}
})
},
/**
* 底部弹出样式处理
*/
bottom(type) {
this.popupstyle = 'bottom'
this.ani = ['slide-bottom']
this.transClass = {
position: 'fixed',
left: 0,
right: 0,
bottom: 0,
paddingBottom: this.safeAreaInsets + 'px',
backgroundColor: this.bg,
borderRadius:this.borderRadius || "0",
}
// TODO type
if (type) return
this.showPoptrans()
},
/**
* 中间弹出样式处理
*/
center(type) {
this.popupstyle = 'center'
//
// #ifdef MP-WEIXIN
this.ani = ['fade']
// #endif
// #ifndef MP-WEIXIN
this.ani = ['zoom-out', 'fade']
// #endif
this.transClass = {
position: 'fixed',
/* #ifndef APP-NVUE */
display: 'flex',
flexDirection: 'column',
/* #endif */
bottom: 0,
left: 0,
right: 0,
top: 0,
justifyContent: 'center',
alignItems: 'center',
borderRadius:this.borderRadius || "0"
}
// TODO type
if (type) return
this.showPoptrans()
},
left(type) {
this.popupstyle = 'left'
this.ani = ['slide-left']
this.transClass = {
position: 'fixed',
left: 0,
bottom: 0,
top: 0,
backgroundColor: this.bg,
borderRadius:this.borderRadius || "0",
/* #ifndef APP-NVUE */
display: 'flex',
flexDirection: 'column'
/* #endif */
}
// TODO type
if (type) return
this.showPoptrans()
},
right(type) {
this.popupstyle = 'right'
this.ani = ['slide-right']
this.transClass = {
position: 'fixed',
bottom: 0,
right: 0,
top: 0,
backgroundColor: this.bg,
borderRadius:this.borderRadius || "0",
/* #ifndef APP-NVUE */
display: 'flex',
flexDirection: 'column'
/* #endif */
}
// TODO type
if (type) return
this.showPoptrans()
},
showPoptrans(){
this.$nextTick(()=>{
this.showPopup = true
this.showTrans = true
})
}
}
}
</script>
<style lang="scss">
.uni-popup {
position: fixed;
/* #ifndef APP-NVUE */
z-index: 99;
/* #endif */
&.top,
&.left,
&.right {
/* #ifdef H5 */
top: var(--window-top);
/* #endif */
/* #ifndef H5 */
top: 0;
/* #endif */
}
.uni-popup__wrapper {
/* #ifndef APP-NVUE */
display: block;
/* #endif */
position: relative;
/* iphonex 等安全区设置,底部安全区适配 */
/* #ifndef APP-NVUE */
// padding-bottom: constant(safe-area-inset-bottom);
// padding-bottom: env(safe-area-inset-bottom);
/* #endif */
&.left,
&.right {
/* #ifdef H5 */
padding-top: var(--window-top);
/* #endif */
/* #ifndef H5 */
padding-top: 0;
/* #endif */
flex: 1;
}
}
}
.fixforpc-z-index {
/* #ifndef APP-NVUE */
z-index: 999;
/* #endif */
}
.fixforpc-top {
top: 0;
}
</style>

View File

@ -0,0 +1,88 @@
{
"id": "uni-popup",
"displayName": "uni-popup 弹出层",
"version": "1.9.2",
"description": " Popup 组件,提供常用的弹层",
"keywords": [
"uni-ui",
"弹出层",
"弹窗",
"popup",
"弹框"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"uni_modules": {
"dependencies": [
"uni-scss",
"uni-transition"
],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

View File

@ -0,0 +1,17 @@
## Popup 弹出层
> **组件名uni-popup**
> 代码块: `uPopup`
> 关联组件:`uni-transition`
弹出层组件,在应用中弹出一个消息提示窗口、提示框等
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-popup)
#### 如使用过程中有任何问题或者您对uni-ui有一些好的建议欢迎加入 uni-ui 交流群871950839

View File

@ -0,0 +1,24 @@
## 1.3.32024-04-23
- 修复 当元素会受变量影响自动隐藏的bug
## 1.3.22023-05-04
- 修复 NVUE 平台报错的问题
## 1.3.12021-11-23
- 修复 init 方法初始化问题
## 1.3.02021-11-19
- 优化 组件UI并提供设计资源详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-transition](https://uniapp.dcloud.io/component/uniui/uni-transition)
## 1.2.12021-09-27
- 修复 init 方法不生效的 Bug
## 1.2.02021-07-30
- 组件兼容 vue3如何创建 vue3 项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
## 1.1.12021-05-12
- 新增 示例地址
- 修复 示例项目缺少组件的 Bug
## 1.1.02021-04-22
- 新增 通过方法自定义动画
- 新增 custom-class 非 NVUE 平台支持自定义 class 定制样式
- 优化 动画触发逻辑,使动画更流畅
- 优化 支持单独的动画类型
- 优化 文档示例
## 1.0.22021-02-05
- 调整为 uni_modules 目录规范

View File

@ -0,0 +1,131 @@
// const defaultOption = {
// duration: 300,
// timingFunction: 'linear',
// delay: 0,
// transformOrigin: '50% 50% 0'
// }
// #ifdef APP-NVUE
const nvueAnimation = uni.requireNativePlugin('animation')
// #endif
class MPAnimation {
constructor(options, _this) {
this.options = options
// 在iOS10+QQ小程序平台下传给原生的对象一定是个普通对象而不是Proxy对象否则会报parameter should be Object instead of ProxyObject的错误
this.animation = uni.createAnimation({
...options
})
this.currentStepAnimates = {}
this.next = 0
this.$ = _this
}
_nvuePushAnimates(type, args) {
let aniObj = this.currentStepAnimates[this.next]
let styles = {}
if (!aniObj) {
styles = {
styles: {},
config: {}
}
} else {
styles = aniObj
}
if (animateTypes1.includes(type)) {
if (!styles.styles.transform) {
styles.styles.transform = ''
}
let unit = ''
if(type === 'rotate'){
unit = 'deg'
}
styles.styles.transform += `${type}(${args+unit}) `
} else {
styles.styles[type] = `${args}`
}
this.currentStepAnimates[this.next] = styles
}
_animateRun(styles = {}, config = {}) {
let ref = this.$.$refs['ani'].ref
if (!ref) return
return new Promise((resolve, reject) => {
nvueAnimation.transition(ref, {
styles,
...config
}, res => {
resolve()
})
})
}
_nvueNextAnimate(animates, step = 0, fn) {
let obj = animates[step]
if (obj) {
let {
styles,
config
} = obj
this._animateRun(styles, config).then(() => {
step += 1
this._nvueNextAnimate(animates, step, fn)
})
} else {
this.currentStepAnimates = {}
typeof fn === 'function' && fn()
this.isEnd = true
}
}
step(config = {}) {
// #ifndef APP-NVUE
this.animation.step(config)
// #endif
// #ifdef APP-NVUE
this.currentStepAnimates[this.next].config = Object.assign({}, this.options, config)
this.currentStepAnimates[this.next].styles.transformOrigin = this.currentStepAnimates[this.next].config.transformOrigin
this.next++
// #endif
return this
}
run(fn) {
// #ifndef APP-NVUE
this.$.animationData = this.animation.export()
this.$.timer = setTimeout(() => {
typeof fn === 'function' && fn()
}, this.$.durationTime)
// #endif
// #ifdef APP-NVUE
this.isEnd = false
let ref = this.$.$refs['ani'] && this.$.$refs['ani'].ref
if(!ref) return
this._nvueNextAnimate(this.currentStepAnimates, 0, fn)
this.next = 0
// #endif
}
}
const animateTypes1 = ['matrix', 'matrix3d', 'rotate', 'rotate3d', 'rotateX', 'rotateY', 'rotateZ', 'scale', 'scale3d',
'scaleX', 'scaleY', 'scaleZ', 'skew', 'skewX', 'skewY', 'translate', 'translate3d', 'translateX', 'translateY',
'translateZ'
]
const animateTypes2 = ['opacity', 'backgroundColor']
const animateTypes3 = ['width', 'height', 'left', 'right', 'top', 'bottom']
animateTypes1.concat(animateTypes2, animateTypes3).forEach(type => {
MPAnimation.prototype[type] = function(...args) {
// #ifndef APP-NVUE
this.animation[type](...args)
// #endif
// #ifdef APP-NVUE
this._nvuePushAnimates(type, args)
// #endif
return this
}
})
export function createAnimation(option, _this) {
if(!_this) return
clearTimeout(_this.timer)
return new MPAnimation(option, _this)
}

View File

@ -0,0 +1,286 @@
<template>
<!-- #ifndef APP-NVUE -->
<view v-show="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
<!-- #endif -->
<!-- #ifdef APP-NVUE -->
<view v-if="isShow" ref="ani" :animation="animationData" :class="customClass" :style="transformStyles" @click="onClick"><slot></slot></view>
<!-- #endif -->
</template>
<script>
import { createAnimation } from './createAnimation'
/**
* Transition 过渡动画
* @description 简单过渡动画组件
* @tutorial https://ext.dcloud.net.cn/plugin?id=985
* @property {Boolean} show = [false|true] 控制组件显示或隐藏
* @property {Array|String} modeClass = [fade|slide-top|slide-right|slide-bottom|slide-left|zoom-in|zoom-out] 过渡动画类型
* @value fade 渐隐渐出过渡
* @value slide-top 由上至下过渡
* @value slide-right 由右至左过渡
* @value slide-bottom 由下至上过渡
* @value slide-left 由左至右过渡
* @value zoom-in 由小到大过渡
* @value zoom-out 由大到小过渡
* @property {Number} duration 过渡动画持续时间
* @property {Object} styles 组件样式 css 样式注意带-连接符的属性需要使用小驼峰写法如`backgroundColor:red`
*/
export default {
name: 'uniTransition',
emits:['click','change'],
props: {
show: {
type: Boolean,
default: false
},
modeClass: {
type: [Array, String],
default() {
return 'fade'
}
},
duration: {
type: Number,
default: 300
},
styles: {
type: Object,
default() {
return {}
}
},
customClass:{
type: String,
default: ''
},
onceRender:{
type:Boolean,
default:false
},
},
data() {
return {
isShow: false,
transform: '',
opacity: 1,
animationData: {},
durationTime: 300,
config: {}
}
},
watch: {
show: {
handler(newVal) {
if (newVal) {
this.open()
} else {
// close,
if (this.isShow) {
this.close()
}
}
},
immediate: true
}
},
computed: {
//
stylesObject() {
let styles = {
...this.styles,
'transition-duration': this.duration / 1000 + 's'
}
let transform = ''
for (let i in styles) {
let line = this.toLine(i)
transform += line + ':' + styles[i] + ';'
}
return transform
},
//
transformStyles() {
return 'transform:' + this.transform + ';' + 'opacity:' + this.opacity + ';' + this.stylesObject
}
},
created() {
//
this.config = {
duration: this.duration,
timingFunction: 'ease',
transformOrigin: '50% 50%',
delay: 0
}
this.durationTime = this.duration
},
methods: {
/**
* ref 触发 初始化动画
*/
init(obj = {}) {
if (obj.duration) {
this.durationTime = obj.duration
}
this.animation = createAnimation(Object.assign(this.config, obj),this)
},
/**
* 点击组件触发回调
*/
onClick() {
this.$emit('click', {
detail: this.isShow
})
},
/**
* ref 触发 动画分组
* @param {Object} obj
*/
step(obj, config = {}) {
if (!this.animation) return
for (let i in obj) {
try {
if(typeof obj[i] === 'object'){
this.animation[i](...obj[i])
}else{
this.animation[i](obj[i])
}
} catch (e) {
console.error(`方法 ${i} 不存在`)
}
}
this.animation.step(config)
return this
},
/**
* ref 触发 执行动画
*/
run(fn) {
if (!this.animation) return
this.animation.run(fn)
},
//
open() {
clearTimeout(this.timer)
this.transform = ''
this.isShow = true
let { opacity, transform } = this.styleInit(false)
if (typeof opacity !== 'undefined') {
this.opacity = opacity
}
this.transform = transform
// nextTick wx
this.$nextTick(() => {
// TODO
this.timer = setTimeout(() => {
this.animation = createAnimation(this.config, this)
this.tranfromInit(false).step()
this.animation.run()
this.$emit('change', {
detail: this.isShow
})
}, 20)
})
},
//
close(type) {
if (!this.animation) return
this.tranfromInit(true)
.step()
.run(() => {
this.isShow = false
this.animationData = null
this.animation = null
let { opacity, transform } = this.styleInit(false)
this.opacity = opacity || 1
this.transform = transform
this.$emit('change', {
detail: this.isShow
})
})
},
//
styleInit(type) {
let styles = {
transform: ''
}
let buildStyle = (type, mode) => {
if (mode === 'fade') {
styles.opacity = this.animationType(type)[mode]
} else {
styles.transform += this.animationType(type)[mode] + ' '
}
}
if (typeof this.modeClass === 'string') {
buildStyle(type, this.modeClass)
} else {
this.modeClass.forEach(mode => {
buildStyle(type, mode)
})
}
return styles
},
//
tranfromInit(type) {
let buildTranfrom = (type, mode) => {
let aniNum = null
if (mode === 'fade') {
aniNum = type ? 0 : 1
} else {
aniNum = type ? '-100%' : '0'
if (mode === 'zoom-in') {
aniNum = type ? 0.8 : 1
}
if (mode === 'zoom-out') {
aniNum = type ? 1.2 : 1
}
if (mode === 'slide-right') {
aniNum = type ? '100%' : '0'
}
if (mode === 'slide-bottom') {
aniNum = type ? '100%' : '0'
}
}
this.animation[this.animationMode()[mode]](aniNum)
}
if (typeof this.modeClass === 'string') {
buildTranfrom(type, this.modeClass)
} else {
this.modeClass.forEach(mode => {
buildTranfrom(type, mode)
})
}
return this.animation
},
animationType(type) {
return {
fade: type ? 0 : 1,
'slide-top': `translateY(${type ? '0' : '-100%'})`,
'slide-right': `translateX(${type ? '0' : '100%'})`,
'slide-bottom': `translateY(${type ? '0' : '100%'})`,
'slide-left': `translateX(${type ? '0' : '-100%'})`,
'zoom-in': `scaleX(${type ? 1 : 0.8}) scaleY(${type ? 1 : 0.8})`,
'zoom-out': `scaleX(${type ? 1 : 1.2}) scaleY(${type ? 1 : 1.2})`
}
},
//
animationMode() {
return {
fade: 'opacity',
'slide-top': 'translateY',
'slide-right': 'translateX',
'slide-bottom': 'translateY',
'slide-left': 'translateX',
'zoom-in': 'scale',
'zoom-out': 'scale'
}
},
// 线
toLine(name) {
return name.replace(/([A-Z])/g, '-$1').toLowerCase()
}
}
}
</script>
<style></style>

View File

@ -0,0 +1,85 @@
{
"id": "uni-transition",
"displayName": "uni-transition 过渡动画",
"version": "1.3.3",
"description": "元素的简单过渡动画",
"keywords": [
"uni-ui",
"uniui",
"动画",
"过渡",
"过渡动画"
],
"repository": "https://github.com/dcloudio/uni-ui",
"engines": {
"HBuilderX": ""
},
"directories": {
"example": "../../temps/example_temps"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
"type": "component-vue"
},
"uni_modules": {
"dependencies": ["uni-scss"],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "y",
"app-nvue": "y"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

View File

@ -0,0 +1,11 @@
## Transition 过渡动画
> **组件名uni-transition**
> 代码块: `uTransition`
元素过渡动画
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-transition)
#### 如使用过程中有任何问题或者您对uni-ui有一些好的建议欢迎加入 uni-ui 交流群871950839

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More