初始化

This commit is contained in:
hezhidong
2025-03-28 09:19:45 +08:00
parent a920f6f06a
commit 91514490ea
25 changed files with 7952 additions and 0 deletions
+27
View File
@@ -0,0 +1,27 @@
node_modules
.DS_Store
/dist
unpackage
uni_modules
# local env files
.env.local
.env.*.local
.env.development
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
.env.development
+20
View File
@@ -0,0 +1,20 @@
{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
"version": "0.0",
"configurations": [{
"default" :
{
"launchtype" : "local"
},
"mp-alipay" :
{
"launchtype" : "local"
},
"mp-weixin" :
{
"launchtype" : "local"
},
"type" : "uniCloud"
}
]
}
+25
View File
@@ -0,0 +1,25 @@
<script>
export default {
onLaunch: function() {
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
},
onHide: function() {
console.log('App Hide')
}
}
</script>
<style>
/*每个页面公共css */
html,body,page{
width: 100%;
height: 100%;
font-size: 28rpx;
}
image{
display: block;
}
</style>
+4
View File
@@ -0,0 +1,4 @@
const baseUrl = "http://192.168.31.166:8189"
// const baseUrl = "http://192.168.31.166:8188"
export default baseUrl
+25
View File
@@ -0,0 +1,25 @@
/*首页*/
import { request } from "./index.js";
// 登录
export function getToken(code){
return request({
method: "get",
url: "/user/getToken",
data: {
code
},
Header1: {
}
})
}
// 创建工单
export function postCreatOrder(data){
return request({
method: "post",
url: "creatOrder/add",
data
})
}
+44
View File
@@ -0,0 +1,44 @@
// const baseUrl = "https://pandamimi.lzyyj.com/prod-api";
// const baseUrl = "http://192.168.31.121:9221";
import baseUrl from "./baseUrl.js"
// const baseUrl = bootUrl
export function request ( optaions ) {
let { url, method, data, header1 } = optaions
method = method || "GET"
data = data || {}
header1 = header1 || {
Authorization: uni.getStorageSync('token')
}
// console.log(com.getCacheToken("userInfo").token)
return new Promise((reslove,reject)=>{
uni.request({
url: baseUrl + url,
method,
header: header1,
data,
success: (res) => {
if(res.data.code == 401 ){
uni.showToast({ title: '登录已失效,请重新登录!', icon: 'none' });
uni.removeStorageSync('userInfo');
uni.removeStorageSync('token');
setTimeout(()=>{
uni.navigateTo({ url: '/pages/user/login' });
}, 1000);
}else if(res.data.code != 200){
reject(res)
uni.showToast({ title: res.data.msg, icon: 'none', duration: 2000 });
}else {
reslove(res.data)
}
},
fail: () => {
reject()
},
complete: () => {
uni.hideLoading()
}
})
})
}
+42
View File
@@ -0,0 +1,42 @@
import baseUrl from "./baseUrl.js"
export function uploadImage (urls,) {
return new Promise( (resovle, reject) =>{
let urlArr = []
for(let i = 0; i < urls.length; i ++){
uni.uploadFile({
url: baseUrl + '/file/upload',
fileName: 'file',
header: {
'content-type': 'multipart/form-data'
},
fileType: "image", // 必填
filePath: urls[i],
success: (res) => {
urlArr.push(res.data)
if( urls.length == urlArr.length){
uni.hideLoading();
uni.showToast({ title: '上传成功', icon: 'success', duration: 2000 });
resovle(urlArr)
}
},
fail: (err) =>{
console.log('--------')
console.log(err)
uni.showToast({ title: '上传失败', icon: 'error', duration: 2000 });
uni.hideLoading();
uni.showModal({
title: '提示',
content: err.msg,
});
resovle([])
},
complete: () => {
}
});
}
})
}
+47
View File
@@ -0,0 +1,47 @@
/*个人中心接口*/
import { request } from "../index.js";
import com from '../../common/common.js'
/**
* 微信一键登录接口
*/
export function login(code){
return request({
method: "get",
url: "/ntcp/wx/getSession",
data: {
code
},
})
}
export function postLogin(code){
return request({
method: "post",
url: "/ntcp/wx/wxLogin",
data: {
code,
appId:'wx42775ea6c049670e'
},
})
}
//
// 上传用户头像
export function postAvataro(avatar){
return request({
method: "get",
url: "/ntcp/volunteer/updateAvatar",
data: {
avatar
}
})
}
// 获取用户信息 ntcp/volunteer/selfInfo
export function getUser(){
return request({
method: "get",
url: "/ntcp/volunteer/selfInfo"
})
}
+164
View File
@@ -0,0 +1,164 @@
/*
表单验证
form为表单
rules为需要验证的表单
rules:{ name: '请输入名称' } name为需要验证的字段
*/
export function rulesFun(form, rules) {
console.log('-------------------------------')
let flage = true
let JSONrules = JSON.stringify(rules)
if (JSONrules !== JSON.stringify({})) {
for (let key in rules) {
if (Array.isArray(form[key]) && form[key].length == 0) {
uni.showToast({
title: rules[key],
})
flage = false
break;
} else if (!form[key] && form[key] !== 0) {
uni.showToast({
title: rules[key],
})
flage = false
break;
}
}
}
return flage
}
/* 手机号验证 */
export function rulesPhone(phoneVal) {
let phoneReg = /(^1\d{10}$)|(^[0-9]\d{7}$)/;
if (!phoneReg.test(phoneVal)) {
uni.showToast({
title: '请输入正确的手机号',
})
return false;
} else {
return true
}
}
/* 身份证验证 */
export function rulesIdCard(IdcardVal) {
var idCardReg = /^(\d{15}$|^\d{18}$|^\d{17}(\d|X|x))$/;
if (!idCardReg.test(IdcardVal)) {
uni.showToast({
title: '身份证号码格式错误!',
})
return false;
} else {
return true
}
}
// 计算
export function calculator(startNum, endNum, operator = '+') {
if (operator == '+') {
return (Number(startNum * 1000) + Number(endNum * 1000)) / 1000
} else if (operator == '-') {
return (Number(startNum * 1000) - Number(endNum * 1000)) / 1000
} else if (operator == '/') {
return (Number(startNum * 1000) / Number(endNum * 1000)) / 1000
} else if (operator == '*') {
return (Number(startNum * 1000) * Number(endNum * 1000)) / 1000
}
}
// timeStr表示时间 separator表示分隔符 type == yaer表示只返回年月日
export function formatDate(timeStr = (new Date()), separator = '-', type) {
const date = new Date(timeStr)
let yaer = date.getFullYear()
let month = date.getMonth() + 1
let day = date.getDate()
let hour = date.getHours()
let minute = date.getMinutes()
let second = date.getSeconds()
if (type == 'year') {
return yaer + separator + month + separator + day
} else {
return yaer + separator + month + separator + day + ' ' + hour + ':' + minute + ':' + second
}
}
// 从解析jwt token里面的信息
function base64Decode(input) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
let str = input.replace(/=+$/, '');
let output = '';
if (str.length % 4 === 1) {
throw new Error("'atob' failed: The string to be decoded is not correctly encoded.");
}
for (let bc = 0, bs, buffer, i = 0; (buffer = str.charAt(i++)); ~buffer &&
(bs = bc % 4 ? bs * 64 + buffer : buffer,
bc++ % 4) ?
output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0) {
buffer = chars.indexOf(buffer);
}
return output;
}
export function parseJWT(token) {
const parts = token.split('.');
if (parts.length !== 3) {
throw new Error('Invalid JWT token');
}
const payload = parts[1];
const decoded = JSON.parse(
decodeURIComponent(
base64Decode(payload.replace(/-/g, '+').replace(/_/g, '/').replace(/\s/g, ''))
.split('')
.map(c =>
`%${('00' + c.charCodeAt(0).toString(16)).slice(-2)}`
)
.join('')
)
);
return decoded;
}
// 防抖函数确保在一定时间内只触发一次点击事件
// fn: 要执行的函数
// delay: 防抖的时间间隔(单位为毫秒,默认为500ms)
export function debounce(fn, delay = 500, immediate = false) {
let timer = null;
return function (...args) {
const context = this;
if (timer) clearTimeout(timer);
if (immediate) {
// 如果立即执行,那么只在第一次触发时执行
const callNow = !timer;
if (callNow) fn.apply(context, args);
// 设置一个延迟的定时器,后续的触发将被防抖处理
timer = setTimeout(() => {
timer = null;
}, delay);
} else {
// 非立即执行模式,按普通防抖逻辑
timer = setTimeout(() => {
fn.apply(context, args);
}, delay);
}
};
}
// 节流函数限制按钮在一段时间内只触发一次(而不是点击结束后再延时执行)
// 节流函数
export function throttle(fn, delay = 1000) {
let last = 0;
return function (...args) {
const now = Date.now();
if (now - last > delay) {
last = now;
fn.apply(this, args);
}
};
}
+43
View File
@@ -0,0 +1,43 @@
import { encryptDes , decryptDes } from "./cryptoJs.js" //des加密 解密
export default {
/*设置本地缓存 返回加密后的值*/
setCacheToken(key, value){
//转为json字符串
var info = JSON.stringify(value);
try {
uni.setStorageSync(key, encryptDes(info,key))
return {info:"保存成功", status:1}
} catch (error) {
return {info:error, status:0}
}
},
/*获取本地缓存 返回解密后的值*/
getCacheToken(key){
var info = decryptDes(uni.getStorageSync(key),key)
//json字符串长度
if(Object.keys(info).length > 1){
//json转为对象数组
return JSON.parse(info)
}
return info
},
/**
* 是否登录
* @param {bool} isToNav 是否跳转
*/
isLogin(isToNav){
isToNav = isToNav || false
//用户信息
const userInfo = this.getCacheToken("userInfo")
//如果未登录, 跳转到登录
if(!userInfo){
uni.showToast({ title: "请登陆后操作", icon: "none" });
if(isToNav){
setTimeout(()=>{uni.reLaunch({ url: "/pages/user/user" })}, 1000)
}
return false
}
return true
}
}
+25
View File
@@ -0,0 +1,25 @@
//import CryptoJS from '@/../node_modules/crypto-js/crypto-js.js'
import CryptoJS from "./js/crypto-js.js";
// DES加密
export const encryptDes = (message, key) => {
const keyHex = CryptoJS.enc.Utf8.parse(key);
const encrypted = CryptoJS.DES.encrypt(message, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
// DES解密
export const decryptDes = (ciphertext, key) => {
const keyHex = CryptoJS.enc.Utf8.parse(key);
// direct decrypt ciphertext
const decrypted = CryptoJS.DES.decrypt({
ciphertext: CryptoJS.enc.Base64.parse(ciphertext)
}, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
File diff suppressed because it is too large Load Diff
+94
View File
@@ -0,0 +1,94 @@
<!-- label 为字段名 -->
<!-- isBorder 是否有边框 默认 true有-->
<template>
<!-- 因为之前钉钉之前的那个不能用着改装了一下微信小程序选择日期组件使用 -->
<view class="input-box" :class="isBorder ? '' : 'border-none'">
<view class="label"><text class="tex">*</text> {{label}}</view>
<view @click="onClickDate" class="date-box">
<view v-if="value" class="time">{{value}}</view>
<view v-else class="time placeholder">请选择{{label}}</view>
<image class="img" src="../../static/jiantou.png"></image>
</view>
<DateText ref="dateTime" :value="sea" :isAll="true" :current="true" @confirm="onConfirm">1212121</DateText>
</view>
</template>
<script>
import { watch } from "vue";
export default {
props: {
value: {
default: ''
},
isBorder: {
default: true
},
label:{
default: '时间'
}
},
data() {
return {
sea: ''
};
},
methods: {
// 点击打开选择日期
onClickDate () {
this.$refs.dateTime.show()
},
onConfirm(e) {
this.$emit('input', e.selectRes)
}
}
}
</script>
<style lang='scss' scoped>
.input-box{
width: 100%;
height: 100rpx;
background: #fff;
padding: 0 16rpx;
box-sizing: border-box;
display: flex;
align-items: center;
font-size: 28rpx;
border-bottom: 2rpx dashed #D9D9D9;
.label{
width: 200rpx;
line-height: 40rpx;
display: flex;
.tex{
display: block;
width: 14rpx;
color: #E14343;
margin-right: 8rpx;
line-height: 40rpx;
}
}
.date-box{
flex: 1;
width: 100%;
height: 100rpx;
display: flex;
justify-content: flex-end;
align-items: center;
.img{
width: 32rpx;
height: 32rpx;
margin-left: 4rpx;
}
.placeholder{
color: #999999;
}
}
}
.border-none{
border: none;
}
</style>
+513
View File
@@ -0,0 +1,513 @@
<template>
<view class="yu-datetime-picker">
<view class="yu-datetime-mask" :class="{'show':showPicker}" @tap="maskClick" @touchmove.stop.prevent catchtouchmove="true"></view>
<view class="yu-datetime-content" :class="{'show':showPicker}">
<view class="yu-datetime-hd" @touchmove.stop.prevent catchtouchmove="true">
<view class="yu-datetime-btn" @tap="pickerCancel">取消</view>
<view class="yu-datetime-btn" :style="{color: color}" @tap="pickerConfirm">确定</view>
</view>
<view class="yu-datetime-view">
<picker-view class="picker-view" v-if="isAll" :indicator-style="itemHeight" :value="values" @change="bindChange">
<picker-view-column>
<view class="yu-datetime-item" v-for="(item,index) in dateObj.years" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="yu-datetime-item" v-for="(item,index) in dateObj.months" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="yu-datetime-item" v-for="(item,index) in dateObj.days" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="yu-datetime-item" v-for="(item,index) in dateObj.hours" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="yu-datetime-item" v-for="(item,index) in dateObj.minutes" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="yu-datetime-item" v-for="(item,index) in dateObj.seconds" :key="index">{{item}}</view>
</picker-view-column>
</picker-view>
<picker-view v-else :indicator-style="itemHeight" :value="dateValues" @change="bindDateChange">
<picker-view-column class="yu-picker-column">
<view class="yu-datetime-item" v-for="(item,index) in dateObj.dates" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="yu-datetime-item" v-for="(item,index) in dateObj.hours" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="yu-datetime-item" v-for="(item,index) in dateObj.minutes" :key="index">{{item}}</view>
</picker-view-column>
<picker-view-column>
<view class="yu-datetime-item" v-for="(item,index) in dateObj.seconds" :key="index">{{item}}</view>
</picker-view-column>
</picker-view>
</view>
</view>
</view>
</template>
<script>
export default {
name: "yuDatetimePicker",
props: {
isAll: { //全部日期有效可选
type: Boolean,
default () {
return true
}
},
current: { //默认显示当前日期时间
type: Boolean,
default () {
return true
}
},
color: { //颜色
type: String,
default () {
return '#3279e4'
}
},
startYear: { //开始年份
type: [String, Number],
default () {
return new Date().getFullYear()
}
},
endYear: { //结束年份
type: [String, Number],
default () {
return '2050'
}
},
value: { //设置默认日期时间,优先级高于current
type: String,
default () {
return ''
}
}
},
data() {
let date = new Date()
let year = date.getFullYear()
let month = date.getMonth() + 1
let day = date.getDate()
let hour = date.getHours()
let minute = date.getMinutes()
let second = date.getSeconds()
let dates = []
let months = []
let years = []
let days = []
let hours = []
let minutes = []
let seconds = []
for (let i = month; i <= month + 2; i++) {//获取包括当前月份在内的3个月内的日期
let localMonth = i;
let localYear = year;
if (i == 13) {
localYear += 1;
}
if (i >= 13) {
localMonth -= 12;
}
let total = new Date(localYear, localMonth, 0).getDate();
if (i == month) {
for (let j = day; j <= total; j++) {
let m = localMonth;
let d = j;
if(localMonth < 10){ m = '0' + m;}
if(j < 10){ d = '0' + d;}
let str = year + '-' + m + '-' + d;
dates.push(str);
}
} else {
for (let j = 1; j <= total; j++) {
let m = localMonth;
let d = j;
if(localMonth < 10){ m = '0' + m;}
if(j < 10){ d = '0' + d;}
let str = localYear + '-' + m + '-' + d;
dates.push(str);
}
}
}
for (let i = parseInt(this.startYear); i <= this.endYear; i++) {
years.push(i)
}
for (let i = 1; i <= 12; i++) {
let str = i;
if(i < 10){ str = '0' + str;}
else{str = '' + str;}
months.push(str)
}
if(this.value){
let valueArr = this.value.split(' ');
let valueDateArr = valueArr[0].split('-');
let totalCurrent = new Date(valueDateArr[0], valueDateArr[1], 0).getDate();
for (let i = 1; i <= totalCurrent; i++) {
let str = i;
if(i < 10){ str = '0' + str;}
else{str = '' + str;}
days.push(str)
}
}else{
let totalCurrent = new Date(year, month, 0).getDate();
for (let i = 1; i <= totalCurrent; i++) {
let str = i;
if(i < 10){ str = '0' + str;}
else{str = '' + str;}
days.push(str)
}
}
for (let i = 0; i < 24; i++) {
let str = i;
if(i < 10){ str = '0' + str;}
else{str = '' + str;}
hours.push(str);
}
for (let i = 0; i < 60; i++) {
let str = i;
if(i < 10){ str = '0' + str;}
else{str = '' + str;}
minutes.push(str);
}
for (let i = 0; i < 60; i++) {
let str = i;
if(i < 10){ str = '0' + str;}
else{str = '' + str;}
seconds.push(str);
}
let dateObj = {
dates,
years,
months,
days,
hours,
minutes,
seconds
}
return {
year,
month,
day,
hour,
minute,
second,
dateObj,
itemHeight: `height: ${uni.upx2px(88)}px;`,
values: [0, 0, 0, 0, 0, 0],
selectArr: [],
selectRes: "",
showPicker: false,
dateValues: [0, 0, 0, 0]
};
},
mounted() {
this.initDate();
if(!this.value && this.current) {
this.showCurrent();
}
},
methods: {
initDate() {
let _this =this;
//解析默认显示的日期时间
if (_this.value) {
let values = [0, 0, 0, 0, 0, 0];
let dateValues = [0, 0, 0, 0];
let valueStr = _this.value;
let valueArr = valueStr.split(' ');
let valueDateArr = valueArr[0].split('-');
let valueTimeArr = valueArr[1].split(':');
if (_this.isAll) {
values[0] = (valueDateArr[0] - _this.startYear) > 0 ? valueDateArr[0] - _this.startYear : 0;
values[1] = parseInt(valueDateArr[1]) - 1;
values[2] = parseInt(valueDateArr[2]) - 1;
values[3] = parseInt(valueTimeArr[0]);
values[4] = parseInt(valueTimeArr[1]);
values[5] = parseInt(valueTimeArr[2]);
_this.$nextTick(() => {
_this.values = values;
})
if ((valueDateArr[0] - _this.startYear) >= 0) {
_this.selectArr = [valueDateArr[0], valueDateArr[1], valueDateArr[2], valueTimeArr[0], valueTimeArr[1],valueTimeArr[2]];
_this.selectRes = _this.value;
} else {
_this.selectArr = [_this.formatNum(_this.startYear), valueDateArr[1], valueDateArr[2], valueTimeArr[0],valueTimeArr[1], valueTimeArr[2]];
_this.selectRes = `${this.formatNum(_this.startYear)+'-'+valueDateArr[1]+'-'+valueDateArr[2]+' '+valueTimeArr[0]+':'+valueTimeArr[1]+':'+valueTimeArr[2]}`;
}
} else {
let str = valueDateArr.join('');
let localStr = _this.formatNum(_this.year) + _this.formatNum(_this.month) + _this.formatNum(_this.day) + '';
if (str < localStr) {
dateValues[0] = 0;
_this.selectArr = [_this.formatNum(_this.year), _this.formatNum(_this.month), _this.formatNum(_this.day), valueTimeArr[0],valueTimeArr[1], valueTimeArr[2]];
_this.selectRes =`${_this.formatNum(_this.year)+'-' + _this.formatNum(_this.month) + '-' + _this.formatNum(_this.day) + ' ' + valueTimeArr[0] +':'+valueTimeArr[1] +':'+valueTimeArr[2]}`;
} else {
let num = 0; //计算默认日期和当前日期相隔天数,计算下标
let start = _this.formatNum(_this.year) + '-' + _this.formatNum(_this.month) + '-' + _this.formatNum(_this.day);
let res = _this.getBetweenDateStr(start, valueArr[0]);
dateValues[0] = res.length - 1;
_this.selectArr = [valueDateArr[0], valueDateArr[1], valueDateArr[2], valueTimeArr[0], valueTimeArr[1],valueTimeArr[2]];
_this.selectRes = _this.value;
}
dateValues[1] = parseInt(valueTimeArr[0]);
dateValues[2] = parseInt(valueTimeArr[1]);
dateValues[3] = parseInt(valueTimeArr[2]);
_this.$nextTick(() => {
_this.dateValues = dateValues;
});
}
return;
}
if (_this.isAll) {
_this.selectArr = [_this.formatNum(_this.startYear), '01', '01', '00', '00', '00'];
_this.selectRes = `${_this.formatNum(_this.startYear)+'-01-01 00:00:00'}`;
} else {
_this.selectArr = [_this.formatNum(_this.year), _this.formatNum(_this.month), '01', '00', '00', '00'];
_this.selectRes = `${_this.formatNum(_this.year)+'-' + _this.formatNum(_this.month) + '-01 00:00:00'}`;
}
},
showCurrent() { //显示当前的日期时间
let arr = [0, 0, 0, 0, 0, 0];
let dateArr = [0, 0, 0, 0];
this.selectArr = [this.formatNum(this.year), this.formatNum(this.month), this.formatNum(this.day), this.formatNum(this.hour), this.formatNum(this.minute), this.formatNum(this.second)];
this.selectRes = `${this.formatNum(this.year)+'-'+this.formatNum(this.month)+'-'+this.formatNum(this.day)+' '+this.formatNum(this.hour)+':'+this.formatNum(this.minute)+':'+this.formatNum(this.second)}`;
if (this.isAll) {
arr[0] = this.year - this.startYear;
arr[1] = this.month - 1;
arr[2] = this.day - 1;
arr[3] = this.hour;
arr[4] = this.minute;
arr[5] = this.second;
this.$nextTick(() => {
this.values = arr;
})
} else {
dateArr[1] = this.hour;
dateArr[2] = this.minute;
dateArr[3] = this.second;
this.$nextTick(() => {
this.dateValues = dateArr;
})
}
},
initDayArr: (year, month) => { //初始化月份天数
let totalDay = new Date(year, month, 0).getDate();
let dayArr = [];
for (let i = 1; i <= totalDay; i++) {
if (i < 10) {
i = '0' + i;
} else {
i = i + '';
}
dayArr.push(i);
};
return dayArr;
},
formatNum(num) { //日期时间的初始化
return num < 10 ? '0' + num : num + '';
},
maskClick() { //日期时间的遮罩
this.showPicker = false;
},
show() { //日期时间的显示
this.showPicker = true;
},
hide() { //日期时间的隐藏
this.showPicker = false;
},
pickerCancel() { //日期时间取消
this.$emit("cancel", {
selectArr: this.selectArr
});
this.showPicker = false;
},
pickerConfirm(e) { //日期时间确定
this.$emit("confirm", {
selectArr: this.selectArr,
selectRes: this.selectRes
});
this.showPicker = false;
},
bindChange(e) { //默认滚动日期时间方法
let valueArr = e.detail.value;
let year = "",
month = "",
day = "",
hour = "",
minute = "",
second = "";
let selectArr = this.selectArr;
let dayArr = [];
year = this.dateObj.years[valueArr[0]];
month = this.dateObj.months[valueArr[1]];
day = this.dateObj.days[valueArr[2]];
hour = this.dateObj.hours[valueArr[3]];
minute = this.dateObj.minutes[valueArr[4]];
second = this.dateObj.seconds[valueArr[5]];
if (year != selectArr[0]) {
dayArr = this.initDayArr(year, month);
this.dateObj.days = dayArr;
};
if (month != selectArr[1]) {
dayArr = this.initDayArr(year, month);
this.dateObj.days = dayArr;
};
this.selectArr = [year, month, day, hour, minute, second];
this.selectRes = `${year+'-'+month+'-'+day+' '+hour+':'+minute+':'+second}`;
this.$nextTick(() => {
this.values = valueArr;
})
},
bindDateChange(e) { //有效日期的滚动日期时间方法
let valueArr = e.detail.value;
let dateStr = "",
dateArr = [],
hour = "",
minute = "",
second = "";
let selectArr = this.selectArr;
let dayArr = [];
dateStr = this.dateObj.dates[valueArr[0]];
dateArr = dateStr.split('-');
hour = this.dateObj.hours[valueArr[1]];
minute = this.dateObj.minutes[valueArr[2]];
second = this.dateObj.seconds[valueArr[3]];
this.selectArr = [dateArr[0], dateArr[1], dateArr[2], hour, minute, second];
this.selectRes = `${dateArr[0]+'-'+dateArr[1]+'-'+dateArr[2]+' '+hour+':'+minute+':'+second}`;
this.$nextTick(() => {
this.dateValues = valueArr;
})
},
//遍历两个日期间的所有日期
getBetweenDateStr(start, end) {
let result = [];
let beginDay = start.split("-");
let endDay = end.split("-");
let diffDay = new Date();
let dateList = new Array;
let i = 0;
diffDay.setDate(beginDay[2]);
diffDay.setMonth(beginDay[1] - 1);
diffDay.setFullYear(beginDay[0]);
result.push(start);
while (i == 0) {
let countDay = diffDay.getTime() + 24 * 60 * 60 * 1000;
diffDay.setTime(countDay);
dateList[2] = diffDay.getDate();
dateList[1] = diffDay.getMonth() + 1;
dateList[0] = diffDay.getFullYear();
if (String(dateList[1]).length == 1) {
dateList[1] = "0" + dateList[1]
};
if (String(dateList[2]).length == 1) {
dateList[2] = "0" + dateList[2]
};
result.push(dateList[0] + "-" + dateList[1] + "-" + dateList[2]);
if (dateList[0] == endDay[0] && dateList[1] == endDay[1] && dateList[2] == endDay[2]) {
i = 1;
}
};
return result;
}
}
}
</script>
<style>
.yu-datetime-picker {
position: relative;
z-index: 888;
}
.yu-datetime-mask {
position: fixed;
z-index: 1000;
top: 0;
right: 0;
left: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.4);
visibility: hidden;
opacity: 0;
transition: all 0.3s ease;
}
.yu-datetime-mask.show {
visibility: visible;
opacity: 1;
}
.yu-datetime-content {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
transition: all 0.3s ease;
transform: translateY(100%);
z-index: 3000;
}
.yu-datetime-content.show {
transform: translateY(0);
}
.yu-datetime-hd {
display: flex;
align-items: center;
padding: 0 30upx;
height: 44px;
background-color: #fff;
position: relative;
text-align: center;
font-size: 15px;
justify-content: space-between;
}
.yu-datetime-btn {
font-size: 14px;
}
.yu-datetime-hd:after {
content: ' ';
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
border-bottom: 1px solid #e5e5e5;
color: #e5e5e5;
transform-origin: 0 100%;
transform: scaleY(0.5);
}
.yu-datetime-view {
width: 100%;
height: 200px;
overflow: hidden;
background-color: rgba(255, 255, 255, 1);
z-index: 666;
}
.yu-datetime-view .picker-view {
height: 100%;
}
.yu-picker-column {
-webkit-flex: 2;
-webkit-box-flex: 2;
flex: 2;
}
.yu-datetime-item {
text-align: center;
width: 100%;
height: 88upx;
line-height: 88upx;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 30upx;
}
</style>
+99
View File
@@ -0,0 +1,99 @@
<!-- label 为字段名 -->
<!-- type 为输入框类型 默认text
maxlength 为长度默认不限
<!-- isBorder 是否有边框 默认 true有-->
-->
<template>
<view class="input-box" :class="isBorder ? '' : 'border-none'">
<view class="label"> <text class="tex">*</text> {{ label }}</view>
<input class="iput" :type="text" :value="sea" @input="onClickInput" :placeholder="'请输入' + label" :maxlength="maxlength" placeholder-style="font-size: 28rpx; color:#999999" >
</view>
</template>
<script>
import { watch } from "vue";
export default {
props: {
value: {
default: ''
},
label: {
default: ''
},
type: {
default: 'text'
},
maxlength: {
default: -1
},
isBorder: {
default: true
}
},
name:"input-li",
data() {
return {
sea: ''
};
},
created() {
// console.log(this.value)
this.sea = this.value
},
watch: {
value: (val) => {
// console.log(val)
// this.sea = val
}
},
methods: {
onClickInput(e) {
this.$emit('input', e.target.value)
},
onClickName() {
this.$emit('click', 'name')
}
}
}
/* emits */
// const emits = emits(['update:modelValue', 'click'])
</script>
<style lang='scss' scoped>
.input-box{
width: 100%;
height: 100rpx;
background: #fff;
padding: 0 16rpx;
box-sizing: border-box;
display: flex;
align-items: center;
font-size: 28rpx;
border-bottom: 2rpx dashed #D9D9D9;
.label{
width: 200rpx;
line-height: 40rpx;
display: flex;
.tex{
display: block;
color: #E14343;
margin-right: 8rpx;
line-height: 40rpx;
width: 14rpx;
}
}
.iput{
flex: 1;
text-align: right;
font-size: 28rpx;
}
}
.border-none{
border: none;
}
</style>
+122
View File
@@ -0,0 +1,122 @@
<!-- label 为字段名 -->
<!-- type 为输入框类型 默认text -->
<!-- laebel 为字段名 -->
<!-- isBorder 是否有边框 默认 true有-->
<template>
<view class="select-box" :class="isBorder ? '' : 'border-none'">
<view class="label"> <text class="tex">*</text> {{ label }}</view>
<view class="uni-list-cell-db">
<picker @change="bindPickerChange" :value="index" range-key="name" :range="array">
<view class="uni-input">
<view v-if="index || index == 0" >{{ array[index].name }}</view>
<view class="placeholder" v-else >请选择{{label}}</view>
<image class="img" src="../../static/jiantou.png" ></image>
</view>
</picker>
</view>
</view>
</template>
<script>
import { watch } from "vue";
export default {
props: {
value: {
default: ''
},
label: {
default: ''
},
array: {
default: []
},
isBorder: {
default: true
}
},
data() {
return {
index: null,
};
},
watch: {
array: function (newArr){
newArr.forEach( (item, index) =>{
if(item.id == this.value){
this.index = index
}
})
}
},
created() {
this.array.forEach( (item, index) =>{
if(item.id == this.value){
this.index = index
}
})
},
methods: {
bindPickerChange: function(e) {
this.index = e.detail.value
this.array.forEach( (item, index) =>{
if(index == e.detail.value) {
this.$emit('input', item.id)
}
})
},
}
}
</script>
<style lang='scss' scoped>
.select-box{
width: 100%;
height: 100rpx;
background: #fff;
padding: 0 16rpx;
box-sizing: border-box;
display: flex;
align-items: center;
font-size: 28rpx;
border-bottom: 2rpx dashed #D9D9D9;
.label{
width: 200rpx;
line-height: 40rpx;
display: flex;
.tex{
display: block;
color: #E14343;
margin-right: 8rpx;
line-height: 40rpx;
width: 14rpx;
}
}
.uni-list-cell-db{
flex: 1;
height: 100rpx;
.uni-input{
width: 100%;
height: 100rpx;
display: flex;
justify-content: flex-end;
align-items: center;
.img{
width: 32rpx;
height: 32rpx;
margin-left: 4rpx;
}
.placeholder{
color: #999999;
}
}
}
}
.border-none{
border: none;
}
</style>
+20
View File
@@ -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>
+109
View File
@@ -0,0 +1,109 @@
import App from './App'
import Inputli from './components/form/input-li.vue';
import Selectli from './components/form/select-li.vue';
import Dateli from './components/form/date-li.vue';
import DateText from './components/form/dateText.vue';
import { getToken } from './api/create.js'
import { formatDate, calculator } from './com/index.js'
// #ifndef VUE3
import Vue from 'vue'
Vue.config.productionTip = false
Vue.prototype.a = '1234456'
const msg = (title,icon = 'none', duration = 1500, mask = false, ) => {
//统一提示方便全局修改
if (Boolean(title) === false) {
return;
}
uni.showToast({
title,
duration,
mask,
icon
});
}
const setNavigationBar = ( title = '教育平台', backgroundColor = '#ffffff') =>{
console.log('更改标题')
// my.setNavigationBar({
// title,
// backgroundColor
// });
}
const navTo = (url, skip = 'navigateTo') =>{
uni[skip]({
url
});
}
const login = () =>{
return new Promise((reslove,reject)=>{
uni.getAuthCode({
success:(user)=>{
console.log(user)
getToken(user.authCode).then((res)=>{
if(res){
reslove(res.data)
console.log(res.data)
}
}).catch(err =>{
reject(err)
})
},
})
})
}
// 提示框 点击确定进入resolve 取消进入reject
const showModel = (content) =>{
return new Promise((resolve, reject)=>{
uni.showModal({
title: '提示',
content: content,
cancelText: '取消',
confirmText: '确定',
success: function (res) {
if (res.confirm) {
console.log('用户点击确定');
resolve('affirm')
} else if (res.cancel) {
console.log('用户点击取消');
reject('cancal')
}
}
});
})
}
Vue.prototype.$navTo = navTo // 页面跳转
Vue.prototype.$msg = msg
Vue.prototype.$setNavigationBar = setNavigationBar
Vue.prototype.$login = login
Vue.prototype.$calculator = calculator // 计算数
Vue.prototype.$formatDate = formatDate // 日期格式修改
Vue.prototype.$showModel = showModel // 提示框
Vue.component("Inputli",Inputli)
Vue.component("Selectli",Selectli)
Vue.component("Dateli",Dateli)
Vue.component("DateText",DateText)
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
+72
View File
@@ -0,0 +1,72 @@
{
"name" : "template",
"appid" : "__UNI__9F20DF1",
"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-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios" : {},
/* SDK */
"sdkConfigs" : {}
}
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "wxc4e1ec19f72d0b73",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "2"
}
+50
View File
@@ -0,0 +1,50 @@
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path" : "pages/login/login",
"style" :
{
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
// 示例模版页面
{
"path": "pages/index/index",
"style": {
// 顶部标题字
"navigationBarTitleText": "uni-app",
// 设置背景颜色
"backgroundColor": "#aaaa7f"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "uni-app",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"lazyCodeLoading": "requiredComponents",
"uniIdRouter": {},
"uni-app": {
"scripts": {
"mp-dingtalk": {
"title": "钉钉小程序",
"env": {
"UNI_PLATFORM": "mp-alipay"
},
"define": {
"MP-DINGTALK": true
}
}
}
}
}
+139
View File
@@ -0,0 +1,139 @@
<template>
<view class="content">
<image class="logo" @click="goSub" src="/static/logo.png"></image>
<view class="">
<Inputli @input="changeTrigger" v-model="form.name" />
<Inputli @click="onClickName" v-model="form.age" :type="number" :maxlength="11" />
<Inputli @click="onClickName" v-model="form.sex" />
<Selectli v-model="form.sex" label="性123别" :array="sexArr" />
<Dateli v-model="form.startTime" />
<button @click="onClickSave">提交</button>
</view>
</view>
</template>
<script>
import { uploadImage } from '../../api/uploadImage.js';
import { rulesIdCard, rulesPhone } from '../../com/index.js';
export default {
data() {
return {
title: 'Hello',
imgArr: [],
form: {
name: '张三2',
age: 18,
sex: '',
startTime: ''
},
sexArr: [],
// 分页
total: 0,
pageSize: 7,
PageNum: 1,
isLoading: false, // 是否正在加载数据,
};
},
created() {
this.$setNavigationBar('钉钉示例模板页面');
setTimeout(() => {
this.sexArr = [
{
name: '男',
id: 1
},
{
name: '女',
id: 2
},
{
name: '未知',
id: 3
}
];
}, 2000);
},
onLoad() {
console.log(this.$calculator(60, 0.3, '+'));
},
// 上拉加载
onReachBottom() {
if (this.PageNum * this.pageSize >= this.total) {
// 证明没有下一页的数据了
return this.$msg('没有数据啦!');
}
if (this.isLoading) return;
},
// 下拉刷新
onPullDownRefresh() {
console.log('下拉刷新了');
dd.stopPullDownRefresh();
},
methods: {
// 登录
async signIn() {
if (uni.getStorageSync('token')) {
console.log('获取列表数据');
} else {
let a = await this.$login();
console.log('获取列表数据');
}
},
onClickSave() {
const res = this.$showModel('提交函数');
res.then(
() => {
console.log('成功了执行');
},
() => {
console.log('点了取消执行');
}
);
console.log(this.form);
console.log(this.sex);
},
onClickName(a) {
// console.log(a)
},
changeTrigger() {
console.log('11111');
},
goSub() {
console.log(888);
},
}
};
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
+133
View File
@@ -0,0 +1,133 @@
<template>
<view class="container">
<view style="text-align: center;">
<image style="width: 120upx;height: 120upx;margin-top: 140upx;border-radius:50%;border: 1px solid #dedfe0;" src="../../static/logo.png"></image>
<view style="font-size: 28upx;margin-top: 32upx">泸州市江阳区新时代文明实践中心</view>
<button class="confirm-btn" @click="wxGetUserInfo">微信登录</button>
<view class="cancal-btn" @click="onClickCancal">取消登录</view>
</view>
</view>
</template>
<script>
import { login, postLogin } from '@/api/user/userApi.js'; //用户中心接口
export default {
data() {
return {
user: {
//用户信息
headerImg: '', //头像
username: '', //昵称 username
isEnterprise: 0 // 0 是用户 1是商家
},
isBackUrl: false // 返回哪里 true 返回领取页面 false 返回 user页面
};
},
onLoad(option) {
this.isBackUrl = option.isback;
},
methods: {
// 点击取消
onClickCancal() {
uni.navigateBack();
},
//授权获取微信用户信息
wxGetUserInfo() {
//新版本使用
var self = this;
uni.getUserProfile({
desc: '登录',
success: data1 => {
uni.login({
provider: 'weixin',
success: loginRes => {
console.log(loginRes);
const code = loginRes.code; //获取code
uni.showLoading({ title: '正在登录' });
postLogin(code).then(res => {
console.log(res);
if (res.code == 200) {
self.$com.setCacheToken('userInfo', res.userInfo); //储存用户信息
self.$com.setCacheToken('token', res.data.access_token); //储存用户token
uni.showToast({ title: '登录成功' });
uni.navigateBack();
}
uni.hideLoading();
});
}
});
},
fail: error => {
uni.showToast({
title: '您取消了授权,登录失败',
icon: 'none'
});
return false;
}
});
return false;
}
}
};
</script>
<style lang="scss">
.footer {
padding-left: 140upx;
margin-top: 32upx;
font-size: 24upx;
color: #666666;
text-align: center;
display: flex;
}
page {
background: #fff;
}
.send-msg {
border-radius: 30px;
color: black;
background: white;
height: 30px;
font-size: 14px;
line-height: 30px;
}
.container {
top: 0;
padding-top: 50px;
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
background: #fff;
image {
margin: 0 auto;
}
}
.cancal-btn {
width: 200px;
height: 42px;
line-height: 42px;
border-radius: 30px;
margin: 0 auto;
margin-top: 60upx;
border: 2rpx solid rgb(220, 223, 230);
color: rgb(220, 223, 230);
}
.confirm-btn {
width: 200px;
height: 42px;
line-height: 42px;
border-radius: 30px;
margin-top: 260upx;
// background-color: $main-color;
color: #fff;
// font-size: $font-lg;
&:after {
border-radius: 60px;
}
}
</style>
Binary file not shown.

After

Width:  |  Height:  |  Size: 436 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

+76
View File
@@ -0,0 +1,76 @@
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
*/
/* 颜色变量 */
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
/* 边框颜色 */
$uni-border-color:#c8c7cc;
/* 尺寸变量 */
/* 文字尺寸 */
$uni-font-size-sm:12px;
$uni-font-size-base:14px;
$uni-font-size-lg:16;
/* 图片尺寸 */
$uni-img-size-sm:20px;
$uni-img-size-base:26px;
$uni-img-size-lg:40px;
/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:20px;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:15px;