Compare commits
No commits in common. "main" and "master" have entirely different histories.
|
|
@ -0,0 +1,21 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<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="/src/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
/// <reference types='@dcloudio/types' />
|
||||
import 'vue'
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
type Hooks = App.AppInstance & Page.PageInstance;
|
||||
|
||||
interface ComponentCustomOptions extends Hooks {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<script setup lang="ts">
|
||||
import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
|
||||
import { postUserInfoAPI } from '@/api/login';
|
||||
import { useInfoStore } from "@/stores";
|
||||
|
||||
onLaunch(() => {
|
||||
console.log("App Launch");
|
||||
postUserInfoAPI({
|
||||
"username": "guest",
|
||||
"password": "admin@123",
|
||||
"loginType": "3"
|
||||
}).then((res: any) => {
|
||||
if (res.code == 200) {
|
||||
const userStore = useInfoStore();
|
||||
userStore.setUserInfo({ token: res.data.access_token, userInfo: JSON.parse(res.data.us) })
|
||||
sessionStorage.setItem('token',res.data.access_token)
|
||||
sessionStorage.setItem('userInfo',JSON.parse(res.data.us))
|
||||
console.log(userStore.userinfo);
|
||||
|
||||
}
|
||||
})
|
||||
});
|
||||
onShow(() => {
|
||||
console.log("App Show");
|
||||
});
|
||||
onHide(() => {
|
||||
console.log("App Hide");
|
||||
});
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.uni-tabbar {
|
||||
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
|
||||
border: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import { http } from "@/utils/http";
|
||||
|
||||
/**
|
||||
* 获取告警信息
|
||||
*/
|
||||
export const getalarmLists = (bidCode: string | null) => {
|
||||
return http({
|
||||
method: "GET",
|
||||
url: "/background/app/index/alarmLists?bidCode=" + bidCode,
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
import { http } from "@/utils/http";
|
||||
interface Car {
|
||||
img: string | undefined;
|
||||
gender: any;
|
||||
carId: any;
|
||||
phoneId: any;
|
||||
status: string;
|
||||
accessType: string;
|
||||
accesssTime: string;
|
||||
bidCode: string;
|
||||
carNum: string;
|
||||
date: string;
|
||||
endDate: string;
|
||||
id: string;
|
||||
phone: string;
|
||||
proId: string;
|
||||
startDate: string;
|
||||
userName: string;
|
||||
}
|
||||
export type CarArray = Car[];
|
||||
/**
|
||||
* 获取车辆信息
|
||||
*/
|
||||
export const getCarList = (bidCode: string) => {
|
||||
return http({
|
||||
method: "GET",
|
||||
url: "/background/app/index/getCarList?bidCode=" + bidCode,
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import { http } from "@/utils/http";
|
||||
|
||||
export interface ApiEngineering {
|
||||
proName: string;
|
||||
proBrief: string;
|
||||
org: string;
|
||||
proType: string;
|
||||
planStartTime: string;
|
||||
planEndTime: string;
|
||||
jlUnit: string;
|
||||
sgUnit: string;
|
||||
}
|
||||
/**
|
||||
* 获取工程信息
|
||||
*/
|
||||
export const getEngineering = (bidCode: string | null) => {
|
||||
return http({
|
||||
method: "GET",
|
||||
url: "/background/app/index/proManagement?bidCode=" + bidCode,
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import { http } from "@/utils/http";
|
||||
interface Personne {
|
||||
userName: string;
|
||||
idNumber: string;
|
||||
phone: string;
|
||||
status: string;
|
||||
sex: string;
|
||||
img: string | undefined;
|
||||
}
|
||||
export type PersonneArray = Personne[];
|
||||
/**
|
||||
* 获取人员信息
|
||||
*/
|
||||
export const getPersonnelList = (bidCode: string) => {
|
||||
return http({
|
||||
method: "GET",
|
||||
url: "/background/app/index/getPersonnelList?bidCode=" + bidCode,
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import { http } from "@/utils/http";
|
||||
|
||||
export interface ApiIntroduction {
|
||||
img: string;
|
||||
proBrief: string;
|
||||
org: string;
|
||||
proType: string;
|
||||
planStartTime: string;
|
||||
planEndTime: string;
|
||||
jlUnit: string;
|
||||
sgUnit: string;
|
||||
}
|
||||
/**
|
||||
* 获取项目简介信息
|
||||
*/
|
||||
export const getProBrief = (bidCode: string | null) => {
|
||||
return http({
|
||||
method: "GET",
|
||||
url: "/background/app/index/getProBrief?bidCode=" + bidCode,
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import { http } from "@/utils/http";
|
||||
|
||||
/**
|
||||
* 获取个人信息
|
||||
*/
|
||||
// export const getMemberProfileAPI = () => {
|
||||
// return http({
|
||||
// method: 'GET',
|
||||
// url: '/member/profile',
|
||||
// })
|
||||
// }
|
||||
|
||||
/**
|
||||
* 修改个人信息
|
||||
* @param data 请求体参数
|
||||
*/
|
||||
export const postUserInfoAPI = (data: any) => {
|
||||
return http({
|
||||
method: "POST",
|
||||
url: "/auth/login",
|
||||
data,
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import { http } from "@/utils/http";
|
||||
|
||||
export type FunctionItem = {
|
||||
img: string;
|
||||
text: string;
|
||||
value: string;
|
||||
};
|
||||
export interface projectnameItem {
|
||||
proName: string;
|
||||
bidCode: string;
|
||||
}
|
||||
export interface timeInfo {
|
||||
durationDay: number;
|
||||
planStartTime: string;
|
||||
planEndTime: string;
|
||||
value: number;
|
||||
value2: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取工程下拉信息
|
||||
*/
|
||||
export const getProsByUser = (roleCode: string) => {
|
||||
return http({
|
||||
method: "GET",
|
||||
url: "/background/app/index/getProsByUser?roleCode=" + roleCode,
|
||||
});
|
||||
};
|
||||
/**
|
||||
* 获取工程进度
|
||||
*/
|
||||
export const getproProgress = (bidCode: string) => {
|
||||
return http({
|
||||
method: "GET",
|
||||
url: "/background/app/index/proProgress?bidCode=" + bidCode,
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
<template>
|
||||
<view class="cmd-avatar" :class="setShapeSizeClass" :style="setIconTextStyle+setNumSizeStyle" @tap="$_click">
|
||||
<image v-if="src" class="cmd-avatar-img" mode="aspectFit" :src="src" @load="$_imageLoad" @error="$_imageError"></image>
|
||||
<cmd-icon v-if="icon && !src && !text" :type="icon" :size="setIconSize" :color="make.color"></cmd-icon>
|
||||
<text v-if="text && !src && !icon" v-text="text"></text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import cmdIcon from '../cmd-icon/cmd-icon.vue'
|
||||
|
||||
/**
|
||||
* 头像组件
|
||||
* @description 用于展示用户头像、数字号、单字符。
|
||||
* @tutorial https://ext.dcloud.net.cn/plugin?id=176
|
||||
* @property {String,Number} text 头像显示文字 - 建议取首位text[0],长度小于3位
|
||||
* @property {String} icon 头像显示图标icon - 列如:home、add
|
||||
* @property {String} src 头像图片地址 - 仅支持相对路径、绝对路径,支持 base64 码
|
||||
* @property {String,Number} size 头像显示大小 - sm,lg,md,任意Number值
|
||||
* @property {String} shape 头像形状 - 圆形:circle,矩形:square
|
||||
* @property {Object} make 自定义头像样式 - 颜色、背景、边距,列如:{'margin-right': '8px'}
|
||||
* @event {Function} click 头像组件点击事件
|
||||
* @event {Function} load 图片载入成功事件
|
||||
* @event {Function} error 图片载入错误事件
|
||||
* @example <cmd-avatar text='CMD'></cmd-avatar>
|
||||
*/
|
||||
export default {
|
||||
name: 'cmd-avatar',
|
||||
|
||||
components: {
|
||||
cmdIcon
|
||||
},
|
||||
|
||||
props: {
|
||||
/**
|
||||
* 大小 sm md lg Number
|
||||
*/
|
||||
size: {
|
||||
validator: val => {
|
||||
return typeof val === 'number' || ['sm', 'lg', 'md'].includes(val);
|
||||
},
|
||||
default: 'md'
|
||||
},
|
||||
/**
|
||||
* 形状 circle圆形 square矩形
|
||||
*/
|
||||
shape: {
|
||||
validator: val => ['circle', 'square'].includes(val),
|
||||
default: 'circle'
|
||||
},
|
||||
/**
|
||||
* 样式属性style
|
||||
*/
|
||||
make: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
'color': ''
|
||||
};
|
||||
}
|
||||
},
|
||||
/**
|
||||
* 图片网络地址
|
||||
*/
|
||||
src: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
/**
|
||||
* 图标type名称
|
||||
*/
|
||||
icon: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
/**
|
||||
* 文本名字建议取首位text[0],长度小于3位
|
||||
*/
|
||||
text: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
// 形状大小
|
||||
setShapeSizeClass() {
|
||||
let classList = []
|
||||
if (['circle', 'square'].includes(this.shape)) {
|
||||
classList.push(`cmd-avatar-${this.shape}`)
|
||||
}
|
||||
if (['sm', 'lg', 'md'].includes(this.size)) {
|
||||
classList.push(`cmd-avatar-${this.size}`)
|
||||
}
|
||||
return classList
|
||||
},
|
||||
// 自定义大小
|
||||
setNumSizeStyle() {
|
||||
return typeof this.size === 'number' ?
|
||||
`width:${this.size}px;` +
|
||||
`height:${this.size}px;` +
|
||||
`font-size:${(this.size / 2)}px;` +
|
||||
`line-height:${this.size}px;` :'';
|
||||
},
|
||||
// 图标文本样式
|
||||
setIconTextStyle() {
|
||||
let styleString = '';
|
||||
for (let it in this.make) {
|
||||
styleString += `${it}:${this.make[it]};`;
|
||||
}
|
||||
return styleString;
|
||||
},
|
||||
// 图标大小
|
||||
setIconSize() {
|
||||
if (typeof this.size === 'number') {
|
||||
return this.size / 2;
|
||||
}
|
||||
if (this.size === 'sm') {
|
||||
return uni.upx2px(64) / 2;
|
||||
}
|
||||
if (this.size === 'lg') {
|
||||
return uni.upx2px(128) / 2;
|
||||
}
|
||||
return uni.upx2px(96) / 2;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 当图片载入完毕时
|
||||
$_imageLoad(e) {
|
||||
this.$emit('load', e);
|
||||
},
|
||||
// 当错误发生时
|
||||
$_imageError(e) {
|
||||
this.$emit('error', e);
|
||||
},
|
||||
// 点击事件
|
||||
$_click(e) {
|
||||
this.$emit('click', e)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.cmd-avatar {
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
border-radius: 6upx;
|
||||
background: #eee;
|
||||
box-shadow: 0 2px 1px -1px rgba(0, 0, 0, .2), 0 1px 1px 0 rgba(0, 0, 0, .14), 0 1px 3px 0 rgba(0, 0, 0, .12);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cmd-avatar-img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.cmd-avatar-lg {
|
||||
width: 128upx;
|
||||
height: 128upx;
|
||||
font-size: 64upx;
|
||||
line-height: 128upx;
|
||||
}
|
||||
|
||||
.cmd-avatar-sm {
|
||||
width: 64upx;
|
||||
height: 64upx;
|
||||
font-size: 32upx;
|
||||
line-height: 64upx;
|
||||
}
|
||||
|
||||
.cmd-avatar-md {
|
||||
width: 96upx;
|
||||
height: 96upx;
|
||||
font-size: 48upx;
|
||||
line-height: 96upx;
|
||||
}
|
||||
|
||||
.cmd-avatar-square {
|
||||
border-radius: 6upx;
|
||||
background-clip: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.cmd-avatar-circle {
|
||||
border-radius: 50%;
|
||||
background-clip: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.vue' {
|
||||
import { DefineComponent } from 'vue'
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import { createSSRApp } from "vue";
|
||||
import App from "./App.vue";
|
||||
|
||||
// 导入 pinia 实例
|
||||
import pinia from "./stores/index";
|
||||
export function createApp() {
|
||||
// 创建 vue 实例
|
||||
const app = createSSRApp(App);
|
||||
|
||||
// 使用 pinia
|
||||
app.use(pinia);
|
||||
|
||||
return {
|
||||
app,
|
||||
};
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
{
|
||||
"name" : "",
|
||||
"appid" : "",
|
||||
"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" : "",
|
||||
"setting" : {
|
||||
"urlCheck" : false
|
||||
},
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-alipay" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-baidu" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"mp-toutiao" : {
|
||||
"usingComponents" : true
|
||||
},
|
||||
"uniStatistics": {
|
||||
"enable": false
|
||||
},
|
||||
"vueVersion" : "3"
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
{
|
||||
"pages": [
|
||||
{
|
||||
"path": "pages/own/own",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/page/page",
|
||||
"style": {
|
||||
"navigationBarTitleText": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/alarm/alarm",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/introduction/introduction",
|
||||
"style": {
|
||||
"navigationBarTitleText": "项目简介",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "pages/functions/car",
|
||||
"style": {
|
||||
"navigationBarTitleText": "车辆管理",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/functions/user",
|
||||
"style": {
|
||||
"navigationBarTitleText": "人员管理",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/functions/engineering",
|
||||
"style": {
|
||||
"navigationBarTitleText": "工程管理",
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"globalStyle": {
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationBarTitleText": "uni-app",
|
||||
"navigationBarBackgroundColor": "#F8F8F8",
|
||||
"backgroundColor": "#F8F8F8"
|
||||
},
|
||||
"tabBar": {
|
||||
"selectedColor": "#13BAA5",
|
||||
"backgroundColor": "#ffffff",
|
||||
"list": [
|
||||
{
|
||||
"pagePath": "pages/own/own",
|
||||
"iconPath": "static/tabBar/page.png",
|
||||
"selectedIconPath": "static/tabBar/pageactive.png",
|
||||
"text": "首页"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/alarm/alarm",
|
||||
"iconPath": "static/tabBar/alarm.png",
|
||||
"selectedIconPath": "static/tabBar/alarmactive.png",
|
||||
"text": "告警"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/introduction/introduction",
|
||||
"iconPath": "static/tabBar/introduction.png",
|
||||
"selectedIconPath": "static/tabBar/introductionactive.png",
|
||||
"text": "简介"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/page/page",
|
||||
"iconPath": "static/tabBar/own.png",
|
||||
"selectedIconPath": "static/tabBar/ownactive.png",
|
||||
"text": "我的"
|
||||
}
|
||||
],
|
||||
"position": "bottom"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
<template>
|
||||
<div class="alarm">
|
||||
<div v-if="alarmLists.length">
|
||||
<div class="alarm-item" v-for="(item, index) in alarmLists" :key="index">
|
||||
<!-- <img :src="item.img" class="alarm-icon" /> -->
|
||||
<cmd-avatar src="../../static/alarm.png" class="alarm-icon"></cmd-avatar>
|
||||
<div class="alarm-info">
|
||||
<p>{{ item.warnContent }}</p>
|
||||
</div>
|
||||
<div :class="{ 'alarm-status': true, 'status-out': item.status === '未处理' }">
|
||||
<p>{{ item.status }}</p>
|
||||
<p>{{ item.time }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="no-data">
|
||||
暂无告警信息
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { getalarmLists } from "@/api/alarm";
|
||||
import { useBidcodeStore } from '@/stores/modules/bidCodeStore'
|
||||
import { onShow, onHide } from '@dcloudio/uni-app'
|
||||
import cmdAvatar from '@/components/cmd-avatar/cmd-avatar.vue'
|
||||
const components = {cmdAvatar}
|
||||
const bidcodeStore = useBidcodeStore()
|
||||
let alarmLists: any = ref<any>([]);
|
||||
onShow(() => {
|
||||
getalarmLists(sessionStorage.getItem('selectedBidcode')).then((res) => {
|
||||
alarmLists.value = res.data
|
||||
})
|
||||
})
|
||||
onHide(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.alarm-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
background-color: #ffff;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
display: block;
|
||||
width: calc(100% - 1rem);
|
||||
height: 1px;
|
||||
background-color: #ccc;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0.5rem;
|
||||
right: 0.5rem;
|
||||
}
|
||||
|
||||
.alarm-icon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin-right: 1rem;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.alarm-info {
|
||||
flex: 1;
|
||||
|
||||
.alarm-text {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 10px;
|
||||
font-size: 0.9rem;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.alarm-status {
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
right: 0.5rem;
|
||||
color: #13baa5;
|
||||
border: #13baa5 1px solid;
|
||||
font-size: smaller;
|
||||
height: 20px;
|
||||
width: 45px;
|
||||
font-size: xx-small;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
border-radius: 0 5px 0 5px;
|
||||
}
|
||||
|
||||
.status-out {
|
||||
color: red !important;
|
||||
border: red 1px solid !important;
|
||||
}
|
||||
}
|
||||
|
||||
.alarm-action-buttons {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-right: 1rem;
|
||||
/* 根据需要调整右侧边距 */
|
||||
|
||||
.alarm-action-button {
|
||||
width: 55px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
font-size: 12px;
|
||||
border: none;
|
||||
background-color: #13baa5;
|
||||
/* 背景颜色可自定义 */
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
border-radius: 0;
|
||||
text-align: center;
|
||||
margin-left: 0.5rem;
|
||||
/* 按钮之间的间距 */
|
||||
margin: 0.5rem 0 1.5rem 10px;
|
||||
}
|
||||
|
||||
.delete-button {
|
||||
background-color: red !important;
|
||||
}
|
||||
}
|
||||
|
||||
.no-data {
|
||||
text-align: center;
|
||||
margin: auto;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
<template>
|
||||
<div class="car">
|
||||
<div v-for="(item, index) in cardata" :key="index">
|
||||
<div class="car-item">
|
||||
<!-- <img :src="item.date" class="car-icon" /> -->
|
||||
<cmd-avatar :text='item.userName[0]' :make="{'color': '#fff','background-color': '#509A48'}" class="car-icon"></cmd-avatar>
|
||||
<div class="car-info">
|
||||
<span class="car-text">{{ item.userName }}</span>
|
||||
<p>车牌号:{{ item.carNum }}</p>
|
||||
<p>电话号码:{{ item.phone }}</p>
|
||||
</div>
|
||||
<div
|
||||
:class="{ 'car-status': true, 'status-out': !item.accessType }"
|
||||
>{{ item.accessType?item.accessType:'入' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from "vue";
|
||||
import { getCarList } from "@/api/functions/car"
|
||||
import type { CarArray } from '@/api/functions/car'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import cmdAvatar from '@/components/cmd-avatar/cmd-avatar.vue'
|
||||
const components = {cmdAvatar}
|
||||
const cardata = ref<CarArray>([])
|
||||
|
||||
const getData = async (bidCode: string) => {
|
||||
getCarList(bidCode).then((res) => {
|
||||
cardata.value = res.data;
|
||||
})
|
||||
};
|
||||
|
||||
const editCar = (carItem: any) => {
|
||||
console.log("编辑车辆:", carItem);
|
||||
};
|
||||
const deleteCar = (carItem: any) => {
|
||||
console.log("删除车辆:", carItem);
|
||||
};
|
||||
onLoad((query) => {
|
||||
getData(query?.bidCode);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.car-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
background-color: #ffff;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
display: block;
|
||||
width: calc(100% - 1rem);
|
||||
height: 1px;
|
||||
background-color: #ccc;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0.5rem;
|
||||
right: 0.5rem;
|
||||
}
|
||||
|
||||
.car-icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-right: 1rem;
|
||||
border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.car-info {
|
||||
flex: 1;
|
||||
|
||||
.car-text {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 10px;
|
||||
font-size: 0.9rem;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.car-status {
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
right: 0.5rem;
|
||||
color: red;
|
||||
border: red 1px solid;
|
||||
font-size: smaller;
|
||||
height: 20px;
|
||||
width: 45px;
|
||||
font-size: xx-small;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
border-radius: 0 5px 0 5px;
|
||||
}
|
||||
|
||||
.status-out {
|
||||
color: #13baa5 !important;
|
||||
border: #13baa5 1px solid !important;
|
||||
}
|
||||
}
|
||||
|
||||
.car-action-buttons {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-right: 1rem;
|
||||
/* 根据需要调整右侧边距 */
|
||||
|
||||
.car-action-button {
|
||||
width: 55px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
font-size: 12px;
|
||||
border: none;
|
||||
background-color: #13baa5;
|
||||
/* 背景颜色可自定义 */
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
border-radius: 0;
|
||||
text-align: center;
|
||||
margin-left: 0.5rem;
|
||||
/* 按钮之间的间距 */
|
||||
margin: 0.5rem 0 1.5rem 10px;
|
||||
}
|
||||
|
||||
.delete-button {
|
||||
background-color: red !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
<template>
|
||||
<div class="my-info">
|
||||
<div v-if="infodata">
|
||||
<p>{{ infodata.proName }}</p>
|
||||
<p>建管单位:{{ infodata.org }}</p>
|
||||
<p>工程类型:{{ infodata.proType }}</p>
|
||||
<p>计划开始时间:{{ infodata.planStartTime }}</p>
|
||||
<p>计划结束时间:{{ infodata.planEndTime }}</p>
|
||||
<p>监理单位:{{ infodata.jlUnit }}</p>
|
||||
<p>施工单位:{{ infodata.sgUnit }}</p>
|
||||
</div>
|
||||
<div v-if="costData" class="cost">
|
||||
<h4 class="title">成本统计</h4>
|
||||
<div class="progressinfo">
|
||||
<div class="field">
|
||||
<div class="field-name">计划成本</div>
|
||||
<div class="field-value">{{ costData.planCost }}</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="field-name">已支出</div>
|
||||
<div class="field-value">{{ costData.expenditureCost }}</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="field-name">剩余</div>
|
||||
<div class="field-value">{{ costData.residueCost }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<table ref="table" border stripe type="selection" emptyText="暂无更多数据">
|
||||
<tr>
|
||||
<th width="50" align="center">序号</th>
|
||||
<th width="130" align="center">支出日期</th>
|
||||
<th width="130" align="center">支出项</th>
|
||||
<th width="130" align="center">支出金额</th>
|
||||
</tr>
|
||||
<tr v-for="(item, index) in costData.proCostList" :key="index">
|
||||
<td>{{ index + 1 }}</td>
|
||||
<td>{{ item.expenditureDate }}</td>
|
||||
<td>
|
||||
{{ item.expenditure }}
|
||||
</td>
|
||||
<td>{{ item.amount }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div v-if="proGxPlanData" class="cost">
|
||||
<h4 class="title">施工进度</h4>
|
||||
<div class="progressinfo">
|
||||
<div class="field">
|
||||
<div class="field-name">计划进度</div>
|
||||
<div class="field-value">{{ proGxPlanData.value2 }}</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="field-name">实际进度</div>
|
||||
<div class="field-value">{{ proGxPlanData.value }}</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="field-name">剩余工期</div>
|
||||
<div class="field-value">{{ proGxPlanData.residueDay }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<table ref="table" border stripe type="selection" emptyText="暂无更多数据" style="align-items: center;text-align: center;">
|
||||
<tr>
|
||||
<!-- <th width="50" align="center">序号</th> -->
|
||||
<th width="130" align="center">施工工序</th>
|
||||
<th width="130" align="center">结束日期</th>
|
||||
<th width="130" align="center">权重占比</th>
|
||||
<th width="130" align="center">进度占比</th>
|
||||
</tr>
|
||||
<tr v-for="(item, index) in proGxPlanData.proGxPlanList" :key="index">
|
||||
<!-- <td>{{ index + 1 }}</td> -->
|
||||
<td>{{ item.name }}</td>
|
||||
<td>
|
||||
{{ item.planEndTime }}
|
||||
</td>
|
||||
<td>{{ item.gxWeight }}</td>
|
||||
<td>{{ item.gxProgress }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, reactive } from "vue";
|
||||
import { getEngineering } from "@/api/functions/engineering";
|
||||
import type { ApiEngineering } from "@/api/functions/engineering";
|
||||
import { useBidcodeStore } from '@/stores/modules/bidCodeStore';
|
||||
import { onShow, onHide } from '@dcloudio/uni-app'
|
||||
const infodata = ref<ApiEngineering>()
|
||||
const bidcodeStore = useBidcodeStore()
|
||||
let costData: any = reactive({
|
||||
proCostList: [],
|
||||
planCost: '',
|
||||
expenditureCost: '',
|
||||
residueCost: '',
|
||||
})
|
||||
let proGxPlanData: any = reactive({
|
||||
proGxPlanList: [],
|
||||
value: '',
|
||||
value2: '',
|
||||
residueDay: '',
|
||||
})
|
||||
onShow(() => {
|
||||
console.log(bidcodeStore.selectedBidcode)
|
||||
getEngineering(bidcodeStore.selectedBidcode).then((res) => {
|
||||
infodata.value = res.data.vo
|
||||
costData = res.data.proCost
|
||||
proGxPlanData.proGxPlanList = res.data.proGxPlan
|
||||
proGxPlanData.value = res.data.item.value
|
||||
proGxPlanData.value2 = res.data.item.value2
|
||||
proGxPlanData.residueDay = res.data.item.residueDay
|
||||
})
|
||||
})
|
||||
onHide(() => {
|
||||
infodata.value = {} as ApiEngineering
|
||||
costData = {}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.my-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 30px;
|
||||
min-height: 83vh;
|
||||
|
||||
span {
|
||||
padding-top: 10px;
|
||||
text-indent: 2em;
|
||||
}
|
||||
|
||||
p {
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding: 10px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cost {
|
||||
border: 1px solid #ccc;
|
||||
margin: 20px 0;
|
||||
|
||||
h4 {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
table {
|
||||
margin: 10px;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
.progressinfo {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.field {
|
||||
width: calc(100% / 3);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
margin: 5px;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.field-value {
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<template>
|
||||
<view>
|
||||
<text>风险识别</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
<template>
|
||||
<div class="car">
|
||||
<div v-for="(item, index) in persondata" :key="index">
|
||||
<div class="car-item">
|
||||
<!-- <img :src="item.img" class="car-icon" /> -->
|
||||
<cmd-avatar :text='item.userName[0]' :make="{'color': '#fff','background-color': '#509A48'}" class="car-icon"></cmd-avatar>
|
||||
<div class="car-info">
|
||||
<span class="car-text">{{ item.userName }} {{ item.sex }}</span>
|
||||
<p>身份证号:{{ item.idNumber }}</p>
|
||||
<p>电话号码:{{ item.phone }}</p>
|
||||
</div>
|
||||
<div :class="{ 'car-status': true, 'status-out': item.status === '入' }">
|
||||
{{ item.status }}
|
||||
</div>
|
||||
</div>
|
||||
<!-- <div class="car-action-buttons">
|
||||
<button class="car-action-button" @click="editPerson(item)">编辑</button>
|
||||
<button class="car-action-button delete-button" @click="deletePerson(item)">
|
||||
删除
|
||||
</button>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from "vue";
|
||||
import { getPersonnelList } from "@/api/functions/user"
|
||||
import type { PersonneArray } from '@/api/functions/user'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import cmdAvatar from '@/components/cmd-avatar/cmd-avatar.vue'
|
||||
const components = {cmdAvatar}
|
||||
const persondata = ref<PersonneArray>([])
|
||||
|
||||
const getData = async (bidCode: string) => {
|
||||
getPersonnelList(bidCode).then((res) => {
|
||||
persondata.value = res.data;
|
||||
})
|
||||
};
|
||||
|
||||
const editPerson = (personitem: any) => {
|
||||
console.log("编辑:", personitem);
|
||||
};
|
||||
const deletePerson = (personitem: any) => {
|
||||
console.log("删除:", personitem);
|
||||
};
|
||||
onLoad((query) => {
|
||||
getData(query?.bidCode);
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.car-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 1rem;
|
||||
background-color: #ffff;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
display: block;
|
||||
width: calc(100% - 1rem);
|
||||
height: 1px;
|
||||
background-color: #ccc;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0.5rem;
|
||||
right: 0.5rem;
|
||||
}
|
||||
|
||||
.car-icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-right: 1rem;
|
||||
// border-radius: 50%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.car-info {
|
||||
flex: 1;
|
||||
|
||||
.car-text {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-top: 10px;
|
||||
font-size: 0.9rem;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
|
||||
.car-status {
|
||||
position: absolute;
|
||||
top: 0.5rem;
|
||||
right: 0.5rem;
|
||||
color: red;
|
||||
border: red 1px solid;
|
||||
font-size: smaller;
|
||||
height: 20px;
|
||||
width: 45px;
|
||||
font-size: xx-small;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
border-radius: 0 5px 0 5px;
|
||||
}
|
||||
|
||||
.status-out {
|
||||
color: #13baa5 !important;
|
||||
border: #13baa5 1px solid !important;
|
||||
}
|
||||
}
|
||||
|
||||
.car-action-buttons {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-right: 1rem;
|
||||
/* 根据需要调整右侧边距 */
|
||||
|
||||
.car-action-button {
|
||||
width: 55px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
font-size: 12px;
|
||||
border: none;
|
||||
background-color: #13baa5;
|
||||
/* 背景颜色可自定义 */
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
border-radius: 0;
|
||||
text-align: center;
|
||||
margin-left: 0.5rem;
|
||||
/* 按钮之间的间距 */
|
||||
margin: 0.5rem 0 1.5rem 10px;
|
||||
}
|
||||
|
||||
.delete-button {
|
||||
background-color: red !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
<template>
|
||||
<view>
|
||||
<text>视频监控</text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<template>
|
||||
<view class="content">
|
||||
<image class="logo" src="/static/logo.png" />
|
||||
<view class="text-area">
|
||||
<text class="title">{{ title }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
const title = ref('Hello')
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.logo {
|
||||
height: 200px;
|
||||
width: 200px;
|
||||
margin-top: 200px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
margin-bottom: 50px;
|
||||
}
|
||||
|
||||
.text-area {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 36px;
|
||||
color: #8f8f94;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<div v-if="infodata">
|
||||
<div class="my-info">
|
||||
<img src="" alt="">
|
||||
<h4 class="title">项目概况</h4>
|
||||
<span>{{ infodata.proBrief }}</span>
|
||||
<p>建管单位:{{ infodata.org }}</p>
|
||||
<p>工程类型:{{ infodata.proType }}</p>
|
||||
<p>计划开始时间:{{ infodata.planStartTime }}</p>
|
||||
<p>计划结束时间:{{ infodata.planEndTime }}</p>
|
||||
<p>监理单位:{{ infodata.jlUnit }}</p>
|
||||
<p>施工单位:{{ infodata.sgUnit }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from "vue";
|
||||
import { getProBrief } from "@/api/introduction";
|
||||
import type { ApiIntroduction } from "@/api/introduction";
|
||||
import { useBidcodeStore } from '@/stores/modules/bidCodeStore'
|
||||
import { onShow, onHide } from '@dcloudio/uni-app'
|
||||
const infodata = ref<ApiIntroduction>()
|
||||
const bidcodeStore = useBidcodeStore()
|
||||
onShow(() => {
|
||||
getProBrief(sessionStorage.getItem('selectedBidcode')).then((res) => {
|
||||
infodata.value = res.data
|
||||
console.log(infodata.value)
|
||||
})
|
||||
})
|
||||
onHide(() => {
|
||||
infodata.value = {} as ApiIntroduction
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.my-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 30px;
|
||||
min-height: 83vh;
|
||||
|
||||
span {
|
||||
padding-top: 10px;
|
||||
text-indent: 2em;
|
||||
}
|
||||
|
||||
p {
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding: 10px 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,403 @@
|
|||
<template>
|
||||
<div class="my-page">
|
||||
<!-- 用户信息卡片 -->
|
||||
<div class="user-info">
|
||||
<div class="card-content">
|
||||
<div class="user-details">
|
||||
<img class="avatar" src="/static/logo.png" />
|
||||
<div class="text-info">
|
||||
<!-- <view class="dropdown">
|
||||
<view class="dropdown-display" @click="triggerDropdown">
|
||||
{{ selectedProname }}
|
||||
</view>
|
||||
<view v-if="isOpen" class="dropdown-options">
|
||||
<view v-for="(option, index) in nameItem" :key="index" class="dropdown-option"
|
||||
@click="selectOption(option)">
|
||||
{{ option.proName }}
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
<uni-data-select
|
||||
v-model="selectedBidcode"
|
||||
:localdata="nameItem"
|
||||
@change="selectOption"
|
||||
></uni-data-select>
|
||||
<p class="email">{{ userName }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 更多功能卡片 -->
|
||||
<div class="card more-functions">
|
||||
<div class="card-content">
|
||||
<h4 class="title">更多功能</h4>
|
||||
<div class="functions-grid">
|
||||
<div class="function-item" v-for="(item, index) in functions" :key="index" @click="goTofunctions(item.value)">
|
||||
<img :src="item.img" :alt="item.text" class="function-icon" />
|
||||
<span class="function-text">{{ item.text }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 项目进度卡片 -->
|
||||
<div class="card project-progress">
|
||||
<div class="card-content">
|
||||
<h4 class="title">项目进度</h4>
|
||||
<div id="chart" style="width: 100%; height: 180px"></div>
|
||||
<div class="progressinfo">
|
||||
<div class="field">
|
||||
<div class="field-name">计划开始时间</div>
|
||||
<div class="field-value">{{ fields.planStartTime }}</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="field-name">计划工期</div>
|
||||
<div class="field-value">{{ fields.durationDay }}</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="field-name">计划结束时间</div>
|
||||
<div class="field-value">{{ fields.planEndTime }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import * as echarts from "echarts";
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useInfoStore } from "@/stores";
|
||||
import { useBidcodeStore } from '@/stores/modules/bidCodeStore'
|
||||
import { getProsByUser, getproProgress } from "@/api/own"
|
||||
import type { projectnameItem, FunctionItem, timeInfo } from "@/api/own"
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
const state = {
|
||||
functions: [
|
||||
{
|
||||
img: "/static/own/engineering.png",
|
||||
text: "工程管理",
|
||||
value: "engineering",
|
||||
},
|
||||
{ img: "/static/own/video.png", text: "视频监控", value: "video" },
|
||||
{ img: "/static/own/risk.png", text: "风险识别", value: "risk" },
|
||||
{ img: "/static/own/user.png", text: "人员管理", value: "user" },
|
||||
{ img: "/static/own/car.png", text: "车辆管理", value: "car" },
|
||||
],
|
||||
}
|
||||
const userStore = useInfoStore();
|
||||
const selectedBidcode = ref<string>("");
|
||||
const selectedProname = ref<string>("");
|
||||
const userName = ref();
|
||||
const isOpen = ref(false)
|
||||
const functions = ref<FunctionItem[]>([]);
|
||||
let nameItem = ref<projectnameItem[]>([])
|
||||
const roleCode = ref();
|
||||
const fields = ref<timeInfo>({
|
||||
planStartTime: "",
|
||||
planEndTime: "",
|
||||
durationDay: 0,
|
||||
value: 0,
|
||||
value2: 0,
|
||||
})
|
||||
const bidcodeStore = useBidcodeStore()
|
||||
|
||||
userName.value = userStore.userinfo?.userInfo.roleName;
|
||||
functions.value = state.functions;
|
||||
roleCode.value = userStore.userinfo?.userInfo.roleCode;
|
||||
// console.log(userStore.userinfo, 'userStore.userinfo');
|
||||
|
||||
|
||||
const goTofunctions = (functionVal: string) => {
|
||||
uni.navigateTo({
|
||||
url: `/pages/functions/${functionVal}?bidCode=${sessionStorage.getItem('selectedBidcode')}`,
|
||||
});
|
||||
};
|
||||
//下拉切换选中事件
|
||||
const triggerDropdown = (): void => {
|
||||
// userSelect.value?.click();
|
||||
|
||||
isOpen.value = true
|
||||
};
|
||||
//下拉切换事件
|
||||
const selectOption = (val: any) => {
|
||||
console.log(val)
|
||||
if (val) {
|
||||
// selectedProname.value = val.proName
|
||||
selectedBidcode.value = val
|
||||
bidcodeStore.setSelectedBidcode(val)
|
||||
sessionStorage.setItem('selectedBidcode',val)
|
||||
isOpen.value = false
|
||||
getEchartdata(val)
|
||||
}
|
||||
}
|
||||
//获取下拉数据
|
||||
const getUserNames = () => {
|
||||
getProsByUser(roleCode.value).then((res) => {
|
||||
if (res.data) {
|
||||
nameItem.value = res.data.map((item: any)=>{
|
||||
return {value:item.bidCode,text:item.proName}
|
||||
});
|
||||
console.log(sessionStorage.getItem('selectedBidcode'))
|
||||
if(sessionStorage.getItem('selectedBidcode')){
|
||||
selectedBidcode.value = sessionStorage.getItem('selectedBidcode')
|
||||
}else{
|
||||
selectedBidcode.value = nameItem.value[0].value;
|
||||
}
|
||||
bidcodeStore.setSelectedBidcode(selectedBidcode.value)
|
||||
getEchartdata(selectedBidcode.value)
|
||||
}
|
||||
});
|
||||
};
|
||||
//获取工程进度
|
||||
const getEchartdata = (val: string) => {
|
||||
getproProgress(val).then((res) => {
|
||||
fields.value = res.data as timeInfo;
|
||||
const remaining = 100 - (fields.value.value2 + fields.value.value)
|
||||
const chartDom = document.getElementById("chart") as HTMLDivElement;
|
||||
const myChart = echarts.init(chartDom);
|
||||
const option = {
|
||||
title: {
|
||||
text: `实际进度:${fields.value.value}%`,
|
||||
left: "center",
|
||||
top: "center",
|
||||
textStyle: {
|
||||
color: "#30DB9D",
|
||||
fontSize: 10,
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: "产品结构",
|
||||
type: "pie",
|
||||
padAngle: 2,
|
||||
startAngle: 90,
|
||||
radius: ["60%", "70%"],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: false,
|
||||
position: "center",
|
||||
},
|
||||
emphasis: {
|
||||
label: {
|
||||
show: true,
|
||||
fontSize: "40",
|
||||
fontWeight: "bold",
|
||||
},
|
||||
},
|
||||
labelLine: {
|
||||
show: false,
|
||||
},
|
||||
data: [
|
||||
{ name: "实际进度", value: fields.value.value },
|
||||
{ name: "计划进度", value: fields.value.value2 },
|
||||
{ name: "剩余进度", value: remaining },
|
||||
],
|
||||
itemStyle: {
|
||||
normal: {
|
||||
color: function (params: { dataIndex: any }) {
|
||||
var colorList = [
|
||||
["#20D7FD", "#05FFA5"],
|
||||
["#FF9905", "#FFD419"],
|
||||
["#FCFCFC", "#FCFCFC"],
|
||||
];
|
||||
var index = params.dataIndex;
|
||||
return new echarts.graphic.LinearGradient(0, 0, 1, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: colorList[index][0],
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: colorList[index][1],
|
||||
},
|
||||
]);
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
myChart.setOption(option);
|
||||
});
|
||||
};
|
||||
onShow(() => {
|
||||
getUserNames()
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.my-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 30px;
|
||||
padding: 30px;
|
||||
background-image: url(" /static/bacimg.png");
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
min-height: 83vh;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: #fff;
|
||||
border-radius: 10px;
|
||||
/* box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); */
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.user-info .card-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.user-details {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
border-radius: 40%;
|
||||
margin-right: 20px;
|
||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 1);
|
||||
}
|
||||
|
||||
.text-info {
|
||||
width: 200px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.dropdown {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
.dropdown-display {
|
||||
padding: 5px 30px 5px 5px;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
width: 200px;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path fill="%23333" d="M5 8l5 5 5-5z"/></svg>') no-repeat;
|
||||
background-position: right 5px center;
|
||||
background-size: 20px 20px;
|
||||
border: none;
|
||||
outline: none;
|
||||
box-shadow: none;
|
||||
background-color: transparent;
|
||||
color: #333;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
|
||||
.dropdown-options {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
overflow: scroll;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||
// overflow: hidden;
|
||||
padding: 6px 12px;
|
||||
}
|
||||
|
||||
.dropdown-option {
|
||||
/* Style your options here */
|
||||
padding: 10px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
|
||||
.email {
|
||||
font-size: 14px;
|
||||
padding-left: 10px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.title {
|
||||
margin: 0;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.more-functions .functions-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
margin: -10px;
|
||||
/* 用于抵消功能项的外边距 */
|
||||
/* padding: 20px; */
|
||||
}
|
||||
|
||||
.function-item {
|
||||
flex: 0 0 calc(25% - 20px);
|
||||
/* 每个功能项占据25%的宽度,减去外边距 */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin: 10px;
|
||||
/* 功能项之间的空间 */
|
||||
box-sizing: border-box;
|
||||
/* 确保边距包含在宽度计算内 */
|
||||
}
|
||||
|
||||
.function-icon {
|
||||
width: 35px;
|
||||
/* 图片宽度 */
|
||||
height: 35px;
|
||||
/* 图片高度,取决于实际需要 */
|
||||
margin-bottom: 8px;
|
||||
/* 图片与文字之间的距离 */
|
||||
}
|
||||
|
||||
.function-text {
|
||||
text-align: center;
|
||||
font-size: 0.8em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
background-color: #eaeaea;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.progress {
|
||||
height: 10px;
|
||||
background-color: #4caf50;
|
||||
width: 0;
|
||||
/* 初始宽度为0,会通过Vue的样式绑定动态设置 */
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.progressinfo {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.field {
|
||||
width: calc(100% / 3);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
margin: 5px;
|
||||
font-size: small;
|
||||
}
|
||||
|
||||
.field-value {
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="my-info">
|
||||
<p>{{ deptName }}</p>
|
||||
<p>用户名:{{ roleName }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from "vue";
|
||||
import { useInfoStore } from "@/stores";
|
||||
import { onShow, onHide } from '@dcloudio/uni-app'
|
||||
let roleName = ref()
|
||||
let deptName = ref()
|
||||
onShow(() => {
|
||||
const userStore = useInfoStore()
|
||||
roleName.value = userStore.userinfo?.userInfo.roleName;
|
||||
deptName.value = userStore.userinfo?.userInfo.deptName;
|
||||
})
|
||||
onHide(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.my-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 30px;
|
||||
min-height: 83vh;
|
||||
|
||||
p {
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding: 10px 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
export {}
|
||||
|
||||
declare module "vue" {
|
||||
type Hooks = App.AppInstance & Page.PageInstance;
|
||||
interface ComponentCustomOptions extends Hooks {}
|
||||
}
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 213 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 943 B |
|
After Width: | Height: | Size: 980 B |
|
After Width: | Height: | Size: 446 B |
|
After Width: | Height: | Size: 450 B |
|
After Width: | Height: | Size: 944 B |
|
After Width: | Height: | Size: 941 B |
|
After Width: | Height: | Size: 805 B |
|
After Width: | Height: | Size: 752 B |
|
|
@ -0,0 +1,10 @@
|
|||
import { createPinia } from "pinia";
|
||||
import persist from "pinia-plugin-persistedstate";
|
||||
|
||||
const pinia = createPinia();
|
||||
|
||||
pinia.use(persist);
|
||||
|
||||
export default pinia;
|
||||
|
||||
export * from "./modules/user";
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
// bidcodeStore.ts
|
||||
import { defineStore } from "pinia";
|
||||
|
||||
interface State {
|
||||
selectedBidcode: string | null; // 假设 bidCode 是字符串类型
|
||||
}
|
||||
|
||||
export const useBidcodeStore = defineStore("bidcode", {
|
||||
state: (): State => ({
|
||||
selectedBidcode: null, // 初始化 selectedBidcode
|
||||
}),
|
||||
actions: {
|
||||
setSelectedBidcode(bidCode: string) {
|
||||
this.selectedBidcode = bidCode;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
import type { LoginResult } from "@/types/user";
|
||||
import { defineStore } from "pinia";
|
||||
import { ref } from "vue";
|
||||
|
||||
// 定义 Store
|
||||
export const useInfoStore = defineStore(
|
||||
"user",
|
||||
() => {
|
||||
// 用户信息
|
||||
const userinfo = ref<LoginResult>();
|
||||
|
||||
const setUserInfo = (val: LoginResult) => {
|
||||
userinfo.value = val;
|
||||
};
|
||||
|
||||
const clearUserInfo = () => {
|
||||
userinfo.value = undefined;
|
||||
};
|
||||
|
||||
return { userinfo, setUserInfo, clearUserInfo };
|
||||
},
|
||||
{
|
||||
persist: {
|
||||
storage: {
|
||||
setItem(key, value) {
|
||||
uni.setStorageSync(key, value);
|
||||
},
|
||||
getItem(key) {
|
||||
return uni.getStorageSync(key);
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
export interface LoginResult {
|
||||
token: string; // 用户令牌
|
||||
userInfo: {
|
||||
roleCode: string;
|
||||
roleName?: string;
|
||||
deptName?: string;
|
||||
}; // 用户角色列表
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/* 颜色变量 */
|
||||
|
||||
/* 行为相关颜色 */
|
||||
$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: #fff;
|
||||
$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: #555; // 二级标题颜色
|
||||
$uni-font-size-subtitle: 18px;
|
||||
$uni-color-paragraph: #3f536e; // 文章段落颜色
|
||||
$uni-font-size-paragraph: 15px;
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
## 1.0.8(2024-03-28)
|
||||
- 修复 在vue2下:style动态绑定导致编译失败的bug
|
||||
## 1.0.7(2024-01-20)
|
||||
- 修复 长文本回显超过容器的bug,超过容器部分显示省略号
|
||||
## 1.0.6(2023-04-12)
|
||||
- 修复 微信小程序点击时会改变背景颜色的 bug
|
||||
## 1.0.5(2023-02-03)
|
||||
- 修复 禁用时会显示清空按钮
|
||||
## 1.0.4(2023-02-02)
|
||||
- 优化 查询条件短期内多次变更只查询最后一次变更后的结果
|
||||
- 调整 内部缓存键名调整为 uni-data-select-lastSelectedValue
|
||||
## 1.0.3(2023-01-16)
|
||||
- 修复 不关联服务空间报错的问题
|
||||
## 1.0.2(2023-01-14)
|
||||
- 新增 属性 `format` 可用于格式化显示选项内容
|
||||
## 1.0.1(2022-12-06)
|
||||
- 修复 当where变化时,数据不会自动更新的问题
|
||||
## 0.1.9(2022-09-05)
|
||||
- 修复 微信小程序下拉框出现后选择会点击到蒙板后面的输入框
|
||||
## 0.1.8(2022-08-29)
|
||||
- 修复 点击的位置不准确
|
||||
## 0.1.7(2022-08-12)
|
||||
- 新增 支持 disabled 属性
|
||||
## 0.1.6(2022-07-06)
|
||||
- 修复 pc端宽度异常的bug
|
||||
## 0.1.5
|
||||
- 修复 pc端宽度异常的bug
|
||||
## 0.1.4(2022-07-05)
|
||||
- 优化 显示样式
|
||||
## 0.1.3(2022-06-02)
|
||||
- 修复 localdata 赋值不生效的 bug
|
||||
- 新增 支持 uni.scss 修改颜色
|
||||
- 新增 支持选项禁用(数据选项设置 disabled: true 即禁用)
|
||||
## 0.1.2(2022-05-08)
|
||||
- 修复 当 value 为 0 时选择不生效的 bug
|
||||
## 0.1.1(2022-05-07)
|
||||
- 新增 记住上次的选项(仅 collection 存在时有效)
|
||||
## 0.1.0(2022-04-22)
|
||||
- 初始化
|
||||
|
|
@ -0,0 +1,565 @@
|
|||
<template>
|
||||
<view class="uni-stat__select">
|
||||
<span v-if="label" class="uni-label-text hide-on-phone">{{label + ':'}}</span>
|
||||
<view class="uni-stat-box" :class="{'uni-stat__actived': current}">
|
||||
<view class="uni-select" :class="{'uni-select--disabled':disabled}">
|
||||
<view class="uni-select__input-box" @click="toggleSelector">
|
||||
<view v-if="current" class="uni-select__input-text">{{textShow}}</view>
|
||||
<view v-else class="uni-select__input-text uni-select__input-placeholder">{{typePlaceholder}}</view>
|
||||
<view v-if="current && clear && !disabled" @click.stop="clearVal">
|
||||
<uni-icons type="clear" color="#c0c4cc" size="24" />
|
||||
</view>
|
||||
<view v-else>
|
||||
<uni-icons :type="showSelector? 'top' : 'bottom'" size="14" color="#999" />
|
||||
</view>
|
||||
</view>
|
||||
<view class="uni-select--mask" v-if="showSelector" @click="toggleSelector" />
|
||||
<view class="uni-select__selector" :style="getOffsetByPlacement" v-if="showSelector">
|
||||
<view :class="placement=='bottom'?'uni-popper__arrow_bottom':'uni-popper__arrow_top'"></view>
|
||||
<scroll-view scroll-y="true" class="uni-select__selector-scroll">
|
||||
<view class="uni-select__selector-empty" v-if="mixinDatacomResData.length === 0">
|
||||
<text>{{emptyTips}}</text>
|
||||
</view>
|
||||
<view v-else class="uni-select__selector-item" v-for="(item,index) in mixinDatacomResData" :key="index"
|
||||
@click="change(item)">
|
||||
<text :class="{'uni-select__selector__disabled': item.disable}">{{formatItemName(item)}}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* DataChecklist 数据选择器
|
||||
* @description 通过数据渲染的下拉框组件
|
||||
* @tutorial https://uniapp.dcloud.io/component/uniui/uni-data-select
|
||||
* @property {String} value 默认值
|
||||
* @property {Array} localdata 本地数据 ,格式 [{text:'',value:''}]
|
||||
* @property {Boolean} clear 是否可以清空已选项
|
||||
* @property {Boolean} emptyText 没有数据时显示的文字 ,本地数据无效
|
||||
* @property {String} label 左侧标题
|
||||
* @property {String} placeholder 输入框的提示文字
|
||||
* @property {Boolean} disabled 是否禁用
|
||||
* @property {String} placement 弹出位置
|
||||
* @value top 顶部弹出
|
||||
* @value bottom 底部弹出(default)
|
||||
* @event {Function} change 选中发生变化触发
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: "uni-data-select",
|
||||
mixins: [uniCloud.mixinDatacom || {}],
|
||||
props: {
|
||||
localdata: {
|
||||
type: Array,
|
||||
default () {
|
||||
return []
|
||||
}
|
||||
},
|
||||
value: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
modelValue: {
|
||||
type: [String, Number],
|
||||
default: ''
|
||||
},
|
||||
label: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: '请选择'
|
||||
},
|
||||
emptyTips: {
|
||||
type: String,
|
||||
default: '无选项'
|
||||
},
|
||||
clear: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
defItem: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 格式化输出 用法 field="_id as value, version as text, uni_platform as label" format="{label} - {text}"
|
||||
format: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
placement: {
|
||||
type: String,
|
||||
default: 'bottom'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showSelector: false,
|
||||
current: '',
|
||||
mixinDatacomResData: [],
|
||||
apps: [],
|
||||
channels: [],
|
||||
cacheKey: "uni-data-select-lastSelectedValue",
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.debounceGet = this.debounce(() => {
|
||||
this.query();
|
||||
}, 300);
|
||||
if (this.collection && !this.localdata.length) {
|
||||
this.debounceGet();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
typePlaceholder() {
|
||||
const text = {
|
||||
'opendb-stat-app-versions': '版本',
|
||||
'opendb-app-channels': '渠道',
|
||||
'opendb-app-list': '应用'
|
||||
}
|
||||
const common = this.placeholder
|
||||
const placeholder = text[this.collection]
|
||||
return placeholder ?
|
||||
common + placeholder :
|
||||
common
|
||||
},
|
||||
valueCom() {
|
||||
// #ifdef VUE3
|
||||
return this.modelValue;
|
||||
// #endif
|
||||
// #ifndef VUE3
|
||||
return this.value;
|
||||
// #endif
|
||||
},
|
||||
textShow() {
|
||||
// 长文本显示
|
||||
let text = this.current;
|
||||
if (text.length > 10) {
|
||||
return text.slice(0, 25) + '...';
|
||||
}
|
||||
return text;
|
||||
},
|
||||
getOffsetByPlacement() {
|
||||
switch (this.placement) {
|
||||
case 'top':
|
||||
return "bottom:calc(100% + 12px);";
|
||||
case 'bottom':
|
||||
return "top:calc(100% + 12px);";
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
localdata: {
|
||||
immediate: true,
|
||||
handler(val, old) {
|
||||
if (Array.isArray(val) && old !== val) {
|
||||
this.mixinDatacomResData = val
|
||||
}
|
||||
}
|
||||
},
|
||||
valueCom(val, old) {
|
||||
this.initDefVal()
|
||||
},
|
||||
mixinDatacomResData: {
|
||||
immediate: true,
|
||||
handler(val) {
|
||||
if (val.length) {
|
||||
this.initDefVal()
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
methods: {
|
||||
debounce(fn, time = 100) {
|
||||
let timer = null
|
||||
return function(...args) {
|
||||
if (timer) clearTimeout(timer)
|
||||
timer = setTimeout(() => {
|
||||
fn.apply(this, args)
|
||||
}, time)
|
||||
}
|
||||
},
|
||||
// 执行数据库查询
|
||||
query() {
|
||||
this.mixinDatacomEasyGet();
|
||||
},
|
||||
// 监听查询条件变更事件
|
||||
onMixinDatacomPropsChange() {
|
||||
if (this.collection) {
|
||||
this.debounceGet();
|
||||
}
|
||||
},
|
||||
initDefVal() {
|
||||
let defValue = ''
|
||||
if ((this.valueCom || this.valueCom === 0) && !this.isDisabled(this.valueCom)) {
|
||||
defValue = this.valueCom
|
||||
} else {
|
||||
let strogeValue
|
||||
if (this.collection) {
|
||||
strogeValue = this.getCache()
|
||||
}
|
||||
if (strogeValue || strogeValue === 0) {
|
||||
defValue = strogeValue
|
||||
} else {
|
||||
let defItem = ''
|
||||
if (this.defItem > 0 && this.defItem <= this.mixinDatacomResData.length) {
|
||||
defItem = this.mixinDatacomResData[this.defItem - 1].value
|
||||
}
|
||||
defValue = defItem
|
||||
}
|
||||
if (defValue || defValue === 0) {
|
||||
this.emit(defValue)
|
||||
}
|
||||
}
|
||||
const def = this.mixinDatacomResData.find(item => item.value === defValue)
|
||||
this.current = def ? this.formatItemName(def) : ''
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {[String, Number]} value
|
||||
* 判断用户给的 value 是否同时为禁用状态
|
||||
*/
|
||||
isDisabled(value) {
|
||||
let isDisabled = false;
|
||||
|
||||
this.mixinDatacomResData.forEach(item => {
|
||||
if (item.value === value) {
|
||||
isDisabled = item.disable
|
||||
}
|
||||
})
|
||||
|
||||
return isDisabled;
|
||||
},
|
||||
|
||||
clearVal() {
|
||||
this.emit('')
|
||||
if (this.collection) {
|
||||
this.removeCache()
|
||||
}
|
||||
},
|
||||
change(item) {
|
||||
if (!item.disable) {
|
||||
this.showSelector = false
|
||||
this.current = this.formatItemName(item)
|
||||
this.emit(item.value)
|
||||
}
|
||||
},
|
||||
emit(val) {
|
||||
this.$emit('input', val)
|
||||
this.$emit('update:modelValue', val)
|
||||
this.$emit('change', val)
|
||||
if (this.collection) {
|
||||
this.setCache(val);
|
||||
}
|
||||
},
|
||||
toggleSelector() {
|
||||
if (this.disabled) {
|
||||
return
|
||||
}
|
||||
|
||||
this.showSelector = !this.showSelector
|
||||
},
|
||||
formatItemName(item) {
|
||||
let {
|
||||
text,
|
||||
value,
|
||||
channel_code
|
||||
} = item
|
||||
channel_code = channel_code ? `(${channel_code})` : ''
|
||||
|
||||
if (this.format) {
|
||||
// 格式化输出
|
||||
let str = "";
|
||||
str = this.format;
|
||||
for (let key in item) {
|
||||
str = str.replace(new RegExp(`{${key}}`, "g"), item[key]);
|
||||
}
|
||||
return str;
|
||||
} else {
|
||||
return this.collection.indexOf('app-list') > 0 ?
|
||||
`${text}(${value})` :
|
||||
(
|
||||
text ?
|
||||
text :
|
||||
`未命名${channel_code}`
|
||||
)
|
||||
}
|
||||
},
|
||||
// 获取当前加载的数据
|
||||
getLoadData() {
|
||||
return this.mixinDatacomResData;
|
||||
},
|
||||
// 获取当前缓存key
|
||||
getCurrentCacheKey() {
|
||||
return this.collection;
|
||||
},
|
||||
// 获取缓存
|
||||
getCache(name = this.getCurrentCacheKey()) {
|
||||
let cacheData = uni.getStorageSync(this.cacheKey) || {};
|
||||
return cacheData[name];
|
||||
},
|
||||
// 设置缓存
|
||||
setCache(value, name = this.getCurrentCacheKey()) {
|
||||
let cacheData = uni.getStorageSync(this.cacheKey) || {};
|
||||
cacheData[name] = value;
|
||||
uni.setStorageSync(this.cacheKey, cacheData);
|
||||
},
|
||||
// 删除缓存
|
||||
removeCache(name = this.getCurrentCacheKey()) {
|
||||
let cacheData = uni.getStorageSync(this.cacheKey) || {};
|
||||
delete cacheData[name];
|
||||
uni.setStorageSync(this.cacheKey, cacheData);
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
$uni-base-color: #6a6a6a !default;
|
||||
$uni-main-color: #333 !default;
|
||||
$uni-secondary-color: #909399 !default;
|
||||
$uni-border-3: #e5e5e5;
|
||||
|
||||
/* #ifndef APP-NVUE */
|
||||
@media screen and (max-width: 500px) {
|
||||
.hide-on-phone {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
.uni-stat__select {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
// padding: 15px;
|
||||
/* #ifdef H5 */
|
||||
cursor: pointer;
|
||||
/* #endif */
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.uni-stat-box {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.uni-stat__actived {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
// outline: 1px solid #2979ff;
|
||||
}
|
||||
|
||||
.uni-label-text {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: $uni-base-color;
|
||||
margin: auto 0;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.uni-select {
|
||||
font-size: 14px;
|
||||
border: 0px;
|
||||
box-sizing: border-box;
|
||||
border-radius: 4px;
|
||||
padding: 0 5px;
|
||||
padding-left: 10px;
|
||||
position: relative;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
user-select: none;
|
||||
/* #endif */
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
border-bottom: solid 0px #000;
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
height: 35px;
|
||||
|
||||
&--disabled {
|
||||
background-color: #f5f7fa;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
}
|
||||
|
||||
.uni-select__label {
|
||||
font-size: 16px;
|
||||
// line-height: 22px;
|
||||
height: 35px;
|
||||
padding-right: 10px;
|
||||
color: $uni-secondary-color;
|
||||
}
|
||||
|
||||
.uni-select__input-box {
|
||||
height: 35px;
|
||||
position: relative;
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
/* #endif */
|
||||
flex: 1;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.uni-select__input {
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.uni-select__input-plac {
|
||||
font-size: 14px;
|
||||
color: $uni-secondary-color;
|
||||
}
|
||||
|
||||
.uni-select__selector {
|
||||
/* #ifndef APP-NVUE */
|
||||
box-sizing: border-box;
|
||||
/* #endif */
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
background-color: #FFFFFF;
|
||||
border: 1px solid #EBEEF5;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
z-index: 3;
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.uni-select__selector-scroll {
|
||||
/* #ifndef APP-NVUE */
|
||||
max-height: 200px;
|
||||
box-sizing: border-box;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
/* #ifdef H5 */
|
||||
@media (min-width: 768px) {
|
||||
.uni-select__selector-scroll {
|
||||
max-height: 600px;
|
||||
}
|
||||
}
|
||||
|
||||
/* #endif */
|
||||
|
||||
.uni-select__selector-empty,
|
||||
.uni-select__selector-item {
|
||||
/* #ifndef APP-NVUE */
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
/* #endif */
|
||||
line-height: 35px;
|
||||
font-size: 14px;
|
||||
text-align: center;
|
||||
/* border-bottom: solid 1px $uni-border-3; */
|
||||
padding: 0px 10px;
|
||||
}
|
||||
|
||||
.uni-select__selector-item:hover {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.uni-select__selector-empty:last-child,
|
||||
.uni-select__selector-item:last-child {
|
||||
/* #ifndef APP-NVUE */
|
||||
border-bottom: none;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.uni-select__selector__disabled {
|
||||
opacity: 0.4;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
/* picker 弹出层通用的指示小三角 */
|
||||
.uni-popper__arrow_bottom,
|
||||
.uni-popper__arrow_bottom::after,
|
||||
.uni-popper__arrow_top,
|
||||
.uni-popper__arrow_top::after,
|
||||
{
|
||||
position: absolute;
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-color: transparent;
|
||||
border-style: solid;
|
||||
border-width: 6px;
|
||||
}
|
||||
|
||||
.uni-popper__arrow_bottom {
|
||||
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
|
||||
top: -6px;
|
||||
left: 10%;
|
||||
margin-right: 3px;
|
||||
border-top-width: 0;
|
||||
border-bottom-color: #EBEEF5;
|
||||
}
|
||||
|
||||
.uni-popper__arrow_bottom::after {
|
||||
content: " ";
|
||||
top: 1px;
|
||||
margin-left: -6px;
|
||||
border-top-width: 0;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
|
||||
.uni-popper__arrow_top {
|
||||
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.03));
|
||||
bottom: -6px;
|
||||
left: 10%;
|
||||
margin-right: 3px;
|
||||
border-bottom-width: 0;
|
||||
border-top-color: #EBEEF5;
|
||||
}
|
||||
|
||||
.uni-popper__arrow_top::after {
|
||||
content: " ";
|
||||
bottom: 1px;
|
||||
margin-left: -6px;
|
||||
border-bottom-width: 0;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
|
||||
|
||||
.uni-select__input-text {
|
||||
// width: 280px;
|
||||
width: 100%;
|
||||
color: $uni-main-color;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
-o-text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.uni-select__input-placeholder {
|
||||
color: $uni-main-color;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.uni-select--mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
"id": "uni-data-select",
|
||||
"displayName": "uni-data-select 下拉框选择器",
|
||||
"version": "1.0.8",
|
||||
"description": "通过数据驱动的下拉框选择器",
|
||||
"keywords": [
|
||||
"uni-ui",
|
||||
"select",
|
||||
"uni-data-select",
|
||||
"下拉框",
|
||||
"下拉选"
|
||||
],
|
||||
"repository": "https://github.com/dcloudio/uni-ui",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.1"
|
||||
},
|
||||
"directories": {
|
||||
"example": "../../temps/example_temps"
|
||||
},
|
||||
"dcloudext": {
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
|
||||
"type": "component-vue"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": ["uni-load-more"],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y",
|
||||
"alipay": "n"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "u",
|
||||
"app-nvue": "n"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "u",
|
||||
"百度": "u",
|
||||
"字节跳动": "u",
|
||||
"QQ": "u",
|
||||
"京东": "u"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
},
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
## DataSelect 下拉框选择器
|
||||
> **组件名:uni-data-select**
|
||||
> 代码块: `uDataSelect`
|
||||
|
||||
当选项过多时,使用下拉菜单展示并选择内容
|
||||
|
||||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-data-select)
|
||||
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
## 1.3.3(2022-01-20)
|
||||
- 新增 showText属性 ,是否显示文本
|
||||
## 1.3.2(2022-01-19)
|
||||
- 修复 nvue 平台下不显示文本的bug
|
||||
## 1.3.1(2022-01-19)
|
||||
- 修复 微信小程序平台样式选择器报警告的问题
|
||||
## 1.3.0(2021-11-19)
|
||||
- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
|
||||
- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-load-more](https://uniapp.dcloud.io/component/uniui/uni-load-more)
|
||||
## 1.2.1(2021-08-24)
|
||||
- 新增 支持国际化
|
||||
## 1.2.0(2021-07-30)
|
||||
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||
## 1.1.8(2021-05-12)
|
||||
- 新增 组件示例地址
|
||||
## 1.1.7(2021-03-30)
|
||||
- 修复 uni-load-more 在首页使用时,h5 平台报 'uni is not defined' 的 bug
|
||||
## 1.1.6(2021-02-05)
|
||||
- 调整为uni_modules目录规范
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"uni-load-more.contentdown": "Pull up to show more",
|
||||
"uni-load-more.contentrefresh": "loading...",
|
||||
"uni-load-more.contentnomore": "No more data"
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import en from './en.json'
|
||||
import zhHans from './zh-Hans.json'
|
||||
import zhHant from './zh-Hant.json'
|
||||
export default {
|
||||
en,
|
||||
'zh-Hans': zhHans,
|
||||
'zh-Hant': zhHant
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"uni-load-more.contentdown": "上拉显示更多",
|
||||
"uni-load-more.contentrefresh": "正在加载...",
|
||||
"uni-load-more.contentnomore": "没有更多数据了"
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"uni-load-more.contentdown": "上拉顯示更多",
|
||||
"uni-load-more.contentrefresh": "正在加載...",
|
||||
"uni-load-more.contentnomore": "沒有更多數據了"
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
{
|
||||
"id": "uni-load-more",
|
||||
"displayName": "uni-load-more 加载更多",
|
||||
"version": "1.3.3",
|
||||
"description": "LoadMore 组件,常用在列表里面,做滚动加载使用。",
|
||||
"keywords": [
|
||||
"uni-ui",
|
||||
"uniui",
|
||||
"加载更多",
|
||||
"load-more"
|
||||
],
|
||||
"repository": "https://github.com/dcloudio/uni-ui",
|
||||
"engines": {
|
||||
"HBuilderX": ""
|
||||
},
|
||||
"directories": {
|
||||
"example": "../../temps/example_temps"
|
||||
},
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"前端组件",
|
||||
"通用组件"
|
||||
],
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": ["uni-scss"],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "y"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "u",
|
||||
"联盟": "u"
|
||||
},
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
|
||||
### LoadMore 加载更多
|
||||
> **组件名:uni-load-more**
|
||||
> 代码块: `uLoadMore`
|
||||
|
||||
|
||||
用于列表中,做滚动加载使用,展示 loading 的各种状态。
|
||||
|
||||
|
||||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-load-more)
|
||||
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
## 1.0.3(2022-01-21)
|
||||
- 优化 组件示例
|
||||
## 1.0.2(2021-11-22)
|
||||
- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
|
||||
## 1.0.1(2021-11-22)
|
||||
- 修复 vue3中scss语法兼容问题
|
||||
## 1.0.0(2021-11-18)
|
||||
- init
|
||||
|
|
@ -0,0 +1 @@
|
|||
@import './styles/index.scss';
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
{
|
||||
"id": "uni-scss",
|
||||
"displayName": "uni-scss 辅助样式",
|
||||
"version": "1.0.3",
|
||||
"description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
|
||||
"keywords": [
|
||||
"uni-scss",
|
||||
"uni-ui",
|
||||
"辅助样式"
|
||||
],
|
||||
"repository": "https://github.com/dcloudio/uni-ui",
|
||||
"engines": {
|
||||
"HBuilderX": "^3.1.0"
|
||||
},
|
||||
"dcloudext": {
|
||||
"category": [
|
||||
"JS SDK",
|
||||
"通用 SDK"
|
||||
],
|
||||
"sale": {
|
||||
"regular": {
|
||||
"price": "0.00"
|
||||
},
|
||||
"sourcecode": {
|
||||
"price": "0.00"
|
||||
}
|
||||
},
|
||||
"contact": {
|
||||
"qq": ""
|
||||
},
|
||||
"declaration": {
|
||||
"ads": "无",
|
||||
"data": "无",
|
||||
"permissions": "无"
|
||||
},
|
||||
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
|
||||
},
|
||||
"uni_modules": {
|
||||
"dependencies": [],
|
||||
"encrypt": [],
|
||||
"platforms": {
|
||||
"cloud": {
|
||||
"tcb": "y",
|
||||
"aliyun": "y"
|
||||
},
|
||||
"client": {
|
||||
"App": {
|
||||
"app-vue": "y",
|
||||
"app-nvue": "u"
|
||||
},
|
||||
"H5-mobile": {
|
||||
"Safari": "y",
|
||||
"Android Browser": "y",
|
||||
"微信浏览器(Android)": "y",
|
||||
"QQ浏览器(Android)": "y"
|
||||
},
|
||||
"H5-pc": {
|
||||
"Chrome": "y",
|
||||
"IE": "y",
|
||||
"Edge": "y",
|
||||
"Firefox": "y",
|
||||
"Safari": "y"
|
||||
},
|
||||
"小程序": {
|
||||
"微信": "y",
|
||||
"阿里": "y",
|
||||
"百度": "y",
|
||||
"字节跳动": "y",
|
||||
"QQ": "y"
|
||||
},
|
||||
"快应用": {
|
||||
"华为": "n",
|
||||
"联盟": "n"
|
||||
},
|
||||
"Vue": {
|
||||
"vue2": "y",
|
||||
"vue3": "y"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
|
||||
|
||||
### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
|
||||
#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
@import './setting/_variables.scss';
|
||||
@import './setting/_border.scss';
|
||||
@import './setting/_color.scss';
|
||||
@import './setting/_space.scss';
|
||||
@import './setting/_radius.scss';
|
||||
@import './setting/_text.scss';
|
||||
@import './setting/_styles.scss';
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
.uni-border {
|
||||
border: 1px $uni-border-1 solid;
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
|
||||
// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
|
||||
// @mixin get-styles($k,$c) {
|
||||
// @if $k == size or $k == weight{
|
||||
// font-#{$k}:#{$c}
|
||||
// }@else{
|
||||
// #{$k}:#{$c}
|
||||
// }
|
||||
// }
|
||||
$uni-ui-color:(
|
||||
// 主色
|
||||
primary: $uni-primary,
|
||||
primary-disable: $uni-primary-disable,
|
||||
primary-light: $uni-primary-light,
|
||||
// 辅助色
|
||||
success: $uni-success,
|
||||
success-disable: $uni-success-disable,
|
||||
success-light: $uni-success-light,
|
||||
warning: $uni-warning,
|
||||
warning-disable: $uni-warning-disable,
|
||||
warning-light: $uni-warning-light,
|
||||
error: $uni-error,
|
||||
error-disable: $uni-error-disable,
|
||||
error-light: $uni-error-light,
|
||||
info: $uni-info,
|
||||
info-disable: $uni-info-disable,
|
||||
info-light: $uni-info-light,
|
||||
// 中性色
|
||||
main-color: $uni-main-color,
|
||||
base-color: $uni-base-color,
|
||||
secondary-color: $uni-secondary-color,
|
||||
extra-color: $uni-extra-color,
|
||||
// 背景色
|
||||
bg-color: $uni-bg-color,
|
||||
// 边框颜色
|
||||
border-1: $uni-border-1,
|
||||
border-2: $uni-border-2,
|
||||
border-3: $uni-border-3,
|
||||
border-4: $uni-border-4,
|
||||
// 黑色
|
||||
black:$uni-black,
|
||||
// 白色
|
||||
white:$uni-white,
|
||||
// 透明
|
||||
transparent:$uni-transparent
|
||||
) !default;
|
||||
@each $key, $child in $uni-ui-color {
|
||||
.uni-#{"" + $key} {
|
||||
color: $child;
|
||||
}
|
||||
.uni-#{"" + $key}-bg {
|
||||
background-color: $child;
|
||||
}
|
||||
}
|
||||
.uni-shadow-sm {
|
||||
box-shadow: $uni-shadow-sm;
|
||||
}
|
||||
.uni-shadow-base {
|
||||
box-shadow: $uni-shadow-base;
|
||||
}
|
||||
.uni-shadow-lg {
|
||||
box-shadow: $uni-shadow-lg;
|
||||
}
|
||||
.uni-mask {
|
||||
background-color:$uni-mask;
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
@mixin radius($r,$d:null ,$important: false){
|
||||
$radius-value:map-get($uni-radius, $r) if($important, !important, null);
|
||||
// Key exists within the $uni-radius variable
|
||||
@if (map-has-key($uni-radius, $r) and $d){
|
||||
@if $d == t {
|
||||
border-top-left-radius:$radius-value;
|
||||
border-top-right-radius:$radius-value;
|
||||
}@else if $d == r {
|
||||
border-top-right-radius:$radius-value;
|
||||
border-bottom-right-radius:$radius-value;
|
||||
}@else if $d == b {
|
||||
border-bottom-left-radius:$radius-value;
|
||||
border-bottom-right-radius:$radius-value;
|
||||
}@else if $d == l {
|
||||
border-top-left-radius:$radius-value;
|
||||
border-bottom-left-radius:$radius-value;
|
||||
}@else if $d == tl {
|
||||
border-top-left-radius:$radius-value;
|
||||
}@else if $d == tr {
|
||||
border-top-right-radius:$radius-value;
|
||||
}@else if $d == br {
|
||||
border-bottom-right-radius:$radius-value;
|
||||
}@else if $d == bl {
|
||||
border-bottom-left-radius:$radius-value;
|
||||
}
|
||||
}@else{
|
||||
border-radius:$radius-value;
|
||||
}
|
||||
}
|
||||
|
||||
@each $key, $child in $uni-radius {
|
||||
@if($key){
|
||||
.uni-radius-#{"" + $key} {
|
||||
@include radius($key)
|
||||
}
|
||||
}@else{
|
||||
.uni-radius {
|
||||
@include radius($key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $direction in t, r, b, l,tl, tr, br, bl {
|
||||
@each $key, $child in $uni-radius {
|
||||
@if($key){
|
||||
.uni-radius-#{"" + $direction}-#{"" + $key} {
|
||||
@include radius($key,$direction,false)
|
||||
}
|
||||
}@else{
|
||||
.uni-radius-#{$direction} {
|
||||
@include radius($key,$direction,false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
@mixin fn($space,$direction,$size,$n) {
|
||||
@if $n {
|
||||
#{$space}-#{$direction}: #{$size*$uni-space-root}px
|
||||
} @else {
|
||||
#{$space}-#{$direction}: #{-$size*$uni-space-root}px
|
||||
}
|
||||
}
|
||||
@mixin get-styles($direction,$i,$space,$n){
|
||||
@if $direction == t {
|
||||
@include fn($space, top,$i,$n);
|
||||
}
|
||||
@if $direction == r {
|
||||
@include fn($space, right,$i,$n);
|
||||
}
|
||||
@if $direction == b {
|
||||
@include fn($space, bottom,$i,$n);
|
||||
}
|
||||
@if $direction == l {
|
||||
@include fn($space, left,$i,$n);
|
||||
}
|
||||
@if $direction == x {
|
||||
@include fn($space, left,$i,$n);
|
||||
@include fn($space, right,$i,$n);
|
||||
}
|
||||
@if $direction == y {
|
||||
@include fn($space, top,$i,$n);
|
||||
@include fn($space, bottom,$i,$n);
|
||||
}
|
||||
@if $direction == a {
|
||||
@if $n {
|
||||
#{$space}:#{$i*$uni-space-root}px;
|
||||
} @else {
|
||||
#{$space}:#{-$i*$uni-space-root}px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@each $orientation in m,p {
|
||||
$space: margin;
|
||||
@if $orientation == m {
|
||||
$space: margin;
|
||||
} @else {
|
||||
$space: padding;
|
||||
}
|
||||
@for $i from 0 through 16 {
|
||||
@each $direction in t, r, b, l, x, y, a {
|
||||
.uni-#{$orientation}#{$direction}-#{$i} {
|
||||
@include get-styles($direction,$i,$space,true);
|
||||
}
|
||||
.uni-#{$orientation}#{$direction}-n#{$i} {
|
||||
@include get-styles($direction,$i,$space,false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
/* #ifndef APP-NVUE */
|
||||
|
||||
$-color-white:#fff;
|
||||
$-color-black:#000;
|
||||
@mixin base-style($color) {
|
||||
color: #fff;
|
||||
background-color: $color;
|
||||
border-color: mix($-color-black, $color, 8%);
|
||||
&:not([hover-class]):active {
|
||||
background: mix($-color-black, $color, 10%);
|
||||
border-color: mix($-color-black, $color, 20%);
|
||||
color: $-color-white;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
@mixin is-color($color) {
|
||||
@include base-style($color);
|
||||
&[loading] {
|
||||
@include base-style($color);
|
||||
&::before {
|
||||
margin-right:5px;
|
||||
}
|
||||
}
|
||||
&[disabled] {
|
||||
&,
|
||||
&[loading],
|
||||
&:not([hover-class]):active {
|
||||
color: $-color-white;
|
||||
border-color: mix(darken($color,10%), $-color-white);
|
||||
background-color: mix($color, $-color-white);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@mixin base-plain-style($color) {
|
||||
color:$color;
|
||||
background-color: mix($-color-white, $color, 90%);
|
||||
border-color: mix($-color-white, $color, 70%);
|
||||
&:not([hover-class]):active {
|
||||
background: mix($-color-white, $color, 80%);
|
||||
color: $color;
|
||||
outline: none;
|
||||
border-color: mix($-color-white, $color, 50%);
|
||||
}
|
||||
}
|
||||
@mixin is-plain($color){
|
||||
&[plain] {
|
||||
@include base-plain-style($color);
|
||||
&[loading] {
|
||||
@include base-plain-style($color);
|
||||
&::before {
|
||||
margin-right:5px;
|
||||
}
|
||||
}
|
||||
&[disabled] {
|
||||
&,
|
||||
&:active {
|
||||
color: mix($-color-white, $color, 40%);
|
||||
background-color: mix($-color-white, $color, 90%);
|
||||
border-color: mix($-color-white, $color, 80%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.uni-btn {
|
||||
margin: 5px;
|
||||
color: #393939;
|
||||
border:1px solid #ccc;
|
||||
font-size: 16px;
|
||||
font-weight: 200;
|
||||
background-color: #F9F9F9;
|
||||
// TODO 暂时处理边框隐藏一边的问题
|
||||
overflow: visible;
|
||||
&::after{
|
||||
border: none;
|
||||
}
|
||||
|
||||
&:not([type]),&[type=default] {
|
||||
color: #999;
|
||||
&[loading] {
|
||||
background: none;
|
||||
&::before {
|
||||
margin-right:5px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
&[disabled]{
|
||||
color: mix($-color-white, #999, 60%);
|
||||
&,
|
||||
&[loading],
|
||||
&:active {
|
||||
color: mix($-color-white, #999, 60%);
|
||||
background-color: mix($-color-white,$-color-black , 98%);
|
||||
border-color: mix($-color-white, #999, 85%);
|
||||
}
|
||||
}
|
||||
|
||||
&[plain] {
|
||||
color: #999;
|
||||
background: none;
|
||||
border-color: $uni-border-1;
|
||||
&:not([hover-class]):active {
|
||||
background: none;
|
||||
color: mix($-color-white, $-color-black, 80%);
|
||||
border-color: mix($-color-white, $-color-black, 90%);
|
||||
outline: none;
|
||||
}
|
||||
&[disabled]{
|
||||
&,
|
||||
&[loading],
|
||||
&:active {
|
||||
background: none;
|
||||
color: mix($-color-white, #999, 60%);
|
||||
border-color: mix($-color-white, #999, 85%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:not([hover-class]):active {
|
||||
color: mix($-color-white, $-color-black, 50%);
|
||||
}
|
||||
|
||||
&[size=mini] {
|
||||
font-size: 16px;
|
||||
font-weight: 200;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
&.uni-btn-small {
|
||||
font-size: 14px;
|
||||
}
|
||||
&.uni-btn-mini {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
&.uni-btn-radius {
|
||||
border-radius: 999px;
|
||||
}
|
||||
&[type=primary] {
|
||||
@include is-color($uni-primary);
|
||||
@include is-plain($uni-primary)
|
||||
}
|
||||
&[type=success] {
|
||||
@include is-color($uni-success);
|
||||
@include is-plain($uni-success)
|
||||
}
|
||||
&[type=error] {
|
||||
@include is-color($uni-error);
|
||||
@include is-plain($uni-error)
|
||||
}
|
||||
&[type=warning] {
|
||||
@include is-color($uni-warning);
|
||||
@include is-plain($uni-warning)
|
||||
}
|
||||
&[type=info] {
|
||||
@include is-color($uni-info);
|
||||
@include is-plain($uni-info)
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
@mixin get-styles($k,$c) {
|
||||
@if $k == size or $k == weight{
|
||||
font-#{$k}:#{$c}
|
||||
}@else{
|
||||
#{$k}:#{$c}
|
||||
}
|
||||
}
|
||||
|
||||
@each $key, $child in $uni-headings {
|
||||
/* #ifndef APP-NVUE */
|
||||
.uni-#{$key} {
|
||||
@each $k, $c in $child {
|
||||
@include get-styles($k,$c)
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
/* #ifdef APP-NVUE */
|
||||
.container .uni-#{$key} {
|
||||
@each $k, $c in $child {
|
||||
@include get-styles($k,$c)
|
||||
}
|
||||
}
|
||||
/* #endif */
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
// @use "sass:math";
|
||||
@import '../tools/functions.scss';
|
||||
// 间距基础倍数
|
||||
$uni-space-root: 2 !default;
|
||||
// 边框半径默认值
|
||||
$uni-radius-root:5px !default;
|
||||
$uni-radius: () !default;
|
||||
// 边框半径断点
|
||||
$uni-radius: map-deep-merge(
|
||||
(
|
||||
0: 0,
|
||||
// TODO 当前版本暂时不支持 sm 属性
|
||||
// 'sm': math.div($uni-radius-root, 2),
|
||||
null: $uni-radius-root,
|
||||
'lg': $uni-radius-root * 2,
|
||||
'xl': $uni-radius-root * 6,
|
||||
'pill': 9999px,
|
||||
'circle': 50%
|
||||
),
|
||||
$uni-radius
|
||||
);
|
||||
// 字体家族
|
||||
$body-font-family: 'Roboto', sans-serif !default;
|
||||
// 文本
|
||||
$heading-font-family: $body-font-family !default;
|
||||
$uni-headings: () !default;
|
||||
$letterSpacing: -0.01562em;
|
||||
$uni-headings: map-deep-merge(
|
||||
(
|
||||
'h1': (
|
||||
size: 32px,
|
||||
weight: 300,
|
||||
line-height: 50px,
|
||||
// letter-spacing:-0.01562em
|
||||
),
|
||||
'h2': (
|
||||
size: 28px,
|
||||
weight: 300,
|
||||
line-height: 40px,
|
||||
// letter-spacing: -0.00833em
|
||||
),
|
||||
'h3': (
|
||||
size: 24px,
|
||||
weight: 400,
|
||||
line-height: 32px,
|
||||
// letter-spacing: normal
|
||||
),
|
||||
'h4': (
|
||||
size: 20px,
|
||||
weight: 400,
|
||||
line-height: 30px,
|
||||
// letter-spacing: 0.00735em
|
||||
),
|
||||
'h5': (
|
||||
size: 16px,
|
||||
weight: 400,
|
||||
line-height: 24px,
|
||||
// letter-spacing: normal
|
||||
),
|
||||
'h6': (
|
||||
size: 14px,
|
||||
weight: 500,
|
||||
line-height: 18px,
|
||||
// letter-spacing: 0.0125em
|
||||
),
|
||||
'subtitle': (
|
||||
size: 12px,
|
||||
weight: 400,
|
||||
line-height: 20px,
|
||||
// letter-spacing: 0.00937em
|
||||
),
|
||||
'body': (
|
||||
font-size: 14px,
|
||||
font-weight: 400,
|
||||
line-height: 22px,
|
||||
// letter-spacing: 0.03125em
|
||||
),
|
||||
'caption': (
|
||||
'size': 12px,
|
||||
'weight': 400,
|
||||
'line-height': 20px,
|
||||
// 'letter-spacing': 0.03333em,
|
||||
// 'text-transform': false
|
||||
)
|
||||
),
|
||||
$uni-headings
|
||||
);
|
||||
|
||||
|
||||
|
||||
// 主色
|
||||
$uni-primary: #2979ff !default;
|
||||
$uni-primary-disable:lighten($uni-primary,20%) !default;
|
||||
$uni-primary-light: lighten($uni-primary,25%) !default;
|
||||
|
||||
// 辅助色
|
||||
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
|
||||
$uni-success: #18bc37 !default;
|
||||
$uni-success-disable:lighten($uni-success,20%) !default;
|
||||
$uni-success-light: lighten($uni-success,25%) !default;
|
||||
|
||||
$uni-warning: #f3a73f !default;
|
||||
$uni-warning-disable:lighten($uni-warning,20%) !default;
|
||||
$uni-warning-light: lighten($uni-warning,25%) !default;
|
||||
|
||||
$uni-error: #e43d33 !default;
|
||||
$uni-error-disable:lighten($uni-error,20%) !default;
|
||||
$uni-error-light: lighten($uni-error,25%) !default;
|
||||
|
||||
$uni-info: #8f939c !default;
|
||||
$uni-info-disable:lighten($uni-info,20%) !default;
|
||||
$uni-info-light: lighten($uni-info,25%) !default;
|
||||
|
||||
// 中性色
|
||||
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
|
||||
$uni-main-color: #3a3a3a !default; // 主要文字
|
||||
$uni-base-color: #6a6a6a !default; // 常规文字
|
||||
$uni-secondary-color: #909399 !default; // 次要文字
|
||||
$uni-extra-color: #c7c7c7 !default; // 辅助说明
|
||||
|
||||
// 边框颜色
|
||||
$uni-border-1: #F0F0F0 !default;
|
||||
$uni-border-2: #EDEDED !default;
|
||||
$uni-border-3: #DCDCDC !default;
|
||||
$uni-border-4: #B9B9B9 !default;
|
||||
|
||||
// 常规色
|
||||
$uni-black: #000000 !default;
|
||||
$uni-white: #ffffff !default;
|
||||
$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
|
||||
|
||||
// 背景色
|
||||
$uni-bg-color: #f7f7f7 !default;
|
||||
|
||||
/* 水平间距 */
|
||||
$uni-spacing-sm: 8px !default;
|
||||
$uni-spacing-base: 15px !default;
|
||||
$uni-spacing-lg: 30px !default;
|
||||
|
||||
// 阴影
|
||||
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
|
||||
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
|
||||
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
|
||||
|
||||
// 蒙版
|
||||
$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// 合并 map
|
||||
@function map-deep-merge($parent-map, $child-map){
|
||||
$result: $parent-map;
|
||||
@each $key, $child in $child-map {
|
||||
$parent-has-key: map-has-key($result, $key);
|
||||
$parent-value: map-get($result, $key);
|
||||
$parent-type: type-of($parent-value);
|
||||
$child-type: type-of($child);
|
||||
$parent-is-map: $parent-type == map;
|
||||
$child-is-map: $child-type == map;
|
||||
|
||||
@if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
|
||||
$result: map-merge($result, ( $key: $child ));
|
||||
}@else {
|
||||
$result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
|
||||
}
|
||||
}
|
||||
@return $result;
|
||||
};
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
// 间距基础倍数
|
||||
$uni-space-root: 2;
|
||||
// 边框半径默认值
|
||||
$uni-radius-root:5px;
|
||||
// 主色
|
||||
$uni-primary: #2979ff;
|
||||
// 辅助色
|
||||
$uni-success: #4cd964;
|
||||
// 警告色
|
||||
$uni-warning: #f0ad4e;
|
||||
// 错误色
|
||||
$uni-error: #dd524d;
|
||||
// 描述色
|
||||
$uni-info: #909399;
|
||||
// 中性色
|
||||
$uni-main-color: #303133;
|
||||
$uni-base-color: #606266;
|
||||
$uni-secondary-color: #909399;
|
||||
$uni-extra-color: #C0C4CC;
|
||||
// 背景色
|
||||
$uni-bg-color: #f5f5f5;
|
||||
// 边框颜色
|
||||
$uni-border-1: #DCDFE6;
|
||||
$uni-border-2: #E4E7ED;
|
||||
$uni-border-3: #EBEEF5;
|
||||
$uni-border-4: #F2F6FC;
|
||||
|
||||
// 常规色
|
||||
$uni-black: #000000;
|
||||
$uni-white: #ffffff;
|
||||
$uni-transparent: rgba($color: #000000, $alpha: 0);
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
@import './styles/setting/_variables.scss';
|
||||
// 间距基础倍数
|
||||
$uni-space-root: 2;
|
||||
// 边框半径默认值
|
||||
$uni-radius-root:5px;
|
||||
|
||||
// 主色
|
||||
$uni-primary: #2979ff;
|
||||
$uni-primary-disable:mix(#fff,$uni-primary,50%);
|
||||
$uni-primary-light: mix(#fff,$uni-primary,80%);
|
||||
|
||||
// 辅助色
|
||||
// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
|
||||
$uni-success: #18bc37;
|
||||
$uni-success-disable:mix(#fff,$uni-success,50%);
|
||||
$uni-success-light: mix(#fff,$uni-success,80%);
|
||||
|
||||
$uni-warning: #f3a73f;
|
||||
$uni-warning-disable:mix(#fff,$uni-warning,50%);
|
||||
$uni-warning-light: mix(#fff,$uni-warning,80%);
|
||||
|
||||
$uni-error: #e43d33;
|
||||
$uni-error-disable:mix(#fff,$uni-error,50%);
|
||||
$uni-error-light: mix(#fff,$uni-error,80%);
|
||||
|
||||
$uni-info: #8f939c;
|
||||
$uni-info-disable:mix(#fff,$uni-info,50%);
|
||||
$uni-info-light: mix(#fff,$uni-info,80%);
|
||||
|
||||
// 中性色
|
||||
// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
|
||||
$uni-main-color: #3a3a3a; // 主要文字
|
||||
$uni-base-color: #6a6a6a; // 常规文字
|
||||
$uni-secondary-color: #909399; // 次要文字
|
||||
$uni-extra-color: #c7c7c7; // 辅助说明
|
||||
|
||||
// 边框颜色
|
||||
$uni-border-1: #F0F0F0;
|
||||
$uni-border-2: #EDEDED;
|
||||
$uni-border-3: #DCDCDC;
|
||||
$uni-border-4: #B9B9B9;
|
||||
|
||||
// 常规色
|
||||
$uni-black: #000000;
|
||||
$uni-white: #ffffff;
|
||||
$uni-transparent: rgba($color: #000000, $alpha: 0);
|
||||
|
||||
// 背景色
|
||||
$uni-bg-color: #f7f7f7;
|
||||
|
||||
/* 水平间距 */
|
||||
$uni-spacing-sm: 8px;
|
||||
$uni-spacing-base: 15px;
|
||||
$uni-spacing-lg: 30px;
|
||||
|
||||
// 阴影
|
||||
$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
|
||||
$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
|
||||
$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
|
||||
|
||||
// 蒙版
|
||||
$uni-mask: rgba($color: #000000, $alpha: 0.4);
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import * as CryptoJS from "crypto-js";
|
||||
|
||||
const cbc_key = CryptoJS.enc.Utf8.parse("zhgd@bonus@zhgd@bonus@1234567890");
|
||||
const cbc_iv = CryptoJS.enc.Utf8.parse("1234567812345678");
|
||||
export default {
|
||||
// 加密
|
||||
encrypt(word: string) {
|
||||
const srcs = CryptoJS.enc.Utf8.parse(word);
|
||||
const encrypted = CryptoJS.AES.encrypt(srcs, cbc_key, {
|
||||
iv: cbc_iv,
|
||||
mode: CryptoJS.mode.ECB,
|
||||
padding: CryptoJS.pad.Pkcs7,
|
||||
});
|
||||
return encrypted.toString();
|
||||
},
|
||||
|
||||
// 解密
|
||||
decrypt(word: string) {
|
||||
const decrypt = CryptoJS.AES.decrypt(decodeURIComponent(word), cbc_key, {
|
||||
iv: cbc_iv,
|
||||
mode: CryptoJS.mode.ECB,
|
||||
padding: CryptoJS.pad.Pkcs7,
|
||||
});
|
||||
return CryptoJS.enc.Utf8.stringify(decrypt).toString();
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
import { useInfoStore } from "@/stores";
|
||||
|
||||
const baseURL = "/api";
|
||||
|
||||
// 添加拦截器
|
||||
const httpInterceptor = {
|
||||
// 拦截前触发
|
||||
invoke(options: UniApp.RequestOptions) {
|
||||
// 1.非http
|
||||
if (!options.url.startsWith("http")) {
|
||||
options.url = baseURL + options.url;
|
||||
}
|
||||
// 2.超时
|
||||
options.timeout = 10000;
|
||||
// 3.添加请求头
|
||||
options.header = {
|
||||
...options.header,
|
||||
"source-client": "miniapp",
|
||||
"decrypt":"decrypt"//后台加密开关
|
||||
};
|
||||
// 4.添加token请求头标识
|
||||
const userStore = useInfoStore();
|
||||
const token = userStore.userinfo?.token;
|
||||
if (token) {
|
||||
options.header.Authorization = "Bearer " + token;
|
||||
}
|
||||
|
||||
// console.log(options);
|
||||
},
|
||||
};
|
||||
uni.addInterceptor("request", httpInterceptor);
|
||||
uni.addInterceptor("uploadFile", httpInterceptor);
|
||||
|
||||
interface Data {
|
||||
data: any;
|
||||
code: string;
|
||||
msg: string;
|
||||
}
|
||||
// 添加类型,支持泛型
|
||||
export const http = <T>(options: UniApp.RequestOptions) => {
|
||||
// 返回Promise对象
|
||||
return new Promise<Data>((resolve, reject) => {
|
||||
uni.request({
|
||||
...options,
|
||||
// 2.请求成功
|
||||
success(res) {
|
||||
// console.log(res);
|
||||
|
||||
if (res.statusCode >= 200 && res.statusCode < 300) {
|
||||
resolve(res.data as Data);
|
||||
} else if (res.statusCode === 401) {
|
||||
// 401错误 -> 清理用户信息,跳转到登录页
|
||||
const userStore = useInfoStore();
|
||||
userStore.clearUserInfo();
|
||||
uni.navigateTo({ url: "/pages/login/login" });
|
||||
reject(res);
|
||||
} else {
|
||||
// 其他错误
|
||||
uni.showToast({
|
||||
icon: "none",
|
||||
title: (res.data as Data).msg || "请求错误",
|
||||
});
|
||||
reject(res);
|
||||
}
|
||||
},
|
||||
// 3.请求失败
|
||||
fail(err) {
|
||||
uni.showToast({
|
||||
title: "网络错误",
|
||||
icon: "none",
|
||||
});
|
||||
reject(err);
|
||||
},
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"extends": "@vue/tsconfig/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"sourceMap": true,
|
||||
"ignoreDeprecations":"5.0",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
},
|
||||
"lib": ["esnext", "dom"],
|
||||
"types": ["@dcloudio/types"]
|
||||
},
|
||||
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import { defineConfig } from "vite";
|
||||
import uni from "@dcloudio/vite-plugin-uni";
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [uni()],
|
||||
server: {
|
||||
proxy: {
|
||||
// 用 '/api' 开头的路径,指向配置的目标地址
|
||||
"/api": {
|
||||
target: "http://192.168.0.14:18080/zhgd",
|
||||
// target: "http://10.40.92.32:18080/zhgd",
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, ""),
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||