Compare commits

...

3 Commits

Author SHA1 Message Date
姜玉琦 62b7274548 Merge branch 'dev_xd' of http://62.234.3.186:3000/jiangyq/YZProjectCloud into dev_xd 2024-10-13 11:26:34 +08:00
姜玉琦 0811adc4a9 Merge branch 'dev_xd' of http://62.234.3.186:3000/jiangyq/YZProjectCloud into dev_xd
# Conflicts:
#	yanzhu-modules/yanzhu-manage/pom.xml
2024-10-13 11:26:27 +08:00
姜玉琦 3535b0d6a8 提交代码 2024-10-13 11:25:16 +08:00
1488 changed files with 30695 additions and 92129 deletions

View File

@ -35,6 +35,7 @@
<minio.version>8.2.2</minio.version>
<poi.version>4.1.2</poi.version>
<pinyin4j.version>2.5.1</pinyin4j.version>
<weixin.version>2.7.0</weixin.version>
<transmittable-thread-local.version>2.14.2</transmittable-thread-local.version>
</properties>
@ -151,6 +152,13 @@
<version>${pinyin4j.version}</version>
</dependency>
<!-- 微信公众号 -->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>${weixin.version}</version>
</dependency>
<!-- 核心模块 -->
<dependency>
<groupId>com.yanzhu</groupId>

View File

@ -2,6 +2,7 @@ package com.yanzhu.auth.controller;
import com.yanzhu.auth.form.LoginBody;
import com.yanzhu.auth.form.RegisterBody;
import com.yanzhu.auth.form.WxLoginBody;
import com.yanzhu.auth.service.SysLoginService;
import com.yanzhu.common.core.constant.SecurityConstants;
import com.yanzhu.common.core.domain.R;
@ -51,6 +52,15 @@ public class TokenController
return R.ok(tokenService.createToken(userInfo));
}
@PostMapping("wxLogin")
public R<?> wxLogin(@RequestBody WxLoginBody form)
{
// 用户登录
LoginUser userInfo = sysLoginService.wxLogin(form.getCode(), form.getAppId());
// 获取登录token
return R.ok(tokenService.createToken(userInfo));
}
/**
*
* @param proId

View File

@ -0,0 +1,35 @@
package com.yanzhu.auth.form;
/**
*
*
* @author ruoyi
*/
public class WxLoginBody {
/**
*
*/
private String code;
/**
*
*/
private String appId;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
}

View File

@ -119,6 +119,84 @@ public class SysLoginService
return userInfo;
}
/**
*
*/
public LoginUser wxLogin(String code, String appId)
{
// 用户名或密码为空 错误
if (StringUtils.isAnyBlank(username, password))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户/密码必须填写");
throw new ServiceException("用户/密码必须填写");
}
// 密码如果不在指定范围内 错误
if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
|| password.length() > UserConstants.PASSWORD_MAX_LENGTH)
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户密码不在指定范围");
throw new ServiceException("用户密码不在指定范围");
}
// 用户名不在指定范围内 错误
if (username.length() < UserConstants.USERNAME_MIN_LENGTH
|| username.length() > UserConstants.USERNAME_MAX_LENGTH)
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户名不在指定范围");
throw new ServiceException("用户名不在指定范围");
}
// IP黑名单校验
String blackStr = Convert.toStr(redisService.getCacheObject(CacheConstants.SYS_LOGIN_BLACKIPLIST));
if (IpUtils.isMatchedIp(blackStr, IpUtils.getIpAddr()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "很遗憾访问IP已被列入系统黑名单");
throw new ServiceException("很遗憾访问IP已被列入系统黑名单");
}
// 查询用户信息
R<LoginUser> userResult = remoteUserService.getUserInfo(username, SecurityConstants.INNER);
if (StringUtils.isNull(userResult) || StringUtils.isNull(userResult.getData()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "登录用户不存在");
throw new ServiceException("登录用户:" + username + " 不存在");
}
if (R.FAIL == userResult.getCode())
{
throw new ServiceException(userResult.getMsg());
}
LoginUser userInfo = userResult.getData();
SysUser user = userResult.getData().getSysUser();
if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "对不起,您的账号已被删除");
throw new ServiceException("对不起,您的账号:" + username + " 已被删除");
}
if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
{
recordLogService.recordLogininfor(username, Constants.LOGIN_FAIL, "用户已停用,请联系管理员");
throw new ServiceException("对不起,您的账号:" + username + " 已停用");
}
passwordService.validate(user, password);
recordLogService.recordLogininfor(username, Constants.LOGIN_SUCCESS, "登录成功");
// 补充用户项目信息
if(Objects.nonNull(user.getActiveComId())){
userInfo.setProjectDeptId(user.getActiveComId());
}
if(Objects.nonNull(user.getActiveComName())){
userInfo.setProjectDeptName(user.getActiveComName());
}
if(Objects.nonNull(user.getActiveProjectId())){
userInfo.setProjectId(user.getActiveProjectId());
}
if(Objects.nonNull(user.getActiveProjectName())){
userInfo.setProjectName(user.getActiveProjectName());
}
return userInfo;
}
public void logout(String loginName)
{
recordLogService.recordLogininfor(loginName, Constants.LOGOUT, "退出成功");

View File

@ -119,5 +119,11 @@
<artifactId>pinyin4j</artifactId>
</dependency>
<!-- 微信小程序 -->
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -83,12 +83,6 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>

View File

@ -1,8 +1,26 @@
node_modules/
dist/**
.project
unpackage/
.DS_Store
wxcomponents/**/*.vue
wxcomponents/**/*.css
.hbuilderx/
# ---> Java
# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*

View File

@ -1,28 +0,0 @@
<script>
import config from './config'
export default {
onLaunch: function(options) {
},
methods: {
//
initApp(query) {
//
this.initConfig()
//
},
initConfig() {
this.globalData.config = config
},
}
}
</script>
<style lang="scss">
@import '@/static/scss/index.scss'
</style>
<style>
page {
background-color: #fff;
height: 100%;
}
</style>

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2022 若依
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.

View File

@ -1,52 +1,40 @@
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">研筑-临时工程项目管理App</h1>
<h4 align="center">基于RuoYi+Flowable 6.x的工作流管理平台</h4>
<p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-43e3941654fa3054c9684bf53d1b1d356a1.png">
</p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v1.1.0</h1>
<h4 align="center">基于UniApp开发的轻量级移动端框架</h4>
<p align="center">
<a href="https://gitee.com/y_project/RuoYi-App/stargazers"><img src="https://gitee.com/y_project/RuoYi-App/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-App"><img src="https://img.shields.io/badge/RuoYi-v1.1.0-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-App/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
<img src="https://gitee.com/tony2y/RuoYi-flowable/badge/star.svg?theme=dark?theme=dark">
</p>
## 平台简介
RuoYi App 移动解决方案采用uniapp框架一份代码多终端适配同时支持APP、小程序、H5实现了与[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)、[RuoYi-Cloud](https://gitee.com/y_project/RuoYi-Cloud)完美对接的移动解决方案!目前已经实现登录、我的、工作台、编辑资料、头像修改、密码修改、常见问题、关于我们等基础功能。
基于RuoYi-vue + Flowable 6.x 的工作流管理平台 ~
* 配套后端代码仓库地址[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue) 或 [RuoYi-Cloud](https://github.com/yangzongzhuan/RuoYi-Cloud) 版本。
* 应用框架基于[uniapp](https://uniapp.dcloud.net.cn/)支持小程序、H5、Android和IOS。
* 前端组件采用[uni-ui](https://github.com/dcloudio/uni-ui)全端兼容的高性能UI框架。
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
* 阿里云优惠券:[点我领取](https://www.aliyun.com/minisite/goods?userCode=brki8iof&share_source=copy_link),腾讯云优惠券:[点我领取](https://cloud.tencent.com/redirect.php?redirect=1025&cps_key=198c8df2ed259157187173bc7f4f32fd&from=//console)&nbsp;&nbsp;
- 不定时同步[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)至最新版本。
- 前端采用Vue、Element UI。
- 后端采用Spring Boot、Spring Security、Redis & Jwt。
- 权限认证使用Jwt支持多终端认证系统。
- 支持加载动态权限菜单,多方式轻松权限控制.
- 项目地址:[Gitee](https://gitee.com/tony2y/RuoYi-flowable.git)&nbsp;&nbsp;&nbsp;[Github](https://github.com/tony2y/RuoYi-flowable.git)
- 阿里云折扣场:[点我进入](https://www.aliyun.com/activity/daily/bestoffer?userCode=q2b8atsa),腾讯云秒杀场:[点我进入](https://curl.qcloud.com/W5KFkBG4)&nbsp;&nbsp;
- 阿里云优惠券:[点我领取](https://www.aliyun.com/daily-act/ecs/activity_selection?userCode=q2b8atsa),腾讯云优惠券:[点我领取](https://curl.qcloud.com/AacfyRxq)&nbsp;&nbsp;
- 特别鸣谢:[RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue)
## 内置功能
- 在线流程设计器
- 在线流程表单设计器
- 单节点配置表单
- 多实例会签任务
- 任务节点配置任务/执行监听器
- 动态配置任务候选人
- 其它流程相关功能点
## 技术文档
## 演示地址
- 官网网站:[http://ruoyi.vip](http://ruoyi.vip)
- 文档地址:[http://doc.ruoyi.vip](http://doc.ruoyi.vip)
- H5页体验[http://h5.ruoyi.vip](http://h5.ruoyi.vip)
- QQ交流群 ①133713780(满)、②146013835
- 小程序体验
- 开源版演示地址http://open.tony2y.top
- Vue2 / Vue3 演示地址(付费版)http://vue3.tony2y.top
- 使用文档https://www.yuque.com/u1024153/icipor
<img src="https://oscimg.oschina.net/oscnet/up-26c76dc90b92acdbd9ac8cd5252f07c8ad9.jpg" alt="小程序演示"/>
## 其它业务系统
## 演示图
<table>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-3ea20e447ac621a161e395fb53ccc683d84.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-a6f23cf9a371a30165e135eff6d9ae89a9d.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-ff5f62016bf6624c1ff27eee57499dccd44.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-b9a582fdb26ec69d407fabd044d2c8494df.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-96427ee08fca29d77934cfc8d1b1a637cef.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-5fdadc582d24cccd7727030d397b63185a3.png"/></td>
</tr>
<tr>
<td><img src="https://oscimg.oschina.net/oscnet/up-0a36797b6bcc50c36d40c3c782665b89efc.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-d77995cc00687cedd00d5ac7d68a07ea276.png"/></td>
<td><img src="https://oscimg.oschina.net/oscnet/up-fa8f5ab20becf59b4b38c1b92a9989e7109.png"/></td>
</tr>
</table>
- [[ 智慧农业认养系统 ]](https://gitee.com/tony2y/smart-breed)基于Java + SpringBoot + Mybatis Plus + Redis + Vue + antdv支持认养、商城、营销、会员、进销存、多租户等功能包含小程序系统管理后台。
- [[ 智慧景区管理系统 ]](https://gitee.com/tony2y/scenic-spot)基于Java + SpringBoot + Mybatis Plus + Redis + Vue + antdv支持景区管理、售票、地块管理、认养、商城、农资管理、积分兑换等功能包含小程序系统管理后台。

View File

@ -1,71 +0,0 @@
import request from '@/utils/request'
import upload from '@/utils/upload'
// 上传文件
export function saveFileManagement(data) {
return request({
url: '/apiwork/fileApi/saveFileManagement',
method: 'post',
data:data
})
}
// 下载文件时调用
export function countLikeNum(val) {
return request({
url: '/apiwork/fileApi/countLikeNum/' + val,
method: 'get',
})
}
// 点赞/取消点赞
export function fileApilike(val) {
return request({
url: '/apiwork/fileApi/like/' + val,
method: 'get',
})
}
// 宣传资料列表
export function findAll(data) {
return request({
url: '/apiwork/fileApi/findAll',
method: 'get',
data: data,
})
}
// 工單提交
export function submitWork(data) {
return request({
'url': '/apiwork/work/tzzrz/createTzzWork',
method: 'post',
data: data,
})
}
// 文件上传
export function uploadFile(data) {
return upload({
url: '/common/upload',
method:'PUT',
name: data.name,
filePath: data.filePath
})
}
// 查询意见反馈类型列表
export function ideaType(data) {
return request({
'url': '/apiwork/tyPublicApi/idea/v1/ideaType',
method: 'get'
})
}
// 提交反馈
export function feedbackSub(data) {
return request({
'url': '/apiwork/tyPublicApi/idea/v1/add',
method: 'post',
data: data,
})
}

View File

@ -1,71 +0,0 @@
import request from '@/utils/request'
// 预警消息
export function update(data) {
return request({
url: '/system/warning',
method: 'put',
data:data
})
}
// 预警消息
export function warningList(query) {
return request({
url: '/system/warning/list',
method: 'get',
params: query
})
}
// 新增投诉工单
export function addOrder(data) {
return request({
url: '/system/order',
method: 'post',
data: data
})
}
// 查询投诉列表
export function listuser(query) {
return request({
url: '/system/order/listuser',
method: 'get',
params: query
})
}
// 查询工单列表
export function listOrder(query) {
return request({
url: '/system/order/list',
method: 'get',
params: query
})
}
// 查询工单列表
export function recordOrder(id) {
return request({
url: '/system/record/list?workOrderId=' + id,
method: 'get'
})
}
// 签到/完成任务
export function record(query) {
return request({
url: '/system/order/task/record',
method: 'post',
data: query
})
}
// 查询工单详情
export function getOrder(id) {
return request({
url: '/system/order/' + id,
method: 'get'
})
}

View File

@ -1,50 +0,0 @@
import request from '@/utils/request'
// 获取用户详细信息
export function getInfo() {
return request({
'url': '/wechat/userinfo/getUserInfo',
'method': 'get'
})
}
// 退出方法
export function logout() {
return request({
'url': '/auth/logout',
'method': 'delete'
})
}
//手机号登陆
export function phoneLogin(data) {
return request({
url: '/auth/phoneLogin',
headers: {
isToken: false
},
method: 'post',
data: data
})
}
//获取OPENID 存sessionkey
export function getOpenIdByCode(data) {
return request({
url: '/auth/getOpenIdByCode',
headers: {
isToken: false
},
method: 'post',
data: data
})
}
//获取微信手机号
export function getWxUserPhone(data) {
return request({
url: '/auth/getWxUserPhone',
method: 'post',
data: data
})
}

View File

@ -1,83 +0,0 @@
<template>
<view class="homeheader" :style="'height:'+safeAreaInsetsTop+'px'">
<u-navbar bgColor="#ffffff" :title="titlenav" :placeholder="background=='#FFF'" :titleStyle="{color:`${textcolor}`}"
:leftIconColor="textcolor" @leftClick="backto(url)" leftIcon="arrow-left">
</u-navbar>
<view class="cjnavbar">
<view class="aaa" :style="'height:'+safeAreaInsetsTop+'px;width:100%;background:'+background">
</view>
</view>
</view>
<!-- <view></view> -->
</template>
<script>
export default {
props: {
"titlenav": {
type: String
},
'background': {
type: String,
default: '#FFF'
},
'textcolor': {
type: String,
default: '#000000'
},
'url': {
type: String,
default: ''
},
},
data() {
return {
safeAreaInsetsTop: 0,
}
},
created() {
this.safeAreaInsetsTop = uni.getSystemInfoSync().safeAreaInsets.top + 44;
},
methods:{
backto(e){
if(e){
if(e.includes('http')){
location.href = e
}else{
uni.reLaunch({
url:e
})
}
}else{
uni.navigateBack()
}
}
}
}
</script>
<style lang="scss" scoped>
.homeheader {
display: flex;
align-items: center;
.cjnavbar {
display: flex;
flex-direction: column;
flex-shrink: 0;
flex-grow: 0;
flex-basis: auto;
align-items: stretch;
align-content: flex-start;
.aaa {
position: fixed;
left: 0;
right: 0;
top: 0;
z-index: 10;
}
}
}
</style>

View File

@ -1,16 +0,0 @@
<template>
<view class="hoemheader">
<u-navbar leftIcon=" " :placeholder="true" :title="titlenav">
<!-- jin -->
</u-navbar>
</view>
</template>
<script>
export default {
props:["titlenav"],
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -1,99 +0,0 @@
<template>
<cover-view>
<view class="" v-if="identity==0" >
<u-tabbar activeColor="rgba(2, 127, 234, 1)" inactiveColor="#000001" :value="value" :fixed="true"
:placeholder="true" :safeAreaInsetBottom="true">
<u-tabbar-item v-for="(item,i) in footerTabbargl" :key="i" @click="toUrl(item.pagePath)" :text="item.text"
class="tabbar_di_list">
<image style="width: 22px; height:22px;" class=" u-page__item__slot-icon" slot="active-icon"
:src="item.selectedIconPath"></image>
<image style="width: 22px; height:22px;" class="u-page__item__slot-icon" slot="inactive-icon"
:src="item.iconPath"></image>
</u-tabbar-item>
</u-tabbar>
</view>
<view class="" v-if="identity==1" >
<u-tabbar activeColor="rgba(2, 127, 234, 1)" inactiveColor="#000001" :value="value" :fixed="true"
:placeholder="true" :safeAreaInsetBottom="true">
<u-tabbar-item v-for="(item,i) in footerTabbarg2" :key="i" @click="toUrl(item.pagePath)" :text="item.text"
class="tabbar_di_list">
<image style="width: 22px; height:22px;" class=" u-page__item__slot-icon" slot="active-icon"
:src="item.selectedIconPath"></image>
<image style="width: 22px; height:22px;" class="u-page__item__slot-icon" slot="inactive-icon"
:src="item.iconPath"></image>
</u-tabbar-item>
</u-tabbar>
</view>
</cover-view>
</template>
<script>
export default {
name: "tabbar",
props: {
value: '',
identity: '',
},
data() {
return {
//
footerTabbargl: [{
"pagePath": "/pages/index",
"iconPath": "/static/tabarimg/fz1.png",
"selectedIconPath": "/static/tabarimg/fz2.png",
"text": "职位"
},
{
"pagePath": "/pages/work/index",
"iconPath": "/static/tabarimg/fz3.png",
"selectedIconPath": "/static/tabarimg/fz4.png",
"text": "消息"
},
{
"pagePath": "/pages/mine/index",
"iconPath": "/static/tabarimg/fz3.png",
"selectedIconPath": "/static/tabarimg/fz4.png",
"text": "我的"
}
],
//
footerTabbarg2: [{
"pagePath": "/pages_loader/pages/index",
"iconPath": "/static/tabarimg/fz1.png",
"selectedIconPath": "/static/tabarimg/fz2.png",
"text": "人才大厅"
},
{
"pagePath": "/pages_loader/pages/work/index",
"iconPath": "/static/tabarimg/fz3.png",
"selectedIconPath": "/static/tabarimg/fz4.png",
"text": "消息"
},
{
"pagePath": "/pages_loader/pages/mine/index",
"iconPath": "/static/tabarimg/fz3.png",
"selectedIconPath": "/static/tabarimg/fz4.png",
"text": "我的"
}
],
};
},
methods: {
// idnexChenage(index) {
// uni.setStorageSync('nvgetIndex', index)
// },
toUrl(url) {
// //console.log(this.value, this.identity, '');
uni.reLaunch({
url: url
})
}
}
}
</script>
<style scoped>
/deep/.tabbar_di_list .u-page__item__slot-icon {
width: 20px !important;
height: 18px !important;
}
</style>

View File

@ -1,167 +0,0 @@
<template>
<view class="uni-section">
<view class="uni-section-header" @click="onClick">
<view class="uni-section-header__decoration" v-if="type" :class="type" />
<slot v-else name="decoration"></slot>
<view class="uni-section-header__content">
<text :style="{'font-size':titleFontSize,'color':titleColor}" class="uni-section__content-title" :class="{'distraction':!subTitle}">{{ title }}</text>
<text v-if="subTitle" :style="{'font-size':subTitleFontSize,'color':subTitleColor}" class="uni-section-header__content-sub">{{ subTitle }}</text>
</view>
<view class="uni-section-header__slot-right">
<slot name="right"></slot>
</view>
</view>
<view class="uni-section-content" :style="{padding: _padding}">
<slot />
</view>
</view>
</template>
<script>
/**
* Section 标题栏
* @description 标题栏
* @property {String} type = [line|circle|square] 标题装饰类型
* @value line 竖线
* @value circle 圆形
* @value square 正方形
* @property {String} title 主标题
* @property {String} titleFontSize 主标题字体大小
* @property {String} titleColor 主标题字体颜色
* @property {String} subTitle 副标题
* @property {String} subTitleFontSize 副标题字体大小
* @property {String} subTitleColor 副标题字体颜色
* @property {String} padding 默认插槽 padding
*/
export default {
name: 'UniSection',
emits:['click'],
props: {
type: {
type: String,
default: ''
},
title: {
type: String,
required: true,
default: ''
},
titleFontSize: {
type: String,
default: '14px'
},
titleColor:{
type: String,
default: '#333'
},
subTitle: {
type: String,
default: ''
},
subTitleFontSize: {
type: String,
default: '12px'
},
subTitleColor: {
type: String,
default: '#999'
},
padding: {
type: [Boolean, String],
default: false
}
},
computed:{
_padding(){
if(typeof this.padding === 'string'){
return this.padding
}
return this.padding?'10px':''
}
},
watch: {
title(newVal) {
if (uni.report && newVal !== '') {
uni.report('title', newVal)
}
}
},
methods: {
onClick() {
this.$emit('click')
}
}
}
</script>
<style lang="scss" >
$uni-primary: #2979ff !default;
.uni-section {
background-color: #fff;
.uni-section-header {
position: relative;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
padding: 12px 10px;
font-weight: normal;
&__decoration{
margin-right: 6px;
background-color: $uni-primary;
&.line {
width: 4px;
height: 12px;
border-radius: 10px;
}
&.circle {
width: 8px;
height: 8px;
border-top-right-radius: 50px;
border-top-left-radius: 50px;
border-bottom-left-radius: 50px;
border-bottom-right-radius: 50px;
}
&.square {
width: 8px;
height: 8px;
}
}
&__content {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
flex: 1;
color: #333;
.distraction {
flex-direction: row;
align-items: center;
}
&-sub {
margin-top: 2px;
}
}
&__slot-right{
font-size: 14px;
}
}
.uni-section-content{
font-size: 14px;
}
}
</style>

View File

@ -1,27 +0,0 @@
// 应用全局配置
module.exports = {
// test
baseUrl: 'http://192.168.16.104:8080',
// baseUrl: 'http://192.168.16.104:8080',
// 应用信息
appInfo: {
// 应用名称
name: "ruoyi-app",
// 应用版本
version: "1.1.0",
// 应用logo
logo: "/static/logo.png",
// 官方网站
site_url: "http://ruoyi.vip",
// 政策协议
agreements: [{
title: "隐私政策",
url: ""
},
{
title: "用户服务协议",
url: ""
}
]
}
}

View File

@ -1,26 +0,0 @@
import Vue from 'vue'
import App from './App'
import store from './store' // store
import plugins from './plugins' // plugins
import uView from '@/uview-ui' //uview
import './permission' // permission
import homebar from "@/components/navbar/homebar.vue"
import navbar from "@/components/navbar/Navbar.vue"
// import Vconsole from 'vconsole'
// let vConsole = new Vconsole();
Vue.use(plugins)
Vue.use(uView)
Vue.config.productionTip = false
Vue.prototype.$store = store
Vue.component('homebar', homebar)
Vue.component('navbar', navbar)
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
// export default vConsole

View File

@ -1,85 +0,0 @@
{
"name" : "移动端",
"appid" : "__UNI__A076EAE",
"description" : "",
"versionName" : "1.1.0",
"versionCode" : "100",
"transformPx" : false,
"app-plus" : {
"usingComponents" : true,
"nvueCompiler" : "急用工",
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"modules" : {},
"distribute" : {
"android" : {
"permissions" : [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>"
]
},
"ios" : {},
"sdkConfigs" : {
"maps" : {
"amap" : {
"appkey_ios" : "",
"appkey_android" : ""
}
}
}
}
},
"quickapp" : {},
"mp-weixin" : {
"appid" : "wxbde64edd3cb15f72",
"setting" : {
"urlCheck" : false,
"es6" : true,
"minified" : true,
"postcss" : true
},
"optimization" : {
"subPackages" : true
},
"usingComponents" : true,
"permission" : {
"scope.userLocation" : {
"desc" : "你的位置信息将用于小程序位置接口的效果展示"
}
},
"requiredPrivateInfos" : [ "chooseAddress", "chooseLocation", "getLocation" ],
"unipush" : {
"enable" : false
}
},
"vueVersion" : "2",
"h5" : {
"template" : "static/index.html",
"devServer" : {
"port" : 9090,
"https" : false
},
"title" : "水务投诉平台",
"router" : {
"mode" : "hash",
"base" : "./"
},
"sdkConfigs" : {
"maps" : {
"qqmap" : {
"key" : "IO6BZ-EJALJ-PXDF5-XOVE6-VRWPO-DUFTO"
}
}
}
}
}

View File

@ -0,0 +1,169 @@
import {request} from '../utils/request'
// 获取流程申请类型
export function myDefinitionList(data) {
return request({
url: '/wxApi/flowTask/myDefinitionList',
method: 'get',
data: data
})
}
// 启动流程实例
export function startProcessInstance(data) {
return request({
url: '/wxApi/flowTask/startProcessInstance',
method: 'post',
data: data
})
}
// 查询流程节点
export function readNotes(deployId) {
return request({
url: '/wxApi/flowTask/readNotes/'+deployId,
method: 'get'
})
}
// 查询流程节点
export function readDeployNotes(deployId) {
return request({
url: '/wxApi/flowTask/readDeployNotes/'+deployId,
method: 'get'
})
}
// 取消流程申请
export function stopProcess(data) {
return request({
url: '/wxApi/flowTask/stopProcess',
method: 'post',
data: data
})
}
// 撤回流程办理
export function revokeProcess(data) {
return request({
url: '/wxApi/flowTask/revokeProcess',
method: 'post',
data: data
})
}
// 审批任务流程
export function complete(data) {
return request({
url: '/wxApi/flowTask/complete',
method: 'post',
data: data
})
}
// 驳回任务流程
export function reject(data) {
return request({
url: '/wxApi/flowTask/reject',
method: 'post',
data: data
})
}
// 退回任务流程
export function returnTask(data) {
return request({
url: '/wxApi/flowTask/return',
method: 'post',
data: data
})
}
// 委派任务流程
export function delegateTask(data) {
return request({
url: '/wxApi/flowTask/delegateTask',
method: 'post',
data: data
})
}
// 转办任务流程
export function assignTask(data) {
return request({
url: '/wxApi/flowTask/assignTask',
method: 'post',
data: data
})
}
// 删除流程实例
export function deleteInstance(instanceId) {
return request({
url: '/wxApi/flowTask/delete/'+instanceId,
method: 'get'
})
}
// 获取所有可回退的节点
export function returnList(data) {
return request({
url: '/wxApi/flowTask/returnList',
method: 'post',
data: data
})
}
// 根据流程Id查询操作日志
export function findCommentByProcInsId(data) {
return request({
url: '/wxApi/flowTask/findCommentByProcInsId',
method: 'get',
data: data
})
}
// 根据条件查询我的代办任务
export function myAwaitFlowTaskList(data) {
return request({
url: '/wxApi/flowTask/myAwaitFlowTaskList',
method: 'post',
data: data
})
}
// 根据条件查询我的已办任务
export function myFinishedFlowTaskList(query) {
return request({
url: '/wxApi/flowTask/myFinishedFlowTaskList',
method: 'get',
params: query
})
}
// 根据条件查询所有流申请
export function allInstanceList(data) {
return request({
url: '/wxApi/flowTask/allList',
method: 'get',
data: data
})
}
// 根据条件查询所有流申请
export function myInstanceList(data) {
return request({
url: '/wxApi/flowTask/myList',
method: 'get',
data: data
})
}
// 根据条件统计所有流程任务
export function queryTaskCount(data) {
return request({
url: '/wxApi/flowTask/queryCount',
method: 'get',
data: data
})
}

View File

@ -0,0 +1,44 @@
import {request} from '../utils/request'
// 获取验证码
export function getCodeImg() {
return request({
url: '/captchaImage',
method: 'get',
})
}
// 登录方法
export function login(data) {
return request({
url: '/wxApi/login',
method: 'post',
data: data,
})
}
// 登录方法
export function updatePwd(data) {
return request({
url: '/wxApi/updatePwd',
method: 'post',
data: data,
})
}
// 用户退出方法
export function loginOut() {
return request({
'url': '/wxApi/loginOut',
'method': 'get'
})
}
// 刷线用户信息
export function refreshUser() {
return request({
'url': '/wxApi/refreshUserInfo',
'method': 'get'
})
}

View File

@ -0,0 +1,60 @@
import {request} from '../utils/request'
// 获取项目编号
export function getProjectNo() {
return request({
url: '/project/projectInfo/findMyDeptProjectNo',
method: 'get'
})
}
// 查询项目信息列表
export function listProjectInfo(query) {
return request({
url: '/project/projectInfo/list',
method: 'get',
params: query
})
}
// 查询项目信息详细
export function getProjectInfo(id) {
return request({
url: '/project/projectInfo/' + id,
method: 'get'
})
}
// 新增项目信息
export function addProjectInfo(data) {
return request({
url: '/project/projectInfo',
method: 'post',
data: data
})
}
// 修改项目信息
export function updateProjectInfo(data) {
return request({
url: '/project/projectInfo',
method: 'put',
data: data
})
}
// 删除项目信息
export function delProjectInfo(id) {
return request({
url: '/project/projectInfo/' + id,
method: 'delete'
})
}
// 我的部门项目
export function findMyDeptProject() {
return request({
url: '/project/projectInfo/findMyDeptProject',
method: 'get'
})
}

View File

@ -0,0 +1,72 @@
import {
request
} from '../utils/request'
// 修改项目申请信息
export function updateProjectApply(data) {
return request({
url: '/project/projectApply',
method: 'put',
data: data
})
}
// 验收申请列表
export function checkApplyList(query) {
return request({
url: '/project/projectApply/checkApplyList',
method: 'get',
params: query
})
}
// 验收申请列表
export function findGroupCountByStatus(query) {
return request({
url: '/project/projectApply/findGroupCountByStatus',
method: 'get',
params: query
})
}
// 创建二维码
export function createQr(id) {
return request({
url: '/project/projectApply/createQr/'+id,
method: 'get'
})
}
// 保存验收
export function editApplyChecked(data) {
return request({
url: '/project/projectApply/editApplyChecked',
method: 'put',
data: data
})
}
// 验收详情
export function findApplyDetailAllCheck(detailId) {
return request({
url: '/manage/proProjectApplyDetailCheck/findAll/'+detailId,
method: 'get'
})
}
export function addApplyDetail(data) {
return request({
url: '/project/projectApply/addApplyDetail',
method: 'post',
data: data
})
}
// 添加验收
export function addApplyDetailCheck(data) {
return request({
url: '/manage/proProjectApplyDetailCheck',
method: 'post',
data: data
})
}

View File

@ -0,0 +1,59 @@
import {request} from '../utils/request'
// 获取用户详细信息
export function getUserInfo() {
return request({
url: '/wxApi/publics/user/info',
method: 'get'
})
}
// 查询用户菜单信息
export function selectRoleMenuList(data) {
return request({
url: '/wxApi/publics/v1/selectRoleMenuList',
method: 'get',
data: data
})
}
// 查询用户待办信息
export function findMyTask(data) {
return request({
url: '/wxApi/flowTask/myAwaitFlowTaskListCount',
method: 'post',
data:data
})
}
// 查询用户部门信息
export function findMyDeptList(){
return request({
url: '/wxApi/publics/v1/findMyDeptList',
method: 'get'
})
}
// 查询用户项目信息
export function findMyProjectList(){
return request({
url: '/wxApi/publics/v1/findMyProjectList',
method: 'get'
})
}
// 查询部门资产列表信息
export function findAllByCategory(category){
return request({
url: '/wxApi/publics/v1/findAllByCategory/'+category,
method: 'get'
})
}
// 获取项目申请详细信息
export function findProjectApplyData(id){
return request({
url: '/wxApi/publics/projectApply/'+id,
method: 'get'
})
}

View File

@ -0,0 +1,181 @@
import {
getToken
} from '/utils/auth'
//全局分享
! function () {
var PageTmp = Page;
Page = function (pageConfig) {
// 设置全局默认分享
pageConfig = Object.assign({
//右上角分享功能
onShareAppMessage() {
return {
title: '智慧工地优管', //分享标题
path: '/pages/login/login', //分享用户点开后页面
success(res) {
console.log('分享成功!')
}
}
}
}, pageConfig);
PageTmp(pageConfig);
};
}();
App({
globalData: {
userData: null,
paramDeptId: '',
useProjectId: '',
useProjectName: '',
searchProject: {
id: "",
text: "全部临时项目",
projectId: "",
projectName: "全部临时项目"
},
projectInfoList: [],
},
onLaunch: function () {
if (!wx.cloud) {
console.error('请使用 2.2.3 或以上的基础库以使用云能力')
} else {
wx.cloud.init({
// env 参数说明:
// env 参数决定接下来小程序发起的云开发调用wx.cloud.xxx会默认请求到哪个云环境的资源
// 此处请填入环境 ID, 环境 ID 可打开云控制台查看
// 如不填则使用默认环境(第一个创建的环境)
// env: 'my-env-id',
traceUser: true,
})
}
this.autoUpdate();
/**
* 初始化页面未登录时跳转到登录页
*/
if (!getToken()) {
setTimeout(() => {
this.toast("请使用手机号码登录");
}, 1000);
wx.redirectTo({
url: '/pages/login/index',
});
return false;
}
},
onLoad() {
},
//页面弹窗
toast: function (msg, type) {
wx.showToast({
title: msg,
icon: type === undefined ? 'none' : type,
duration: 1000,
mask: true
});
},
/**
* 计算时差
* @param {*} val
*/
getDurationDate: function (val) {
// 计算出相差天数
let days = Math.floor(val / (24 * 3600 * 1000))
// 计算出小时数
let leave1 = val % (24 * 3600 * 1000) // 计算天数后剩余的毫秒数
let hours = Math.floor(leave1 / (3600 * 1000))
// 计算相差分钟数
let leave2 = leave1 % (3600 * 1000) // 计算小时数后剩余的毫秒数
let minutes = Math.floor(leave2 / (60 * 1000))
// 计算相差秒数
let leave3 = leave2 % (60 * 1000) // 计算分钟数后剩余的毫秒数
let seconds = Math.round(leave3 / 1000)
if (days > 0) {
if (days < 10) days = "0" + days;
if (hours < 10) hours = "0" + hours;
if (minutes < 10) minutes = "0" + minutes;
if (seconds < 10) seconds = "0" + seconds;
return days + '天' + hours + '小时' + minutes + '分钟' + seconds + '秒';
}
if (hours > 0) {
if (hours < 10) hours = "0" + hours;
if (minutes < 10) minutes = "0" + minutes;
if (seconds < 10) seconds = "0" + seconds;
return hours + '小时' + minutes + '分钟' + seconds + '秒';
}
if (minutes > 0) {
if (minutes < 10) minutes = "0" + minutes;
if (seconds < 10) seconds = "0" + seconds;
return minutes + '分钟' + seconds + '秒';
}
if (seconds > 0) {
if (seconds < 10) seconds = "0" + seconds;
return seconds + '秒';
}
},
//版本自动更新
autoUpdate: function () {
var self = this
// 获取小程序更新机制兼容
if (wx.canIUse('getUpdateManager')) {
const updateManager = wx.getUpdateManager()
//1. 检查小程序是否有新版本发布
updateManager.onCheckForUpdate(function (res) {
// 请求完新版本信息的回调
if (res.hasUpdate) {
//2. 小程序有新版本,则静默下载新版本,做好更新准备
updateManager.onUpdateReady(function () {
wx.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success: function (res) {
if (res.confirm) {
//3. 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate()
} else if (res.cancel) {
//如果需要强制更新,则给出二次弹窗,如果不需要,则这里的代码都可以删掉了
wx.showModal({
title: '温馨提示~',
content: '本次更新可能会导致旧版本无法正常访问,请使用新版本',
success: function (res) {
self.autoUpdate()
//第二次提示后,强制更新
// if (res.confirm) {
// // 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
// updateManager.applyUpdate()
// } else if (res.cancel) {
// //重新回到版本更新提示
// self.autoUpdate()
// }
}
})
}
}
})
})
updateManager.onUpdateFailed(function () {
// 新的版本下载失败
wx.showModal({
title: '已经有新版本了哟~',
content: '新版本已经上线啦~,请您删除当前小程序,重新搜索打开哟~',
})
})
}
})
} else {
// 如果希望用户在最新版本的客户端上体验您的小程序,可以这样子提示
wx.showModal({
title: '提示',
content: '当前微信版本过低,无法使用该功能,请升级到最新微信版本后重试。'
})
}
}
})

View File

@ -0,0 +1,81 @@
{
"pages": [
"pages/login/login",
"pages/index/index",
"pages/updatePwd/index",
"pages/project_flowable/initTask/index",
"pages/project_flowable/myFlowDefinition/index",
"pages/project_flowable/await/index",
"pages/project_flowable/approveTask/index",
"pages/project_flowable/finished/index",
"pages/project_flowable/detailTask/index",
"pages/project_flowable/editTask/index",
"pages/project_flowable/myProcessIns/index",
"pages/project_info/list/index",
"pages/project_info/add/index",
"pages/project_info/edit/index",
"pages/project_check/list/index",
"pages/project_check/edit/index",
"pages/project_check/info/index"
],
"usingComponents": {
"van-row": "@vant/weapp/row",
"van-col": "@vant/weapp/col",
"van-popup": "@vant/weapp/popup/index",
"van-picker": "@vant/weapp/picker/index",
"van-datetime-picker": "@vant/weapp/datetime-picker/index",
"van-radio": "@vant/weapp/radio/index",
"van-radio-group": "@vant/weapp/radio-group/index",
"van-toast": "@vant/weapp/toast/index",
"ec-canvas": "ec-canvas/ec-canvas",
"van-sticky": "@vant/weapp/sticky",
"van-calendar": "@vant/weapp/calendar/index",
"van-icon": "@vant/weapp/icon/index",
"van-image": "@vant/weapp/image/index",
"pie-chart": "pages/components/pie-chart/index",
"deep-select": "pages/components/deep-select/index",
"select-btn": "pages/components/select-btn/index",
"bar-chart": "pages/components/bar-chart/index",
"bar-chart-warning": "pages/components/bar-chart-warning/index",
"pz-screen": "pages/components/pz-screen/index",
"pz-screen-training": "pages/components/pz-screen-training/index",
"pz-screen-training-index": "pages/components/pz-screen-training-index/index",
"select-date": "pages/components/select-date/index",
"voucher-select": "pages/components/voucher-select/index",
"voucher-selects": "pages/components/voucher-selects/index",
"voucher-selected": "pages/components/voucher-selected/index",
"voucher-date": "pages/components/voucher-date/index",
"voucher-datetime": "pages/components/voucher-datetime/index",
"file-uploader": "pages/components/file-uploader/index",
"file-uploader-all":"pages/components/file-uploader-all/index",
"project-select": "pages/components/project-select/index",
"safety-pie-chart": "./components/safety-pie-chart/index",
"safety-pie-charts": "./components/safety-pie-charts/index",
"safety-bar-chart": "./components/safety-bar-chart/index",
"safety-bar-charts": "./components/safety-bar-charts/index",
"safety-bar-chartss": "./components/safety-bar-chartss/index",
"voucher-many-select": "pages/components/voucher-many-select/index",
"sign": "pages/components/sign/sign",
"safety-number": "./components/number/index",
"select-person": "./components/select-person/index",
"select-group-person": "./components/select-group-person/index",
"van-dropdown-menu": "@vant/weapp/dropdown-menu/index",
"van-dropdown-item": "@vant/weapp/dropdown-item/index",
"curve-echarts": "pages/components/curve-echarts/index"
},
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#191d28",
"navigationBarTextStyle": "white"
},
"style": "v2",
"sitemapLocation": "sitemap.json",
"permission": {
"scope.userLocation": {
"desc": "你的位置信息将用于小程序位置接口的效果展示"
}
},
"requiredPrivateInfos": [
"getLocation"
]
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,37 @@
import { link } from '../mixins/link';
import { VantComponent } from '../common/component';
VantComponent({
classes: [
'title-class',
'label-class',
'value-class',
'right-icon-class',
'hover-class',
],
mixins: [link],
props: {
title: null,
value: null,
icon: String,
size: String,
label: String,
center: Boolean,
isLink: Boolean,
required: Boolean,
clickable: Boolean,
titleWidth: String,
customStyle: String,
arrowDirection: String,
useLabelSlot: Boolean,
border: {
type: Boolean,
value: true,
},
},
methods: {
onClick(event) {
this.$emit('click', event.detail);
this.jumpLink();
},
},
});

View File

@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}

View File

@ -0,0 +1,45 @@
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="custom-class {{ utils.bem('cell', [size, { center, required, borderless: !border, clickable: isLink || clickable }]) }}"
hover-class="van-cell--hover hover-class"
hover-stay-time="70"
style="{{ customStyle }}"
bind:tap="onClick"
>
<van-icon
wx:if="{{ icon }}"
name="{{ icon }}"
class="van-cell__left-icon-wrap"
custom-class="van-cell__left-icon"
/>
<slot wx:else name="icon" />
<view
style="{{ titleWidth ? 'max-width:' + titleWidth + ';min-width:' + titleWidth : '' }}"
class="van-cell__title title-class"
>
<block wx:if="{{ title }}">{{ title }}</block>
<slot wx:else name="title" />
<view wx:if="{{ label || useLabelSlot }}" class="van-cell__label label-class">
<slot wx:if="{{ useLabelSlot }}" name="label" />
<block wx:elif="{{ label }}">{{ label }}</block>
</view>
</view>
<view class="van-cell__value value-class">
<block wx:if="{{ value || value === 0 }}">{{ value }}</block>
<slot wx:else />
</view>
<van-icon
wx:if="{{ isLink }}"
name="{{ arrowDirection ? 'arrow' + '-' + arrowDirection : 'arrow' }}"
class="van-cell__right-icon-wrap right-icon-class"
custom-class="van-cell__right-icon"
/>
<slot wx:else name="right-icon" />
<slot name="extra" />
</view>

View File

@ -0,0 +1 @@
@import '../common/index.wxss';.van-cell{position:relative;display:-webkit-flex;display:flex;box-sizing:border-box;width:100%;padding:10px 16px;padding:var(--cell-vertical-padding,10px) var(--cell-horizontal-padding,16px);font-size:14px;font-size:var(--cell-font-size,14px);line-height:24px;line-height:var(--cell-line-height,24px);color:#323233;color:var(--cell-text-color,#323233);background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:auto;right:0;bottom:0;left:16px;border-bottom:1px solid #ebedf0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.van-cell--borderless:after{display:none}.van-cell-group{background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell__label{margin-top:3px;margin-top:var(--cell-label-margin-top,3px);font-size:12px;font-size:var(--cell-label-font-size,12px);line-height:18px;line-height:var(--cell-label-line-height,18px);color:#969799;color:var(--cell-label-color,#969799)}.van-cell__value{overflow:hidden;text-align:right;vertical-align:middle;color:#969799;color:var(--cell-value-color,#969799)}.van-cell__title,.van-cell__value{-webkit-flex:1;flex:1}.van-cell__title:empty,.van-cell__value:empty{display:none}.van-cell__left-icon-wrap,.van-cell__right-icon-wrap{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;height:24px;height:var(--cell-line-height,24px);font-size:16px;font-size:var(--cell-icon-size,16px)}.van-cell__left-icon-wrap{margin-right:5px}.van-cell__right-icon-wrap{margin-left:5px;color:#969799;color:var(--cell-right-icon-color,#969799)}.van-cell__left-icon{vertical-align:middle}.van-cell__left-icon,.van-cell__right-icon{line-height:24px;line-height:var(--cell-line-height,24px)}.van-cell--clickable.van-cell--hover{background-color:#f2f3f5;background-color:var(--cell-active-color,#f2f3f5)}.van-cell--required{overflow:visible}.van-cell--required:before{position:absolute;content:"*";left:8px;left:var(--padding-xs,8px);font-size:14px;font-size:var(--cell-font-size,14px);color:#ee0a24;color:var(--cell-required-color,#ee0a24)}.van-cell--center{-webkit-align-items:center;align-items:center}.van-cell--large{padding-top:12px;padding-top:var(--cell-large-vertical-padding,12px);padding-bottom:12px;padding-bottom:var(--cell-large-vertical-padding,12px)}.van-cell--large .van-cell__title{font-size:16px;font-size:var(--cell-large-title-font-size,16px)}.van-cell--large .van-cell__value{font-size:16px;font-size:var(--cell-large-value-font-size,16px)}.van-cell--large .van-cell__label{font-size:14px;font-size:var(--cell-large-label-font-size,14px)}

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,92 @@
import { VantComponent } from "../common/component";
const nextTick = () => new Promise((resolve) => setTimeout(resolve, 20));
VantComponent({
classes: ["title-class", "content-class"],
relation: {
name: "collapse",
type: "ancestor",
current: "collapse-item",
},
props: {
name: null,
title: null,
value: null,
icon: String,
label: String,
disabled: Boolean,
clickable: Boolean,
border: {
type: Boolean,
value: true,
},
isLink: {
type: Boolean,
value: true,
},
},
data: {
contentHeight: 0,
expanded: false,
transition: false,
},
mounted() {
this.updateExpanded()
.then(nextTick)
.then(() => {
const data = { transition: true };
if (this.data.expanded) {
data.contentHeight = "auto";
}
this.setData(data);
});
},
methods: {
updateExpanded() {
if (!this.parent) {
return Promise.resolve();
}
const { value, accordion } = this.parent.data;
const { children = [] } = this.parent;
const { name } = this.data;
const index = children.indexOf(this);
const currentName = name == null ? index : name;
const expanded = accordion ? value === currentName : (value || []).some((name) => name === currentName);
const stack = [];
if (expanded !== this.data.expanded) {
stack.push(this.updateStyle(expanded));
}
stack.push(this.set({ index, expanded }));
return Promise.all(stack);
},
updateStyle(expanded) {
return this.getRect(".van-collapse-item__content")
.then((rect) => rect.height)
.then((height) => {
if (expanded) {
return this.set({
contentHeight: height ? `${height}px` : "auto",
});
}
return this.set({ contentHeight: `${height}px` })
.then(nextTick)
.then(() => this.set({ contentHeight: 0 }));
});
},
onClick() {
if (this.data.disabled) {
return;
}
const { name, expanded } = this.data;
const index = this.parent.children.indexOf(this);
const currentName = name == null ? index : name;
this.parent.switch(currentName, !expanded);
},
onTransitionEnd() {
if (this.data.expanded) {
this.setData({
contentHeight: "auto",
});
}
},
},
});

View File

@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"van-cell": "../cell/index"
}
}

View File

@ -0,0 +1,15 @@
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="van-collapse-item custom-class mkl-collapse {{ index !== 0 ? 'van-hairline--top' : '' }}">
<van-cell custom-class="van-cell mkl-cell {{expanded?'mkl-cell__expanded':''}}" title="{{ title }}" title-class="title-class" icon="{{ icon }}" value="{{ value }}" label="{{ label }}" is-link="{{ isLink }}" clickable="{{ clickable }}" border="{{ border && expanded }}" class="{{ utils.bem('collapse-item__title', { disabled, expanded }) }}" right-icon-class="van-cell__right-icon" hover-class="van-cell--hover" bind:click="onClick">
<slot name="title" slot="title" />
<slot name="icon" slot="icon" />
<slot name="value" />
<slot name="right-icon" slot="right-icon" />
</van-cell>
<view class="mkl-collapse-container {{ utils.bem('collapse-item__wrapper', { transition }) }}" style="height: {{ contentHeight }};" bind:transitionend="onTransitionEnd">
<!-- <view class="mkl-cell__bottom"></view> -->
<view class="van-collapse-item__content content-class">
<slot />
</view>
</view>
</view>

View File

@ -0,0 +1,60 @@
@import "../common/index.wxss";
.van-collapse-item__title .van-cell__right-icon {
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
transition: -webkit-transform 0.3s;
transition: transform 0.3s;
transition: transform 0.3s, -webkit-transform 0.3s;
}
.van-collapse-item__title--expanded .van-cell__right-icon {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
}
.van-collapse-item__title--disabled .van-cell,
.van-collapse-item__title--disabled .van-cell__right-icon {
color: #c8c9cc !important;
}
.van-collapse-item__title--disabled .van-cell--hover {
background-color: #fff !important;
}
.van-collapse-item__wrapper {
overflow: hidden;
}
.van-collapse-item__wrapper--transition {
transition: height 0.3s ease-in-out;
}
.van-collapse-item__content {
padding: 0 25rpx;
color: #969799;
font-size: 13px;
line-height: 1.5;
}
.mkl-collapse {
padding: 0 25rpx;
margin-bottom: 40rpx;
}
.mkl-cell {
background: #fff;
padding: 25rpx;
border-radius: 20rpx;
/* border-top-left-radius: 20rpx;
border-top-right-radius: 20rpx; */
box-shadow: 0px 0px 10px #ddd;
/* margin-bottom: 40rpx; */
}
.mkl-cell__expanded {
border-radius: 20rpx 20rpx 0 0;
}
.mkl-cell__bottom {
height: 40rpx;
}
.mkl-collapse-container {
box-shadow: 0px 0px 10px #ddd;
transition: height 0.2s;
border-radius: 0 0 20rpx 20rpx;
background: #f5f5f5;
}

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,47 @@
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'collapse-item',
type: 'descendant',
current: 'collapse',
},
props: {
value: {
type: null,
observer: 'updateExpanded',
},
accordion: {
type: Boolean,
observer: 'updateExpanded',
},
border: {
type: Boolean,
value: true,
},
},
methods: {
updateExpanded() {
this.children.forEach((child) => {
child.updateExpanded();
});
},
switch(name, expanded) {
const { accordion, value } = this.data;
const changeItem = name;
if (!accordion) {
name = expanded
? (value || []).concat(name)
: (value || []).filter((activeName) => activeName !== name);
} else {
name = expanded ? name : '';
}
if (expanded) {
this.$emit('open', changeItem);
} else {
this.$emit('close', changeItem);
}
this.$emit('change', name);
this.$emit('input', name);
},
},
});

View File

@ -0,0 +1,3 @@
{
"component": true
}

View File

@ -0,0 +1,3 @@
<view class="custom-class van-collapse {{ border ? 'van-hairline--top-bottom' : '' }} ">
<slot />
</view>

View File

@ -0,0 +1 @@
@import "../common/index.wxss";

View File

@ -0,0 +1,7 @@
export declare const RED = "#ee0a24";
export declare const BLUE = "#1989fa";
export declare const WHITE = "#fff";
export declare const GREEN = "#07c160";
export declare const ORANGE = "#ff976a";
export declare const GRAY = "#323233";
export declare const GRAY_DARK = "#969799";

View File

@ -0,0 +1,7 @@
export const RED = '#ee0a24';
export const BLUE = '#1989fa';
export const WHITE = '#fff';
export const GREEN = '#07c160';
export const ORANGE = '#ff976a';
export const GRAY = '#323233';
export const GRAY_DARK = '#969799';

View File

@ -0,0 +1,3 @@
import { VantComponentOptions, CombinedComponentInstance } from '../definitions/index';
declare function VantComponent<Data, Props, Methods>(vantOptions?: VantComponentOptions<Data, Props, Methods, CombinedComponentInstance<Data, Props, Methods>>): void;
export { VantComponent };

View File

@ -0,0 +1,101 @@
import { basic } from '../mixins/basic';
const relationFunctions = {
ancestor: {
linked(parent) {
this.parent = parent;
},
unlinked() {
this.parent = null;
},
},
descendant: {
linked(child) {
this.children = this.children || [];
this.children.push(child);
},
unlinked(child) {
this.children = (this.children || []).filter((it) => it !== child);
},
},
};
function mapKeys(source, target, map) {
Object.keys(map).forEach((key) => {
if (source[key]) {
target[map[key]] = source[key];
}
});
}
function makeRelation(options, vantOptions, relation) {
const { type, name, linked, unlinked, linkChanged } = relation;
const { beforeCreate, destroyed } = vantOptions;
if (type === 'descendant') {
options.created = function () {
beforeCreate && beforeCreate.bind(this)();
this.children = this.children || [];
};
options.detached = function () {
this.children = [];
destroyed && destroyed.bind(this)();
};
}
options.relations = Object.assign(options.relations || {}, {
[`../${name}/index`]: {
type,
linked(node) {
relationFunctions[type].linked.bind(this)(node);
linked && linked.bind(this)(node);
},
linkChanged(node) {
linkChanged && linkChanged.bind(this)(node);
},
unlinked(node) {
relationFunctions[type].unlinked.bind(this)(node);
unlinked && unlinked.bind(this)(node);
},
},
});
}
function VantComponent(vantOptions = {}) {
const options = {};
mapKeys(vantOptions, options, {
data: 'data',
props: 'properties',
mixins: 'behaviors',
methods: 'methods',
beforeCreate: 'created',
created: 'attached',
mounted: 'ready',
relations: 'relations',
destroyed: 'detached',
classes: 'externalClasses',
});
const { relation } = vantOptions;
if (relation) {
makeRelation(options, vantOptions, relation);
}
// add default externalClasses
options.externalClasses = options.externalClasses || [];
options.externalClasses.push('custom-class');
// add default behaviors
options.behaviors = options.behaviors || [];
options.behaviors.push(basic);
// map field to form-field behavior
if (vantOptions.field) {
options.behaviors.push('wx://form-field');
}
if (options.properties) {
Object.keys(options.properties).forEach((name) => {
if (Array.isArray(options.properties[name])) {
// miniprogram do not allow multi type
options.properties[name] = null;
}
});
}
// add default options
options.options = {
multipleSlots: true,
addGlobalClass: true,
};
Component(options);
}
export { VantComponent };

View File

@ -0,0 +1 @@
.van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3}.van-clearfix:after{display:table;clear:both;content:""}.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:-50%;right:-50%;bottom:-50%;left:-50%;border:0 solid #eee;-webkit-transform:scale(.5);transform:scale(.5)}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px}

View File

@ -0,0 +1 @@
.van-clearfix:after{display:table;clear:both;content:""}

View File

@ -0,0 +1 @@
.van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3}

View File

@ -0,0 +1 @@
.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:-50%;right:-50%;bottom:-50%;left:-50%;border:0 solid #eee;-webkit-transform:scale(.5);transform:scale(.5)}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px}

View File

@ -0,0 +1,8 @@
/// <reference types="miniprogram-api-typings" />
export declare function isDef(value: any): boolean;
export declare function isObj(x: any): boolean;
export declare function isNumber(value: any): boolean;
export declare function range(num: number, min: number, max: number): number;
export declare function nextTick(fn: Function): void;
export declare function getSystemInfoSync(): WechatMiniprogram.GetSystemInfoSyncResult;
export declare function addUnit(value?: string | number): string | undefined;

View File

@ -0,0 +1,32 @@
export function isDef(value) {
return value !== undefined && value !== null;
}
export function isObj(x) {
const type = typeof x;
return x !== null && (type === 'object' || type === 'function');
}
export function isNumber(value) {
return /^\d+(\.\d+)?$/.test(value);
}
export function range(num, min, max) {
return Math.min(Math.max(num, min), max);
}
export function nextTick(fn) {
setTimeout(() => {
fn();
}, 1000 / 30);
}
let systemInfo = null;
export function getSystemInfoSync() {
if (systemInfo == null) {
systemInfo = wx.getSystemInfoSync();
}
return systemInfo;
}
export function addUnit(value) {
if (!isDef(value)) {
return undefined;
}
value = String(value);
return isNumber(value) ? `${value}px` : value;
}

View File

@ -0,0 +1,2 @@
export declare function canIUseModel(): boolean;
export declare function canIUseFormFieldButton(): boolean;

View File

@ -0,0 +1,31 @@
import { getSystemInfoSync } from './utils';
function compareVersion(v1, v2) {
v1 = v1.split('.');
v2 = v2.split('.');
const len = Math.max(v1.length, v2.length);
while (v1.length < len) {
v1.push('0');
}
while (v2.length < len) {
v2.push('0');
}
for (let i = 0; i < len; i++) {
const num1 = parseInt(v1[i], 10);
const num2 = parseInt(v2[i], 10);
if (num1 > num2) {
return 1;
}
if (num1 < num2) {
return -1;
}
}
return 0;
}
export function canIUseModel() {
const system = getSystemInfoSync();
return compareVersion(system.SDKVersion, '2.9.3') >= 0;
}
export function canIUseFormFieldButton() {
const system = getSystemInfoSync();
return compareVersion(system.SDKVersion, '2.10.3') >= 0;
}

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,27 @@
import { VantComponent } from '../common/component';
VantComponent({
props: {
dot: Boolean,
info: null,
size: null,
color: String,
customStyle: String,
classPrefix: {
type: String,
value: 'van-icon',
},
name: {
type: String,
observer(val) {
this.setData({
isImageName: val.indexOf('/') !== -1,
});
},
},
},
methods: {
onClick() {
this.$emit('click');
},
},
});

View File

@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"van-info": "../info/index"
}
}

View File

@ -0,0 +1,20 @@
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="custom-class {{ classPrefix }} {{ isImageName ? 'van-icon--image' : classPrefix + '-' + name }}"
style="color: {{ color }};font-size: {{ utils.addUnit(size) }};{{ customStyle }}"
bind:tap="onClick"
>
<van-info
wx:if="{{ info !== null || dot }}"
dot="{{ dot }}"
info="{{ info }}"
custom-class="van-icon__info"
/>
<image
wx:if="{{ isImageName }}"
src="{{ name }}"
mode="aspectFit"
class="van-icon__image"
/>
</view>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,8 @@
import { VantComponent } from '../common/component';
VantComponent({
props: {
dot: Boolean,
info: null,
customStyle: String,
},
});

View File

@ -0,0 +1,3 @@
{
"component": true
}

View File

@ -0,0 +1,7 @@
<wxs src="../wxs/utils.wxs" module="utils" />
<view
wx:if="{{ info !== null && info !== '' || dot }}"
class="custom-class van-info {{ utils.bem('info', { dot }) }}"
style="{{ customStyle }}"
>{{ dot ? '' : info }}</view>

View File

@ -0,0 +1 @@
@import '../common/index.wxss';.van-info{position:absolute;top:0;right:0;box-sizing:border-box;white-space:nowrap;text-align:center;-webkit-transform:translate(50%,-50%);transform:translate(50%,-50%);-webkit-transform-origin:100%;transform-origin:100%;min-width:16px;min-width:var(--info-size,16px);padding:0 3px;padding:var(--info-padding,0 3px);color:#fff;color:var(--info-color,#fff);font-weight:500;font-weight:var(--info-font-weight,500);font-size:12px;font-size:var(--info-font-size,12px);font-family:Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif;font-family:var(--info-font-family,Avenir-Heavy,PingFang SC,Helvetica Neue,Arial,sans-serif);line-height:14px;line-height:calc(var(--info-size, 16px) - var(--info-border-width, 1px)*2);background-color:#ee0a24;background-color:var(--info-background-color,#ee0a24);border:1px solid #fff;border:var(--info-border-width,1px) solid var(--white,#fff);border-radius:16px;border-radius:var(--info-size,16px)}.van-info--dot{min-width:0;border-radius:100%;width:8px;width:var(--info-dot-size,8px);height:8px;height:var(--info-dot-size,8px);background-color:#ee0a24;background-color:var(--info-dot-color,#ee0a24)}

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,16 @@
import { VantComponent } from '../common/component';
VantComponent({
props: {
color: String,
vertical: Boolean,
type: {
type: String,
value: 'circular',
},
size: String,
textSize: String,
},
data: {
array12: Array.from({ length: 12 }),
},
});

View File

@ -0,0 +1,3 @@
{
"component": true
}

View File

@ -0,0 +1,18 @@
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="custom-class van-loading {{ vertical ? 'van-loading--vertical' : '' }}">
<view
class="van-loading__spinner van-loading__spinner--{{ type }}"
style="color: {{ color }}; width: {{ utils.addUnit(size) }}; height: {{ utils.addUnit(size) }}"
>
<view
wx:if="{{ type === 'spinner' }}"
wx:for="{{ array12 }}"
wx:key="index"
class="van-loading__dot"
/>
</view>
<view class="van-loading__text" style="font-size: {{ utils.addUnit(textSize) }};">
<slot />
</view>
</view>

View File

@ -0,0 +1 @@
@import '../common/index.wxss';:host{font-size:0;line-height:1}.van-loading{display:-webkit-inline-flex;display:inline-flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;color:#c8c9cc;color:var(--loading-spinner-color,#c8c9cc)}.van-loading__spinner{position:relative;box-sizing:border-box;width:30px;width:var(--loading-spinner-size,30px);max-width:100%;max-height:100%;height:30px;height:var(--loading-spinner-size,30px);-webkit-animation:van-rotate .8s linear infinite;animation:van-rotate .8s linear infinite;-webkit-animation:van-rotate var(--loading-spinner-animation-duration,.8s) linear infinite;animation:van-rotate var(--loading-spinner-animation-duration,.8s) linear infinite}.van-loading__spinner--spinner{-webkit-animation-timing-function:steps(12);animation-timing-function:steps(12)}.van-loading__spinner--circular{border:1px solid transparent;border-top-color:initial;border-radius:100%}.van-loading__text{margin-left:8px;margin-left:var(--padding-xs,8px);color:#969799;color:var(--loading-text-color,#969799);font-size:14px;font-size:var(--loading-text-font-size,14px);line-height:20px;line-height:var(--loading-text-line-height,20px)}.van-loading__text:empty{display:none}.van-loading--vertical{-webkit-flex-direction:column;flex-direction:column}.van-loading--vertical .van-loading__text{margin:8px 0 0;margin:var(--padding-xs,8px) 0 0}.van-loading__dot{position:absolute;top:0;left:0;width:100%;height:100%}.van-loading__dot:before{display:block;width:2px;height:25%;margin:0 auto;background-color:currentColor;border-radius:40%;content:" "}.van-loading__dot:first-of-type{-webkit-transform:rotate(30deg);transform:rotate(30deg);opacity:1}.van-loading__dot:nth-of-type(2){-webkit-transform:rotate(60deg);transform:rotate(60deg);opacity:.9375}.van-loading__dot:nth-of-type(3){-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:.875}.van-loading__dot:nth-of-type(4){-webkit-transform:rotate(120deg);transform:rotate(120deg);opacity:.8125}.van-loading__dot:nth-of-type(5){-webkit-transform:rotate(150deg);transform:rotate(150deg);opacity:.75}.van-loading__dot:nth-of-type(6){-webkit-transform:rotate(180deg);transform:rotate(180deg);opacity:.6875}.van-loading__dot:nth-of-type(7){-webkit-transform:rotate(210deg);transform:rotate(210deg);opacity:.625}.van-loading__dot:nth-of-type(8){-webkit-transform:rotate(240deg);transform:rotate(240deg);opacity:.5625}.van-loading__dot:nth-of-type(9){-webkit-transform:rotate(270deg);transform:rotate(270deg);opacity:.5}.van-loading__dot:nth-of-type(10){-webkit-transform:rotate(300deg);transform:rotate(300deg);opacity:.4375}.van-loading__dot:nth-of-type(11){-webkit-transform:rotate(330deg);transform:rotate(330deg);opacity:.375}.van-loading__dot:nth-of-type(12){-webkit-transform:rotate(1turn);transform:rotate(1turn);opacity:.3125}@-webkit-keyframes van-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}@keyframes van-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}

View File

@ -0,0 +1 @@
export declare const basic: string;

View File

@ -0,0 +1,27 @@
export const basic = Behavior({
methods: {
$emit(...args) {
this.triggerEvent(...args);
},
set(data, callback) {
this.setData(data, callback);
return new Promise((resolve) => wx.nextTick(resolve));
},
getRect(selector, all) {
return new Promise((resolve) => {
wx.createSelectorQuery()
.in(this)
[all ? 'selectAll' : 'select'](selector)
.boundingClientRect((rect) => {
if (all && Array.isArray(rect) && rect.length) {
resolve(rect);
}
if (!all && rect) {
resolve(rect);
}
})
.exec();
});
},
},
});

View File

@ -0,0 +1 @@
export declare const button: string;

View File

@ -0,0 +1,15 @@
export const button = Behavior({
externalClasses: ['hover-class'],
properties: {
id: String,
lang: String,
businessId: Number,
sessionFrom: String,
sendMessageTitle: String,
sendMessagePath: String,
sendMessageImg: String,
showMessageCard: Boolean,
appParameter: String,
ariaLabel: String,
},
});

View File

@ -0,0 +1 @@
export declare const link: string;

View File

@ -0,0 +1,17 @@
export const link = Behavior({
properties: {
url: String,
linkType: {
type: String,
value: 'navigateTo',
},
},
methods: {
jumpLink(urlKey = 'url') {
const url = this.data[urlKey];
if (url) {
wx[this.data.linkType]({ url });
}
},
},
});

View File

@ -0,0 +1 @@
export declare const openType: string;

View File

@ -0,0 +1,25 @@
export const openType = Behavior({
properties: {
openType: String,
},
methods: {
bindGetUserInfo(event) {
this.$emit('getuserinfo', event.detail);
},
bindContact(event) {
this.$emit('contact', event.detail);
},
bindGetPhoneNumber(event) {
this.$emit('getphonenumber', event.detail);
},
bindError(event) {
this.$emit('error', event.detail);
},
bindLaunchApp(event) {
this.$emit('launchapp', event.detail);
},
bindOpenSetting(event) {
this.$emit('opensetting', event.detail);
},
},
});

View File

@ -0,0 +1,5 @@
/// <reference types="miniprogram-api-typings" />
declare type IPageScrollOption = WechatMiniprogram.Page.IPageScrollOption;
declare type Scroller = (event: IPageScrollOption) => void;
export declare const pageScrollMixin: (scroller: Scroller) => string;
export {};

View File

@ -0,0 +1,33 @@
function getCurrentPage() {
const pages = getCurrentPages();
return pages[pages.length - 1] || {};
}
function onPageScroll(event) {
const { vanPageScroller = [] } = getCurrentPage();
vanPageScroller.forEach((scroller) => {
if (typeof scroller === 'function') {
scroller(event);
}
});
}
export const pageScrollMixin = (scroller) =>
Behavior({
attached() {
const page = getCurrentPage();
if (Array.isArray(page.vanPageScroller)) {
page.vanPageScroller.push(scroller.bind(this));
} else {
page.vanPageScroller =
typeof page.onPageScroll === 'function'
? [page.onPageScroll.bind(page), scroller.bind(this)]
: [scroller.bind(this)];
}
page.onPageScroll = onPageScroll;
},
detached() {
const page = getCurrentPage();
page.vanPageScroller = (page.vanPageScroller || []).filter(
(item) => item !== scroller
);
},
});

View File

@ -0,0 +1 @@
export declare const touch: string;

View File

@ -0,0 +1,36 @@
const MIN_DISTANCE = 10;
function getDirection(x, y) {
if (x > y && x > MIN_DISTANCE) {
return 'horizontal';
}
if (y > x && y > MIN_DISTANCE) {
return 'vertical';
}
return '';
}
export const touch = Behavior({
methods: {
resetTouchStatus() {
this.direction = '';
this.deltaX = 0;
this.deltaY = 0;
this.offsetX = 0;
this.offsetY = 0;
},
touchStart(event) {
this.resetTouchStatus();
const touch = event.touches[0];
this.startX = touch.clientX;
this.startY = touch.clientY;
},
touchMove(event) {
const touch = event.touches[0];
this.deltaX = touch.clientX - this.startX;
this.deltaY = touch.clientY - this.startY;
this.offsetX = Math.abs(this.deltaX);
this.offsetY = Math.abs(this.deltaY);
this.direction =
this.direction || getDirection(this.offsetX, this.offsetY);
},
},
});

View File

@ -0,0 +1 @@
export declare const transition: (showDefaultValue: boolean) => string;

View File

@ -0,0 +1,118 @@
import { isObj } from '../common/utils';
const getClassNames = (name) => ({
enter: `van-${name}-enter van-${name}-enter-active enter-class enter-active-class`,
'enter-to': `van-${name}-enter-to van-${name}-enter-active enter-to-class enter-active-class`,
leave: `van-${name}-leave van-${name}-leave-active leave-class leave-active-class`,
'leave-to': `van-${name}-leave-to van-${name}-leave-active leave-to-class leave-active-class`,
});
const nextTick = () => new Promise((resolve) => setTimeout(resolve, 1000 / 30));
export const transition = function (showDefaultValue) {
return Behavior({
properties: {
customStyle: String,
// @ts-ignore
show: {
type: Boolean,
value: showDefaultValue,
observer: 'observeShow',
},
// @ts-ignore
duration: {
type: null,
value: 300,
observer: 'observeDuration',
},
name: {
type: String,
value: 'fade',
},
},
data: {
type: '',
inited: false,
display: false,
},
methods: {
observeShow(value, old) {
if (value === old) {
return;
}
value ? this.enter() : this.leave();
},
enter() {
const { duration, name } = this.data;
const classNames = getClassNames(name);
const currentDuration = isObj(duration) ? duration.enter : duration;
this.status = 'enter';
this.$emit('before-enter');
Promise.resolve()
.then(nextTick)
.then(() => {
this.checkStatus('enter');
this.$emit('enter');
this.setData({
inited: true,
display: true,
classes: classNames.enter,
currentDuration,
});
})
.then(nextTick)
.then(() => {
this.checkStatus('enter');
this.transitionEnded = false;
this.setData({
classes: classNames['enter-to'],
});
})
.catch(() => {});
},
leave() {
if (!this.data.display) {
return;
}
const { duration, name } = this.data;
const classNames = getClassNames(name);
const currentDuration = isObj(duration) ? duration.leave : duration;
this.status = 'leave';
this.$emit('before-leave');
Promise.resolve()
.then(nextTick)
.then(() => {
this.checkStatus('leave');
this.$emit('leave');
this.setData({
classes: classNames.leave,
currentDuration,
});
})
.then(nextTick)
.then(() => {
this.checkStatus('leave');
this.transitionEnded = false;
setTimeout(() => this.onTransitionEnd(), currentDuration);
this.setData({
classes: classNames['leave-to'],
});
})
.catch(() => {});
},
checkStatus(status) {
if (status !== this.status) {
throw new Error(`incongruent status: ${status}`);
}
},
onTransitionEnd() {
if (this.transitionEnded) {
return;
}
this.transitionEnded = true;
this.$emit(`after-${this.status}`);
const { show, display } = this.data;
if (!show && display) {
this.setData({ display: false });
}
},
},
});
};

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,145 @@
import { VantComponent } from "../common/component";
import { pickerProps } from "../picker/shared";
const COLUMNSPLACEHOLDERCODE = "000000";
VantComponent({
classes: ["active-class", "toolbar-class", "column-class"],
props: Object.assign(Object.assign({}, pickerProps), {
value: {
type: Array,
observer(value) {
this.value = value;
this.getSelect();
this.setValues();
},
},
columns: {
type: Array,
value: [],
observer(value) {
this.getSelect();
this.setValues();
},
},
}),
data: {
displayColumns: [],
typeToColumnsPlaceholder: {},
},
mounted() {
// setTimeout(() => {
// this.setValues();
// }, 0);
},
methods: {
getPicker() {
if (this.picker == null) {
this.picker = this.selectComponent(".van-multi-select__picker");
}
return this.picker;
},
onCancel(event) {
this.emit("cancel", event.detail);
},
onConfirm(event) {
const detail = event.detail;
const values = this.parseOutputValues(detail.value);
this.emit("confirm", {text:values.map((x) => x.text),value: values.map((x) => x.key), index:detail.index });
},
emit(type, detail) {
detail.values = detail.value;
delete detail.value;
this.$emit(type, detail);
},
// parse output columns data
parseOutputValues(values) {
return values.map((value, index) => {
return {
key: value.key,
text: value.text,
};
});
},
onChange(event) {
const { index, picker, value } = event.detail;
this.select = { value, index };
this.setValues();
const values = this.parseOutputValues(value);
this.$emit("change", {
picker,
values: values,
value: values.map((x) => x.key),
text: values.map((x) => x.text),
index,
});
},
//初始化赋值核心方法
getSelect(columns = this.data.columns, index = 0, displayColumns = []) {
if (this.value && this.value.length > 0) {
const key = this.value[index];
if (columns && columns.length > 0) {
let selectColumn = columns.find((x) => key == x.key);
if (selectColumn) {
displayColumns.push(selectColumn);
if (selectColumn.childs && selectColumn.childs.length > 0) {
this.getSelect(selectColumn.childs, index + 1, displayColumns);
}
}
}
this.select = {
index: this.value.length - 1,
value: displayColumns,
};
}
},
getColumns(columns = this.data.columns, index = 0, displayColumns = [], select) {
if (columns && columns.length > 0) {
let defaultIndex = 0;
if (select) {
if (index <= select.index) {
const val = select.value[index];
if(val&&val.key){
columns.forEach((x, i) => {
if (x.key == val.key) {
defaultIndex = i;
}
});
}
}
}
displayColumns.push({
values: columns,
defaultIndex: defaultIndex,
});
let firstColumn = columns[defaultIndex];
if (firstColumn.childs && firstColumn.childs.length > 0) {
index++;
this.getColumns(firstColumn.childs, index, displayColumns, select);
}
}
return displayColumns;
},
setValues() {
// const picker = this.getPicker();
// if (!picker) {
// return;
// }
let { select } = this;
const stack = this.getColumns(undefined, undefined, undefined, select);
this.setData({
displayColumns: stack,
});
},
getValues() {
const picker = this.getPicker();
return picker ? picker.getValues().filter((value) => !!value) : [];
},
reset(value) {
this.value = value || [];
return this.setValues();
},
},
});

View File

@ -0,0 +1,6 @@
{
"component": true,
"usingComponents": {
"van-picker": "../picker/index"
}
}

View File

@ -0,0 +1 @@
<van-picker class="van-multi-select__picker" active-class="active-class" toolbar-class="toolbar-class" column-class="column-class" show-toolbar value-key="text" title="{{ title }}" loading="{{ loading }}" columns="{{ displayColumns }}" item-height="{{ itemHeight }}" visible-item-count="{{ visibleItemCount }}" cancel-button-text="{{ cancelButtonText }}" confirm-button-text="{{ confirmButtonText }}" bind:change="onChange" bind:confirm="onConfirm" bind:cancel="onCancel" />

View File

@ -0,0 +1 @@
@import '../common/index.wxss';

View File

@ -0,0 +1 @@
export {};

View File

@ -0,0 +1,123 @@
import { VantComponent } from '../common/component';
import { isObj, range } from '../common/utils';
const DEFAULT_DURATION = 200;
VantComponent({
classes: ['active-class'],
props: {
valueKey: String,
className: String,
itemHeight: Number,
visibleItemCount: Number,
initialOptions: {
type: Array,
value: [],
},
defaultIndex: {
type: Number,
value: 0,
observer(value) {
this.setIndex(value);
},
},
},
data: {
startY: 0,
offset: 0,
duration: 0,
startOffset: 0,
options: [],
currentIndex: 0,
},
created() {
const { defaultIndex, initialOptions } = this.data;
this.set({
currentIndex: defaultIndex,
options: initialOptions,
}).then(() => {
this.setIndex(defaultIndex);
});
},
methods: {
getCount() {
return this.data.options.length;
},
onTouchStart(event) {
this.setData({
startY: event.touches[0].clientY,
startOffset: this.data.offset,
duration: 0,
});
},
onTouchMove(event) {
const { data } = this;
const deltaY = event.touches[0].clientY - data.startY;
this.setData({
offset: range(
data.startOffset + deltaY,
-(this.getCount() * data.itemHeight),
data.itemHeight
),
});
},
onTouchEnd() {
const { data } = this;
if (data.offset !== data.startOffset) {
this.setData({ duration: DEFAULT_DURATION });
const index = range(
Math.round(-data.offset / data.itemHeight),
0,
this.getCount() - 1
);
this.setIndex(index, true);
}
},
onClickItem(event) {
const { index } = event.currentTarget.dataset;
this.setIndex(index, true);
},
adjustIndex(index) {
const { data } = this;
const count = this.getCount();
index = range(index, 0, count);
for (let i = index; i < count; i++) {
if (!this.isDisabled(data.options[i])) return i;
}
for (let i = index - 1; i >= 0; i--) {
if (!this.isDisabled(data.options[i])) return i;
}
},
isDisabled(option) {
return isObj(option) && option.disabled;
},
getOptionText(option) {
const { data } = this;
return isObj(option) && data.valueKey in option
? option[data.valueKey]
: option;
},
setIndex(index, userAction) {
const { data } = this;
index = this.adjustIndex(index) || 0;
const offset = -index * data.itemHeight;
if (index !== data.currentIndex) {
return this.set({ offset, currentIndex: index }).then(() => {
userAction && this.$emit('change', index);
});
}
return this.set({ offset });
},
setValue(value) {
const { options } = this.data;
for (let i = 0; i < options.length; i++) {
if (this.getOptionText(options[i]) === value) {
return this.setIndex(i);
}
}
return Promise.resolve();
},
getValue() {
const { data } = this;
return data.options[data.currentIndex];
},
},
});

View File

@ -0,0 +1,3 @@
{
"component": true
}

View File

@ -0,0 +1,22 @@
<wxs src="./index.wxs" module="getOptionText" />
<view
class="van-picker-column custom-class"
style="height: {{ itemHeight * visibleItemCount }}px"
bind:touchstart="onTouchStart"
catch:touchmove="onTouchMove"
bind:touchend="onTouchEnd"
bind:touchcancel="onTouchEnd"
>
<view style="transition: transform {{ duration }}ms; line-height: {{ itemHeight }}px; transform: translate3d(0, {{ offset + (itemHeight * (visibleItemCount - 1)) / 2 }}px, 0)">
<view
wx:for="{{ options }}"
wx:for-item="option"
wx:key="index"
data-index="{{ index }}"
style="height: {{ itemHeight }}px"
class="van-ellipsis van-picker-column__item {{ option && option.disabled ? 'van-picker-column__item--disabled' : '' }} {{ index === currentIndex ? 'van-picker-column__item--selected active-class' : '' }}"
bindtap="onClickItem"
>{{ getOptionText(option, valueKey) }}</view>
</view>
</view>

View File

@ -0,0 +1,8 @@
function isObj(x) {
var type = typeof x;
return x !== null && (type === 'object' || type === 'function');
}
module.exports = function (option, valueKey) {
return isObj(option) && option[valueKey] != null ? option[valueKey] : option;
}

View File

@ -0,0 +1 @@
@import '../common/index.wxss';.van-picker-column{overflow:hidden;text-align:center;color:#000;color:var(--picker-option-text-color,#000);font-size:16px;font-size:var(--picker-option-font-size,16px)}.van-picker-column__item{padding:0 5px}.van-picker-column__item--selected{font-weight:500;font-weight:var(--font-weight-bold,500);color:#323233;color:var(--picker-option-selected-text-color,#323233)}.van-picker-column__item--disabled{opacity:.3;opacity:var(--picker-option-disabled-opacity,.3)}

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