云息.NET数采项目初始化2

master
ccongli 1 year ago
parent 3a876258b4
commit b8b9d7b86a

1
.gitattributes vendored

@ -0,0 +1 @@
*.js linguist-language=C#

72
.gitignore vendored

@ -0,0 +1,72 @@
/Vol.Vue/node_modules
/Vue.Net/VOL.Web/bin
/Vue.Net/VOL.WebApi/bin
/Vue.Net/VOL.WebApi/Download/ExcelExport
/Vue.Net/VOL.WebApi/Download/Logger
/Vue.Net/VOL.WebApi/Download/SqlLog
/Vue.Net/VOL.WebApi/obj
/Vue.Net/.vs
/Vue.Net/VOL.Entity/bin
/Vue.Net/VOL.Entity/obj
/Vue.Net/VOL.AppManager/bin
/Vue.Net/VOL.AppManager/obj
/Vue.Net/VOL.Builder/obj
/Vue.Net/VOL.Builder/bin
/Vue.Net/VOL.Core/obj
/Vue.Net/VOL.Core/bin
/Vue.Net/VOL.Order/obj
/Vue.Net/VOL.Order/bin
/Vue.Net/VOL.System/obj
/Vue.Net/VOL.System/bin
/Vue.Net/VOL.Web/obj
/Vue.Net/VOL.WebApi/Download/*
/Vol.Vue/dist
/Vue.Net/VOL.WebApi/wwwroot/Upload/
/Vue.Net/VOL.Web
/开发版dev/Vue.NetCore/Vol.Vue/node_modules
/开发版dev/Vue.NetCore/Vue.Net/VOL.System/bin
/开发版dev/Vue.NetCore/Vue.Net/VOL.WebApi/bin
/开发版dev/Vue.NetCore/Vue.Net/VOL.Entity/bin
/开发版dev/Vue.NetCore/Vue.Net/VOL.Builder/bin
/开发版dev/Vue.NetCore/Vue.Net/VOL.Core/obj
/开发版dev/Vue.NetCore/Vue.Net/VOL.Builder/obj
/开发版dev/Vue.NetCore/Vue.Net/VOL.Entity/obj
/开发版dev/Vue.NetCore/Vue.Net/VOL.System/obj
/开发版dev/Vue.NetCore/Vue.Net/VOL.WebApi/obj
/开发版dev/Vue.NetCore/Vue.Net/VOL.Core/bin
/_ReSharper.Caches/*
/.vs/*
/开发版dev/Vue.NetCore/Vue.Net/_ReSharper.Caches/*
/开发版dev/Vue.NetCore/Vue.Net/.vs/*
/Vue.Net/_ReSharper.Caches/ReSharperPlatformVs16192_607b9a31.VOL.00
/开发版dev/Vue.NetCore/Vue.Net/VOL.WebApi/Download/Logger/Queue/WriteError
/开发版dev/Vue.NetCore/Vue.Net/.vs
/.Net6版本/.vs
/.Net6版本/VOL.AppManager/obj
/.Net6版本/VOL.AppManager/bin
/.Net6版本/VOL.Builder/obj
/.Net6版本/VOL.Builder/bin
/.Net6版本/VOL.Core/obj
/.Net6版本/VOL.Core/bin
/.Net6版本/VOL.Entity/obj
/.Net6版本/VOL.Entity/bin
/.Net6版本/VOL.Order/obj
/.Net6版本/VOL.Order/bin
/.Net6版本/VOL.System/obj
/.Net6版本/VOL.System/bin
/.Net6版本/VOL.WebApi/obj
/.Net6版本/VOL.WebApi/bin
/.Net6版本/VOL.WebApi/Properties/PublishProfiles
/开发版dev/Net6开发版/VOL.WebApi/obj
/开发版dev/Net6开发版/VOL.WebApi/bin
/开发版dev/Net6开发版/VOL.System/obj
/开发版dev/Net6开发版/VOL.System/bin
/开发版dev/Net6开发版/VOL.Entity/obj
/开发版dev/Net6开发版/VOL.Entity/bin
/开发版dev/Net6开发版/VOL.Core/obj
/开发版dev/Net6开发版/VOL.Core/bin
/开发版dev/Net6开发版/VOL.Builder/obj
/开发版dev/Net6开发版/VOL.Builder/bin
/开发版dev/Net6开发版/.vs
/Vue.Net/VOL.WebApi/Properties
/.Net6版本/VOL.WebApi/Properties

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 283591387@qq.com jxx
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.

@ -0,0 +1,138 @@
## Vue + .NetCore前后端分离不一样的快速发开框架(提供Vue2/Vue3版本)
## 框架核心
- 快速开发(基础功能全部由代码生成器生成)
- 支持前端、后台自定义业务代码扩展,后台提供了大量常用扩展与通用类
- 前端、后台提供了近300个扩展方法与属性,开发人员可在此功能上编写扩展自定义业务代码
- 代码生成(代码生成器可直接生成主/从表前后端业务代码,有30多种属性可在线配置生成的代码)
- 前端table自动转换key/value
- 前端表单select/checkbox自动绑定数据源,不需要写任何代码
- 支持(主从表)一对一前后端代码全自动生成、并支持数据源自动绑定与业务代码扩展,不需要写任何代码
- 支持一对多从表自定义扩展(不限从表类型与从表数量) , 一对多从表使用扩展可轻松实现
- 如果能上手框架可以体会到不用996,更不用掉头发的感觉^_^
## 框架适用范围
- 前后端分离项目
- 编写各种后台restful api接口。后台基础代码由代码生成器完成,在生成的代码上继续编写业务即可
- 前端表单开发(直接上手看demo即可)
- 配合app做H5或全h5开发
- 移动端开发、app、微信小程序(uniapp),见下面介绍
- 在现有的代码生成器功能上,继续定制开发代码生成器功能,解决重复性工作
## 框架开发依赖环境
- 后台VS2019、vs2022 、.NetCore3.1 、.Net6、EFCore3.1/6.0、JWT、Dapper、SignalR、Quartz.Net、Autofac、SqlServer/MySql/PGSql/Oracle、Redis
- 前端VsCode、Vue2/vue3需要安装nodejs)、vuex、axios、promise、element ui、element plus
## 链接
## [vol框架视频](https://www.cctalk.com/m/group/90268531)
## [vol框架企业版](http://pro.volcore.xyz/)
## [NET视频教程(微软MVP-ACE录制)](https://space.bilibili.com/525836469)
## [元讯趣编程交流社区](https://www.qubcedu.com/)
## 项目启动与上手
- http://v2.volcore.xyz/document/guide
## vue2版本
- http://v2.volcore.xyz
## vue3版本
- http://www.volcore.xyz
## 演示地址2
- http://120.48.115.252:9990/
## App/H5开发
- http://v2.volcore.xyz/app/guide
## 2023.05.13增加审批流程分支、条件功能
![Home](/imgs/flow.png)
![Home](/imgs/flow2.png)
![Home](/imgs/flow3.png)
## 框架移动端uniapp已发布,同样全自动生成代码,扫描小程序二维码即可查看
![Home](/imgs/qrcode.png)
![Home](/imgs/app-01.png)
![Home](/imgs/app-02.png)
![Home](/imgs/m001.png)
![Home](/imgs/m002.png)
## 框架已支持Vue3版本
![Home](/imgs/v3.png)
## 框架已增加低代码设计器
![Home](/imgs/fd01.png)
![Home](/imgs/fd02.png)
## 框架2.0已更新(部分新增功能截图)
增加切换皮肤功能
![Home](/imgs/h.png)
![Home](/imgs/home_them.png)
增加可复用的后台请求参数校验
![Home](/imgs/validator.png)
增加树形菜单与代码生成页面使用
![Home](/imgs/x7tree.png)
增加文本编辑器直接发布静态页面功能
![Home](/imgs/editor.png)
一对一多从表显示(只需要少量代码就可完成成,其他都由代码生成器生成)
![Home](/imgs/m1.png)
表合并显示 (只需要几行代码完成代码生成器生成的页面实现扩展)
![Home](/imgs/span.png)
从图上传图片 (只需要几行代码完成代码生成器生成的页面实现扩展)
![Home](/imgs/p1.png)
一对多从表(不限从表数量)扩展
![Home](/imgs/multi.png)
图表
![Home](/imgs/charts.png)
## 1、只读基础表单
整个只读的基础表单的所有前后端代码,全部由代码生成器生成,代码生成器中几乎不需要配置,并支持并后端业务代码扩展,直接生成代码后,配置菜单权限即可
![Home](/imgs/table1.png)
## 2、自动绑定下拉框数据表单
整个自动绑定下拉框数据表单的所有前后端代码,全部由代码生成器生成,并支持并后端业务代码扩展,在代码生成器中只需要指定数据源编号,页面加载时会根据编号自动加载数据源并绑定
![Home](/imgs/table2.png)
## 3、启用图片支持、审核表单
整个启用图片支持、审核表单的所有前后端代码,全部由代码生成器生成,并支持并后端业务代码扩展,审核功能需要在菜单配置权限、代码生成器中勾选启用图片支持
![Home](/imgs/table3.png)
## 4、高级查询
整个表单的所有前后端代码,全部由代码生成器生成,并支持并后端业务代码扩展,查询字段、类型(下拉框、日期、TextArea等)、所在行与列都由代码生成器完成,不需要写任何代码
![Home](/imgs/tablesearch4.png)
## 5、主从表新建、编辑
主从表新建、编辑所有前后端代码,全部由代码生成器生成,并支持并后端业务代码扩展,新建、编辑从表配置、字段、类型(下拉框、日期、TextArea等)、所在行与列、字段是否只读、标签显示的长度等都由代码生成器完成,不需要写任何代码
![Home](/imgs/editTbale2.png)
## 6、excel导入
excel导入整个页面都由代码生成器生成导入的字段、字段是否必填下载模板也由代码生成器上配置(自己根据实际需要决定是否采用此方法),导入时会验证是否为空与数据的合法性,逻辑校验自己实现扩展方法即可
![Home](/imgs/importTable1.png)
## 7、H5开发
![Home](/imgs/h5.jpg)
## 8、权限分配
目前只实现了对用户的角色的Action进行权限分配
![Home](/imgs/auth.png)
## 9、代码生成器
代码生成器提供了20多种可配置的属性可灵活配置显示、查询、编辑、导入、导出、主从关系等功能<a href="http://132.232.2.109/document/coder">点击看代码生成器文档</a>
![Home](/imgs/coder.png)
其他功能。。。。。
## 框架预览
- 框架内置了大量的通用组件可直接使用,并内置了基于本框架定制开发的代码生成器,尽量避免重复性代码编写。
- 框架不仅仅是快速开发,更多的是倾向于业务代码扩展的编写与代码规范。
- 如果有什么问题或建议提issue或加QQ283591387
- QQ2群913189178
- QQ3群743852316
-
- vue3地址http://www.volcore.xyz
- vue2地址http://v2.volcore.xyz
- 帐号admin666密码123456本地超级管理员帐号admin密码123456)
- github地址https://github.com/cq-panda/vue.netcore
- gitee码云https://gitee.com/x_discoverer/Vue.NetCore
- 框架文档http://v2.volcore.xyz/document/guide
- 框架更新日志http://v2.volcore.xyz/document/log

@ -0,0 +1,7 @@
1、mysql日志批量写入失败提示:The used command is not allowed with this MySQL version
解决办法:在数据库中执行:set global local_infile = 'ON';
2、日志批量写入数据时出错:To use MySq1Bu1kLoader. Loca1=true, set AllowLoadLocalInfile =true in the connection string.
解决办法在后台项目appsettings.json中找到mysql数据库链接配置中添加AllowLoadLocalInfile =true

File diff suppressed because one or more lines are too long

@ -0,0 +1,14 @@
现在框架只支持pgsql数据库以下字段类型
uuid , int2 , int4 , int8 , char , varchar , text , xml ,
date , decimal , money , float4 , float8
如果还需要其他字段类型请修改获取pgsql表结构信息
[pic][pic]
框架默认PGSQL所有的表名都是大写开头如果数据库表名是小写请修改以下配置
[pic]
[pic]

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 460 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 173 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 229 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

@ -0,0 +1 @@
/unpackage

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

@ -0,0 +1,95 @@
<script>
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style>
/*每个页面公共css */
.u-tabbar>.u-tabbar__content {
padding-bottom: 10rpx;
border-top: 1px solid #eee;
}
/* .u-popup .u-fade-enter-active{
z-index: 999999 !important;
} */
uni-toast {
z-index: 99999999 !important;
}
uni-page-body,
html,
body {
height: 100%;
}
uni-page-body>uni-view:first-child {
height: 100%;
}
.sort-form-popup .u-fade-enter-to {
z-index: 9999999 !important;
}
.u-button {
border-color: unset !important;
border-width: 0 !important;
}
/* .grid-u-model>.u-transition {
z-index: 99999999 !important;
} */
.grid-u-model .u-transition {
z-index: 99999999 !important;
}
// #ifdef MP-WEIXIN
page {
height: 100%;
}
page>view:first-child {
height: 100%;
}
// #endif
.vol-action-sheet-select-container {
min-height: 200rpx;
display: flex;
flex-direction: column;
}
.vol-action-sheet-select-container .vol-action-sheet-select-title {
padding: 24rpx;
text-align: center;
position: relative;
border-bottom: 1px solid rgb(233 233 233);
}
.vol-action-sheet-select-container .vol-action-sheet-select-title .vol-action-sheet-select-confirm {
position: absolute;
right: 30rpx;
color: #007AFF;
font-weight: 500;
}
.vol-action-sheet-select-container .vol-action-sheet-select-content {
flex: 1;
height: 0;
overflow: scroll;
}
.u-popup .u-transition{
z-index: 99999999 !important;
}
</style>

@ -0,0 +1,107 @@
.lotus-address-picker {
font-size: 26rpx;
padding-top: 30rpx;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
line-height: normal;
padding-right: 30rpx;
box-sizing: border-box;
}
.lotus-address-picker-box {
/*display: -webkit-box;
display: -webkit-flex;*/
display: flex;
align-items: center;
justify-content: center;
justify-content: flex-start;
padding-top: 10rpx;
padding-bottom: 10rpx;
}
.lotus-address-picker-box-item {
height: 600upx;
overflow-y: auto;
width: 33.333%;
padding-left: 20rpx;
padding-right: 20rpx;
box-sizing: border-box;
}
.lotus-address-picker2 {
color: #e93b3d;
position: relative;
}
/* .lotus-address-picker2:after {
content: '';
position: absolute;
right: 0;
top: 65%;
transform: translateY(-35%) rotate(-45deg);
width: 20rpx;
height: 10rpx;
border-left-width: 4rpx;
border-bottom-width: 4rpx;
border-left-style: solid;
border-bottom-style: solid;
border-left-color: #e93b3d;
border-bottom-color: #e93b3d;
} */
.lotus-address-mask {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 999;
background: rgba(0, 0, 0, 0.5);
}
.lotus-address-box {
background: #fff;
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: auto;
}
.lotus-address-action {
font-size: 30rpx;
/*display: -webkit-box;
display: -webkit-flex;*/
display: flex;
align-items: center;
justify-content: center;
justify-content: space-between;
padding: 25rpx 30rpx;
position: relative;
}
.lotus-address-action:after {
content: " ";
position: absolute;
left: 0;
top: 0;
right: 0;
height: 1px;
border-top: 1px solid #eee;
color: #eee;
transform-origin: 0 0;
transform: scaleY(0.5);
}
.lotus-address-action:before {
content: " ";
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
border-bottom: 1px solid #eee;
color: #eee;
transform-origin: 0 100%;
transform: scaleY(0.5);
}
.lotus-address-action-cancel {
color: #969696;
}
.lotus-address-action-affirm {
color: #e93b3d;
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,233 @@
<template>
<!--地址picker-->
<view :status="checkStatus" v-if="lotusAddressData.visible" class="lotus-address-mask">
<view :class="lotusAddressData.visible?'lotus-address-box':'lotus-address-box lotus-address-box-out'">
<view class="lotus-address-action">
<text @tap="cancelPicker" class="lotus-address-action-cancel">取消</text>
<text @tap="chosedVal" class="lotus-address-action-affirm">确认</text>
</view>
<view class="lotus-address-picker-box">
<!---->
<scroll-view scroll-y :scroll-into-view="'pid'+pChoseIndex" class="lotus-address-picker-box-item">
<view @tap="clickPicker(0,pIndex,pItem);" :id="'pid'+pIndex" :class="pIndex === pChoseIndex?'lotus-address-picker lotus-address-picker2':'lotus-address-picker'" v-for="(pItem,pIndex) in province" :key="pIndex">{{pItem}}</view>
</scroll-view>
<!---->
<scroll-view scroll-y :scroll-into-view="'cid'+cChoseIndex" class="lotus-address-picker-box-item">
<view @tap="clickPicker(1,cIndex,cItem);" :id="'cid'+cIndex" :class="cIndex === cChoseIndex?'lotus-address-picker lotus-address-picker2':'lotus-address-picker'" v-for="(cItem,cIndex) in city" :key="cIndex">{{cItem}}</view>
</scroll-view>
<!---->
<scroll-view scroll-y :scroll-into-view="'tid'+tChoseIndex" class="lotus-address-picker-box-item">
<view @tap="clickPicker(2,tIndex,tItem);" :id="'tid'+tIndex" :class="tIndex === tChoseIndex?'lotus-address-picker lotus-address-picker2':'lotus-address-picker'" v-for="(tItem,tIndex) in town" :key="tIndex">{{tItem}}</view>
</scroll-view>
<!--区END-->
</view>
</view>
</view>
<!--地址picker END-->
</template>
<script>
import {lotusAddressJson} from "./Winglau14-lotusAddress.js";
export default {
props:['lotusAddressData'],
data() {
return {
visible: false,
province:[],
city:[],
town:[],
provinceName:'',
cityName:'',
townName:'',
type:0,//01
pChoseIndex:-1,
cChoseIndex:-1,
tChoseIndex:-1
};
},
methods:{
//
cancelPicker(){
const provinceCode = this.getTarId(this.provinceName);
const cityCode = this.getTarId(this.cityName);
const townCode = this.getTarId(this.townName);
this.visible = false;
this.$emit("choseVal",{
province:this.provinceName,
provinceCode,
city:this.cityName,
cityCode,
town:this.townName,
townCode,
isChose:0,
visible:false
});
},
//
chosedVal() {
this.type = 1;
const provinceCode = this.getTarId(this.provinceName);
const cityCode = this.getTarId(this.cityName);
const townCode = this.getTarId(this.townName);
this.visible = false;
let isChose = 0;
// isChose = 1
if((this.provinceName&&this.cityName)||(this.provinceName&&this.cityName&&this.townName)){
isChose = 1;
}
this.$emit("choseVal",{
province:this.provinceName,
provinceCode,
city:this.cityName,
cityCode,
town:this.townName,
townCode,
isChose,
visible:false
});
},
//value
getTarId(name,type){
let id = 0;
lotusAddressJson.map((item,index)=>{
if(item.name === name){
id = item.value;
}
});
return id;
},
//
getCityArr(parentId){
let city = [];
lotusAddressJson.map((item,index)=>{
if(item.parent === parentId){
city.push(item.name);
}
});
return city;
},
//
getTownArr(parentId){
let town = [];
lotusAddressJson.map((item,index)=>{
if(index>34&&item.parent === parentId){
town.push(item.name);
}
});
return town;
},
//
initFn(){
if(!this.province.length){
lotusAddressJson.map((item,index)=>{
if(index<=34){
this.province.push(item.name);
}
});
}
//
const p = this._props.lotusAddressData.provinceName;
const c = this._props.lotusAddressData.cityName;
const t = this._props.lotusAddressData.townName;
//
if(p){
this.pChoseIndex = this.getTarIndex(this.province,p);
}
//
if(p&&c){
const pid = this.getTarId(p);
this.city = this.getCityArr(pid);
this.cChoseIndex = this.getTarIndex(this.city,c);
}
//
if(p&&c&&t){
const cid= this.getTarId(c);
this.town = this.getTownArr(cid);
this.tChoseIndex = this.getTarIndex(this.town,t);
}
//
if(!p&&!c&&!t){
this.pChoseIndex = -1;
this.cChoseIndex = -1;
this.tChoseIndex = -1;
this.city = [];
this.town = [];
}
},
//
getChosedData(){
const pid = this.getTarId(this.provinceName,'province');
this.city = this.getCityArr(pid);
const cid= this.getTarId(this.cityName,'city');
this.town = this.getTownArr(cid);
//index
if(this.provinceName){
this.pChoseIndex = this.getTarIndex(this.province,this.provinceName);
}
if(this.cityName){
this.cChoseIndex = this.getTarIndex(this.city,this.cityName);
}
if(this.townName){
this.tChoseIndex = this.getTarIndex(this.town,this.townName);
}
},
//
clickPicker(type,index,name){
//
if(type === 0){
this.pChoseIndex = index;
this.provinceName = name;
this.cChoseIndex = -1;
this.tChoseIndex = -1;
this.cityName = '';
this.townName = '';
}
//
if(type ===1){
this.cChoseIndex = index;
this.cityName = name;
this.tChoseIndex = -1;
this.townName = '';
}
//
if(type === 2){
this.tChoseIndex = index;
this.townName = name;
}
//
this.getChosedData();
},
//index
getTarIndex(arr,tarName){
let cIndex = 0;
arr.map((item,index)=>{
if(item === tarName){
cIndex = index;
}
});
return cIndex;
}
},
computed:{
checkStatus(){
let t = null;
const _this = this;
if(!_this.visible){
_this.visible = _this._props.lotusAddressData.visible;
//
_this.provinceName = _this._props.lotusAddressData.provinceName;
_this.cityName = _this._props.lotusAddressData.cityName;
_this.townName = _this._props.lotusAddressData.townName;
//
_this.initFn();
t = _this.visible;
}
return t;
}
}
}
</script>
<style lang="less">
@import "./Winglau14-lotusAddress.css";
</style>

@ -0,0 +1,950 @@
<template>
<view class="view-grid">
<view class="fx-height"></view>
<view class="fx-header">
<view class="fx-header-total">
<text></text><text class="fx-header-row-total">{{rowTotal}}</text><text>条数据</text>
</view>
<view @click="griFabBtnClick(btn)" v-if="btn.hidden===false||btn.hidden===undefined" class="btn-item"
v-for="(btn,index) in fabButtons" :key="index">
<u-icon :name="btn.icon" :size="btn.size||18"></u-icon>
<view>{{btn.name}}</view>
</view>
</view>
<slot name="gridHeader"></slot>
<!-- 表格数据 -->
<view class="view-grid-list">
<vol-table v-if="isCreated" :class="[className]" :url="tableUrl" @cellClick="gridCellClick"
@rowButtons="getRowButtons" @rowButtonClick="gridRowButtonClick" @rowClick="gridRowClick"
:defaultLoadPage="load" @loadBefore="loadGridTableBefore" :index="rowIndex" :ck="ck"
@loadAfter="loadGridTableAfter" ref="table" :direction="direction" :titleField="titleField"
:height="height" @formatter="cellFormatter" :columns.sync="columns" :textInline="textInline">
<!-- <view style="height: 50rpx;"></view> -->
<!-- <view class="vol-table-title-buttons" slot="title">
<view @click.native.stop="gridRowClick()" class="vol-table-title-buttons-del">
<u-icon size="20" color="#e64340" name="trash"></u-icon>
</view>
<view class="vol-table-title-buttons-edit">
<u-icon size="20" name="edit-pen"></u-icon>
</view>
</view> -->
</vol-table>
<slot name="gridFooter"></slot>
</view>
<!-- 搜索 -->
<u-popup @touchmove.prevent :zIndex="999999" :show="searchModel" @close="searchModel=false">
<view style="background: #f7f7f7;" class="vol-action-sheet-select-container"
:style="{'max-height':(maxHeight+'px')}">
<view style="background: #FFFFFF" class="vol-action-sheet-select-title">
搜索
<view class="f-icon" @click="searchModel=false"></view>
</view>
<slot name="searchHeader"></slot>
<view class="vol-action-sheet-select-content">
<view class="search-item" @click="sortSelectModel=true">
<view class="f-form-label">排序字段</view>
<view style="flex:1;">
<view style="color:rgb(192 196 204);font-size:15px;" v-show="base.isEmpty(sortField)">
请选择排序字段
</view>
<view style="font-size:15px;" v-show="!base.isEmpty(sortField)">
{{sortName}}
</view>
</view>
<u-icon name="arrow-right"></u-icon>
</view>
<view class="search-item" style="margin-bottom: 20rpx;">
<view class="f-form-label">排序方式</view>
<view style="flex:1;">
<view style="font-size:15px;">
<u-radio-group v-model="orderType" placement="row">
<u-radio :customStyle="{'margin-right': '20px'}" label="降序" name="desc">
</u-radio>
<u-radio :customStyle="{'margin-right': '20px'}" label="升序" name="asc">
</u-radio>
</u-radio-group>
</view>
</view>
</view>
<vol-form :load-key="false" ref="search" @onChange="searchGridFormOnChange"
:form-options.sync="searchFormOptions" :formFields.sync="searchFormFields">
</vol-form>
<view class="search-btns">
<view class="btn">
<u-button @click="resetSearchForm()" :customStyle="{'border-radius': '6px'}" type="success"
icon="reload" text="重置"></u-button>
</view>
<view class="btn">
<u-button @click="searchClick" :customStyle="{'border-radius': '6px'}" type="primary"
icon="search" text="搜索"></u-button>
</view>
</view>
</view>
</view>
</u-popup>
<!-- 搜索请选择排序字段 -->
<view class="sort-form-popup">
<u-popup @touchmove.prevent :zIndex="9999999" :show="sortSelectModel" @close="sortSelectModel=false;">
<view class="vol-action-sheet-select-container" style="max-height:400px">
<view class="vol-action-sheet-select-title">请选择排序
</view>
<view class="search-action-sheet-select-content">
<view v-show="item.type!='group'" @click="sortSelectClick(item)" :key="index"
v-for="(item,index) in searchFormOptions" class="serch-action-sheet-select-item">
{{item.title}}
</view>
</view>
</view>
</u-popup>
</view>
<!-- 新建编辑操作 -->
<u-popup @touchmove.prevent :zIndex="999999" :show="model" @close="model=false">
<view class="vol-action-sheet-select-container" :style="{'max-height':(maxHeight+'px')}">
<view class="vol-action-sheet-select-title">
{{buttons.length?(currentAction=='Add'?'新增':'编辑'):'基本信息'}}
<view class="f-icon" @click="model=false"></view>
</view>
<slot name="modelHeader"></slot>
<view class="vol-action-sheet-select-content">
<vol-form @input-confirm="inputConfirm" :labelWidth="labelWidth" :load-key="false"
@onChange="editGirdFormOnChange" ref="form" @extraClick="gridExtraClick"
:form-options.sync="editFormOptions" :formFields.sync="editFormFields">
</vol-form>
</view>
<slot name="modelBody"></slot>
<view class="btns" :class="{'l-btn':buttons.length>4}">
<view v-show="!btn.hidden" class="btn" v-for="(btn,index) in buttons" :key="index">
<u-button @click="btnClick(btn)" :customStyle="{'border-radius': '6px'}" :type="btn.type"
:icon="btn.icon" :text="btn.name"></u-button>
</view>
<view style="padding: 0 20rpx;width: 100%;" v-if="!buttons.length">
<u-button @click="model=false" :customStyle="{'border-radius': '6px'}" type="primary"
text="关 闭"></u-button>
</view>
</view>
<slot name="modelFooter"></slot>
</view>
</u-popup>
<!-- 表格排序查询最后面增加一个排序字段选择-->
<!-- <view class="fab-buttons">
<view class="icon-item" v-show="showFabButons" v-for="(btn,index) in fabButtons" :key="index"
style="background-color: #ffff;">
<u-icon :color="btn.color" @click="griFabBtnClick(btn)" :name="btn.icon" size="20"></u-icon>
</view>
<view class="switch-btn" v-show="showButtons" @click="showFabButons=!showFabButons">
<u-icon color="#1890FF" name="list-dot" size="20"></u-icon>
</view>
</view> -->
<view class="grid-u-model">
<u-modal :show="showDel" cancelText="取消" :showCancelButton="true" :showConfirmButton="true"
@cancel="cancelDel" @confirm="confirmDel" title="警告">
<view style="color: red;">确定要删除此数据吗!</view>
</u-modal>
</view>
</view>
</template>
<script>
export default {
name: "view-grid",
props: {
options: {
type: Object,
default: () => {
return {
columns: [],
detail: [],
editFormFields: {},
editFormOptions: [],
searchFormFields: {},
searchFormOptions: [],
table: {},
extend: () => {
return {
methods: {
}
}
}
}
}
}
},
data() {
return {
rowTotal: 0,
isWx: false,
className: 'vol-table-888888',
rowIndex: false, //table
load: true, //table
height: 0, //table/
direction: "list", //"horizontal"//list
titleField: "", //tabledirectionlist
fabButtons: [], //
currentAction: 'Add', //
currentRow: {}, //
maxHeight: 0,
model: false, //
showFabButons: true,
showButtons: true, //
textInline: true, //
columns: this.options.columns,
editFormFields: JSON.parse(JSON.stringify(this.options.editFormFields)),
searchFormOptions: this.options.searchFormOptions,
searchFormFields: JSON.parse(JSON.stringify(this.options.searchFormFields)),
editFormOptions: this.options.editFormOptions,
permission: [],
buttons: [], //
hasEditpermission: false, //
searchModel: false, //
sortField: '',
sortName: '',
orderType: 'desc',
sortSelectModel: false, //
tableUrl: "", //tableurl
tableAction: "", //
showDel: false,
isCreated: false,
labelWidth: 80, //
ck:false //checkbox(table)
}
},
methods: {
onInited() {
console.log("viewgridinit")
},
onTableCreated() {
this.onInited();
},
cellFormatter(row, column, index, callback) {
if (this.formatter) {
return callback(this.formatter(row, column, index));
}
return callback(row[column.field]);
},
gridRowClick(index, row, columns) {
this.currentRow = row;
this.currentAction = 'Update';
this.hiddenDelButton(false)
//this.editFormFields.Name=Math.random();
if (this.$refs.form) {
this.$refs.form.reset(row);
} else {
this.resetEditForm(row)
}
// Object.assign(this.editFormFields, row);
if (this.rowClick && !this.rowClick(index, row, columns)) {
return;
};
if (this.modelOpenBefore(row) && this.modelOpenAfter(row)) {
this.model = true;
}
},
gridCellClick(index, row, column) {
if (this.cellClick && !this.cellClick(index, row, column)) {
return;
};
},
hiddenDelButton(hidden) {
let delButton = this.buttons.find(x => {
return x.value == 'del'
});
if (delButton) {
delButton.hidden = hidden;
}
},
gridAdd() {
this.currentAction = 'Add';
this.hiddenDelButton(true);
this.resetEditForm();
if (this.modelOpenBefore(null) && this.modelOpenAfter(null)) {
this.model = true;
}
},
resetEditForm(source) {
if (this.$refs.form) {
this.$refs.form.reset(source);
return;
}
//
this.resetGridForm(this.editFormFields, source, this.options.editFormOptions);
},
btnClick(btn) {
//console.log(btn.onClick)
btn.onClick.call(this)
},
modelOpenBefore(row) {
return true
},
modelOpenAfter(row) {
return true
},
showSearch() {
this.searchModel = true;
},
resetGridForm(formFields, source, formOptions) {
for (const key in formFields) {
if (source && source.hasOwnProperty(key)) {
formFields[key] = source[key];
} else {
if (Array.isArray(formFields[key])) {
formFields[key].splice(0);
if (formOptions.some(x => {
return x.field == key && x.range
})) {
formFields[key].push(...['', '']);
}
} else {
formFields[key] = ""
}
}
}
},
resetSearchForm() {
this.sortField = '';
this.sortName = '';
this.resetGridForm(this.searchFormFields, null, this.options.searchFormOptions);
},
searchClick() {
this.searchModel = false;
//this.$refs.table.load(null,true);
this.refresh();
},
search() {
this.refresh();
},
refresh() { //
this.$refs.table.load(null, true);
},
sortSelectClick(item) {
this.sortField = item.field;
this.sortName = item.title;
this.sortSelectModel = false;
// this.order
},
editGirdFormOnChange(field, value,item) { //select
this.editFormOnChange && this.editFormOnChange(field, value,item)
},
searchGridFormOnChange(field, value,item) { //select
this.searchFormOnChange && this.searchFormOnChange(field, value,item)
},
getSearchItem(field) { //
let data = this.searchFormOptions.find(x => {
return x.field == field
});
return (data || {}).type
},
getSearchParameters() { //
let query = {
wheres: []
};
for (const key in this.searchFormFields) {
let value = this.searchFormFields[key];
if (this.base.isEmpty(value)) continue;
if (typeof value == "number") {
value = value + "";
}
let displayType = this.getSearchItem(key);
//
if (displayType == "cascader" && Array.isArray(value)) {
//--
value = value.length ? (value[value.length - 1] + "") : "";
}
//,
if (
typeof value == "string" || ["date", "datetime", "range"].indexOf(displayType) == -1
) {
query.wheres.push({
name: key,
value: typeof value == "string" ? (value + '').trim() : value.join(","),
displayType: displayType
});
continue;
}
for (let index = 0; index < value.length; index++) {
if (!this.base.isEmpty(value[index])) {
query.wheres.push({
name: key,
value: (value[index] + '').trim(),
displayType: (() => {
if (["date", "datetime", "range"].indexOf(displayType) != -1) {
return index ? "lessorequal" : "thanorequal";
}
return displayType;
})()
});
}
}
}
return query;
},
loadGridTableBefore(param, callback) { //
param.wheres = this.getSearchParameters().wheres;
if (this.orderType) {
param.order = this.orderType;
}
if (this.sortField) {
param.sort = this.sortField;
}
if (this.searchBefore && !this.searchBefore(param)) {
return callback(false);
}
callback(true)
},
loadGridTableAfter(data, callback) { //
this.rowTotal = data.total;
if (this.searchAfter && !this.searchAfter(data.rows, data)) {
return callback(false);
}
callback(true)
},
gridDel() {
this.showDel = true;
},
cancelDel() {
this.showDel = false;
},
confirmDel() {
let url = 'api' + this.options.table.url + 'del';
let key = this.currentRow[this.options.table.key];
if (this.delBefore && !this.delBefore(key, this.currentRow)) {
return;
}
this.http.post(url, [key], true).then(result => {
this.$toast(result.message);
this.showDel = false;
if (!result.status) {
return;
}
this.model = false;
//()
this.refresh();
this.delAfter && !this.delAfter(key, this.currentRow);
})
},
gridSave() {
if (!this.$refs.form.validate()) {
return;
}
let editFormFields = {};
editFormFields[this.options.table.key] = this.currentRow[this.options.table.key]
//string
for (const key in this.editFormFields) {
let _val = this.editFormFields[key];
if (Array.isArray(_val)) {
//
if (this.editFormOptions.some(x => {
return x.field == key && x.type == 'img'
})) {
let imgs = _val.filter(c => {
return c.orginUrl
});
imgs = imgs.map(m => {
return m.orginUrl
}).join(',');
editFormFields[key] = imgs;
} else {
editFormFields[key] = _val.join(',');
}
} else {
editFormFields[key] = _val
}
//
}
let formData = {
mainData: editFormFields,
detailData: null,
delKeys: null
};
if (this.currentAction == 'Add') {
if (this.addBefore && !this.addBefore(formData)) {
return;
}
} else {
if (this.updateBefore && !this.updateBefore(formData)) {
return;
}
}
let url = 'api' + this.options.table.url + (this.currentAction);
this.http.post(url, formData, true).then(result => {
this.$toast(result.message);
if (!result.status) {
return;
}
this.refresh();
if (this.currentAction == 'Add') {
if (this.addAfter && !this.addAfter(this.editFormFields)) {
return;
}
} else if (this.updateAfter && !this.updateAfter(this.editFormFields)) {
return;
}
this.model = false;
})
},
initPermissionButtons() { //
let _permission = (this.permission.find(x => {
return (this.tableAction || this.options.table.name).toUpperCase() == x.tableName
.toUpperCase()
}) || {}).permission;
if (!_permission) {
return;
}
if (_permission.indexOf("Delete") != -1) {
this.buttons.push({
name: "删除",
icon: 'close',
value: 'del',
hidden: true,
type: 'error',
onClick: () => {
this.gridDel();
}
})
}
//
if (_permission.indexOf("Update") != -1 || _permission.indexOf("Add") != -1) {
this.buttons.push(...[{
name: "重置",
icon: 'reload',
value: 'reset',
hidden: false,
type: 'success',
onClick: () => {
this.resetEditForm();
}
}, {
name: "提交",
icon: 'checkbox-mark',
value: 'add',
hidden: false,
type: 'primary',
onClick: () => {
this.gridSave();
}
}])
this.hasEditpermission = true;
} else {
//
this.editFormOptions.forEach(x => {
x.readonly = true;
x.required = false;
})
}
//table
let fabButtons = [{
icon: "reload", //
value: "search",
name: "刷新",
size: '18',
hidden: false,
color: '#009688',
onClick: () => {
this.refresh();
}
}, {
icon: "search",
value: "search",
name: "查询",
hidden: false,
size: '20',
color: 'rgb(7 185 14)',
onClick: () => {
this.showSearch();
}
}]
if (_permission.indexOf("Add") != -1) {
fabButtons.unshift({
icon: "plus", //
hidden: false,
name: "添加",
size: '17',
color: 'rgb(2, 171, 255)',
onClick: () => {
this.gridAdd();
}
})
}
this.fabButtons.push(...fabButtons);
},
async initPermission() {
let permission = this.$store.getters.getMenu();
if (permission.length) {
this.permission = permission;
this.initPermissionButtons();
return;
}
await this.http.get("api/menu/getTreeMenu", {}, false).then(result => {
this.permission = result.menu?result.menu:result;
this.$store.commit("setPermission", result);
this.initPermissionButtons();
})
},
initSource() {
let keys = [];
keys.push(...this.columns.filter(x => {
return x.bind && x.bind.key && !x.bind.data.length;
}).map(x => {
return x.bind.key
}))
keys.push(...this.searchFormOptions.filter(x => {
return x.key || x.dataKey && !x.data.length
}).map(x => {
return x.key || x.dataKey
}))
keys.push(...this.editFormOptions.filter(x => {
if (x.type == 'img' || x.type == "file" || x.type == 'excel') {
x.url = "api/" + this.options.table.name + '/upload'
}
return x.key || x.dataKey && !x.data.length
}).map(x => {
return x.key || x.dataKey
}))
if (!keys.length) {
return;
}
keys = [...new Set(keys)];
this.http.post("api/Sys_Dictionary/GetVueDictionary", keys, false).then(result => {
result.forEach(item => {
this.columns.forEach(x => {
if (x.bind && x.bind.key == item.dicNo) {
x.bind.data = item.data;
}
})
this.searchFormOptions.forEach(x => {
if ((x.key || x.dataKey) == item.dicNo) {
x.data = item.data;
}
})
this.editFormOptions.forEach(x => {
if ((x.key || x.dataKey) == item.dicNo) {
x.data = item.data;
}
})
})
})
},
initSearchFormDateRange() {
this.searchFormOptions.forEach(option => {
if (option.type == 'date' || option.type == 'datetime' && !option.hasOwnProperty("range")) {
if (!Array.isArray(this.searchFormFields[option.field])) {
this.searchFormFields[option.field] = ['', ''];
}
option.range = true;
}
})
},
initFormAttr() {
this.editFormOptions.forEach(x => {
if (!x.hasOwnProperty('readonly')) {
x.readonly = false;
}
if (!x.hasOwnProperty('required')) {
x.required = false;
}
})
},
griFabBtnClick(btn) { //
btn.onClick();
},
getRowButtons(index, row, callback) {
if (this.rowButtons) {
callback(this.rowButtons(index, row))
return;
}
return [];
},
gridRowButtonClick(btn, index, row) {
this.rowButtonClick && this.rowButtonClick(btn, index, row);
},
gridExtraClick(option, fields) {
this.extraClick && this.extraClick(option, fields);
},
inputConfirm(field, e) { //input
console.log(field)
}
},
async created() {
this.initSearchFormDateRange();
await this.initPermission();
this.isCreated = true;
let _$this = this;
// uni.getSystemInfo({
// success: function(res) {
// _$this.height = res.windowHeight - 10;
// }
// });
this.titleField = (this.columns.find(x => {
return x.link
}) || {}).field;
this.tableUrl = 'api' + this.options.table.url + 'getPageData';
let extend;
// #ifdef MP-WEIXIN
this.isWx = true;
if (_$this.$parent.options.extend && typeof _$this.$parent.options.extend == 'function') {
extend = _$this.$parent.options.extend();
if (extend.methods) {
Object.assign(_$this, extend.methods)
}
}
// #endif
if (_$this.options.extend && typeof _$this.options.extend == 'function') {
extend = _$this.options.extend();
if (extend.methods) {
Object.assign(_$this, extend.methods)
}
}
if (!this.isWx) {
this.onInited();
this.initSource();
}
},
mounted() {
if (this.isWx) {
this.onInited();
this.initSource();
}
if (!this.height || this.height < 0) {
uni.getSystemInfo({
success: (resu) => {
var view = uni.createSelectorQuery().in(this).select(".view-grid-list");
view.boundingClientRect().exec(res => {
let h = 0;
if (this.columns.some(x => {
return x.summary
})) {
h = 49
}
this.height = resu.windowHeight - res[0].top - h;
// - (this.direction ==
// 'list' ?
// 0 : 52)
console.log(this.height)
})
}
})
}
uni.getSystemInfo({
success: (res) => {
this.maxHeight = res.screenHeight * 0.82;
}
});
},
watch: {
// #ifdef MP-WEIXIN
columns: {
handler(newValue, oldValue) {
console.log('change2222');
},
immediate: true,
deep: true
},
// #endif
}
}
</script>
<style lang="less" scoped>
.view-grid {
height: 100%;
overflow: hidden;
background: #f9f9f9;
.fx-height {
height: 70rpx;
}
// background: #fbfbfb;
.fx-header {
padding: 0 20rpx;
box-sizing: border-box;
top: 0;
position: absolute;
display: flex;
width: 100%;
height: 70rpx;
z-index: 99;
background: #f7f7f7;
align-items: center;
.btn-item {
height: 100%;
align-items: center;
display: flex;
font-size: 28rpx;
margin-left: 18rpx;
}
}
.fx-header-total {
flex: 1;
font-size: 28rpx;
color: #555;
box-sizing: border-box;
.fx-header-row-total {
font-weight: bolder;
font-size: 30rpx;
margin: 0 6rpx;
}
}
}
.vol-action-sheet-select-container {
min-height: 600rpx;
display: flex;
flex-direction: column;
.vol-action-sheet-select-title {
padding: 24rpx;
text-align: center;
position: relative;
border-bottom: 1px solid rgb(233 233 233);
// .vol-action-sheet-select-confirm {
// position: absolute;
// right: 30rpx;
// color: #007AFF;
// font-weight: 500;
// }
.f-icon {
position: absolute;
right: 0rpx;
top: 0;
font-size: 28rpx;
color: #2979FF;
line-height: 49px;
height: 47px;
width: 80px;
padding-right: 30rpx;
text-align: right;
}
}
.vol-action-sheet-select-content {
flex: 1;
height: 0;
background: #f7f7f7;
overflow: scroll;
}
.btns {
display: flex;
padding: 30rpx 20rpx 40rpx 0;
background: #f7f7f7;
.btn {
flex: 1;
margin-left: 20rpx;
}
}
.l-btn {
display: inline-block;
width: 100%;
.btn {
float: left;
width: 31.5%;
margin-left: 1.5%;
margin-top: 20rpx;
}
}
}
.search-btns {
display: flex;
padding: 30rpx 20rpx 40rpx 0;
background: #f7f7f7;
.btn {
flex: 1;
margin-left: 20rpx;
}
}
.fab-buttons {
position: absolute;
z-index: 999;
bottom: 240rpx;
right: 20rpx;
.icon-item {
margin-bottom: 22rpx;
padding: 16rpx;
background: #eee;
border-radius: 50%;
border: 1px solid #f9f9f9;
box-shadow: 1px 6rpx 20rpx rgb(225 225 225);
}
}
.switch-btn {
// position: absolute;
z-index: 999;
bottom: 160rpx;
right: 2px;
padding: 5px;
background: #ecf5ff;
border: 1px solid #eee;
border-top-left-radius: 5px;
border-bottom-left-radius: 5px;
}
.search-item {
display: flex;
background: #FFFFFF;
padding: 30rpx 18rpx;
border-bottom: 1px solid #eee;
.f-form-label {
width: 80px;
position: relative;
padding-left: 10px;
color: #4c4c4c;
font-size: 30rpx;
}
}
.serch-action-sheet-select-item {
border-bottom: 1px solid rgb(243 243 243);
padding: 26rpx;
text-align: center;
}
.vol-table-title-buttons {
display: flex;
padding-right: 26rpx;
.vol-table-title-buttons-edit,
.vol-table-title-buttons-del {
padding: 0 10rpx;
}
}
</style>
<!-- <style scoped>
.fab-buttons /deep/ {
.u-icon{
background: #eee;
border-radius: 50%;
}
}
</style> -->

@ -0,0 +1,34 @@
<template>
<view :class="['vol-'+type]">
<slot></slot>
</view>
</template>
<script>
export default {
props: {
type: {
type: String,
default: "primary"
}
}
}
</script>
<style lang="less" scoped>
.vol-primary {
box-shadow: 1px 1px 9px #efefef;
border: 1px solid #ddf0fb;
background-color: #eef9ff;
position: relative;
border-radius: 4px;
line-height: 26rpx;
font-size: 26rpx;
color: #404b50;
letter-spacing: 1px;
line-height:1.9;
padding: 10rpx 16rpx;
// margin: 16rpx 20rpx;
}
</style>

@ -0,0 +1,483 @@
<template>
<view class="audit-model-content">
<view style="background: #ffff;">
<u-tabs :list="list" @click="tabsClick"></u-tabs>
</view>
<view v-show="currentIndex == 0 || !hasFlow" class="audit-content">
<view class="fx-right" v-if="isCurrentUser || !hasFlow">
<view v-if="!hasFlow">
<u-alert :title="'当前选中【' + rowLen + '】条记录待审核..'" type="success" :closable="false" />
</view>
<view class="rd" style="display: flex;margin-bottom: 20rpx;">
<span>审批</span>
<u-radio-group style="margin-left:15px" v-model="auditParam.value">
<view style="margin-right: 30rpx;" v-for="item in auditParam.data" :key="item.value">
<u-radio :name="item.value" :label="item.text">
</u-radio>
</view>
</u-radio-group>
</view>
<view style="border: 1px solid #d0d0d0;border-radius: 6rpx;">
<u--textarea border="none" :height="100" v-model="auditParam.reason" placeholder="请输入审批内容">
</u--textarea>
</view>
<view class="btn">
<u-button type="primary" shape="square" @click="auditClick"></u-button>
</view>
</view>
<view class="fx-left" v-if="hasFlow">
<!-- <u-divider text="流程信息" :hairline="true"></u-divider>
-->
<view class="v-steps" style="padding-left: 30rpx;">
<view v-for="(item, index) in workFlowSteps" :key="index">
<view class="step-item" :class="{'step-item-ad':item.auditId||item.stepAttrType=='start'}"
v-if="item.stepAttrType == 'start'">
<!-- <view class="left-item">
<view>流程开始</view>
<view class="left-date">{{ item.createDate }}</view>
</view> -->
<view class="right-item">
<view class="step-line"></view>
<i class="step-circle"></i>
<view class="step-title">
{{ item.stepName }}
</view>
<view class="step-text">发起人{{ item.creator }}</view>
</view>
</view>
<view class="step-item" v-else-if="item.stepAttrType == 'end'">
<!-- <view class="left-item">
<view>流程结束</view>
</view> -->
<view class="right-item">
<view class="step-line"></view>
<i class="step-circle"></i>
<view class="step-title">
{{ item.stepName }}
</view>
</view>
</view>
<view v-else :class="{ 'step-current': item.isCurrent }" class="step-item">
<view class="right-item">
<view class="step-line"></view>
<i class="step-circle"></i>
<view class="step-title">
{{ item.stepName }}
</view>
<view class="step-text">审批人{{ item.auditor }}</view>
<view class="step-text">
{{ getAuditStatus(item.auditStatus) }}
</view>
<view class="step-text">
审批时间 {{ item.auditDate || '待审批' }}
</view>
<view class="step-text"> {{ item.remark || '-' }}</view>
</view>
</view>
</view>
</view>
</view>
</view>
<view v-show="currentIndex===1">
<view class="f-item" v-for="(item,index) in formData" :key="index">
<view class="f-name">{{item.name}}</view>
<view class="f-value">{{item.value}}</view>
</view>
</view>
<view v-show="currentIndex ===2">
<vol-table titleField="auditDate" :tableData="tableData" :columns="columns" :pagination-hide="true"
:load-key="false" :text-inline="false" :ck="false"></vol-table>
</view>
</view>
</template>
<script>
let currentOption = {}
export default {
props: {
data: {
type: Object,
default: () => {
return {
table: "",
tableKey: ""
}
}
}
},
data() {
return {
currentIndex: 0,
list: [{
name: '审批'
}, {
name: '详细信息',
}, {
name: '审批记录'
}],
height: 550,
width: 1000,
workFlowSteps: [],
hasFlow: false,
formData: [],
isFlow: false,
auditParam: {
//
rows: 0, //
model: false, //
value: -1, //
reason: '', //
status: [0, 2], //
data: [{
text: '通过',
value: 1
},
{
text: '拒绝',
value: 3
},
{
text: '驳回',
value: 4
}
],
},
tableData: [],
columns: [{
title: '节点',
field: 'stepName',
width: 100
},
{
title: '审批人',
field: 'auditor',
width: 80
},
{
title: '审批结果',
field: 'auditStatus',
width: 70,
bind: {
data: []
}
},
{
title: '审批时间',
field: 'auditDate',
width: 145
},
{
title: '备注',
field: 'remark',
width: 120
}
],
isCurrentUser: null,
activeName: "audit",
auditDic: [],
rowLen: 0,
currentRows: []
}
},
methods: {
tabsClick(item) {
console.log(item)
this.currentIndex = item.index;
this.list[item.index].inited = true;
},
getAuditStatus(key) {
return (this.auditDic.find(x => {
return x.key === key + ''
}) || {
value: key
}).value || '待审批';
},
auditClick() {
if (this.auditParam.value == -1) {
this.$toast('请选择审批项');
return;
}
//
//
let keys = this.currentRows.map(x => {
return x[currentOption.key]
});
let url =
`api/${currentOption.table}/audit?auditReason=${this.auditParam.reason}&auditStatus=${this.auditParam.value}`
// this.$emit('onAudit', '');
// return;
this.http.post(url, keys, '审核中....').then((x) => {
this.$toast(x.message||'审批成功');
if (!x.status) {
return;
}
this.isCurrentUser = false;
this.$emit('onAudit', x);
});
},
getAuditInfo(option) {
const table = option.table;
const url = `api/Sys_WorkFlow/getSteps?tableName=${table}`
let ids = this.currentRows.map(x => {
return x[option.key]
});
this.http.post(url, ids, true).then(result => {
if (!result.status) {
this.$toast(result.message);
return;
}
this.hasFlow = !!(result.list || []).length;
if (!this.hasFlow) {
let auditStatus = Object.keys(this.currentRows[0]).find(x => {
return x.toLowerCase() === 'auditstatus'
});
let checkStatus = this.currentRows.every((x) => {
return this.auditParam.status.some(c => {
return c === x[auditStatus] || !x[auditStatus]
})
});
if (!checkStatus) {
this.$toast('只能选择待审批或审核中的数据');
return;
}
this.rowLen = this.currentRows.length;
this.isCurrentUser = true;
//
return;
}
if (!this.auditDic.length) {
this.auditDic.push(...(result.auditDic || []))
this.columns.forEach(item => {
if (item.field == 'auditStatus') {
item.bind.data = this.auditDic;
}
})
}
this.isCurrentUser = result.list.some(x => {
return x.isCurrentUser
})
this.workFlowSteps.length = 0;
this.workFlowSteps.push(...result.list);
this.tableData.length = 0;
result.log.forEach(x => {
if (x.stepAttrType = 'start') {
x.stepName = '进入流程';
x.auditDate = x.createDate;
}
})
this.tableData.push(...result.log)
this.formData.length = 0;
this.formData.push(...(result.form || []))
})
},
initFlow(rows, flow) {
this.isFlow = !!flow;
this.currentRows = rows;
this.activeName = 'audit'
this.auditParam.reason = '';
this.auditParam.value = -1;
if (flow) {
currentOption = {
table: rows[0].WorkTable,
key: "WorkTableKey" // rows[0].WorkTableKey
}
}
this.getAuditInfo(currentOption);
// else {
// currentOption = {
// table: props.option.url.replaceAll('/', ''),
// key: props.option.key
// }
// }
}
},
created() {
let rows = [{
WorkTable: this.data.workTable,
WorkTableKey: this.data.tableKey
}]
this.initFlow(rows, true);
}
};
</script>
<style lang="less" scoped>
// .audit-model-content {
// padding: 10px;
// }
.step-item {
background: #fff;
display: flex;
}
.left-item {
min-width: 180px;
text-align: right;
padding-right: 25px;
padding-top: 8px;
.left-date {
font-size: 13px;
padding-top: 7px;
color: #6c6c6c;
}
}
.right-item {
cursor: pointer;
position: relative;
border-bottom: 1px solid #f3f3f3;
padding: 5px 0 5px 5px;
}
.left-item,
.right-item {
padding-bottom: 10px;
}
.right-item:last-child {
border-bottom: 0;
}
.step-line {
top: 16px;
left: -10px;
width: 1px;
height: 100%;
position: absolute;
background-color: #ebedf0;
}
.step-circle {
position: absolute;
top: 17px;
left: -9px;
z-index: 2;
font-size: 12px;
line-height: 1;
transform: translate(-50%, -50%);
width: 7px;
height: 7px;
background-color: #a1a1a1;
border-radius: 50%;
}
.right-item::before {
content: '';
}
.step-content {
padding-top: 2px;
font-size: 14px;
color: #828282;
line-height: 1.5;
}
.step-title {
font-weight: bold;
padding-top: 3px;
}
.step-text {
font-size: 13px;
color: #999999;
padding-top: 6px;
}
.step-current {
* {
color: #2f95ff !important;
}
.step-circle {
background: #2f95ff !important;
}
// border-radius: 5px;
// border: 1px solid #d6eaff;
font-size: 13px;
padding-top: 6px;
// background-color: #eff7ffd9;
color: black;
}
.audit-content {
// background: #f9f9f9;
padding: 10px;
border-radius: 4px;
// display: flex;
.fx-left {
margin-top: 20rpx;
flex: 1;
.rd {
display: flex;
align-items: baseline;
}
}
.fx-right {
// width: 400px;
.btn {
margin-top: 10px;
text-align: center;
}
}
}
.cell-item {
font-weight: 500;
}
.desc-top {
padding: 5px 10px 0 10px;
}
.step-item-ad {
* {
color: #9f9898 !important;
}
}
.f-item {
padding: 20rpx;
display: flex;
color: rgb(48, 49, 51);
font-size: 26rpx;
border-bottom: 1px solid #f5f5f5;
.f-name {
width: 200rpx;
}
.f-value {
flex: 1;
text-align: right;
}
}
</style>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,45 @@
<template>
<u-tabbar @change="onChange" activeColor="rgb(0 161 252)" :zIndex="99999" :value="index" :placeholder="false"
:fixed="true">
<u-tabbar-item text="首页" icon="home" :name="0"></u-tabbar-item>
<u-tabbar-item text="菜单" icon="grid" :name="1"></u-tabbar-item>
<u-tabbar-item text="统计" icon="file-text" :name="2"></u-tabbar-item>
<u-tabbar-item text="消息" icon="bell" :name="3"></u-tabbar-item>
<u-tabbar-item text="我的" icon="account" :name="4"></u-tabbar-item>
</u-tabbar>
</template>
<script>
export default {
props: {
index: {
type: Number,
default: 0
},
},
name: "vol-tabbar",
data() {
return {
list: [
"/pages/home/home",
"/pages/menu/menu",
"/pages/form/form",
"/pages/message/message",
"/pages/user/user"
]
};
},
methods: {
onChange(nameIndex) {
uni.switchTab({
url: this.list[nameIndex]
})
}
}
}
</script>
<style>
</style>

@ -0,0 +1,781 @@
<template>
<view class="vol-table" :class="className">
<!-- 自定义显示 -->
<view v-if="custom">
<u-list :upperThreshold="-999" v-if="tableHeight" :height="tableHeight" @scrolltolower="scrolltolower">
<!-- 小程序不支持标签里面调用方法manifest.json并且要配置 "scopedSlotsCompiler":"legacy",属性 -->
<!-- <view v-for="(row,dataIndex) in rowsData" :key="dataIndex">
<slot name="row" :row="row" :column="inColumns" :index="dataIndex" :page="page"></slot>
</view> -->
<slot name="data" :rows="rowsData" :column="inColumns" :page="page"></slot>
</u-list>
</view>
<!-- 水平显示 -->
<view v-else-if="direction=='horizontal'">
<view class="vol-table-head">
<view class="cell-index" v-if="index">
#
</view>
<view class="cell-ck vol-table-head-cell" v-if="ck">
<u-checkbox-group @change="checkAll">
<u-checkbox :checked="checked" :size="16"></u-checkbox>
</u-checkbox-group>
<!-- <u-checkbox v-model="checked" :size="16"></u-checkbox> -->
</view>
<view @click="headerClick(column)" class="vol-table-head-cell"
:class="['vol-table-cell-'+(column.align||'center')]"
:style="{width:column.width+'px',flex:column.width?'unset':1}" v-if="!column.hidden" :key="index"
v-for="(column,index) in inColumns">
{{column.title}}
<text v-if="column.sort" class="cell-order"
:class="{'acitved-sort':sort==column.field,'acitved-order':order=='asc'}"></text>
<text v-if="column.sort" class="cell-order"
:class="{'acitved-sort':sort==column.field,'acitved-order':order=='desc'}"></text>
</view>
</view>
<view class="vol-table-body">
<u-empty mode="list" v-if="!rowsData.length&&page>0" text="无数据"
icon="http://cdn.uviewui.com/uview/empty/list.png"></u-empty>
<u-list :upperThreshold="-999" v-if="tableHeight" :height="tableHeight" @scrolltolower="scrolltolower">
<view @click="tableRowClick(rowindex,columns)" :key="rowindex" class="vol-table-body-rows"
v-for="(row,rowindex) in rowsData">
<view class="cell-index" v-if="index">
{{rowindex+1}}
</view>
<view class="cell-ck vol-table-body-cell" v-if="ck">
<!-- <u-checkbox v-model="row.ck" :size="16"></u-checkbox> -->
<u-checkbox-group @change="()=>{ rowItemCheckClick(row,rowindex)}">
<u-checkbox :checked="row.ck" :size="16"></u-checkbox>
</u-checkbox-group>
</view>
<view :style="{width:column.width+'px',flex:column.width?'unset':1}" :key="cindex"
class="vol-table-body-cell"
:class="[textInline?'text-inline':'','vol-table-cell-'+(column.align||'center')]"
v-if="!column.hidden" v-for="(column,cindex) in columns">
<view class="vol-cell" @click.stop="cellClick(rowindex,row,column)" v-if="column.click">
<view :style="column.style" v-if="column.formatter">
<rich-text :nodes="rowFormatter(row,column,rowindex)+''"></rich-text>
</view>
<view :style="column.style" v-else>{{row[column.field]}}</view>
</view>
<view class="vol-cell" v-else-if="column.formatter">
<rich-text :nodes="rowFormatter(row,column,rowindex)+''"></rich-text>
</view>
<view class="vol-cell" v-else-if="column.type=='img'">
<u--image @click="previewImage(row[column.field],index)"
style="float:left;margin-left:5px;" width="40px" height="40px" radius="4px"
:src="src" v-for="(src,index) in getImgSrc(row[column.field])" :key="index">
</u--image>
</view>
<view class="vol-cell" v-else-if="column.bind">
{{rowFormatterValue(row,column)}}
</view>
<view v-else-if="column.type=='editor'">
<u-parse :content="row[column.field]"></u-parse>
</view>
<view class="vol-cell" v-else-if="column.type=='date'">
{{(row[column.field]||'').substr(0,10)}}
</view>
<view class="vol-cell" v-else> {{row[column.field]===null?'':row[column.field]}}</view>
</view>
</view>
<slot></slot>
</u-list>
<!-- 显示合计 -->
<view v-if="hasSummary" :key="rowindex" class="vol-table-body-rows vol-table-summary"
v-for="(row,rowindex) in summary">
<view class="cell-index" v-if="index"></view>
<view :style="{width:column.width+'px',flex:column.width?'unset':1}"
:class="{'text-inline':textInline}" :key="cindex" class="vol-table-body-cell"
v-if="!column.hidden" v-for="(column,cindex) in columns">
<view class="vol-cell"> {{base.isEmpty(row[column.field])?'':row[column.field]}}</view>
</view>
</view>
</view>
</view>
<!-- 列表显示 -->
<view v-else class="vol-table-list">
<!-- {{JSON.stringify(columns)}} -->
<u-list :upperThreshold="-999" v-if="tableHeight" :height="tableHeight" @scrolltolower="scrolltolower">
<u-empty mode="list" v-if="!rowsData.length&&page>0" text="无数据"
icon="http://cdn.uviewui.com/uview/empty/list.png">
</u-empty>
<view :key="rowindex" v-for="(row,rowindex) in rowsData">
<view v-if="titleField" class="vol-table-list-item-title">
<text class="vol-table-list-item-title-border"></text>
<view class="vol-table-list-item-title-left">
<rich-text :nodes="getListTitleValue(row,index)+''"></rich-text>
</view>
<!-- <slot :data="row" name="title"></slot> -->
</view>
<view @click="tableRowClick(rowindex,columns)" class="vol-table-list-item">
<view :key="cindex" class="vol-table-list-item-cell"
v-if="!column.hidden&&column.field!=titleField&&showColumn(row,column)" v-for="(column,cindex) in columns">
<view class="cell-left" :style="{width:(column.width||90)+'px'}"> {{column.title}}</view>
<view class="cell-right">
<view @click.stop="cellClick(rowindex,row,column)" v-if="column.click">
<view :style="column.style" v-if="column.formatter">
<rich-text :nodes="rowFormatter(row,column,rowindex)+''"></rich-text>
</view>
<view :style="column.style" v-else>{{row[column.field]}}</view>
</view>
<view v-else-if="column.formatter">
<rich-text :nodes="rowFormatter(row,column)+''"></rich-text>
</view>
<view v-else-if="column.type=='editor'">
<u-parse :content="row[column.field]"></u-parse>
</view>
<view v-else-if="column.bind">
{{rowFormatterValue(row,column)}}
</view>
<view style="display: flex;justify-content: flex-end;" v-else-if="column.type=='img'">
<view @click.stop="previewImage(row[column.field],index)" style="margin-left:10px;"
width="50px" height="50px" v-for="(src,index) in getImgSrc(row[column.field])">
<view>
<u--image width="50px" height="50px" radius="4px" :src="src" :key="index">
</u--image>
</view>
</view>
</view>
<view v-else-if="column.type=='date'">
{{(row[column.field]||'').substr(0,10)}}
</view>
<view v-else> {{row[column.field]==null?'':row[column.field]}}</view>
</view>
</view>
</view>
<view class="extent-button-item" @click.stop>
<view :key="btnIndex" class="extent-button" v-for="(btn,btnIndex) in rowButtons(rowindex,row)">
<u-button :icon="btn.icon" :hairline="true" :shape="btn.shape" :disabled="btn.disabled"
:plain="btn.plain" :type="btn.type" style="height:60rpx;" size="small"
@click="rowBtnClick(btn,rowindex,row)" :text="btn.text">
</u-button>
</view>
</view>
</view>
<slot></slot>
</u-list>
</view>
<u-overlay :opacity="0" :show="showOverlay" @click="showOverlay = false">
<view class="loading-warp">
<u-loading-icon text="加载中..." textSize="16"></u-loading-icon>
<!-- <view class="loading-warp-msg" @tap.stop>正在加载</view> -->
</view>
</u-overlay>
</view>
</template>
<script>
export default {
name: "vol-table",
props: {
custom: { //table
type: Boolean,
default: false
},
size: {
type: Number,
default: 30 //
},
loadKey: {
type: Boolean,
default: true
},
direction: {
type: String,
default: "list" //"horizontal"//list
},
titleField: { //directionlist
type: String,
default: ""
},
height: {
type: Number,
default: 0
},
autoHeight: {
type: Boolean,
default: true
},
textInline: { //
type: Boolean,
default: false
},
index: { //
type: Boolean,
default: false
},
ck: { //checkbox(table)
type: Boolean,
default: false
},
columns: {
type: Array,
default: () => {
return []
}
},
url: {
type: String,
default: ""
},
defaultLoadPage: {
// url
type: Boolean,
default: true,
},
tableData: {
type: Array,
default: () => {
return []
}
},
rowClick: null
},
data() {
return {
checked: false,
showOverlay: false,
className: 'vol-table-' + (~~(Math.random() * 1000000)),
rowsData: [],
sort: '',
order: "",
tableHeight: 0,
inColumns: [],
page: 1,
loaded: false,
hasSummary: false,
lastHeight: 0,
summary: [],
//extent-button
};
},
methods: {
scrolltolower() {
if (!this.url) {
this.$emit('scrolltolower');
}
if (this.loaded) {
return;
}
this.page = this.page + 1;
this.load()
},
load(params, reset) {
if (!this.url) {
return
}
let status = true;
if (reset) {
//this.rowsData.splice(0);
this.page = 1;
this.loaded = false;
}
let param = {
page: this.page,
rows: this.size,
sort: this.sort,
order: this.order || "desc",
wheres: [], // [{ name: "", value: "xx" }]
};
this.$emit("loadBefore", param, (result) => {
status = result;
});
if (!status) return;
param.wheres = JSON.stringify(param.wheres);
this.showOverlay = true;
this.http.post(this.url, param, false).then(data => {
this.showOverlay = false;
this.$emit("loadAfter", data, (result) => {
status = result;
});
if (!status) return;
if (!data.rows.length || data.rows.length < param.rows) {
this.loaded = true;
}
// for (var i = 0; i < 4; i++) {
// data.rows.push(...JSON.parse(JSON.stringify(data.rows)))
// }
//
if (data.summary) {
if (!this.summary.length) {
let summary = []
for (let key in data.summary) {
let obj = {};
obj[key] = data.summary[key];
summary.push(obj);
}
this.summary = summary;
} else {
this.summary.forEach(x => {
for (let key in data.summary) {
x[key] = data.summary[key];
}
})
}
}
console.log(this.summary)
if (reset) {
this.rowsData.splice(0);
}
this.rowsData.push(...data.rows);
})
},
tableRowClick(index, columns) {
if (this.rowClick) {
this.rowClick(index, this.rowsData[index], columns);
return;
}
this.$emit('rowClick', index, this.rowsData[index], columns);
},
rowFormatter(row, column, index) {
let _val;
this.$emit('formatter', row, column, index, (val) => {
_val = val;
})
return _val;
},
rowFormatterValueList(val, column) {
let valArr = val.split(",").filter((x) => {
return x !== "" && x !== undefined;
});
for (let index = 0; index < valArr.length; index++) {
column.bind.data.forEach((x) => {
if (x.key + "" == valArr[index] + "") {
valArr[index] = x.value;
}
});
}
return valArr.join(",");
},
rowFormatterValue(row, column) {
if (this.base.isEmpty(row[column.field])) {
return '';
}
let _val = row[column.field] + '';
if (!column.bind.data.length) {
return _val;
}
if (column.type == "selectList" || column.type == 'checkbox') {
return this.rowFormatterValueList(_val, column)
}
let _obj = column.bind.data.find(x => {
return x.key + '' == _val
});
if (_obj) {
return _obj.value;
}
return _val;
},
getListTitleValue(row, index) {
let column = this.inColumns.find(x => {
return x.field == this.titleField
});
if (column.formatter) {
return this.rowFormatter(row, column, index)
}
if (column.bind) {
return this.rowFormatterValue(row, column)
}
if (column.type == 'date') {
return (row[this.titleField] || '--').substr(0, 10);
}
return row[this.titleField] || '--'
},
headerClick(column) {
if (this.sort == column.field) {
this.order = this.order == 'desc' ? 'asc' : 'desc'
} else {
this.sort = column.field;
this.order = 'desc'
}
},
getData() {
if (!this.url) {
//this.rowsData.push(...this.tableData)
return
}
if (!this.defaultLoadPage) {
return
};
this.load();
},
getImgSrc(imgs) {
if (this.base.isEmpty(imgs)) {
return []
}
if (imgs.indexOf('base64,') != -1) {
return [imgs];
}
let _imgs = imgs.split(',').map(x => {
if (x.startsWith('http')) {
return x;
}
return this.http.ipAddress + x
});
return _imgs;
},
loadSource() {
let dicKeys = this.inColumns.filter(x => {
return x.bind && x.bind.key && !x.bind.data.length
}).map(m => {
return m.bind.key
});
if (!dicKeys.length) {
return
}
this.http.post('api/Sys_Dictionary/GetVueDictionary', dicKeys, true).then(result => {
result.forEach(item => {
this.inColumns.forEach(x => {
if (x.bind && x.bind.key && !x.bind.data.length && x.bind.key == item
.dicNo) {
x.bind.data = item.data;
}
})
})
})
},
cellClick(rowIndex, row, column) {
this.$emit('cellClick', rowIndex, row, column)
},
rowButtons(index, row) {
let _buttons = [];
this.$emit('rowButtons', index, row, (buttons) => {
_buttons = buttons;
})
console.log(_buttons)
return (_buttons || []) //.reverse();
},
rowBtnClick(btn, rowindex, row) {
this.$emit('rowButtonClick', btn, rowindex, row);
},
previewImage(urls, index) {
uni.previewImage({
current: index,
urls: this.getImgSrc(urls),
longPressActions: {}
});
},
initSummary() {
if (this.summary.length) {
this.hasSummary = true;
return;
}
this.summary = this.columns.filter(x => {
return x.summary
}).map(x => {
let obj = {};
obj[x.field] = 0;
return obj;
})
this.hasSummary = this.summary.length > 0
},
caclHeaderHeight() {
if (this.direction == 'list') {
return;
}
console.log('555')
var view = uni.createSelectorQuery().in(this).select(".vol-table-head");
view.boundingClientRect().exec(res => {
if (this.lastHeight > 0 && this.lastHeight == this.tableHeight) {
return;
}
this.tableHeight = this.tableHeight - (res[0] || {
height: 0
}).height;
this.lastHeight = this.tableHeight;
})
},
checkAll() {
this.checked = !this.checked;
this.rowsData.forEach(x => {
this.$set(x, 'ck', this.checked);
})
},
getSelectRows() {
return this.rowsData.filter(x => {
return x.ck
});
},
rowItemCheckClick(row, index) {
console.log('rowItemCheckClick')
// #ifdef MP-WEIXIN
this.tableData[index].ck = !row.ck;
// #endif
this.$set(row, 'ck', !row.ck);
},
showColumn(row,column){
if (!column.showColumn) {
return true;
}
return column.showColumn(row,column);
}
},
created() {
this.initSummary();
this.getData();
this.inColumns = this.columns;
if (this.loadKey) {
this.loadSource();
}
this.tableHeight = this.height;
},
mounted() {
if (this.autoHeight && this.height <= 0) {
uni.getSystemInfo({
success: (resu) => {
var view = uni.createSelectorQuery().in(this).select(".vol-table");
view.boundingClientRect().exec(res => {
this.tableHeight = resu.windowHeight - res[0].top;
if (this.hasSummary) {
this.tableHeight = this.tableHeight - 49;
}
this.caclHeaderHeight()
})
}
})
} else {
this.caclHeaderHeight()
}
},
watch: {
height(newVal) {
console.log(newVal)
if (newVal <= 0) {
return;
}
this.tableHeight = newVal;
this.caclHeaderHeight();
},
// #ifdef MP-WEIXIN
inColumns: {
handler(newValue, oldValue) {
if (newValue && newValue.length) {
this.$emit('update:columns', newValue)
this.initSummary();
}
},
immediate: true,
deep: true
},
columns: {
handler(newValue, oldValue) {
this.inColumns = newValue;
},
immediate: true,
deep: true
},
// #endif
tableData: {
handler(newValue, oldValue) {
this.rowsData = newValue;
},
immediate: true,
deep: true
}
},
}
</script>
<style lang="less" scoped>
.vol-table-head {
padding: 0 8rpx;
display: flex;
background: #f3f3f3;
align-items: center;
text-align: center;
font-weight: bold;
.vol-table-head-cell {
padding: 18rpx 6rpx;
flex: 1;
width: 0;
font-size: 26rpx;
.cell-order {
color: #abadb1;
}
.acitved-sort.acitved-order {
color: #4097f8;
}
}
}
.cell-ck {
width: 52rpx !important;
flex: none !important;
padding: 0 8rpx;
min-height: 55rpx;
display: flex;
justify-content: center;
}
.vol-table-body-rows {
display: flex;
padding: 0 8rpx;
align-items: center;
.vol-table-body-cell {
word-break: break-all;
padding: 0 6rpx;
text-align: center;
flex: 1;
width: 0;
font-size: 24rpx;
color: #484848;
.vol-cell {
padding: 30rpx 0rpx;
}
}
.text-inline {
.vol-cell {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
.vol-table-cell-left {
text-align: left !important;
}
.vol-table-summary {
bottom: 0;
width: 100%;
background: #f3f3f3 !important;
z-index: 999;
position: absolute;
font-weight: bold;
}
.vol-table-body-rows:nth-child(even) {
background: #f9f9f9;
border-top: 1px solid #f3f3f3;
border-bottom: 1px solid #f3f3f3;
}
.cell-index {
width: 30px;
padding: 28rpx 6rpx;
font-size: 26rpx;
text-align: center;
color: #6a6a6a;
}
</style>
<style scoped lang="less">
.vol-table-list {
padding: 14rpx 0;
background: #f9f9f9;
}
.vol-table-list-item-title {
text-align: left;
margin: 18rpx 0 14rpx 22rpx;
font-size: 28rpx;
line-height: 30rpx;
padding-left: 10rpx;
display: flex;
justify-content: center;
align-items: center;
.vol-table-list-item-title-left {
flex: 1;
font-size: 28rpx;
// font-weight: bold;
}
.vol-table-list-item-title-border {
display: inline-block;
background: #818181;
padding: 7px 2px;
border-radius: 4px;
margin-right: 5px;
}
}
.vol-table-list-item {
margin: 8rpx 16rpx;
background: #FFFFFF;
box-shadow: 1px 1px 14px rgb(245 245 245 / 32%);
border: 1px solid #f3f3f3;
border-radius: 10rpx;
.vol-table-list-item-cell {
display: flex;
padding: 20rpx 28rpx;
border-bottom: 1px solid #f9f9f9ee;
font-size: 26rpx;
.cell-left {
border-radius: 5px;
width: 180rpx;
color: #5c5c5c;
}
.cell-right {
flex: 1;
width: 0;
text-align: right;
}
}
}
.extent-button-item {
display: flex;
justify-content: flex-end;
margin: 0rpx 16rpx;
// padding: 10rpx;
top: -10rpx;
position: relative;
background: #ffff;
}
.extent-button {
padding: 10rpx 10rpx;
// display: inline-block;
// float: right;
// min-width: 20%;
// margin-right: 20rpx;
// margin-bottom: 20rpx;
}
.loading-warp {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
.loading-warp-msg {
min-width: 120px;
height: 40px;
justify-content: center;
background-color: #414141;
align-items: center;
text-align: center;
line-height: 40px;
border-radius: 5px;
color: #fff;
}
}
</style>

@ -0,0 +1,151 @@
.peng-tree-mask {
position: fixed;
top: 0rpx;
right: 0rpx;
bottom: 0rpx;
left: 0rpx;
z-index: 9998;
background-color: rgba(0, 0, 0, 0.6);
opacity: 0;
transition: all 0.3s ease;
visibility: hidden;
}
.peng-tree-mask.show {
visibility: visible;
opacity: 1;
}
.peng-tree-cnt {
position: fixed;
top: 0rpx;
right: 0rpx;
bottom: 0rpx;
left: 0rpx;
z-index: 9999;
top: 360rpx;
transition: all 0.3s ease;
transform: translateY(100%);
}
.peng-tree-cnt.show {
transform: translateY(0);
}
.peng-tree-bar {
background-color: #fff;
height: 72rpx;
padding-left: 20rpx;
padding-right: 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
border-bottom-width: 1rpx !important;
border-bottom-style: solid;
border-bottom-color: #f5f5f5;
font-size: 32rpx;
color: #757575;
line-height: 1;
}
.peng-tree-bar-confirm {
color: #007aff;
}
.peng-tree-view {
position: absolute;
top: 0rpx;
right: 0rpx;
bottom: 0rpx;
left: 0rpx;
top: 72rpx;
background-color: #fff;
padding-top: 20rpx;
padding-right: 20rpx;
padding-bottom: 20rpx;
padding-left: 20rpx;
}
.peng-tree-view-sc {
height: 100%;
overflow: hidden;
}
.peng-tree-item {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 26rpx;
color: #757575;
line-height: 1;
height: 0;
opacity: 0;
transition: 0.2s;
position: relative;
overflow: hidden;
}
.peng-tree-item.show {
height: 80rpx;
opacity: 1;
}
.peng-tree-item.showchild:before {
transform: rotate(90deg);
}
.peng-tree-item.last:before {
opacity: 0;
}
.peng-tree-icon {
width: 26rpx;
height: 26rpx;
margin-right: 8rpx;
}
.peng-tree-label {
flex: 1;
display: flex;
align-items: center;
height: 100%;
line-height: 1.2;
}
.peng-tree-check {
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
}
.peng-tree-check-yes,
.peng-tree-check-no {
width: 20px;
height: 20px;
border-top-left-radius: 20%;
border-top-right-radius: 20%;
border-bottom-right-radius: 20%;
border-bottom-left-radius: 20%;
border-top-width: 1rpx;
border-left-width: 1rpx;
border-bottom-width: 1rpx;
border-right-width: 1rpx;
border-style: solid;
border-color: #007aff;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
.peng-tree-check-yes-b {
width: 12px;
height: 12px;
border-top-left-radius: 20%;
border-top-right-radius: 20%;
border-bottom-right-radius: 20%;
border-bottom-left-radius: 20%;
background-color: #007aff;
}
.peng-tree-check .radio {
border-top-left-radius: 50%;
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
border-bottom-left-radius: 50%;
}
.peng-tree-check .radio .peng-tree-check-yes-b {
border-top-left-radius: 50%;
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
border-bottom-left-radius: 50%;
}
.hover-c {
opacity: 0.6;
}

File diff suppressed because one or more lines are too long

@ -0,0 +1,75 @@
/*****************************************************************************************
** Author:jxx 2022
** QQ:283591387
**http://v2.volcore.xyz/document/api 【代码生成页面ViewGrid】
**http://v2.volcore.xyz/document/vueDev
**http://v2.volcore.xyz/document/netCoreDev
*****************************************************************************************/
//此js文件是用来自定义扩展业务代码可以扩展一些自定义页面或者重新配置生成的代码
let extension = {
components: {
//查询界面扩展组件
gridHeader: '',
gridBody: '',
gridFooter: '',
//新建、编辑弹出框扩展组件
modelHeader: '',
modelBody: '',
modelFooter: ''
},
tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
buttons: { view: [], box: [], detail: [] }, //扩展的按钮
methods: {
//下面这些方法可以保留也可以删除
onInit() { //框架初始化配置前,
//示例:在按钮的最前面添加一个按钮
// this.buttons.unshift({ //也可以用push或者splice方法来修改buttons数组
// name: '按钮', //按钮名称
// icon: 'el-icon-document', //按钮图标vue2版本见iview文档iconvue3版本见element ui文档icon(注意不是element puls文档)
// type: 'primary', //按钮样式vue2版本见iview文档buttonvue3版本见element ui文档button
// onClick: function () {
// this.$Message.success('点击了按钮');
// }
// });
//示例:设置修改新建、编辑弹出框字段标签的长度
// this.boxOptions.labelWidth = 150;
},
onInited() {
//框架初始化配置后
//如果要配置明细表,在此方法操作
//this.detailOptions.columns.forEach(column=>{ });
},
searchBefore(param) {
//界面查询前,可以给param.wheres添加查询参数
//返回false则不会执行查询
return true;
},
searchAfter(result) {
//查询后result返回的查询数据,可以在显示到表格前处理表格的值
return true;
},
addBefore(formData) {
//新建保存前formData为对象包括明细表可以给给表单设置值自己输出看formData的值
return true;
},
updateBefore(formData) {
//编辑保存前formData为对象包括明细表、删除行的Id
return true;
},
rowClick({ row, column, event }) {
//查询界面点击行事件
// this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
},
modelOpenAfter(row) {
//点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
//(1)判断是编辑还是新建操作: this.currentAction=='Add';
//(2)给弹出框设置默认值
//(3)this.editFormFields.字段='xxx';
//如果需要给下拉框设置默认值请遍历this.editFormOptions找到字段配置对应data属性的key值
//看不懂就把输出看console.log(this.editFormOptions)
}
}
};
export default extension;

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

@ -0,0 +1,39 @@
import App from './App'
// #ifndef VUE3
import Vue from 'vue'
import uView from '@/uni_modules/uview-ui'
import common from './util/common.js'
import http from './util/http.js'
import store from './store'
Vue.prototype.$toast = function(message,duration) {
uni.showToast({
icon: "none",
title: message,
duration:duration||2000
})
}
Vue.prototype.http=http;
Vue.prototype.$store = store;
Vue.use(uView)
Vue.config.productionTip = false;
Vue.prototype.base=common;
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import {
createSSRApp
} from 'vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
}
// #endif

@ -0,0 +1,101 @@
{
"name" : "vol",
"appid" : "__UNI__7909AB8",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* */
"modules" : {},
/* */
"distribute" : {
/* android */
"android" : {
"permissions" : [
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.NFC\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios" : {},
/* SDK */
"sdkConfigs" : {
"ad" : {}
},
"icons" : {
"android" : {
"hdpi" : "unpackage/res/icons/72x72.png",
"xhdpi" : "unpackage/res/icons/96x96.png",
"xxhdpi" : "unpackage/res/icons/144x144.png",
"xxxhdpi" : "unpackage/res/icons/192x192.png"
},
"ios" : {
"appstore" : "unpackage/res/icons/1024x1024.png",
"ipad" : {
"app" : "unpackage/res/icons/76x76.png",
"app@2x" : "unpackage/res/icons/152x152.png",
"notification" : "unpackage/res/icons/20x20.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"proapp@2x" : "unpackage/res/icons/167x167.png",
"settings" : "unpackage/res/icons/29x29.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"spotlight" : "unpackage/res/icons/40x40.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png"
},
"iphone" : {
"app@2x" : "unpackage/res/icons/120x120.png",
"app@3x" : "unpackage/res/icons/180x180.png",
"notification@2x" : "unpackage/res/icons/40x40.png",
"notification@3x" : "unpackage/res/icons/60x60.png",
"settings@2x" : "unpackage/res/icons/58x58.png",
"settings@3x" : "unpackage/res/icons/87x87.png",
"spotlight@2x" : "unpackage/res/icons/80x80.png",
"spotlight@3x" : "unpackage/res/icons/120x120.png"
}
}
}
}
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "wx2f2d6e605d60671f",
"setting" : {
"urlCheck" : false
},
"scopedSlotsCompiler" : "legacy",
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "2"
}

@ -0,0 +1,274 @@
{
"pages": [ //pageshttps://uniapp.dcloud.io/collocation/pages{
{
"path": "pages/home/home",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#00aaff",
"app-plus": { //
"titleNView": false
},
"navigationStyle": "custom" //
}
},
{
"path": "pages/login/login",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationBarBackgroundColor": "#FFFFFF",
"app-plus": { //
"titleNView": false
}
}
},
{
"path": "pages/menu/menu",
"style": {
"navigationBarTitleText": "菜单",
"enablePullDownRefresh": false,
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#00aaff"
}
},
{
"path": "pages/form/form",
"style": {
"navigationBarTitleText": "统计",
"enablePullDownRefresh": false,
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#00aaff"
}
},
{
"path": "pages/message/message",
"style": {
"navigationBarTitleText": "消息",
"enablePullDownRefresh": false,
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#00aaff"
}
},
{
"path": "pages/user/user",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#00aaff",
"app-plus": { //
"titleNView": false
},
"navigationStyle": "custom" //
}
},
{
"path": "pages/user/about/about",
"style": {
"navigationBarTitleText": "关于vol",
"enablePullDownRefresh": false,
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#00aaff"
}
}, {
"path": "pages/user/modifyPwd/modifyPwd",
"style": {
"navigationBarTitleText": "修改密码",
"enablePullDownRefresh": false
}
}, {
"path": "pages/order/App_Appointment/App_Appointment",
"style": {
"navigationBarTitleText": "只读页面"
}
}, {
"path": "pages/order/App_Appointment1/App_Appointment1",
"style": {
"navigationBarTitleText": "水平显示"
}
}, {
"path": "pages/appmanager/App_TransactionAvgPrice/App_TransactionAvgPrice",
"style": {
"navigationBarTitleText": "自动绑定下拉框"
}
}, {
"path": "pages/appmanager/App_Transaction/App_Transaction",
"style": {
"navigationBarTitleText": "下拉框事件"
}
}, {
"path": "pages/appmanager/App_Transaction1/App_Transaction1",
"style": {
"navigationBarTitleText": "格式化自定义样式"
}
}, {
"path": "pages/order/SellOrder/SellOrder",
"style": {
"navigationBarTitleText": "主从表"
}
}, {
"path": "pages/order/SellOrder/Detail/Detail",
"style": {
"navigationBarTitleText": "订单详情"
}
}, {
"path": "pages/form/form1",
"style": {
"navigationBarTitleText": "表单vol-form",
"enablePullDownRefresh": false
}
}, {
"path": "pages/form/form2",
"style": {
"navigationBarTitleText": "只读表单vol-form",
"enablePullDownRefresh": false
}
}, {
"path": "pages/table/table1/table1",
"style": {
"navigationBarTitleText": "table水平显示",
"enablePullDownRefresh": false
}
}, {
"path": "pages/table/table2/table2",
"style": {
"navigationBarTitleText": "table列表显示",
"enablePullDownRefresh": false
}
}, {
"path": "pages/table/table3/table3",
"style": {
"navigationBarTitleText": "table手动绑定数据",
"enablePullDownRefresh": false
}
}, {
"path": "pages/pagedemo/pagedemo",
"style": {
"navigationBarTitleText": "完整扩展页面",
"enablePullDownRefresh": false
}
}, {
"path": "pages/message/detail/detail",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}, {
"path": "pages/form/charts/chart1",
"style": {
"navigationBarTitleText": "图表",
"enablePullDownRefresh": false
}
}, {
"path": "pages/order/SellOrder/SellOrderAduit",
"style": {
"navigationBarTitleText": "审核",
"enablePullDownRefresh": false
}
}, {
"path": "pages/map/map",
"style": {
"navigationBarTitleText": "地图",
"enablePullDownRefresh": false
}
}, {
"path": "pages/table/table4/table4",
"style": {
"navigationBarTitleText": "自定义table内容一",
"enablePullDownRefresh": false
}
}, {
"path": "pages/table/table5/table5",
"style": {
"navigationBarTitleText": "自定义table内容二",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/flow/flow",
"style" :
{
"navigationBarTitleText": "审批流程",
"enablePullDownRefresh": false
}
},{
"path" : "pages/flow/audit/audit",
"style" :
{
"navigationBarTitleText": "审批",
"enablePullDownRefresh": false
}
}
],
//()https://www.iconfont.cn/search/index
"tabBar": { //pagespath
"color": "#535353",
"selectedColor": "#2f92f9",
"fontSize": "12px",
"borderStyle": "white", //"white",//#e8e8e8",// "black",
"backgroundColor": "#ffffff",
"list": [{
"pagePath": "pages/home/home",
"iconPath": "static/icons/home.png",
"selectedIconPath": "static/icons/home_active.png",
"text": "首页"
},
{
"pagePath": "pages/menu/menu",
"iconPath": "static/icons/menu.png",
"selectedIconPath": "static/icons/menu_active.png",
"text": "菜单"
},
{
"pagePath": "pages/flow/flow",
"iconPath": "static/icons/stats.png",
"selectedIconPath": "static/icons/stats_active.png",
"text": "审批流程"
},
{
"pagePath": "pages/message/message",
"iconPath": "static/icons/message.png",
"selectedIconPath": "static/icons/message_active.png",
"text": "消息"
},
{
"pagePath": "pages/user/user",
"iconPath": "static/icons/user.png",
"selectedIconPath": "static/icons/user_active.png",
"text": "消息"
}
]
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#00aaff",
"navigationBarTextStyle": "white",
"backgroundColor": "#FFFFFF"
},
"easycom": {
"autoscan": true,
"custom": {
"^vol-(.*)": "@/components/vol-$1/vol-$1.vue",
"^view-(.*)": "@/components/view-$1/view-$1.vue"
// ,
// "^grid-(.*)": "@/pages/menu/grid-$1.vue"
}
}
}

@ -0,0 +1,52 @@
<template>
<view>
<view-grid ref="grid" :index="true" :options="options">
<!-- 自定义slot -->
<view @click="viewClick" slot="gridHeader" class="grid-header">
<vol-alert>
<view>1搜索编辑或新建弹出框点击下拉框查看效果</view>
<view>2设置columns的align=true内容居左显示</view>
<view>3设置this.ck=true显示checkbox</view>
<view>4示例见:App_TransactionExtend.js文件说明</view>
</vol-alert>
</view>
<vol-alert slot="search">
<view>点击状态下拉框可监听事件</view>
</vol-alert>
<vol-alert slot="edit">
<view>点击状态下拉框给姓名随机设置一个值</view>
</vol-alert>
</view-grid>
</view>
</template>
<script>
//************************************************
// *Authorjxx
// *QQ283591387
// *
//************************************************
import extend from './App_TransactionExtend.js'
import options from './App_TransactionOptions.js';
let _options = options();
_options.extend = extend;
export default {
data() {
return {
gridHeaderText: "", //便
options: _options
}
},
onShow() {},
methods: {
viewClick() {
//grid
console.log(this.$refs.grid.searchFormFields)
}
}
}
</script>
<style>
</style>

@ -0,0 +1,66 @@
//************************************************
// *Authorjxx
// *QQ283591387
// *自定义业务逻辑扩展
//************************************************
export default function() {
return {
methods: {
onInited() { //页面参数初始化
this.ck = true; //设置显示checkbox只有水平(table)显示类型时才生效
this.height = this.height - 40;
//设置table为水平显示或者list列表显示
this.direction = 'horizontal' //list
this.textInline = false;
//this.rowIndex=true;
this.columns.forEach(column => {
//设置居左显示
column.align = 'left';
//指定单元格宽度
if (column.field == 'Quantity' || column.field == 'TransactionType') {
column.width = 40
}
if (column.field == 'Name') {
column.width = 50
}
})
this.fabButtons.push({
name: "获取选中行",
icon: "scan",
onClick: () => {
let rows=this.$refs.table.getSelectRows();
this.$toast(''+rows.length+'行');
console.log(rows);
}
})
},
searchFormOnChange(field, value) { //查询弹出框下拉框或日期选中事件
if (field == "TransactionType") {
this.$toast(`,${value}`)
}
},
editFormOnChange(field, value) { //新建编辑弹出框下拉框或日期选中事件
if (field == "TransactionType") {
//点击【状态】给名字随机设置一个值
this.editFormFields.Name = ~~(Math.random() * 100000);
this.$toast(`,${value}`)
}
},
rowClick(index, row, column) { //行点击事件(默认触发编辑)
return true;
},
searchBefore(params) { //查询前
return true;
},
updateBefore(formData) { //更新保存前操作
return true;
},
addBefore(formData) { //新建保存前操作
return true;
}
}
}
}

@ -0,0 +1,34 @@
//************************************************
// *Authorjxx
// *QQ283591387
// *代码由框架生成,任何更改都可能导致被代码生成器覆盖
// *业务请在App_Transaction.js中编写
//************************************************
export default function() {
return {
editFormFields: {"Quantity":"","Describe":"","Name":"","PhoneNo":"","TransactionType":"","CowType":""},
editFormOptions: [{"title":"姓名","required":true,"field":"Name"},
{"title":"电话","required":true,"field":"PhoneNo"},
{"type":"group"},
{"key":"cq","data":[],"title":"状态","required":true,"field":"TransactionType","type":"select"},
{"key":"nav","data":[],"title":"类型","field":"CowType","type":"select"},
{"type":"group"},
{"title":"数量","required":true,"field":"Quantity","type":"number"},
{"title":"描述","required":true,"field":"Describe"}],
searchFormFields: {"Name":"","PhoneNo":"","TransactionType":"","CowType":"","Creator":"","CreateDate":""},
searchFormOptions: [{"title":"姓名","field":"Name","type":"text"},{"title":"电话","field":"PhoneNo","type":"text"},{"key":"cq","data":[],"title":"状态","field":"TransactionType","type":"select"},{"type":"group"},{"key":"nav","data":[],"title":"类型","field":"CowType","type":"select"},{"title":"提交人","field":"Creator"},{"title":"提交时间","field":"CreateDate","type":"date"}],
columns: [{field:'Name',title:'',type:'string',link:true},
{field:'PhoneNo',title:'',type:'string'},
{field:'Quantity',title:'',type:'int'},
{field:'TransactionType',title:'',type:'int',bind:{ key:'cq',data:[]}},
{field:'CreateDate',title:'',type:'date'}],
table: {
key: 'Id',
footer: "Foots",
cnName: '',
name: 'App_Transaction',
url: "/App_Transaction/",
sortName: "Id"
}
}
}

@ -0,0 +1,43 @@
<template>
<view>
<view-grid ref="grid" :index="true" :options="options">
<!-- 自定义slot -->
<view @click="viewClick" slot="gridHeader" class="grid-header">
<vol-alert>
<view>列表数据自定义style显示</view>
<view></view>
</vol-alert>
</view>
</view-grid>
</view>
</template>
<script>
//************************************************
// *Authorjxx
// *QQ283591387
// *
//************************************************
import extend from './App_TransactionExtend1.js'
import options from './App_TransactionOptions1.js';
let _options = options();
_options.extend = extend;
export default {
data() {
return {
gridHeaderText: "", //便
options: _options
}
},
onShow() {},
methods: {
viewClick() {
//grid
console.log(this.$refs.grid.searchFormFields)
}
}
}
</script>
<style>
</style>

@ -0,0 +1,65 @@
//************************************************
// *Authorjxx
// *QQ283591387
// *自定义业务逻辑扩展
//************************************************
export default function() {
return {
methods: {
onInited() { //页面参数初始化
this.height = this.height - 40;
//设置table超出换行显示
//this.textInline = false;
//设置列宽度
//this.columns[1].width = 70;
//设置table为水平显示或者list列表显示
//this.direction = 'horizontal'//list
//如果为list列表显示指定list的标题列
//this.titleField="字段";
//设置自定义样式
this.columns.forEach(column => {
if (column.field == 'Quantity' || column.field == 'TransactionType') {
//自定义格式化显示,在下面的formatter实现具体逻辑
column.formatter = true;
column.title="888888";
}
})
console.log("11")
//页面打开时禁用加载数据
//this.load=false;
//页面打开时默认弹出查询框
//this.searchModel = true;
},
formatter(row, column) { //自定义格式化
if (column.field == 'TransactionType') {
if (row.TransactionType == 1) {
return `<span style="color: #ffff;background: #00aaff;padding: 2px 10px;
border-radius: 3px;font-size: 10px;"> 是</span>`;
}
return `<span style="color: #ffff;background: #3eb703;padding: 2px 10px;
border-radius: 3px;font-size: 10px;"> 否</span>`;
}
if (column.field == 'Quantity' && row[column.field] >= 100) {
return '<a style="color:red;">' + row[column.field] + '</a>';
}
return row[column.field]
},
rowClick(index, row, column) { //行点击事件(默认触发编辑)
return true;
},
searchBefore(params) { //查询前
return true;
},
updateBefore(formData) { //更新保存前操作
return true;
},
addBefore(formData) { //新建保存前操作
return true;
}
}
}
}

@ -0,0 +1,34 @@
//************************************************
// *Authorjxx
// *QQ283591387
// *代码由框架生成,任何更改都可能导致被代码生成器覆盖
// *业务请在App_Transaction.js中编写
//************************************************
export default function() {
return {
editFormFields: {"Quantity":"","Describe":"","Name":"","PhoneNo":"","TransactionType":"","CowType":""},
editFormOptions: [{"title":"姓名","required":true,"field":"Name"},
{"title":"电话","required":true,"field":"PhoneNo"},
{"type":"group"},
{"key":"cq","data":[],"title":"状态","required":true,"field":"TransactionType","type":"select"},
{"key":"nav","data":[],"title":"类型","field":"CowType","type":"select"}],
searchFormFields: {"Name":"","PhoneNo":"","TransactionType":"","CowType":"","Creator":"","CreateDate":""},
searchFormOptions: [{"title":"姓名","field":"Name","type":"text"},{"title":"电话","field":"PhoneNo","type":"text"},{"key":"cq","data":[],"title":"状态","field":"TransactionType","type":"select"},{"type":"group"},{"key":"nav","data":[],"title":"类型","field":"CowType","type":"select"},{"title":"提交人","field":"Creator"},{"title":"提交时间","field":"CreateDate","type":"date"}],
columns: [{field:'Name',title:'',type:'string',link:true},
{field:'PhoneNo',title:'',type:'string'},
{field:'Quantity',title:'',type:'int'},
{field:'TransactionType',title:'',type:'int',bind:{ key:'cq',data:[]}},
{field:'CowType',title:'',type:'string',bind:{ key:'nav',data:[]}},
{field:'Describe',title:'',type:'string'},
{field:'Creator',title:'',type:'string'},
{field:'CreateDate',title:'',type:'datetime'}],
table: {
key: 'Id',
footer: "Foots",
cnName: '',
name: 'App_Transaction',
url: "/App_Transaction/",
sortName: "Id"
}
}
}

@ -0,0 +1,51 @@
<template>
<view>
<view-grid ref="grid" :index="true" :options="options">
<!-- 自定义slot -->
<view @click="viewClick" slot="gridHeader" class="grid-header">
<vol-alert>
<view>1移动端同样支持编辑/新建/查询数据源自动绑定</view>
<view>2开发与配置方式与PC端相同,都由代码生成器完成</view>
<view>3[城市]字段省市区县选择</view>
<view>42023.03.20更新components文件夹后才能使用</view>
<view>5省市区县见App_TransactionAvgPriceExtend.js</view>
</vol-alert>
</view>
<view slot="searchHeader">
<vol-alert>
<view>页面已增加省市区县选择</view>
</vol-alert>
</view>
</view-grid>
</view>
</template>
<script>
//************************************************
// *Authorjxx
// *QQ283591387
// *
//************************************************
import extend from './App_TransactionAvgPriceExtend.js'
import options from './App_TransactionAvgPriceOptions.js';
let _options = options();
_options.extend = extend;
export default {
data() {
return {
options: _options
}
},
onShow() {},
methods: {
viewClick() {
//grid
console.log(this.$refs.grid.searchFormFields)
}
}
}
</script>
<style>
</style>

@ -0,0 +1,73 @@
//************************************************
// *Authorjxx
// *QQ283591387
// *自定义业务逻辑扩展
//************************************************
export default function() {
return {
methods: {
onInited() { //页面参数初始化
//设置table超出换行显示
//this.textInline = false;
//设置列宽度
//this.columns[1].width = 70;
//设置table为水平显示或者list列表显示
//this.direction = 'horizontal'//list
//如果为list列表显示指定list的标题列
this.titleField = "CreateDate";
//this.height=this.height-65;
//设置自定义格式显示
//this.columns.forEach(column=>{
// if(column.field=='字段'){
// //自定义格式化显示,在下面的formatter实现具体逻辑
// //column.formatter=true;
// //指定字段为date类型不显示时分秒
// //column.type="date";
// //设置列宽度
// //column.width = 70;
// }
// })
//页面打开时禁用加载数据
this.load = false;
//页面打开时默认弹出查询框
this.searchModel = true;
//设置查询与编辑的城市字段为省市区县选择(2023.03.20更新components文件夹后才能使用)
this.searchFormOptions.forEach(x => {
if (x.field == 'City') {
x.type = 'city'
}
})
this.editFormOptions.forEach(x => {
if (x.field == 'City') {
x.type = 'city'
}
})
},
formatter(row, column) { //自定义格式化
// if(column.field=='xx'){
// return '<a style="color:red;">' + row[column.field] + '</a>';
// }
//return row[column.field]
},
rowClick(index, row, column) { //行点击事件(默认触发编辑)
return true;
},
searchBefore(params) { //查询前
return true;
},
updateBefore(formData) { //更新保存前操作
return true;
},
addBefore(formData) { //新建保存前操作
return true;
}
}
}
}

@ -0,0 +1,35 @@
//************************************************
// *Authorjxx
// *QQ283591387
// *代码由框架生成,任何更改都可能导致被代码生成器覆盖
// *业务请在App_TransactionAvgPrice.js中编写
//************************************************
export default function() {
return {
editFormFields: {"Variety":[],"AgeRange":"","City":"","AvgPrice":"","Date":"","IsTop":"","Creator":"","CreateDate":""},
editFormOptions: [{"key":"pz","data":[],"title":"多选","required":true,"field":"Variety","type":"checkbox"},
{"key":"age","data":[],"title":"值范围","required":true,"field":"AgeRange","type":"select"},
{"key":"city","data":[],"title":"城市","required":true,"field":"City","type":"select"},
{"title":"价格","required":true,"field":"AvgPrice","type":"decimal"},
{"title":"日期","required":true,"field":"Date","type":"date"},
{"key":"top","data":[],"title":"置顶","required":true,"field":"IsTop","type":"select"}],
searchFormFields: {"Variety":"","AgeRange":"","City":"","Date":"","IsTop":"","Enable":""},
searchFormOptions: [{"key":"pz","data":[],"title":"多选","field":"Variety","type":"select"},{"key":"age","data":[],"title":"值范围","field":"AgeRange","type":"select"},{"key":"city","data":[],"title":"城市","field":"City","type":"select"},{"type":"group"},{"title":"日期","field":"Date","type":"datetime"},{"key":"top","data":[],"title":"置顶","field":"IsTop","type":"select"},{"key":"enable","data":[],"title":"是否启用","field":"Enable","type":"select"}],
columns: [{field:'Variety',title:'',type:'string',bind:{ key:'pz',data:[]}},
{field:'AgeRange',title:'',type:'string',bind:{ key:'age',data:[]}},
{field:'City',title:'',type:'string',bind:{ key:'city',data:[]}},
{field:'AvgPrice',title:'',type:'decimal',link:true},
{field:'Date',title:'',type:'date'},
{field:'IsTop',title:'',type:'int',bind:{ key:'top',data:[]}},
{field:'Creator',title:'',type:'string',readonly:true},
{field:'CreateDate',title:'',type:'datetime',readonly:true}],
table: {
key: 'Id',
footer: "Foots",
cnName: '',
name: 'App_TransactionAvgPrice',
url: "/App_TransactionAvgPrice/",
sortName: "Id"
}
}
}

@ -0,0 +1,29 @@
<template>
<vol-audit v-if="isInit" @onAudit="onAudit" :data="data"></vol-audit>
</template>
<script>
export default {
data() {
return {
isInit:false,
data: {
workTable: "",
tableKey: ""
}
}
},
methods:{
onAudit(){
var pages = getCurrentPages(); //
var prevPage = pages[pages.length - 2]; //
prevPage.$vm.search();
}
},
onLoad(options) {
this.data.workTable = options.workTable;
this.data.tableKey = options.tableKey;
//console.log(this.data)
this.isInit=true;
}
}
</script>

@ -0,0 +1,290 @@
<template>
<view class="flow-container" style="background: rgb(247 247 247);">
<view style="background: #ffff;">
<u-tabs :list="list" @click="click"></u-tabs>
</view>
<view v-if="isInited">
<view v-show="currentIndex===index" v-for="(data,index) in list" :key="index">
<vol-table titleField="WorkName" :columns="data.columns" :ref="'list'+index" @loadBefore="loadBefore"
@rowButtonClick="rowButtonClick" @loadAfter="loadAfter" @rowButtons="getRowButtons"
v-if="data.inited" :url="data.url">
</vol-table>
</view>
</view>
</view>
</template>
<script>
/*
被审批的表需要添加移动端菜单并且给当前角色分配审批权限
*/
export default {
data() {
return {
isInited: false,
currentIndex: 0,
value: "",
list: [{
name: '待审批',
url: "api/Sys_WorkFlowTable/getPageData",
inited: true,
badge: {
value: 0,
},
columns: this.getColumns()
}, {
name: '已审批',
url: "api/Sys_WorkFlowTable/getPageData",
badge: {
value: 0,
},
inited: false,
columns: this.getColumns()
}, {
name: '我的提交',
url: "api/Sys_WorkFlowTable/getPageData",
badge: {
value: 0,
},
inited: false,
columns: this.getColumns()
}],
initData: []
}
},
onLoad() {
this.isInited = true;
// this.http.post('api/Sys_Dictionary/GetVueDictionary', [''], false).then(result => {
// let list = result[0].data.map(x => {
// return {
// key: x.key,
// name: x.value,
// url: "api/App_DataList/getList?type=" + x.key
// }
// })
// this.list.push(...list);
// this.initData = this.list.map(x => {
// return false
// });
// this.initData[0] = true;
// this.isInited = true;
// })
},
methods: {
getColumns() {
return [{
field: 'WorkFlowTable_Id',
title: 'WorkFlowTable_Id',
type: 'guid',
width: 110,
hidden: true,
readonly: true,
require: true,
align: 'left'
},
// {field:'WorkFlow_Id',title:'id',type:'guid',width:110,hidden:true,align:'left'},
{
field: 'WorkName',
title: '流程名称',
type: 'string',
width: 130,
align: 'left',
sort: true
},
// {field:'WorkTableKey',title:'id',type:'string',width:180,hidden:true,align:'left'},
// {field:'WorkTable',title:'',type:'string',width:100,align:'left'},
{
field: 'WorkTableName',
title: '业务名称',
type: 'string',
width: 120,
align: 'left'
},
// {field:'CurrentStepId',title:'ID',type:'string',width:110,align:'left'},
{
field: 'StepName',
title: '当前节点',
type: 'string',
width: 120,
align: 'left'
},
{
field: 'AuditStatus',
title: '审批状态',
type: 'int',
bind: {
key: 'audit',
data: []
},
width: 110,
align: 'left'
},
{
field: 'Creator',
title: '提交人',
type: 'string',
width: 100,
align: 'left'
},
{
field: 'CreateDate',
title: '提交时间',
type: 'datetime',
width: 150,
align: 'left',
sort: true
}
]
},
rowClick(row) {
},
getRowButtons(index, row, callback) {
let buttons = []
if (this.currentIndex === 0) {
buttons = [{
text: "审批",
shape: "circle",
type: "error",
// plain: true
}]
} else {
buttons = [{
text: "查看",
shape: "circle",
type: "primary"
}]
}
callback(buttons);
},
rowButtonClick(btn, rowindex, row) {
//
if (this.currentIndex === 0) {
} else {
//
}
//{WorkTable:options.WorkTable,WorkTableKey:options.WorkTableKey}
uni.navigateTo({
url: "/pages/flow/audit/audit?workTable=" + row.WorkTable + '&tableKey=' + row.WorkTableKey
})
//this.$toast('')
},
click(item) {
console.log(item)
this.currentIndex = item.index;
this.list[item.index].inited = true;
},
search() {
console.log('审批后')
//
this.$refs.list0[0].load(null, true);
this.$refs.list1 && this.$refs.list1[0].load(null, true)
},
loadBefore(params, callback) {
// if (this.currentIndex===0) {
// params.
// }
params.value = this.currentIndex;
//
//console.log('table' + JSON.stringify(params))
callback(true);
},
loadAfter(data, callback) {
//if (!this.list[this.currentIndex].badge.value) {
this.list[this.currentIndex].badge.value = data.total;
//}
//
data.rows.forEach(row => {
if (row.img) {
row.img = this.base.getUrl(this.http.ipAddress, row.img, row.size);
}
})
callback(true);
}
}
}
</script>
<style lang="less" scoped>
.search-header {
padding: 16rpx;
display: flex;
align-items: center;
}
.table-demo {
background: #f4f4f4;
padding: 10rpx;
}
.grid-item {
margin: 8rpx 16rpx;
padding: 16rpx;
border-radius: 8rpx;
display: flex;
background: #ffff;
.grid-content {
display: flex;
flex: 1;
flex-direction: column;
padding-right: 20rpx;
.grid-title {
font-size: 32rpx;
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.grid-bottom {
flex: 1;
align-items: flex-end;
padding-top: 20rpx;
display: flex;
font-size: 24rpx;
color: #959595;
.grid-bottom-left {
flex: 1;
width: 0;
}
.success,
.error {
margin-right: 30rpx;
}
.success {
color: #00aa00;
}
.error {
color: #e54648;
}
}
}
}
.grid-item:first-child {
margin-top: 16rpx;
}
</style>
<style scoped>
.flow-container /deep/ .vol-table-list {
padding: 0 !important;
}
</style>

@ -0,0 +1,111 @@
export default {
canvas2d:true,
timing: "easeOut",
duration: 1000,
rotate: false,
rotateLock: false,
color: ["#1890FF", "#91CB74", "#FAC858", "#EE6666", "#73C0DE", "#3CA272", "#FC8452", "#9A60B4", "#ea7ccc"],
padding: [15, 15, 0, 5],
fontSize: 13,
fontColor: "#666666",
dataLabel: true,
dataPointShape: true,
dataPointShapeType: "solid",
touchMoveLimit: 60,
enableScroll: false,
enableMarkLine: false,
legend: {
show: true,
position: "bottom",
float: "center",
padding: 5,
margin: 5,
backgroundColor: "rgba(0,0,0,0)",
borderColor: "rgba(0,0,0,0)",
borderWidth: 0,
fontSize: 13,
fontColor: "#666666",
lineHeight: 11,
hiddenColor: "#CECECE",
itemGap: 10
},
xAxis: {
disableGrid: true,
disabled: false,
axisLine: true,
axisLineColor: "#CCCCCC",
calibration: false,
fontColor: "#666666",
fontSize: 13,
rotateLabel: false,
rotateAngle: 45,
itemCount: 5,
boundaryGap: "center",
splitNumber: 5,
gridColor: "#CCCCCC",
gridType: "solid",
dashLength: 4,
gridEval: 1,
scrollShow: false,
scrollAlign: "left",
scrollColor: "#A6A6A6",
scrollBackgroundColor: "#EFEBEF",
format: ""
},
yAxis: {
data: [{
min: 0
}],
disabled: false,
disableGrid: false,
splitNumber: 5,
gridType: "solid",
dashLength: 8,
gridColor: "#CCCCCC",
padding: 10,
showTitle: false
},
extra: {
column: {
type: "group",
width: 30,
activeBgColor: "#000000",
activeBgOpacity: 0.08,
seriesGap: 2,
categoryGap: 3,
barBorderCircle: false,
linearType: "none",
linearOpacity: 1,
colorStop: 0,
meterBorder: 1,
meterFillColor: "#FFFFFF"
},
tooltip: {
showBox: true,
showArrow: true,
showCategory: false,
borderWidth: 0,
borderRadius: 0,
borderColor: "#000000",
borderOpacity: 0.7,
bgColor: "#000000",
bgOpacity: 0.7,
gridType: "solid",
dashLength: 4,
gridColor: "#CCCCCC",
fontColor: "#FFFFFF",
splitLine: true,
horizentalLine: false,
xAxisLabel: false,
yAxisLabel: false,
labelBgColor: "#FFFFFF",
labelBgOpacity: 0.7,
labelFontColor: "#666666"
},
markLine: {
type: "solid",
dashLength: 4,
data: []
}
}
}

@ -0,0 +1,22 @@
<template>
<view>
整理中
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>

@ -0,0 +1,223 @@
<template>
<view class="v-form-container">
<u-notice-bar color="#54a6ff" bgColor="#e9f3ff" text="这里是一些常用功能,后续会不断更新........."></u-notice-bar>
<view class="grid-list" v-for="(item,index) in grid">
<view class="grid-title">
<view class="grid-title-text">
<view class="grid-title-border"></view>
<view> {{item.name}}</view>
</view>
</view>
<view class="grid-item" @click="gridClick(data.path)" v-for="(data,dindex) in item.data" :key="dindex">
<view class="grid-icon" :class="data.bg">
<u-icon color="#ffff" size="26" :name="data.icon"></u-icon>
</view>
<view class="grid-text">
{{data.name}}
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
grid: [{
name: "volt-able表格",
data: [{
name: "水平显示",
icon: "file-text",
bg: "color1",
path: "/pages/table/table1/table1"
}, {
name: "列表显示",
icon: "list-dot",
bg: "color2",
path: "/pages/table/table2/table2"
}]
},
{
name: "volt-able表格自定义内容",
data: [{
name: "自定内容表一",
icon: "order",
bg: "color4",
path: "/pages/table/table4/table4"
}, {
name: "自定内容表二",
icon: "more-circle",
bg: "color5",
path: "/pages/table/table5/table5"
}]
},
{
name: "表单",
data: [{
name: "表单(级联)",
icon: "file-text",
bg: "color5",
path: "/pages/form/form2"
}, {
name: "只读表单",
icon: "calendar",
bg: "color3",
path: "/pages/form/form1"
}, {
name: "事件绑定",
icon: "pause-circle",
bg: "color2",
path: "/pages/form/form2"
}, {
name: "自定义",
icon: "edit-pen",
bg: "color4",
path: ""
}]
},
{
name: "地图",
data: [{
name: "地图地位",
icon: "map",
bg: "color4",
path: "/pages/map/map"
}, {
name: "地图轨迹",
icon: "play-circle",
bg: "color3",
path: ""
}, {
name: "地图标记",
icon: "thumb-up",
bg: "color1",
path: ""
}]
}, {
name: "图表",
data: [{
name: "图表1",
icon: "share",
bg: "color3",
path: "/pages/form/charts/chart1"
}, {
name: "图表2",
icon: "photo",
bg: "color2",
path: ""
}]
}
]
}
},
onShow() {},
methods: {
gridClick(path) {
if (!path) {
this.$toast('开发中')
return;
}
uni.navigateTo({
url: path
})
}
}
}
</script>
<style lang="less" scoped>
.v-form-container {
background: #fbfbfb;
height: calc(100vh - 110rpx);
overflow: scroll;
padding-bottom: 90rpx;
}
.grid-list {
border-top: 1px solid #f9f9f9;
border-bottom: 1px solid #f9f9f9;
margin-bottom: 24rpx;
width: 100%;
display: inline-block;
background: #ffff;
.grid-item {
width: 20%;
text-align: center;
float: left;
padding: 20rpx 0;
}
.grid-title {
border-bottom: 1px solid #f7f7f7;
padding: 20rpx;
// margin: 10px;
// font-weight: bold;
.grid-title-border {
display: inline-block;
background: #00aaff;
padding: 18rpx 8rpx;
border-radius: 10rpx;
margin-right: 14rpx;
}
.grid-title-text {
display: flex;
// border-left: 16rpx solid #00aaff;
line-height: 1.1;
padding-left: 10rpx;
}
}
.grid-icon {
width: 80rpx;
height: 80rpx;
background: #eee;
border-radius: 34rpx;
// position: relative;
left: 0;
right: 0;
margin: auto;
justify-content: center;
align-items: center;
display: flex;
}
.color1 {
background-image: linear-gradient(#e8b752, #e8b752);
}
//
.color2 {
background-image: linear-gradient(#e55764, #e55764);
}
.color3 {
background-image: linear-gradient(#78c4df, #78c4df);
}
.color4 {
background-image: linear-gradient(#69a0f1, #69a0f1);
}
.color5 {
background-image: linear-gradient(#736be2, #736be2);
}
.grid-text {
font-size: 24rpx;
color: #7e7e7e;
margin-top: 10rpx;
}
}
</style>
<style scoped>
.grid-list /deep/ .u-icon {
flex-direction: column !important;
}
</style>

@ -0,0 +1,97 @@
<template>
<view class="form-test">
<vol-alert>
<view>vol-form设置readonly属性只读</view>
</vol-alert>
<vol-form @onChange="onChange" :load-key="true" ref="form" :form-options.sync="editFormOptions"
:formFields.sync="editFormFields">
</vol-form>
<vol-alert style="margin-top: 40rpx;">
<view>标签显示在上方</view>
</vol-alert>
<vol-form labelPosition="left" :load-key="true" ref="form2" :form-options.sync="editFormOptions"
:formFields.sync="editFormFields">
</vol-form>
</view>
</template>
<script>
export default {
data() {
return {
editFormFields: {
inputText: "这是必填输入框",
pwd: "12345",
selectVal: "1",
selectListVal: [], //
dateValue: "2022-03-27",
datetimeValue: "2022-03-27 20:15"
},
editFormOptions: [{
"title": "输入框",
"required": true,
"field": "inputText",
readonly: true
}, {
"title": "密码框",
"field": "pwd",
"type": "password",
readonly: true
}, {
type: "group" //
},
{
"title": "下拉框",
"field": "selectVal",
type: "select",
"required": true,
data: [],
readonly: true,
key: "enable"
},
{
"title": "多选框",
"field": "selectListVal",
type: "selectList",
"required": true,
data: [],
key: "pn",
readonly: true
},
{
type: "group" //
},
{
"title": "日期",
"required": true,
"type": "date",
"field": "dateValue",
readonly: true
},
{
"title": "日期时分秒",
"type": "datetime",
"field": "datetimeValue",
readonly: true
}
]
}
},
methods: {
},
onShow() {
}
}
</script>
<style lang="less" scoped>
.form-test {
margin-top: -20rpx;
background: #fbfbfb;
padding-top: 20rpx;
overflow: scroll;
}
</style>

@ -0,0 +1,374 @@
<template>
<view class="form-test">
<vol-alert>
<view>vol-form封装了事件绑定下拉框自动绑定数据源级联组件多选单选日期日期范围选择等常用组件操作,见form2.vue文件</view>
</vol-alert>
<vol-form @input-confirm="inputConfirm" @extraClick="extraClick" @onChange="onChange" :load-key="true"
ref="form" :form-options.sync="editFormOptions" :formFields.sync="editFormFields">
</vol-form>
<view class="btns">
<view class="btn">
<u-button type="primary" @click="reset" shape="circle" text="重置表单"></u-button>
</view>
<view class="btn">
<u-button type="success" @click="vailForm" shape="circle" text="校验表单"></u-button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
test: {
a: 1,
b: 2
},
editFormFields: {
inputText: "",
inputText2: "",
customInput: "",
textarea: "这里的文字有点长文字有点长。。",
pwd: "12345",
readonlyText: "只读输入框",
cascader1: null,
cascader2: null,
cascader3: '004',
selectVal: "",
selectListVal: [], //
dateValue: this.base.getDate(), //
datetimeValue: "2022-03-27 20:15",
dateRange: ["2022-03-10", "2022-06-20"], //
inputRange: [100000000, 900000000], //
province: "北京市,北京市,海淀区", //
inputDecimal: null, //
inputNumber: null, //
switchValue: 1,
radioVal: null, //
selectClickValue: "",
dateClickValue: null,
imgs: [{
url: "http://api.volcore.xyz/Upload/Tables/Sys_User/202006191408112343/1111s.jpg"
}, {
url: "http://api.volcore.xyz/Upload/Tables/App_News/202204201140571762/20-05.png"
}]
},
editFormOptions: [{
"title": "输入框",
"required": true,
"field": "inputText"
},
{
"title": "自定义按钮",
"field": "customInput",
extra: {
style: "background: #00aaff;margin-left:16rpx;border-radius: 30rpx;font-size: 24rpx;padding: 4rpx 16rpx;color: #ffff;",
text: "按钮",
icon: "map",
color: "#ffff",
size: 12
}
},
{
type: "group", //
style: "margin-top: 10px;font-weight: 500;font-size: 26rpx;color: #848383;",
title: "选中输入框,键盘点击搜索或者扫描枪扫描触发回车事件"
},
{
"title": "回车事件",
"required": false,
"field": "inputText2"
},
{
"title": "表单字段定义按钮及点击事件,示例见form2.vue",
style: "padding-left:16rpx;font-weight: 500;color: #9e9e9e;font-size: 26rpx;",
type: "group"
},
{
"title": "多文本",
"field": "textarea",
type: "textarea"
}, {
"title": "密码框",
"field": "pwd",
"type": "password"
},
{
"title": "只读框",
"field": "readonlyText",
"type": "text",
readonly: true
},
{
type: "group", //
style: "margin-top: 10px;font-weight: 500;font-size: 26rpx;color: #848383;",
title: "省市区县type设置city(2023.03.20更新components文件夹)"
},
{
"title": "省市区县",
"field": "province",
type: "city" //typecity
},
{
type: "group", //
style: "margin-top: 10px;font-weight: 500;font-size: 26rpx;color: #848383;",
title: "设置checkStrictly=true,只能选择最后一级节点"
},
{
"title": "树形级联",
"field": "cascader1",
type: "cascader",
"required": true,
checkStrictly: true, //,
data: [],
key: "tree_roles"
},
{
type: "group", //
style: "margin-top: 10px;font-weight: 500;font-size: 26rpx;color: #848383;",
title: "设置checkStrictly=false,可以选择任意节点"
},
{
"title": "树形级联2",
"field": "cascader2",
type: "cascader",
"required": true,
checkStrictly: false, //,
data: [],
key: "tree_roles"
},
{
type: "group", //
style: "margin-top: 10px;font-weight: 500;font-size: 26rpx;color: #848383;",
title: "自定义级联data数据源格式见form2.vue文件"
},
{
"title": "自定义级联",
"field": "cascader3",
type: "cascader",
"required": true,
checkStrictly: false, //,
data: [{
id: "001",
parentId: null,
name: "一级节点"
}, {
id: "002",
parentId: "001",
name: "二级节点"
}, {
id: "003",
parentId: null,
name: "三级节点"
}, {
id: "004",
parentId: "003",
name: "四级节点"
}]
},
{
type: "group", //
style: "margin-top: 10px;font-weight: 500;font-size: 26rpx;color: #848383;",
title: "下拉框绑定"
},
{
"title": "下拉框",
"field": "selectVal",
type: "select",
"required": true,
data: [],
key: "pn"
},
{
"title": "多选框",
"field": "selectListVal",
type: "selectList",
"required": true,
data: [],
key: "pn"
},
{
type: "group" //
},
{
type: "group", //
style: "margin-top: 10px;font-weight: 500;font-size: 26rpx;color: #848383;",
title: "日期设置min与max属性限制选择范围"
},
{
"title": "日期",
"required": true,
"type": "date",
"field": "dateValue",
//datetim
//2023.04.02util->common.js使
// min:'2023-04-01',
// max:'2023-07-02'
//
min: this.base.addDay(this.base.getDate(), -15),
max: this.base.getDate()
},
{
"title": "日期时分秒",
"type": "datetime",
"field": "datetimeValue"
},
{
"title": "日期范围",
"type": "date",
range: true, //
"field": "dateRange"
},
{
"title": "区间输入",
"type": "decimal", //numbertext
range: true, //
"field": "inputRange"
},
{
type: "group", //
style: "margin-top: 10px;font-weight: 500;font-size: 26rpx;color: #848383;",
title: "只能输入小数与整数(在手机上查看)"
},
{
"title": "小数",
"type": "decimal",
field: "inputDecimal" //
},
{
"title": "整数",
"type": "number",
field: "inputNumber" //
},
{
type: "group" //
},
//placement
{
type: "group", //
style: "margin-top: 10px;font-weight: 500;font-size: 26rpx;color: #848383;",
title: "单选添加事件,并隐藏【单选】字段"
},
{
"title": "是否值",
"type": "switch",
"field": "switchValue"
},
{
"title": "单选",
"type": "radio",
data: [],
key: "pn",
placement:'row',//rowcolumn ,uvivew
//placement:"column",
"field": "radioVal"
},
//placement
{
type: "group", //
style: "margin-top: 10px;font-weight: 500;font-size: 26rpx;color: #848383;",
title: "注册选择事件,见onChange方法说明"
},
{
"title": "下拉框事件",
"type": "select",
"field": "selectClickValue",
data: [],
key: "pn"
},
{
"title": "日期事件",
"type": "date",
"field": "dateClickValue"
}, {
type: "group" //
},
{
"title": "图片上传",
"type": "img",
//readonly:true,//
"url": "api/sys_user/upload", //upload
"multiple": true, //
"maxCount": 3, //3
"field": "imgs"
},
],
}
},
methods: {
extraClick(item) {
//
this.editFormFields.customInput = ~~(Math.random() * 10000000)
this.$toast('表单按钮点击:' + item.title)
},
onChange(field, value, item, data) { //
if (field == "selectClickValue" || field == "dateClickValue") {
this.$toast(`选择字段${field}${value}`)
return;
}
if (field == 'switchValue') {
//
let op = this.editFormOptions.find(c => {
return c.field == 'radioVal'
});
//
this.$set(op, 'hidden', value + '' === "1")
return;
}
},
vailForm() {
if (this.$refs.form.validate()) {
this.$toast("表单校验成功")
}
},
reset() {
this.$refs.form.reset();
this.$toast("表单已重置")
},
inputConfirm(field, e) {
this.$toast(`字段${field}回车事件`)
console.log(field)
}
},
onShow() {
},
onReady() {
//onReady
this.editFormFields.inputText = 'vol框架';
},
onLoad() {
}
}
</script>
<style lang="less" scoped>
.form-test {
height: auto;
margin-top: -20rpx;
background: #f6f6f6;
padding-top: 20rpx;
}
.btns {
display: flex;
padding: 0rpx 20rpx;
.btn {
flex: 1;
padding: 20rpx;
}
}
</style>

@ -0,0 +1,230 @@
<template>
<view>
<image style="width: 100%;" mode="widthFix" src="/static/swiper1.png"></image>
<!-- <u-swiper height="360rpx" :list="swiperList" :radius="0"></u-swiper> -->
<view class="home-content">
<view class="app-name">vol框架移动端</view>
<view class="card-container">
<view class="fn-title">基础功能</view>
<u-grid :border="false" @click="gridClick" col="4">
<u-grid-item v-for="(item,index) in fn" :key="index">
<view :class="['grid-item-bg','grid-item-bg-'+(index+1)]">
<image style="width:50rpx;height: 50rpx;" :src="item.icon"></image>
</view>
<view class="grid-text">{{item.name}}</view>
</u-grid-item>
</u-grid>
</view>
<view style="padding:30rpx;padding-top:0;">
<vol-alert type="primary">
<view>1VOL移动端基于uniappuview开发</view>
<view>2移动端与PC端同样自动控制权限</view>
<view>3移动端代码完全由代码生成器生成</view>
<view>4移动端与PC端同一套后台接口,开发方式不变</view>
<view>5移动端同样viewgridvolformvoltable组件</view>
</vol-alert>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
height: 0,
swiperList: [
'/static/swiper1.png',
'/static/swiper2.png',
'/static/swiper3.png'
],
fn: [{
name: "审批流程",
icon: '/static/flow.png',
path: "/pages/flow/flow",
subPage: false //
}, {
name: "表单示例",
icon: '/static/form.png',
path: "/pages/form/form",
subPage: true //
},
{
name: "Table组件",
icon: '/static/fc.png',
path: "/pages/form/form",
subPage: true //
},
{
name: "菜单列表",
icon: '/static/table.png',
path: "/pages/menu/menu",
subPage: false //
},
{
name: "地图导航",
icon: '/static/fc.png',
path: "/pages/map/map",
subPage: true //
},
//
{
name: "敬请期待",
icon: '/static/fc.png',
path: "",
},
{
name: "敬请期待",
icon: '/static/fc.png',
path: "",
},
{
name: "敬请期待",
icon: '/static/fc.png',
path: "",
}
],
}
},
onLoad() {
var _this = this;
//
uni.getSystemInfo({
success: function(data) {
// this
_this.height = data.statusBarHeight;
}
})
},
onShow() {},
methods: {
getStyle(item) {
return {
paddingTop: 20 + 'rpx',
background: item.color,
padding: '50%',
color: "#ffff",
'border-radius': '50%',
left: '-24rpx'
}
},
gridClick(index) {
const item = this.fn[index];
if (!item.path) {
return;
}
//pages.jsontabBarpath
//uni
if (item.subPage) {
//navigateTo
uni.navigateTo({
url: this.fn[index].path
})
return;
}
//
uni.switchTab({
url: this.fn[index].path
})
},
swiperClick(index) {
}
}
}
</script>
<style lang="less" scoped>
.home-content {
z-index: 999;
position: relative;
margin-top: -220rpx;
}
.app-name {
text-align: center;
color: #ffff;
font-weight: bolder;
font-size: 60rpx;
top: -40rpx;
position: relative;
}
.card-container {
box-shadow: 1px 1px 9px #b9b6b629;
margin: 30rpx 30rpx 30rpx 30rpx;
border: 1px solid #f1f1f1;
border-radius: 10rpx;
padding: 26rpx 10rpx 14rpx 10rpx;
background: #ffff;
.fn-title {
font-family: 黑体;
font-size: 30rpx;
font-weight: bold;
//color: #8f9ca2;
padding: 4rpx 20rpx 30rpx 20rpx;
}
.grid-text {
padding-top: 8rpx;
font-size: 26rpx;
color: #626262;
padding-bottom: 20rpx;
}
}
.grid-item-bg {
border-radius: 50%;
width: 86rpx;
height: 86rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 5px 3px 6px #e0ddddb0;
}
.grid-item-bg-1 {
background-image: linear-gradient(to bottom right, #97caff, #47a1fe);
}
.grid-item-bg-2 {
background-image: linear-gradient(to bottom right, #f8bcbc, #f07e7e);
}
.grid-item-bg-3 {
background-image: linear-gradient(to bottom right, #afb5e6, #808cf0);
}
.grid-item-bg-4 {
background-image: linear-gradient(to bottom right, #98e4e2, #56c3bf);
}
.grid-item-bg-5 {
background-image: linear-gradient(to bottom right, #d1d1d1, #c878e7);
}
.grid-item-bg-6 {
background-image: linear-gradient(to bottom right, #97caff, #47a1fe);
}
.grid-item-bg-7 {
background-image: linear-gradient(to bottom right, #98e4e2, #56c3bf);
}
.grid-item-bg-8 {
background-image: linear-gradient(to bottom right, #afb5e6, #808cf0);
}
</style>

@ -0,0 +1,159 @@
<template>
<view class="login-container">
<view class="login-title">请登陆</view>
<view class="login-item">
<u--input v-model="userInfo.userName" placeholder="请输入帐号" prefixIcon="account" shape="circle"
border="bottom" clearable prefixIconStyle="font-size: 22px;color: #909399"></u--input>
</view>
<view class="login-item">
<u--input v-model="userInfo.password" type="password" placeholder="请输入密码" prefixIcon="lock-open"
shape="circle" border="bottom" clearable prefixIconStyle="font-size: 22px;color: #909399"></u--input>
</view>
<view class="login-item login-code">
<u--input v-model="userInfo.verificationCode" placeholder="请输入验证码" prefixIcon="scan" shape="circle"
border="bottom" clearable prefixIconStyle="font-size: 22px;color: #909399"></u--input>
<image class="img" @click="getVierificationCode" :src="codeSrc"></image>
</view>
<view class="login-btn">
<u-button @click="login" :loading="loading" :loadingText="loading?'登录中..':''"
:customStyle="{'border-radius': '10rpx'}" size="large" type="primary" text="登录">
</u-button>
</view>
<view style="margin-top: -20rpx;">
<vol-alert type="primary">
<view>演示帐号admin666 密码123456</view>
<view>本地帐号admin &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;密码123456</view>
</vol-alert>
</view>
<u-divider text="其他方式登陆"></u-divider>
<view class="login-other">
<view class="login-other-item"></view>
<view>
<image @click="wechatLogin" class="img" :key="index" v-for="(src,index) in icons" :src="src"></image>
</view>
<view class="login-other-item"></view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
loading: false,
codeSrc: "",
userInfo: {
userName: "admin666",
password: "123456",
UUID: "",
verificationCode: ""
},
icons: []
}
},
methods: {
login() {
if (this.base.isEmpty(this.userInfo.userName))
return this.$toast("请输入用户名");
if (this.base.isEmpty(this.userInfo.password))
return this.$toast("请输入密码");
if (this.base.isEmpty(this.userInfo.verificationCode))
return this.$toast("请输入验证码");
this.userInfo.userName = this.userInfo.userName.trim();
this.userInfo.password = this.userInfo.password.trim();
this.userInfo.verificationCode = this.userInfo.verificationCode.trim();
this.loading = true;
this.http
.post("api/user/login", this.userInfo, "正在登录....")
.then((result) => {
if (!result.status) {
this.loading = false;
this.getVierificationCode();
return this.$toast(result.message);
}
this.$toast("登录成功,正在跳转!");
this.$store.commit("setUserInfo", result.data);
uni.switchTab({
url: "/pages/home/home"
})
});
},
getVierificationCode() {
this.http.get("api/User/getVierificationCode").then(x => {
this.codeSrc = "data:image/png;base64," + x.img;
this.userInfo.UUID = x.uuid;
});
},
wechatLogin() {
}
},
onLoad() {
this.getVierificationCode();
// #ifdef MP-WEIXIN
this.icons = ['https://img.yzcdn.cn/vant/share-icon-wechat.png']
return
// #endif
this.icons = ['https://img.yzcdn.cn/vant/share-icon-qq.png',
'https://img.yzcdn.cn/vant/share-icon-wechat.png',
'https://img.yzcdn.cn/vant/share-icon-weibo.png'
]
}
}
</script>
<style lang="less" scoped>
.login-container {
height: auto;
.login-title {
padding-left: 20rpx;
font-size: 38rpx;
margin-bottom: 40rpx;
}
padding: 80rpx 60rpx 0 60rpx;
.login-item {
padding: 12rpx 0;
border-bottom: 1px solid #eee;
margin-bottom: 20rpx;
/deep/ .u-icon {
width: 80rpx;
}
}
.login-code {
border-bottom: none;
display: flex;
.img {
width: 120rpx;
height: 54rpx;
}
}
.login-btn {
margin: 50rpx 0 50rpx 0;
}
}
.login-other {
display: flex;
.login-other-item {
flex: 1;
margin: 0 25rpx;
}
.img {
width: 50px;
height: 50px;
margin: 0 30rpx;
}
.img:first-child {
margin-left: 0;
}
}
</style>

@ -0,0 +1,291 @@
<template>
<view class="page-section page-section-gap">
<map :enable-satellite="satellite" id="w-map" @controltap="controltap" @markertap="markertap"
:show-compass="true" :show-scale="true" :scale="scale" :controls="controls"
:style="{height:nintyPercentScreenHeight,width:'750rpx'}" :latitude="latitude" :longitude="longitude"
:markers="covers">
</map>
</view>
</template>
<script>
export default {
data() {
return {
scale: 15,
id: "w-marker-map", // 使 marker id
title: 'map',
longitude:116.38,
latitude: 39.87,
satellite: false, //
covers: [
{
id: 100,
longitude:116.38,
latitude: 39.87,
iconPath: "/static/location-2.png",
},
{
id: 200,
longitude:116.38,
latitude: 39.8622,
iconPath: "/static/location-1.png",
}
],
phoneHeight: 1200,
phoneWidth: 0,
controls: [],
}
},
onLoad(option) {
this.latitude = option.latitude;
this.longitude = option.longitude
},
onReady() {
uni.getSystemInfo({
success: (res) => {
this.phoneHeight = res.windowHeight;
this.phoneWidth = res.windowWidth
}
});
},
computed: { //
nintyPercentScreenHeight() { //
if (this.phoneHeight !== '' && this.phoneWidth !== '') {
return 750 / (this.phoneWidth) * (this.phoneHeight) + 'rpx'
} else {
return '1250rpx'
}
},
},
methods: {
scaleMinus() {
if (this.scale < 3) {
return;
}
this.scale = this.scale - 1;
},
scalePlus() {
if (this.scale > 18) {
return;
}
this.scale = this.scale + 1;
},
toLocation() {
//this.scale=this.scale-1;
uni.createMapContext("w-map", this).moveToLocation({
longitude: this.longitude,
latitude: this.latitude
});
},
openMap() {
console.log(this.detail)
console.log(this.detail.latitude)
uni.openLocation({
//
latitude: this.detail.latitude,
//
longitude: this.detail.longitude,
//
address: this.detail.title,
//
scale: 13,
success: function() {
console.log('成功的回调success');
}
});
return;
},
controltap(e) {
}
}
}
</script>
<style scoped lang="less">
.bottom {
background: #EEEEEE;
height: 40%;
width: 100%;
position: fixed;
bottom: 0;
z-index: 99999;
}
.controls {
position: absolute;
width: 60rpx;
z-index: 999999;
right: 26rpx;
bottom: 180rpx;
.scale {
background: #FFFFFF;
text-align: center;
border-radius: 10rpx;
margin-bottom: 30rpx;
.minus,
.plus {
font-size: 48rpx;
color: #3a3a3a;
}
}
}
.vol-action-sheet-select-title {
padding: 15px;
font-weight: bold;
text-align: center;
border-bottom: 1px solid #f5f5f5;
}
.map-type {
// position: absolute;
position: fixed;
z-index: 9999;
background: #FFFFFF;
border-radius: 4px;
padding: 5px;
top: 10px;
left: 10px;
display: flex;
flex-direction: initial;
// #ifdef H5
top: 60px;
// #endif
}
.map-text {
font-size: 13px;
padding: 1px 5px;
color: #6c6c6c;
}
.actived {
color: #0698e1;
}
.river-list {
display: flex;
padding: 20rpx 32rpx;
border-bottom: 1px solid #f3f3f3;
color: #464646;
.left {
flex: 1;
}
.small {
font-size: 24rpx;
color: #acacac;
padding-top: 10rpx;
}
.icon {
// width: 100px;
}
}
.h-list {
margin-top: 12rpx;
padding: 0 12rpx;
// padding-bottom: 73px;
// display: inline-block;
// width: 100%;
// padding-bottom: ;
// width: 100%;
.h-list-item {
padding: 12rpx;
padding-top: 0;
box-sizing: border-box;
margin-bottom: 12rpx;
display: flex;
// box-shadow: 2px 4px 9px #f0f0f0;
// float: left;
// width: 50%;
// flex-direction: column;
// padding-bottom: 0;
background: #ffff;
}
.h-list-item-img {
padding-top: 10rpx;
// width: 260rpx;
}
.h-list-content {
padding: 14rpx 24rpx;
display: flex;
flex-direction: column;
// font-size: 28rpx;
flex: 1;
}
.h-list-title {
line-height: 1.1;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.h-list-line {
flex: 1;
// margin: 10rpx;
// border-bottom: 1px solid #f7f7f7;
// padding-top: 12rpx;
}
.h-list-attr {
font-size: 24rpx;
color: #9d9d9d;
padding: 14rpx 0;
}
.h-list-tag {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.h-list-tag-item {
background: #e8f8ff;
font-size: 12px;
color: #44a1f9;
padding: 1px 3px 2px 3px;
margin-right: 3px;
border-radius: 3px;
}
.h-list-bottom {
font-size: 26rpx;
display: flex;
color: #565454;
.price {
text-align: right;
flex: 1;
}
.num {
color: #e10000;
font-size: 30rpx;
margin-right: 8rpx;
font-weight: bolder;
}
}
}
</style>

@ -0,0 +1,37 @@
//************************************************
// *Authorjxx
// *QQ283591387
// *自定义业务逻辑扩展
//************************************************
export default function() {
return {
methods: {
onInited() {
this.textInline = true;
this.columns[1].width = 70;
this.columns[1].formatter = true;
//this.direction = 'horizontal'
this.listTileFiled="PhoneNo";
// let _this = this;
// uni.getSystemInfo({
// success: function(res) {
// _this.height = res.windowHeight - 0;
// }
// });
},
formatter(row, column) {
let val = row[column.field];
return '<a style="color:red;">' + val + '</a>';
},
rowClick(index, row, column) {
return true;
},
updateBefore(formData) {
this.$toast(JSON.stringify(formData))
},
addBefore(formData) {
this.$toast(JSON.stringify(formData))
}
}
}
}

@ -0,0 +1,150 @@
<template>
<view>
<u-empty v-if="!menu.length" text=" " mode="search" icon="http://cdn.uviewui.com/uview/empty/search.png">
</u-empty>
<view v-if="menu.length" class="menu-container">
<view class="menu-left">
<view @click="itemClick(item,index)" class="menu-item" :class="{'menu-item-select':selectIndex===index}"
:key="index" v-for="(item,index) in getMenu()">{{item.name}}</view>
<view style="height:52px;"></view>
</view>
<view class="menu-right">
<view @click="menuClick(item,index)" class="menu-right-item" v-for="(item,index) in rightData"
:key="index">
<view class="text">
{{item.name}}
</view>
<view class="r-icon">
<u-icon name="arrow-right" color="rgb(221 221 208)" size="16"></u-icon>
</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
selectIndex: 0,
menu: [],
rightData: []
}
},
onLoad() {
let menu = this.$store.getters.getMenu();
if (menu.length) {
return this.menu = menu;
}
this.http.get("api/menu/getTreeMenu", {}, false).then(result => {
this.menu = result.menu?result.menu:result;
if (this.menu.length) {
this.itemClick(this.getMenu()[0], 0);
}
this.$store.commit("setPermission", JSON.parse(JSON.stringify(this.menu)));
})
},
onShow() {
},
methods: {
getMenu() {
return this.menu.filter(c => {
return !c.parentId
})
},
itemClick(item, index) {
this.selectIndex = index;
this.rightData = this.menu.filter(x => {
return x.parentId == item.id
});
},
menuClick(item, index) {
let path=item.path||item.url;
if (path) {
if(path[0]!='/'){
path='/'+path;
}
uni.navigateTo({
url: path
})
}
}
}
}
</script>
<style lang="less" scoped>
.menu-container {
display: flex;
height: 100%;
overflow: hidden;
.menu-left {
overflow: scroll;
width: 200rpx;
background-color: #f7f8fa;
border-right: 1px solid #f7f8fa;
height: 100%;
.menu-item {
position: relative;
display: block;
box-sizing: border-box;
padding: 34rpx 16rpx;
overflow: hidden;
color: #323233;
font-size: 28rpx;
line-height: 36rpx;
background-color: #f7f8fa;
user-select: none;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.menu-item-select {
background: white;
}
.menu-item-select:before {
position: absolute;
top: 50%;
left: 0;
width: 8rpx;
height: 34rpx;
background-color: #007ef3;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
content: '';
}
}
.menu-right {
overflow: scroll;
flex: 1;
width: 0;
margin-bottom: 53px;
// display: flex;
.menu-right-item {
padding: 30rpx 30rpx 30rpx 50rpx;
color: #727272;
font-size: 28rpx;
border-bottom: 1px solid #f3f3f3;
display: flex;
.text {
flex: 1;
}
.r-icon {
width: 30rpx;
}
}
}
}
</style>

@ -0,0 +1,145 @@
//************************************************
// *Authorjxx
// *QQ283591387
// *代码由框架生成,任何更改都可能导致被代码生成器覆盖
// *业务请在#TableName.js中编写
//************************************************
export default function() {
return {
columns: [{
field: 'Id',
title: 'ID',
type: 'int',
hidden: true,
readonly: true,
require: true,
align: 'left'
},
{
field: 'Name',
title: '',
type: 'string',
width: 140,
require: true,
sort: true
},
{
field: 'PhoneNo',
title: '',
type: 'string',
link: true,
width: 90,
require: true,
align: 'left'
},
{
field: 'Describe',
title: '',
type: 'string',
require: true,
sort: true,
align: 'left'
},
{
field: 'Creator',
title: '',
sort: true,
type: 'string'
},
{
field: 'CreateDate',
title: '',
type: 'date'
}
],
detail: [],
editFormFields: {
"Name": "",
"Id": "",
"Describe": "",
"PhoneNo": "",
"CreateDate": "",
"Creator": "",
"Modifier": "",
"ModifyDate": "",
Enable: 1
},
editFormOptions: [{
"title": "姓名",
"required": true,
"field": "Name",
"disabled": true
}, {
"title": "描述",
"required": true,
"field": "Describe",
"disabled": true
},
{
"title": "电话",
"required": true,
"field": "PhoneNo",
"disabled": true
}, {
type: 'group'
}, {
"title": "创建时间",
"field": "CreateDate",
type: 'date'
}, {
"title": "是否值",
"field": "Enable",
type: 'number',
// data:[{key:1,value:'是'},{key:0,value:'否'}]
}
],
searchFormFields: {
"Name": "",
"Id": "",
"Describe": "",
"PhoneNo": "",
"CreateDate": ["", ""],
"Creator": "",
"Modifier": "",
"ModifyDate": "",
Enable: 1
},
searchFormOptions: [{
"title": "姓名",
"required": true,
"field": "Name",
"disabled": true
},
{
"title": "电话",
"required": true,
"field": "PhoneNo",
"disabled": true
}, {
"title": "创建时间",
"field": "CreateDate",
range: true,
type: 'date'
}, {
"title": "是否值",
"field": "Enable",
type: 'select',
data: [{
key: 1,
value: '是'
}, {
key: 0,
value: '否'
}]
}
],
table: {
key: '#key',
footer: "Foots",
cnName: '#cnName',
name: '#TableName',
url: "#url",
sortName: "#SortName"
}
}
}

@ -0,0 +1,50 @@
<template>
<view style="padding: 20rpx;">
<u-skeleton rows="15" :loading="loading" :title="false">
<view class="title">{{data.title}}</view>
<view class="sm-text"><text class="user">{{data.creator}}</text>{{data.createDate}}</view>
<u-parse :content="data.content"></u-parse>
<view style="height: 20rpx;"></view>
</u-skeleton>
</view>
</template>
<script>
export default {
data() {
return {
loading: true,
data: {}
}
},
methods: {
},
onLoad(option) {
uni.setNavigationBarTitle({
title: option.title
})
this.http.get("api/app_news/getDetail?id=" + option.id, {}, false).then(result => {
this.data = result;
this.loading = false;
})
}
}
</script>
<style scoped>
.title {
font-weight: bolder;
}
.sm-text {
padding: 20rpx 0 5rpx 0;
font-size: 26rpx;
color: #8f8f8f;
}
.user {
margin-right: 40rpx;
}
</style>

@ -0,0 +1,107 @@
<template>
<view>
<view @click="toDetail(item)" class="message-list-item" v-for="(item,index) in data" :key="index">
<view class="message-list-item-left">
<u--image width="80px" height="80px" radius="5px" :src="item.imageUrl"></u--image>
</view>
<view class="message-list-item-right">
<view class="message-list-item-right-title">
{{item.title}}
</view>
<view class="message-list-item-right-small-text">
<view style="font-weight: bold; flex: 1;">{{item.creator}}</view>
<view class="flag" v-if="index<=3"></view>
<view class="text">{{item.createDate.substring(0,16)}}</view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
list: {
type: Array,
default: () => {
return []
}
}
},
methods: {
toDetail(item) {
uni.navigateTo({
url: '/pages/message/detail/detail?id=' + item.id + '&title=' + item.title
})
}
},
data() {
return {
data: []
}
},
created() {
this.data = this.list;
},
// #ifdef MP-WEIXIN
watch: {
list: {
handler(val) {
this.data = val;
},
immediate: true,
deep: true
}
},
// #endif
}
</script>
<style lang="less" scoped>
.message-list-item {
min-height: 100rpx;
display: flex;
margin: 14rpx 14rpx 0 14rpx;
background: white;
padding: 16rpx;
border-radius: 10rpx;
border: 1px solid #f5f5f5;
}
.message-list-item-left {
margin-right: 16rpx;
}
.message-list-item-right {
display: flex;
flex-direction: column;
.message-list-item-right-title {
flex: 1;
font-size: 30rpx;
}
.message-list-item-right-small-text {
display: flex;
font-size: 24rpx;
color: #a7a7a7;
.text {
flex: 1;
}
.text:last-child {
text-align: right;
}
.flag {
padding: 1px 5px;
border-radius: 3px;
font-size: 20rpx;
background: #f44336;
color: #ffff;
position: relative;
top: -2px;
}
}
}
</style>

@ -0,0 +1,155 @@
<template>
<view class="message-container">
<u-sticky bgColor="#fff">
<u-tabs :list="list1"></u-tabs>
</u-sticky>
<view class="message-list">
<u-skeleton rows="3" :loading="loading" avatar :title="false">
<u-list @scrolltolower="scrolltolower" :height="height" :lowerThreshold='50'>
<message-list :list="list"></message-list>
<view style="height: 50px;"></view>
</u-list>
<!-- <u-list @scrolltolower="scrolltolower" :height="height" :lowerThreshold='50'>
<view @click="toDetail(item)" class="message-list-item" v-for="(item,index) in list" :key="index">
<view class="message-list-item-left">
<u--image width="80px" height="80px" radius="5px" :src="item.imageUrl"></u--image>
</view>
<view class="message-list-item-right">
<view class="message-list-item-right-title">
{{item.title}}
</view>
<view class="message-list-item-right-small-text">
<view class="text">{{item.creator}}</view>
<view class="flag" v-if="index<=3"></view>
<view class="text">{{item.createDate.substring(0,16)}}</view>
</view>
</view>
</view>
<view style="height: 50px;"></view>
</u-list> -->
</u-skeleton>
</view>
</view>
</template>
<script>
import messagelist from './message-list.vue'
export default {
components:{
'message-list':messagelist
},
methods: {
scrolltolower() {
this.getList();
},
async getNav() {
await this.http.get('api/app_news/getNav', {}, true).then(result => {
this.list1 = result
})
},
getList() {
if (this.page < 0) {
return;
}
this.page++;
let url = 'api/app_news/getList?newsType=' + this.id + "&page=" + this.page;
this.http.get(url, {}, false).then(result => {
result.forEach(item => {
item.imageUrl = this.http.ipAddress + item.imageUrl;
})
if (!result.length) {
this.page = -1;
}
this.list.push(...result);
this.loading = false;
})
}
},
async onLoad() {
let _this = this;
uni.getSystemInfo({
success: function(res) {
_this.height = res.windowHeight - 50;
}
});
await this.getNav();
if (!this.list1.length) {
this.loading = false;
return;
}
this.id = this.list1[0].id;
this.getList();
},
data() {
return {
id: 0,
page: 0,
loading: true,
height: 0,
list1: [{
name: '',
}, {
name: '',
}],
list: []
}
}
}
</script>
<style lang="less" scoped>
.message-container {
background-color: #f9f9f9;
}
.message-list {
.message-list-item {
min-height: 100rpx;
display: flex;
margin: 14rpx 14rpx 0 14rpx;
background: white;
padding: 16rpx;
border-radius: 10rpx;
border: 1px solid #f5f5f5;
}
.message-list-item-left {
margin-right: 16rpx;
}
.message-list-item-right {
display: flex;
flex-direction: column;
.message-list-item-right-title {
flex: 1;
font-size: 30rpx;
}
.message-list-item-right-small-text {
display: flex;
font-size: 24rpx;
color: #a7a7a7;
.text {
flex: 1;
}
.text:last-child {
text-align: right;
}
.flag {
padding: 1px 5px;
border-radius: 3px;
font-size: 20rpx;
background: #f44336;
color: #ffff;
position: relative;
top: -2px;
}
}
}
}
</style>

@ -0,0 +1,66 @@
<template>
<view>
<view-grid ref="grid" @testBtnClick="testBtnClick" :index="true" :options="options">
<!-- 自定义slot -->
<view slot="gridHeader" class="grid-header">
<vol-alert>
<view>1页面由代码生成器生成,自动控制前后端权限</view>
<view>2当前页面在后台菜单上配置的只读不能添加与修改</view>
<view>3点击搜索框扫描图标可以扫描搜索</view>
<view>4示例代码见App_Appointment.vue文件</view>
<view>5点击列表数据,弹出框中也有扫一扫示例</view>
</vol-alert>
<view style="padding: 20rpx;border-bottom: 1px solid #f5f3f3;">
<u-search @search="searchInputClick" @custom="searchInputClick" placeholder="请输入电话搜索"
:showAction="true" actionText="搜索" searchIcon="scan" @clickIcon="scanClick" :animation="false"
v-model="searchText">
</u-search>
</view>
</view>
</view-grid>
</view>
</template>
<script>
//************************************************
// *Authorjxx
// *QQ283591387
// *
//************************************************
import extend from './App_AppointmentExtend.js'
import options from './App_AppointmentOptions.js';
let _options = options();
_options.extend = extend;
export default {
data() {
return {
searchText: "",
options: _options,
show: false,
row: {}
}
},
onShow() {},
methods: {
scanClick() {
//
uni.scanCode({
success: (res) => {
this.searchText = res.result;
this.searchInputClick();
}
})
},
testBtnClick(){
this.$toast('测试按钮');
},
searchInputClick() { //
//App_AppointmentExtend.jssearchInputClick
this.$refs.grid.searchInputClick(this.searchText);
},
}
}
</script>
<style>
</style>

@ -0,0 +1,108 @@
//************************************************
// *Authorjxx
// *QQ283591387
// *自定义业务逻辑扩展
//************************************************
export default function() {
return {
methods: {
onInited() { //页面参数初始化
//设置table超出换行显示
//this.textInline = false;
//设置列宽度
//this.columns[1].width = 70;
//设置table为水平显示或者list列表显示
//this.direction = 'horizontal'//list
//如果为list列表显示指定list的标题列
//this.titleField="字段";
//设置自定义格式显示
//this.columns.forEach(column=>{
// if(column.field=='字段'){
// //自定义格式化显示,在下面的formatter实现具体逻辑
// //column.formatter=true;
// //指定字段为date类型不显示时分秒
// //column.type="date";
// //设置列宽度
// //column.width = 70;
// }
// })
//页面打开时禁用加载数据
//this.load=false;
//页面打开时默认弹出查询框
//this.searchModel = true;
this.height = this.height - 65;
this.fabButtons.push({
name: "测试按钮",
icon: "search",
onClick: () => {
this.$emit('testBtnClick', {
value: "测试"
})
}
})
//编辑弹出框姓名字段增加一个扫一扫操作
this.editFormOptions.forEach(item => {
if (item.field == 'Name') {
item.extra = {
style: "color: #0762c4;margin-left:30rpx;",
text: "扫一扫",
icon: "scan",
color: "#0762c4",
size: 20
}
}
})
},
extraClick(option, fields) { //上面的扫一扫点击事件触发
if (option.field == 'Name') {
this.$toast('');
uni.scanCode({
success: (res) => {
this.editFormFields.Name = res.result;
}
})
}
},
formatter(row, column) { //自定义格式化
// if(column.field=='xx'){
// return '<a style="color:red;">' + row[column.field] + '</a>';
// }
//return row[column.field]
},
rowClick(index, row, column) { //行点击事件
return true;
},
updateBefore(formData) { //更新保存前操作
return true;
},
addBefore(formData) { //新建保存前操作
return true;
},
searchInputClick(searchText) {
//这里设置的是动态属性searchText名字可以自己随便写
this.searchText = searchText;
this.search();
},
searchBefore(params) { //查询前
//界面上的扫描或者搜索框操作,与上面的searchInputClick配合使用
if (this.searchText) {
params.wheres.push({
name: "PhoneNo",
value: this.searchText,
displayType: "like"
})
}
return true;
}
}
}
}

@ -0,0 +1,32 @@
//************************************************
// *Authorjxx
// *QQ283591387
// *代码由框架生成,任何更改都可能导致被代码生成器覆盖
// *业务请在App_Appointment.js中编写
//************************************************
export default function() {
return {
editFormFields: {"Name":"","PhoneNo":"","Describe":"","CreateDate":"","Creator":""},
editFormOptions: [{"title":"姓名","required":true,"field":"Name","disabled":true},
{"type":"group"},
{"title":"电话","required":true,"field":"PhoneNo","disabled":true},
{"title":"描述","required":true,"field":"Describe","disabled":true}],
searchFormFields: {"Name":"","PhoneNo":"","CreateDate":"","Creator":""},
searchFormOptions: [{"title":"姓名","field":"Name"},{"title":"电话","field":"PhoneNo"},{"title":"创建时间","field":"CreateDate","type":"datetime"},{"title":"创建人","field":"Creator"}],
columns: [{field:'Name',title:'',type:'string',link:true,readonly:true},
{field:'PhoneNo',title:'',type:'string',readonly:true},
{field:'Describe',title:'',type:'string',readonly:true},
{field:'CreateDate',title:'',type:'datetime',readonly:true},
{field:'Creator',title:'',type:'string',readonly:true},
{field:'Modifier',title:'',type:'string',readonly:true},
{field:'ModifyDate',title:'',type:'datetime',readonly:true}],
table: {
key: 'Id',
footer: "Foots",
cnName: '+',
name: 'App_Appointment',
url: "/App_Appointment/",
sortName: "CreateDate"
}
}
}

@ -0,0 +1,67 @@
<template>
<view>
<view-grid ref="grid" @delTest="delTest" :index="true" :options="options">
<view slot="gridHeader" class="grid-header">
{{gridHeaderText}}
<vol-alert>
<view>1.设置direction属性改变数据显示方向</view>
<view>2.此示例包括:列隐藏,自定义超链接,自定义列点击事件</view>
<view>3.见App_Appointment1.vue/.js文件</view>
</vol-alert>
</view>
</view-grid>
<u-modal title="提示" @cancel="show=false" width="500rpx" @confirm="confirm" showCancelButton showConfirmButton
confirmColor="red" :show="show">
<view style="text-align: center;">确定删除数据吗?</view>
</u-modal>
</view>
</template>
<script>
//************************************************
// *Authorjxx
// *QQ283591387
// *
//************************************************
import extend from './App_AppointmentExtend1.js'
import options from './App_AppointmentOptions1.js';
export default {
data() {
let _options = options();
_options.extend = extend;
return {
gridHeaderText: "", //便
options: _options,
show: false,
row: {}
}
},
onShow() {},
methods: {
delTest(row) {
this.row = row;
this.show = true;
},
confirm() {
//
//
const url = 'api/App_Appointment/del';
this.http.post(url, [this.row.Id], true).then(result => {
this.$toast(result.message)
if (!result.status) {
return
}
//
this.show=false;
//,
this.$refs.grid.search();
})
}
}
}
</script>
<style>
</style>

@ -0,0 +1,78 @@
//************************************************
// *Authorjxx
// *QQ283591387
// *自定义业务逻辑扩展
//************************************************
export default function() {
return {
methods: {
onInited() { //页面参数初始化
//设置table超出换行显示
//this.textInline = false;
//设置列宽度
//this.columns[1].width = 70;
//设置table为水平显示或者list列表显示
this.direction = 'horizontal' //list
this.columns.forEach(column => {
//动态隐藏字段
if (["Creator", "Modifier", "ModifyDate", "PhoneNo"].indexOf(column.field) != -1) {
column.hidden = true;
}
if (column.field == 'CreateDate') {
column.type = "date";
column.width = 80;
}
if (column.field == 'Describe') {
column.width = 140;
//设置描述字段超链接与点击事件
column.formatter = true;
column.click = true;
}
})
//动态添加一个操作列
//具体实现见下面formatter、cellClick方法及App_Appointment.vue中的删除弹出框操作
this.columns.push({
field: "操作",
title: "操作",
formatter: true,
click: true
})
//显示行号
this.rowIndex = true;
},
formatter(row, column) { //自定义格式化
if (column.field == 'Describe') {
return '<a style="color:#2485e9;">' + row[column.field] + '</a>';
} else if (column.field == '') {
return '<a style="color:#2485e9;font-size:26rpx"></a>';
}
return row[column.field]
},
cellClick(index, row, column) {
if (column.field == 'Describe') {
this.$toast(':' + row.Describe)
} else if (column.field == '') {
//删除操作(这里只是举例,框架内置了删除方法,点击行弹出框中(菜单分配了删除按钮才能看到))
//调用删除提示见App_Appointment.vue中
this.$emit('delTest',row)
}
},
rowClick(index, row, column) { //行点击事件
return true;
},
updateBefore(formData) { //更新保存前操作
return true;
},
addBefore(formData) { //新建保存前操作
return true;
}
}
}
}

@ -0,0 +1,32 @@
//************************************************
// *Authorjxx
// *QQ283591387
// *代码由框架生成,任何更改都可能导致被代码生成器覆盖
// *业务请在App_Appointment.js中编写
//************************************************
export default function() {
return {
editFormFields: {"Name":"","PhoneNo":"","Describe":"","CreateDate":"","Creator":""},
editFormOptions: [{"title":"姓名","required":true,"field":"Name","disabled":true},
{"type":"group"},
{"title":"电话","required":true,"field":"PhoneNo","disabled":true},
{"title":"描述","required":true,"field":"Describe","disabled":true}],
searchFormFields: {"Name":"","PhoneNo":"","CreateDate":"","Creator":""},
searchFormOptions: [{"title":"姓名","field":"Name"},{"title":"电话","field":"PhoneNo"},{"title":"创建时间","field":"CreateDate","type":"datetime"},{"title":"创建人","field":"Creator"}],
columns: [{field:'Name',title:'',type:'string',link:true,readonly:true},
{field:'PhoneNo',title:'',type:'string',readonly:true},
{field:'Describe',title:'',type:'string',readonly:true},
{field:'CreateDate',title:'',type:'datetime',readonly:true},
{field:'Creator',title:'',type:'string',readonly:true},
{field:'Modifier',title:'',type:'string',readonly:true},
{field:'ModifyDate',title:'',type:'datetime',readonly:true}],
table: {
key: 'Id',
footer: "Foots",
cnName: '+',
name: 'App_Appointment',
url: "/App_Appointment/",
sortName: "CreateDate"
}
}
}

@ -0,0 +1,340 @@
<template>
<view class="order-detail">
<vol-alert>
<view>1订单详情页面由自己维护</view>
<view>2框架已封装vol-table与vol-form组件可直接使用</view>
<view>3可参照此页面实现一对一或者一对多</view>
</vol-alert>
<!--主表信息 -->
<view class="order-main">
<view class="title">订单信息</view>
<vol-form class="main-form" :load-key="true" ref="form" :form-options="editFormOptions"
:formFields.sync="editFormFields">
</vol-form>
</view>
<!-- 明细列表信息 -->
<view class="order-detail-list">
<view class="detail-btns">
<view class="detail-btn" @click="showDetailBtnClick">
<u-button icon="plus" type="primary" shape="circle" size="small" text="添加"></u-button>
</view>
<view class="detail-btn" @click="save">
<u-button icon="checkmark" type="success" shape="circle" size="small" text="保存"></u-button>
</view>
</view>
<u-sticky bgColor="#fff">
<u-tabs :list="list"></u-tabs>
</u-sticky>
<vol-table :height="300" @rowClick="rowClick" :tableData="rows" direction="horizontal"
:columns.sync="columns" ref="table">
</vol-table>
</view>
<u-popup @touchmove.prevent class="form-popup" :zIndex="999999" :show="detailModel" @close="detailModel=false;">
<view class="vol-action-sheet-select-container" style="max-height:500px">
<view class="vol-action-sheet-select-title" @click="detailModel=false;">
<text class="vol-action-sheet-select-confirm">取消</text>
</view>
<vol-form :load-key="true" ref="detail" :form-options="detailFormOptions"
:formFields.sync="detailFormFields">
</vol-form>
<view style="padding: 15px;">
<view v-show="!isAdd" style="margin-bottom: 28rpx;">
<u-button @click="showDel=true" icon="trash" type="error" shape="circle" text="删除"></u-button>
</view>
<u-button @click="addRow" icon="checkmark" type="primary" shape="circle" text="确认"></u-button>
</view>
</view>
</u-popup>
<!-- 删除提示 -->
<u-modal :show="showDel" cancelText="取消" class="del-u-modal" :showCancelButton="true" :showConfirmButton="true"
@cancel="showDel=false" @confirm="confirmDel" title="警告">
<view style="color: red;">确定要删除此数据吗!</view>
</u-modal>
</view>
</template>
<script>
export default {
data() {
return {
showDel: false, //
currentRow: {},
currendtIndex: -1, //
isAdd: false, //
orderId: null, //id
list:[{
name: '订单明细',
},{
name: '订单详情',
},{
name: '订单统计',
}],
//
editFormFields: {
"OrderType": "",
"TranNo": "",
"Qty": "",
"SellNo": ""
},
editFormOptions: [{
"key": "ordertype",
"data": [],
"title": "订单类型",
"required": true,
"field": "OrderType",
"type": "select"
},
{
"title": "Id",
"required": true,
"field": "ttt",
hidden: true
},
{
"title": "运单号",
"required": true,
"field": "TranNo"
},
{
"title": "销售数量",
"required": true,
"field": "Qty",
"type": "number"
},
{
"title": "销售订单号",
"required": true,
"field": "SellNo"
}
],
//vol-form
rows: [], //
columns: [{
field: 'OrderList_Id',
title: '明细表主键',
hidden: true
},
{
field: 'ProductName',
title: '商品名称',
type: "select",
bind: {
key: "pn",
data: []
},
},
{
field: 'MO',
title: '批次',
type: 'string',
require: true
},
{
field: 'Qty',
title: '数量',
type: 'int',
require: true
},
{
field: 'Creator',
title: '创建人',
type: 'string',
readonly: true
}
],
detailModel: false,
detailFormFields: {
ProductName: "",
MO: "",
Qty: 0
},
detailFormOptions: [{
field: 'ProductName',
title: '商品名称',
type: "select",
"data": [],
key: "pn",
},
{
field: 'MO',
title: '批次',
type: 'string',
require: true
},
{
field: 'Qty',
title: '数量',
type: 'int',
require: true
}
],
}
},
methods: {
save() { //
let url = ''
if (this.orderId) { //
url = "api/SellOrder/update"
} else {
url = "api/SellOrder/add"
}
let params = {
mainData: this.editFormFields,
detailData: this.rows
}
this.http.post(url, params, true).then(result => {
this.$toast(result.message);
if (!result.status) {
return;
}
this.getOrderData();
this.getOrderListData();
//
})
},
confirmDel() { //
let url = "api/SellOrder/delDetail?orderList_Id=" + this.currentRow.OrderList_Id;
//delDetail
// this.http.get(url,{},true).then(result=>{
// if(result.status){
this.showDel = false;
this.detailModel=false;
this.rows.splice(this.currnetDelIndex, 1);
this.$toast("删除成功");
return;
// }
// })
},
showDetailBtnClick() { //
this.isAdd = true;
this.showDetail(-1, {
ProductName: '',
MO: null,
Qty: null
});
},
rowClick(index, row) { //
this.isAdd = false;
this.showDetail(index, row);
},
showDetail(index, row) {
this.currendtIndex = index;
this.detailFormFields = JSON.parse(JSON.stringify(row));
this.detailModel = true;
},
addRow() { //
if (!this.$refs.detail.validate()) {
return false
}
//
if (this.currendtIndex != -1) {
Object.assign(this.rows[this.currendtIndex], this.detailFormFields);
} else { //
this.rows.push(this.detailFormFields);
}
this.detailModel = false
},
getOrderData() { //()
let params = {
page: 1,
row: 1
};
//
params.wheres = JSON.stringify([{
name: "Order_Id",
value: this.orderId
}]);
this.http.post("api/SellOrder/getPageData", params, true).then(result => {
Object.assign(this.editFormFields, result.rows[0])
})
},
getOrderListData() { //()
//uviewlist
let params = {
page: 1,
rows: 30
};
//
params.value = this.orderId;
this.http.post("api/SellOrder/getDetailPage", params, true).then(result => {
this.rows = result.rows;
})
}
},
onShow() {
//
let routes = getCurrentPages(); //
let params = routes[routes.length - 1].options; //
if (params && params.orderId) {
this.orderId = params.orderId;
//
this.getOrderData();
//
this.getOrderListData();
} else {
this.orderId = null;
}
uni.setNavigationBarTitle({
title: this.orderId ? '订单编辑' : '新建订单'
})
}
}
</script>
<style scoped lang="less">
.order-detail {
margin-top: -20rpx;
background: #fbfbfb;
padding-top: 20rpx;
overflow-y: scroll;
overflow-x: hidden;
}
.order-main,
.order-detail-list {
// margin: 20rpx;
border-radius: 10rpx;
}
.main-form,
.detail-form {
border: 1px solid #ebebeb;
border-bottom: 0;
border-radius: 4px;
display: inline-block;
width: 100%;
}
.title {
text-align: left;
margin: 9px 0 7px 0;
font-size: 15px;
border-left: 8px solid #00aaff;
line-height: 16px;
padding-left: 5px;
display: flex;
position: relative;
.detail-icon {
position: absolute;
width: 60rpx;
right: 0;
height: 44rpx;
}
}
.detail-form {
margin-bottom: 30rpx;
}
.detail-btns {
margin: 15rpx 8rpx;
display: flex;
.detail-btn {
margin-left: 30rpx;
}
}
</style>

@ -0,0 +1,44 @@
<template>
<view>
<view-grid ref="grid" :index="true" :options="options">
<!-- 自定义slot -->
<view @click="viewClick" slot="gridHeader" class="grid-header">
<vol-alert>
<view>点击编辑或新建跳转到主从表页面,见SellOrder.vue</view>
<view></view>
</vol-alert>
</view>
</view-grid>
</view>
</template>
<script>
//************************************************
// *Authorjxx
// *QQ283591387
// *
//************************************************
import extend from './SellOrderExtend.js'
import options from './SellOrderOptions.js';
let _options = options();
_options.extend = extend;
export default {
data() {
return {
gridHeaderText: "", //便
options: _options
}
},
onShow() {
},
methods: {
viewClick() {
//grid
console.log(this.$refs.grid.searchFormFields)
}
}
}
</script>
<style>
</style>

@ -0,0 +1,114 @@
<template>
<view class="audit-container">
<!-- 这里同样直接复制不用修改 -->
<view class="audit-form">
<view style="font-weight: bolder;padding: 20rpx;">订单信息</view>
<vol-form ref="form" :form-options.sync="formOptions" :formFields.sync="formFields">
</vol-form>
</view>
<view class="audit-action">
<!-- 6显示审批操作直接复制,2022.09.26之前的代码需要更新components文件架3 -->
<vol-audit ref="audit"></vol-audit>
</view>
</view>
</template>
<script>
export default {
data() {
return {
//4
formFields: {
"AuditStatus": "",
"AuditDate": "",
"OrderType": "",
"TranNo": "",
"Qty": "",
"SellNo": ""
},
//5SellOrderOptions.jseditFormFieldseditFormOptions
formOptions: [{
"key": "ordertype",
"data": [],
readonly: true,
"title": "订单类型",
"field": "OrderType",
"type": "select"
},
{
"title": "运单号",
readonly: true,
"field": "TranNo"
},
{
"title": "销售数量",
"field": "Qty",
readonly: true
},
{
"title": "销售订单号",
"field": "SellNo",
readonly: true
},
{
"key": "audit",
"data": [],
"title": "审核状态",
"field": "AuditStatus",
readonly: true
},
{
"title": "审核时间",
"field": "AuditDate",
readonly: true
},
]
}
},
methods: {},
onLoad(options) {
//7Order_Id
let wheres = [{
name: "Order_Id",
value: options.orderId
}]
let params = {
page: 1,
rows: 30,
wheres: JSON.stringify(wheres)
};
//7SellOrder
this.http.post('api/SellOrder/getPageData', params, true).then(result => {
if (!result.rows.length) {
this.$toast('未查到数据')
return;
}
Object.assign(this.formFields, result.rows[0]);
//
this.$nextTick(() => {
//(SellOrderOptions.js)
//
this.$refs.audit.load(options.orderId, 'SellOrder');
})
})
}
}
</script>
<style lang="less" scoped>
.audit-container {
position: absolute;
height: 100%;
width: 100%;
overflow-y: scroll;
background: #f9f9f9;
padding: 20rpx;
box-sizing: border-box;
.audit-form,
.audit-action {
border-radius: 5px;
background: #ffff;
}
}
</style>

@ -0,0 +1,96 @@
//************************************************
// *Authorjxx
// *QQ283591387
// *自定义业务逻辑扩展
//************************************************
export default function() {
return {
methods: {
onInited() { //页面参数初始化
this.height = this.height - 40;
//设置table超出换行显示
//this.textInline = false;
//设置列宽度
//this.columns[1].width = 70;
//设置table为水平显示或者list列表显示
//this.direction = 'horizontal'//list
//如果为list列表显示指定list的标题列
//this.titleField="字段";
//设置自定义格式显示
//this.columns.forEach(column=>{
// if(column.field=='字段'){
// //自定义格式化显示,在下面的formatter实现具体逻辑
// //column.formatter=true;
// //指定字段为date类型不显示时分秒
// //column.type="date";
// //设置列宽度
// //column.width = 70;
// }
// })
//页面打开时禁用加载数据
//this.load=false;
//页面打开时默认弹出查询框
//this.searchModel = true;
},
//审核操作:
//1、实现rowButtons方法返回审批按钮注意表必须有AuditStatus字段int类型
rowButtons(rowindex, row) {
//没有审核权限按钮的不显示
// let hasAudit = this.permission.some(x => {
// return x.tableName == 'SellOrder' && x.permission.indexOf('Audit') != -1
// });
// if (!hasAudit) {
// return [];
// }
//AuditStatus === 0审核中的数据
if (row.AuditStatus === 0) {
return [{
text: "审核",
type: "error",
shape: "circle"
}]
}
//返回查看审批按钮
return [{
text: "查看审核",
type: "primary",
shape: "circle"
}]
},
//2、实现rowButtons按钮点击方法并跳转到审批页面(创建一个审批页面SellOrderAduit.vue并在pages.json中添加页面配置)
//3、具体实现见SellOrderAduit.vue页面
rowButtonClick(btn, rowindex, row) {
uni.navigateTo({
url: "/pages/order/SellOrder/SellOrderAduit?orderId=" + row.Order_Id
})
},
formatter(row, column) { //自定义格式化
// if(column.field=='xx'){
// return '<a style="color:red;">' + row[column.field] + '</a>';
// }
//return row[column.field]
},
rowClick(index, row, column) { //行点击事件(默认触发编辑)
//跳转到详情页面
let url = "/pages/order/SellOrder/Detail/Detail?orderId=" + row.Order_Id;
uni.navigateTo({
url: url
})
return false;
},
gridAdd() { //点击添加跳转到详情页面
let url = "/pages/order/SellOrder/Detail/Detail";
uni.navigateTo({
url: url
})
}
}
}
}

@ -0,0 +1,35 @@
//************************************************
// *Authorjxx
// *QQ283591387
// *代码由框架生成,任何更改都可能导致被代码生成器覆盖
// *业务请在SellOrder.js中编写
//************************************************
export default function() {
return {
editFormFields: {"AuditStatus":"","AuditDate":"","OrderType":"","TranNo":"","Qty":"","SellNo":""},
editFormOptions: [{"key":"audit","data":[],"title":"审核状态","required":true,"field":"AuditStatus","type":"number"},
{"title":"审核时间","field":"AuditDate"},
{"type":"group"},
{"key":"ordertype","data":[],"title":"订单类型","required":true,"field":"OrderType","type":"select"},
{"title":"运单号","required":true,"field":"TranNo"},
{"title":"销售数量","required":true,"field":"Qty","type":"number"},
{"type":"group"},
{"title":"销售订单号","required":true,"field":"SellNo"}],
searchFormFields: {"OrderType":"","TranNo":"","SellNo":"","Qty":"","AuditStatus":"","AuditDate":""},
searchFormOptions: [{"title":"销售数量","field":"Qty","type":"number"},{"type":"group"},{"title":"运单号","field":"TranNo"},{"title":"销售订单号","field":"SellNo"},{"key":"ordertype","data":[],"title":"订单类型","field":"OrderType","type":"select"},{"type":"group"},{"key":"audit","data":[],"title":"审核状态","field":"AuditStatus","type":"select"},{"title":"审核时间","field":"AuditDate","type":"datetime"}],
columns: [{field:'OrderType',title:'',type:'int',bind:{ key:'ordertype',data:[]}},
{field:'TranNo',title:'',type:'string',link:true},
{field:'SellNo',title:'',type:'string'},
{field:'Qty',title:'',type:'int'},
{field:'AuditStatus',title:'',type:'int',bind:{ key:'audit',data:[]}},
{field:'AuditDate',title:'',type:'datetime'}],
table: {
key: 'Order_Id',
footer: "Foots",
cnName: '',
name: 'SellOrder',
url: "/SellOrder/",
sortName: "CreateDate"
}
}
}

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

Loading…
Cancel
Save