Explorar el Código

oa框架搭建

sunlupeng hace 1 año
padre
commit
e27b488268

+ 5 - 23
components/myUnits/purchaseUnit/unit.vue

@@ -1,8 +1,7 @@
 <template>
-	<view>
-		<view v-if="initIndex==2" class='my-unit'>
+	<view class='my-unit'>
 			<view class="unit-head">
-				<text style="font-weight: bold;font-size: 26upx;">{{info.name}}</text>
+				<text style="font-weight: bold;font-size: 26upx;">{{info.title}}</text>
 			</view>
 			<view class="unit-body">
 				<view style="display: flex;justify-content: center;align-items:center;">
@@ -10,30 +9,13 @@
 					<text style="margin-left: 10upx;" >{{info.status}}</text>
 				</view>
 				
-				<text style="color: gray;">{{parseTime(info.startTime)}}</text>
+				<text style="color: gray;">{{parseTime(info.time)}}</text>
 			</view>
 			<view class="unit-foot">
-				<text style="color: gray;">当前处理人</text>
-				<text style="font-weight: bold;">{{info.currentAuditUser.nickname}}</text>
+				<text style="color: gray;">{{ initIndex==2?'当前处理人':'发起人' }}</text>
+				<text style="font-weight: bold;">{{info.nickname}}</text>
 			</view>
 		</view>
-		<view v-else class='my-unit'>
-			<view class="unit-head">
-				<text style="font-weight: bold;font-size: 26upx;">{{info.processInstance.name}}</text>
-			</view>
-			<view class="unit-body">
-				<view style="display: flex;justify-content: center;align-items:center;">
-					<uni-icons type="settings" size="20"></uni-icons>
-					<text style="margin-left: 10upx;" >{{info.name}}</text>
-				</view>
-				<text style="color: gray;">{{parseTime(info.createTime)}}</text>
-			</view>
-			<view class="unit-foot">
-				<text style="color: gray;">发起人</text>
-				<text style="font-weight: bold;">{{info.processInstance.startUser.nickname}}</text>
-			</view>
-		</view>
-	</view>
     
 </template>
 	

+ 5 - 0
pages.json

@@ -71,6 +71,11 @@
     "style": {
       "navigationBarTitleText": "浏览文本"
     }
+  }, {
+    "path": "pages/oa/universal/index",
+    "style": {
+      "navigationBarTitleText": "通用审批"
+    }
   }],
   "tabBar": {
     "color": "#000000",

+ 2 - 1
pages/index.vue

@@ -189,7 +189,8 @@ export default {
       this.current = e.detail.current
     },
     changeGrid(e) {
-      this.$modal.showToast('模块建设中~')
+      // this.$modal.showToast('模块建设中~')
+      this.$tab.navigateTo('/pages/oa/universal/index')
     }
   }
 }

+ 1 - 1
pages/message/index.vue

@@ -143,7 +143,7 @@
 <style lang="scss" scoped>
 	.popup-body{
 		z-index: 99;
-		margin-bottom: 60px;
+		// margin-bottom: 60px;
 	}
 	.popup-close{
 		cursor: pointer;

+ 101 - 0
pages/oa/dataList.vue

@@ -0,0 +1,101 @@
+<template>
+	<view class='my-unit'>
+		<view class="unit-head">
+			<text style="font-weight: bold;font-size: 26upx;">{{ info.title }}</text>
+		</view>
+		<view class="unit-body">
+			<view style="display: flex;justify-content: center;align-items:center;">
+				<uni-icons type="settings" size="20"></uni-icons>
+				<text style="margin-left: 10upx;">{{ info.status }}</text>
+			</view>
+
+			<text style="color: gray;">{{ parseTime(info.time) }}</text>
+		</view>
+		<view class="unit-foot">
+			<text style="color: gray;">{{ initIndex == 2 ? '当前处理人' : '发起人' }}</text>
+			<text style="font-weight: bold;">{{ info.nickname }}</text>
+		</view>
+	</view>
+
+</template>
+
+<script>
+export default {
+	props: {
+		info: {
+			type: Object
+		},
+		initIndex: {
+			type: Number
+		}
+	},
+	data() {
+		return {
+			unitModel1: [
+				{ prop: "", label: "匹配商铺数" },
+				{ prop: "", label: "已报价商铺数" },
+				{ prop: "", label: "最新报价", class: "color-red", isMoney: true },
+				{ prop: "", label: "商品报价", class: "color-999", isMoney: true },
+				{ prop: "", label: "税点", class: "color-999" },
+				{ prop: "", label: "税费", class: "color-999", isMoney: true },
+				{ prop: "", label: "运费", class: "color-999", isMoney: true },
+			]
+		}
+	},
+	methods: {
+		doDel() {
+			this.$store.commit("switch_loading")
+		}
+	},
+	computed: {
+
+	},
+	created() {
+
+	},
+}
+</script>
+<style lang='scss'>
+.my-unit {
+	margin: 20upx 10upx;
+	background-color: #ffffff;
+	font-size: 28upx;
+	transform: all 1s;
+	border-radius: 10upx;
+	box-shadow: rgba(0, 0, 0, 0.08) 0px 0px 3;
+
+	.unit-head {
+		padding: 20upx 20upx 10upx 20upx;
+		/* height: 80upx; */
+		box-sizing: border-box;
+		/* border-bottom: 2upx solid #f5f5f5; */
+	}
+
+	.unit-body {
+		padding: 0 20upx;
+		display: flex;
+		flex-wrap: wrap;
+		justify-content: space-between;
+		align-items: center;
+
+		text {
+			font-size: 20upx;
+			line-height: 55upx;
+		}
+	}
+
+	.unit-foot {
+		height: 88upx;
+		padding: 0 20upx;
+		border-top: 2upx solid #f5f5f5;
+		border-bottom: none;
+		line-height: 88upx;
+		display: flex;
+		flex-wrap: wrap;
+
+		text {
+			width: 30%;
+		}
+	}
+}
+</style>

+ 78 - 0
pages/oa/myTabs.vue

@@ -0,0 +1,78 @@
+<template>
+	<view :class="{'my-tabs':true}">
+		<view  v-for="(item,index) in getModelData" :key="index" :class="{'tab-item':true,'active':formatIndex==index}" @tap="tap(index)">
+			{{item.label}}
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props:['initIndex'],
+		data() {
+			return {
+				getModelData:[
+					{label:"发起提交"},
+					{label:"查看数据"},
+				]
+			}
+		},
+		computed:{
+			formatIndex(){
+				return this.initIndex
+			}
+		},
+		methods: {
+			tap(index){
+				console.log("我点击了",index);
+				this.$emit("change",index);
+			}
+		}
+	}
+</script>
+<style lang='scss'>
+	.my-tabs {
+		background-color: #ffffff;
+		height: 88upx;
+		font-size: 28upx;
+		display: flex;
+		position: sticky;
+		justify-content: space-around;
+		box-sizing: border-box;
+		// border-top: 2upx solid #dddddd;
+		border-bottom: 2upx solid #dddddd;
+		min-width: 100%;
+		overflow-x: auto;
+		
+		.tab-item{
+			color: gray;
+			line-height: 48upx;
+			padding: 20upx;
+			min-width: 100upx;
+			text-align: center;
+		}
+		.tab-item.active{
+			position: relative;
+			color: black;
+			font-weight: bold;
+		}
+		.tab-item.active::after{
+			content: "";
+			position: absolute;
+			bottom: 0;
+			left:50%;
+			transform: translateX(-50%);
+			width: 100%;
+			border-bottom: 4upx solid black;
+			animation: test ease 1 1.5s;
+		}
+	}
+	.my-tabs.space-between{
+		justify-content: space-between;
+	}
+	@keyframes test{
+		0%{width: 100%}
+		50%{width: 150%}
+		100%{width: 100%}
+	}
+</style>

+ 355 - 0
pages/oa/universal/formCreate.vue

@@ -0,0 +1,355 @@
+<template>
+	<view class="container">
+		<uni-card :is-shadow="false" is-full>
+			<text class="uni-h6">uni-forms 组件一般由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据。</text>
+		</uni-card>
+		<uni-section title="基本用法" type="line">
+			<view class="example">
+				<!-- 基础用法,不包含校验规则 -->
+				<uni-forms ref="baseForm" :model="baseFormData" labelWidth="80px">
+					<uni-forms-item label="姓名" required>
+						<uni-easyinput v-model="baseFormData.name" placeholder="请输入姓名" />
+					</uni-forms-item>
+					<uni-forms-item label="年龄" required>
+						<uni-easyinput v-model="baseFormData.age" placeholder="请输入年龄" />
+					</uni-forms-item>
+					<uni-forms-item label="性别" required>
+						<uni-data-checkbox v-model="baseFormData.sex" :localdata="sexs" />
+					</uni-forms-item>
+					<uni-forms-item label="兴趣爱好" required>
+						<uni-data-checkbox v-model="baseFormData.hobby" multiple :localdata="hobbys" />
+					</uni-forms-item>
+					<uni-forms-item label="自我介绍">
+						<uni-easyinput type="textarea" v-model="baseFormData.introduction" placeholder="请输入自我介绍" />
+					</uni-forms-item>
+					<uni-forms-item label="日期时间">
+						<uni-datetime-picker type="datetime" return-type="timestamp"
+							v-model="baseFormData.datetimesingle" />
+					</uni-forms-item>
+					<uni-forms-item label="选择城市">
+						<uni-data-picker v-model="baseFormData.city" :localdata="cityData" popup-title="选择城市">
+						</uni-data-picker>
+					</uni-forms-item>
+
+					<uni-forms-item label="选择技能">
+						<uni-data-select v-model="baseFormData.skills" :localdata="skillsRange" >
+						</uni-data-select>
+					</uni-forms-item>
+				</uni-forms>
+			</view>
+		</uni-section>
+
+		<uni-section title="对齐方式" type="line">
+			<view class="example">
+				<view class="segmented-control">
+					<uni-segmented-control :current="current" :values="items" @clickItem="onClickItem"
+						styleType="button">
+					</uni-segmented-control>
+				</view>
+				<!-- 展示不同的排列方式 -->
+				<uni-forms ref="baseForm" :modelValue="alignmentFormData" :label-position="alignment">
+					<uni-forms-item label="姓名" required>
+						<uni-easyinput v-model="baseFormData.name" placeholder="请输入姓名" />
+					</uni-forms-item>
+					<uni-forms-item label="年龄" required>
+						<uni-easyinput v-model="baseFormData.age" placeholder="请输入年龄" />
+					</uni-forms-item>
+				</uni-forms>
+			</view>
+		</uni-section>
+
+		<uni-section title="表单校验" type="line">
+			<view class="example">
+				<!-- 基础表单校验 -->
+				<uni-forms ref="valiForm" :rules="rules" :model="valiFormData" labelWidth="80px">
+					<uni-forms-item label="姓名" required name="name">
+						<uni-easyinput v-model="valiFormData.name" placeholder="请输入姓名" />
+					</uni-forms-item>
+					<uni-forms-item label="年龄" required name="age">
+						<uni-easyinput v-model="valiFormData.age" placeholder="请输入年龄" />
+					</uni-forms-item>
+					<uni-forms-item label="自我介绍">
+						<uni-easyinput type="textarea" v-model="valiFormData.introduction" placeholder="请输入自我介绍" />
+					</uni-forms-item>
+				</uni-forms>
+				<button type="primary" @click="submit('valiForm')">提交</button>
+			</view>
+		</uni-section>
+
+		<uni-section title="自定义校验规则" type="line">
+			<view class="example">
+				<!-- 自定义表单校验 -->
+				<uni-forms ref="customForm" :rules="customRules" labelWidth="80px" :modelValue="customFormData">
+					<uni-forms-item label="姓名" required name="name">
+						<uni-easyinput v-model="customFormData.name" placeholder="请输入姓名" />
+					</uni-forms-item>
+					<uni-forms-item label="年龄" required name="age">
+						<uni-easyinput v-model="customFormData.age" placeholder="请输入年龄" />
+					</uni-forms-item>
+					<uni-forms-item label="兴趣爱好" required name="hobby">
+						<uni-data-checkbox v-model="customFormData.hobby" multiple :localdata="hobbys" />
+					</uni-forms-item>
+				</uni-forms>
+				<button type="primary" @click="submit('customForm')">提交</button>
+			</view>
+		</uni-section>
+
+
+		<uni-section title="动态表单" type="line">
+			<view class="example">
+				<!-- 动态表单校验 -->
+				<uni-forms ref="dynamicForm" :rules="dynamicRules" :model="dynamicFormData" labelWidth="80px">
+					<uni-forms-item label="邮箱" required name="email">
+						<uni-easyinput v-model="dynamicFormData.email" placeholder="请输入姓名" />
+					</uni-forms-item>
+					<uni-forms-item v-for="(item,index) in dynamicFormData.domains" :key="item.id"
+						:label="item.label+' '+index" required :rules="item.rules" :name="['domains',index,'value']">
+						<view class="form-item">
+							<uni-easyinput v-model="dynamicFormData.domains[index].value" placeholder="请输入域名" />
+							<button class="button" size="mini" type="default" @click="del(item.id)">删除</button>
+						</view>
+					</uni-forms-item>
+				</uni-forms>
+				<view class="button-group">
+					<button type="primary" size="mini" @click="add">新增域名</button>
+					<button type="primary" size="mini" @click="submit('dynamicForm')">提交</button>
+				</view>
+			</view>
+		</uni-section>
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				// 基础表单数据
+				baseFormData: {
+					name: '',
+					age: '',
+					introduction: '',
+					sex: 2,
+					hobby: [5],
+					datetimesingle: 1627529992399,
+					city: '',
+					skills: 0
+				},
+				// 城市数据
+				cityData: [{
+					text: "北京",
+					value: "10001",
+				}, {
+					text: "上海",
+					value: "10002",
+				}, {
+					text: "深圳",
+					value: "10004",
+				}],
+				skillsRange: [{
+						value: 0,
+						text: "编程"
+					},
+					{
+						value: 1,
+						text: "绘画"
+					},
+					{
+						value: 2,
+						text: "运动"
+					},
+				],
+				// 表单数据
+				alignmentFormData: {
+					name: '',
+					age: '',
+				},
+				// 单选数据源
+				sexs: [{
+					text: '男',
+					value: 0
+				}, {
+					text: '女',
+					value: 1
+				}, {
+					text: '保密',
+					value: 2
+				}],
+				// 多选数据源
+				hobbys: [{
+					text: '跑步',
+					value: 0
+				}, {
+					text: '游泳',
+					value: 1
+				}, {
+					text: '绘画',
+					value: 2
+				}, {
+					text: '足球',
+					value: 3
+				}, {
+					text: '篮球',
+					value: 4
+				}, {
+					text: '其他',
+					value: 5
+				}],
+				// 分段器数据
+				current: 0,
+				items: ['左对齐', '顶部对齐'],
+				// 校验表单数据
+				valiFormData: {
+					name: '',
+					age: '',
+					introduction: '',
+				},
+				// 校验规则
+				rules: {
+					name: {
+						rules: [{
+							required: true,
+							errorMessage: '姓名不能为空'
+						}]
+					},
+					age: {
+						rules: [{
+							required: true,
+							errorMessage: '年龄不能为空'
+						}, {
+							format: 'number',
+							errorMessage: '年龄只能输入数字'
+						}]
+					}
+				},
+				// 自定义表单数据
+				customFormData: {
+					name: '',
+					age: '',
+					hobby: []
+				},
+				// 自定义表单校验规则
+				customRules: {
+					name: {
+						rules: [{
+							required: true,
+							errorMessage: '姓名不能为空'
+						}]
+					},
+					age: {
+						rules: [{
+							required: true,
+							errorMessage: '年龄不能为空'
+						}]
+					},
+					hobby: {
+						rules: [{
+								format: 'array'
+							},
+							{
+								validateFunction: function(rule, value, data, callback) {
+									if (value.length < 2) {
+										callback('请至少勾选两个兴趣爱好')
+									}
+									return true
+								}
+							}
+						]
+					}
+
+				},
+				dynamicFormData: {
+					email: '',
+					domains: []
+				},
+				dynamicLists: [],
+				dynamicRules: {
+					email: {
+						rules: [{
+							required: true,
+							errorMessage: '域名不能为空'
+						}, {
+							format: 'email',
+							errorMessage: '域名格式错误'
+						}]
+					}
+				}
+			}
+		},
+		computed: {
+			// 处理表单排列切换
+			alignment() {
+				if (this.current === 0) return 'left'
+				if (this.current === 1) return 'top'
+				return 'left'
+			}
+		},
+		onLoad() {},
+		onReady() {
+			// 设置自定义表单校验规则,必须在节点渲染完毕后执行
+			this.$refs.customForm.setRules(this.customRules)
+		},
+		methods: {
+			onClickItem(e) {
+				console.log(e);
+				this.current = e.currentIndex
+			},
+			add() {
+				this.dynamicFormData.domains.push({
+					label: '域名',
+					value: '',
+					rules: [{
+						'required': true,
+						errorMessage: '域名项必填'
+					}],
+					id: Date.now()
+				})
+			},
+			del(id) {
+				let index = this.dynamicLists.findIndex(v => v.id === id)
+				this.dynamicLists.splice(index, 1)
+			},
+			submit(ref) {
+				console.log(this.baseFormData);
+				this.$refs[ref].validate().then(res => {
+					console.log('success', res);
+					uni.showToast({
+						title: `校验通过`
+					})
+				}).catch(err => {
+					console.log('err', err);
+				})
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.example {
+		padding: 15px;
+		background-color: #fff;
+	}
+
+	.segmented-control {
+		margin-bottom: 15px;
+	}
+
+	.button-group {
+		margin-top: 15px;
+		display: flex;
+		justify-content: space-around;
+	}
+
+	.form-item {
+		display: flex;
+		align-items: center;
+		flex: 1;
+	}
+
+	.button {
+		display: flex;
+		align-items: center;
+		height: 35px;
+		line-height: 35px;
+		margin-left: 10px;
+	}
+</style>

+ 92 - 0
pages/oa/universal/index.vue

@@ -0,0 +1,92 @@
+<template>
+	<view class='purchase-list'>
+		<my-tabs @change="tapChange" :initIndex="initIndex"></my-tabs>
+		<scroll-view class="purchase-body" scroll-y="true" @scrolltolower="scrolltolower" @scroll="scroll">
+			<view v-if="initIndex === 0">
+				<form-Create></form-Create>
+			</view>
+			<view v-if="initIndex === 1">
+				<data-List v-for="(item,index) in listData" :key="index" :info="item"></data-List>
+			</view>
+			
+		</scroll-view>
+	</view>
+</template>
+<script>
+	import { getTodoTaskPage, getDoneTaskPage,getMyProcessInstancePage } from "@/api/work/index"
+	import myTabs from '../myTabs.vue'
+	import dataList from '../dataList.vue'
+	import formCreate from './formCreate.vue'
+	import myPull from '@/static/js/myPull.js'
+	export default {
+		components:{myTabs,dataList,formCreate},
+		data() {
+			return {
+				initIndex: 0,
+				pageNo: 1,
+				pageSize: 10
+			}
+		},
+		onLoad(){
+			this.refresh();
+		},
+		methods: {
+			/**
+			 * @name 获取列表
+			 */
+			getList(page,done){
+				console.log(`获取第${page}页数据`);
+				if(this.initIndex==1){
+					getDoneTaskPage({pageNo:page,pageSize: this.pageSize}).then(response => {
+						let dataList = response.data.list;
+						let list = []
+						dataList.forEach(v => {
+							list.push({
+								title:v.processInstance.name,
+								status: v.name,
+								time:v.createTime,
+								nickname:v.processInstance.startUser.nickname
+							})
+						})
+						done(list);
+					});
+				}
+			},
+			
+			/**
+			 * @name 触底加载
+			 */
+			scrolltolower(event){
+				this.getList(this.page,this.__pulldone)
+			},
+			
+			scroll(e){
+				// 重新设置pulldown
+				this.setPullDown(e.detail.scrollTop<10)
+			},
+			/**
+			 * @name 改变tab
+			 * @param val 索引
+			 */
+			tapChange(val){
+				this.initIndex=val;
+				this.page = 1;
+				this.getList(this.page,this.__pulldone)
+			}
+		},
+		mixins:[myPull({})],
+		
+	}
+</script>
+<style lang='scss' scoped>
+	.purchase-list {
+		background-color: #f5f5f5;
+		height: 100%;
+		overflow: hidden;
+		
+		.purchase-body{
+			height: calc(100% - 88upx);
+			overflow: auto
+		}
+	}
+</style>

+ 30 - 3
pages/work/index.vue

@@ -30,19 +30,46 @@
 				console.log(`获取第${page}页数据`);
 				if(this.initIndex==0){
 					getTodoTaskPage({pageNo:page,pageSize: this.pageSize}).then(response => {
-						let list = response.data.list;
+						let dataList = response.data.list;
+						let list = []
+						dataList.forEach(v => {
+							list.push({
+								title:v.processInstance.name,
+								status: v.name,
+								time:v.createTime,
+								nickname:v.processInstance.startUser.nickname
+							})
+						})
 						done(list);
 					});
 				}
 				if(this.initIndex==1){
 					getDoneTaskPage({pageNo:page,pageSize: this.pageSize}).then(response => {
-						let list = response.data.list;
+						let dataList = response.data.list;
+						let list = []
+						dataList.forEach(v => {
+							list.push({
+								title:v.processInstance.name,
+								status: v.name,
+								time:v.createTime,
+								nickname:v.processInstance.startUser.nickname
+							})
+						})
 						done(list);
 					});
 				}
 				if(this.initIndex==2){
 					getMyProcessInstancePage({pageNo:page,pageSize: this.pageSize}).then(response => {
-						let list = response.data.list;
+						let dataList = response.data.list;
+						let list = []
+						dataList.forEach(v => {
+							list.push({
+								title:v.name,
+								status: v.status,
+								time:v.startTime,
+								nickname:v.currentAuditUser.nickname
+							})
+						})
 						done(list);
 					});
 				}