业主单位

This commit is contained in:
ancong 2025-11-09 10:40:43 +08:00
parent 3f7474432a
commit 7dcac380a8
32 changed files with 4475 additions and 420 deletions

View File

@ -13,6 +13,7 @@ export const getcompanylist = async (data: any) => {
data: data
})
}
/**
*
*

View File

@ -148,7 +148,60 @@ export const getcheckTableIdtree = async () => {
*/
export const getexecutionprojectlist = async (contractId: any) => {
return await request.http({
url: '/safety_hazard/execution/project/list/web/' + contractId,
url: '/safety_hazard/execution/project/list/pad/' + contractId,
// isPost: false,
isPost: '1'
})
}
/**
*使 safety_hazard:project:list
* @returns
*/
export const setprojectcurrent = async (projectId: any) => {
return await request.http({
// url: `/safety_hazard/execution/project/current/${appType}/${projectId}`,
// isPost: false,
url: `/safety_hazard/execution/project/current/1/${projectId}`,
isPost: '0'
})
}
/**
*
使 safety_hazard:contract:list
* @returns
*/
export const setcontractcurrent = async (contractId: any) => {
return await request.http({
// url: `/safety_hazard/execution/contract/current/${appType}/${contractId}`,
url: `/safety_hazard/execution/contract/current/1/${contractId}`,
// isPost: false,
isPost: '0'
})
}
/**
*APP类型获取当前使用的项目(app_type ) safety_hazard:project:list
* @returns
*/
export const getprojectcurrent = async () => {
return await request.http({
//url: '/safety_hazard/execution/project/current/' + appType,
// isPost: false,
url: '/safety_hazard/execution/project/current/1',
isPost: '1'
})
}
/**
*APP类型获取当前使用的合同(app_type ) safety_hazard:contract:list
* @returns
*/
export const getcontractcurrent = async () => {
return await request.http({
// url: '/safety_hazard/execution/contract/current/' + appType,
url: '/safety_hazard/execution/contract/current/1',
// isPost: false,
isPost: '1'
})

View File

@ -0,0 +1,149 @@
<template>
<view class="" style="height: 100vh;">
<u-signature title="" :landscape="false" ref="signatureRef" :showWatermark="showWatermark" :watermark="watermark"
:penSize="penSize" :openSmooth="openSmooth" :disableScroll="true" :backgroundColor="backgroundColor"
@confirm="onConfirm" :showClose="false" @close="onClose"></u-signature>
</view>
</template>
<script>
export default {
data() {
return {
penSize: 5,
basicResult: '',
watermarkResult: '',
backgroundColor: '#fff',
openSmooth: false,
showWatermark: true,
watermark: {
showOnSave: true,
text: '火灾与建筑物安全隐患排查平台',
color: 'rgba(0, 0, 0, 0.1)',
fontSize: 15,
fontFamily: 'Arial',
rotate: 60,
spacing: 100,
single: false
}
}
},
methods: {
clear() {
this.$refs.signatureRef.clear()
},
undo() {
this.$refs.signatureRef.undo()
},
confirm() {
// debugger
this.$refs.signatureRef.getImage().then(res => {
// debugger
this.basicResult = res;
console.log('sdadsa', res)
})
},
onClose() {
uni.navigateBack()
},
onConfirm(res) {
// debugger
// this.$refs.signatureRef.getImage().then(res => {
// debugger
// this.basicResult = res;
// console.log('sdadsa', res)
// })
// this.basicResult = res;
// this.showImageModal = true;
this.$emit("onConfirm", res); //
}
}
}
</script>
<style lang="scss">
.signature-container {
width: 100%;
height: 300px;
// height: 100%;
border: 1px solid #d6d7d8;
border-radius: 8px;
}
.preview-container {
width: 100%;
height: 300px;
// height: 100%;
border: 1px solid #d6d7d8;
border-radius: 8px;
}
.preview-title {
font-size: 14px;
text-align: center;
padding: 10px;
}
.button-container {
display: flex;
flex-direction: row;
justify-content: space-around;
margin-bottom: 10px;
gap: 10px;
}
//
.watermark-controls {
background-color: #f8f9fa;
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
}
.control-item {
display: flex;
flex-direction: row;
align-items: center;
margin-bottom: 12px;
padding: 8px 0;
border-bottom: 1px solid #eee;
}
.control-item:last-child {
border-bottom: none;
margin-bottom: 0;
}
.control-label {
width: 80px;
font-size: 14px;
color: #666;
flex-shrink: 0;
}
.control-input {
flex: 1;
height: 32px;
border: 1px solid #ddd;
border-radius: 4px;
padding: 0 8px;
font-size: 14px;
background-color: #fff;
}
.control-slider {
flex: 1;
margin: 0 10px;
}
.control-value {
width: 50px;
text-align: right;
font-size: 12px;
color: #999;
}
.control-switch {
margin-left: auto;
}
</style>

View File

@ -1,8 +1,26 @@
<template>
<view class="" style="height: 100vh;">
<u-signature title="" :landscape="false" ref="signatureRef" :showWatermark="showWatermark" :watermark="watermark"
:penSize="penSize" :openSmooth="openSmooth" :disableScroll="true" :backgroundColor="backgroundColor"
@confirm="onConfirm" :showClose="false" @close="onClose"></u-signature>
<view class="u-page" style=" border: 1px solid #d6d7d8;
border-radius: 8px;">
<u-signature ref="signatureRef" title="" :showWatermark="showWatermark" :watermark="watermark" :penSize="penSize"
:openSmooth="openSmooth" :disableScroll="true" :showClose="false" :backgroundColor="backgroundColor"
@confirm="onConfirm"></u-signature>
<!--
<view class="button-container">
<u-button size="small" type="primary" @click="clear">清空</u-button>
<u-button size="small" type="primary" @click="undo">撤销</u-button>
<u-button size="small" type="primary" @click="confirm">完成</u-button>
</view> -->
<!--
<view class="button-container">
<u-button size="small" type="error" @click="goLandscape">横屏模式</u-button>
</view>
<card title="预览">
<image :src="basicResult" class="result-image" mode="widthFix"></image>
</card> -->
</view>
</template>
@ -23,12 +41,17 @@
fontSize: 15,
fontFamily: 'Arial',
rotate: 60,
spacing: 100,
spacing: 150,
single: false
}
}
},
methods: {
goLandscape() {
uni.navigateTo({
url: '/pages/componentsB/signature/landscape'
})
},
clear() {
this.$refs.signatureRef.clear()
},
@ -36,26 +59,34 @@
this.$refs.signatureRef.undo()
},
confirm() {
// debugger
this.$refs.signatureRef.getImage().then(res => {
// debugger
this.basicResult = res;
console.log('sdadsa', res)
this.basicResult = res
})
},
onClose() {
uni.navigateBack()
},
onConfirm(res) {
// debugger
// this.$refs.signatureRef.getImage().then(res => {
// debugger
// this.basicResult = res;
// console.log('sdadsa', res)
// })
this.basicResult = res;
this.showImageModal = true;
// this.basicResult = res
// this.showImageModal = true
this.$emit("onConfirm", res); //
},
//
onFontSizeChange(e) {
this.watermark.fontSize = e.detail.value;
},
onRotateChange(e) {
this.watermark.rotate = e.detail.value;
},
onSpacingChange(e) {
this.watermark.spacing = e.detail.value;
7
},
onShowWatermarkChange(e) {
this.showWatermark = e.detail.value;
},
onSingleWatermarkChange(e) {
this.watermark.single = e.detail.value;
},
onWatermarkConfirm(res) {
this.watermarkResult = res
}
}
}
@ -64,16 +95,16 @@
<style lang="scss">
.signature-container {
width: 100%;
height: 300px;
// height: 100%;
// height: 300px;
height: 100vh;
border: 1px solid #d6d7d8;
border-radius: 8px;
}
.preview-container {
width: 100%;
margin: 0 auto;
height: 300px;
// height: 100%;
border: 1px solid #d6d7d8;
border-radius: 8px;
}

View File

@ -119,6 +119,9 @@
<view class="menufhbox">
<view @click="fanhui()" style="display: flex; align-items: center; margin-left:10px;"><u-icon
name="arrow-leftward" color="#fff" size="20"></u-icon></view>
<view style="display: flex; align-items: center; margin-right: 20px;" v-if="userStore.parentmenutitle=='执行'">
系统合同号{{userStore.xththstr}}
</view>
<view style="display: flex; align-items: center; margin-right: 20px;">
{{userStore.parentmenutitle}}/{{userStore.childrenmenutitle}}
</view>
@ -155,12 +158,14 @@
style="float: right;margin-top: 15px; margin-left: 10px;"></u-icon> -->
</view>
</template>
<view v-for="(item,i) in menu.data" :key="i" class="menu_item_back">
<view @click="getItem(index,i)" style="border-top:1rpx solid #575555"
:class="collapse_item_path==item.path?'menu_item_active':'menu_item'">
<text style="float: left;margin-top:15px;margin-left: 35px;">{{item.title}}</text>
<block v-for="(item,i) in menu.data" :key="i">
<view class="menu_item_back" v-if="item.isshow">
<view @click="getItem(index,i)" style="border-top:1rpx solid #575555"
:class="collapse_item_path==item.path?'menu_item_active':'menu_item'">
<text style="float: left;margin-top:15px;margin-left: 35px;">{{item.title}}</text>
</view>
</view>
</view>
</block>
</uni-collapse-item>
</uni-collapse>
</view>
@ -223,22 +228,36 @@
collapse_item_path: '',
menu_data: [{
title: "项目",
isshow: (this.$checkPermi(['safety_hazard:project:list']) || this.$checkPermi([
'safety_hazard:company:list'
]) || this.$checkPermi(['safety_hazard:contract:list'])),
title_icon: {
color: '#fff',
size: '22',
type: 'list-dot'
},
data: [{
title: "合同管理",
path: "/pages/hetong/hetong",
},
{
title: "项目列表",
path: "/pages/xiangmu/listindex",
}
isshow: this.$checkPermi(['safety_hazard:project:list'])
}, {
title: "业主单位",
path: "/pages/xiangmu/yezhudanwei",
isshow: this.$checkPermi(['safety_hazard:company:list'])
},
{
title: "合同管理",
path: "/pages/hetong/hetong",
isshow: this.$checkPermi(['safety_hazard:contract:list'])
},
]
}, {
title: "执行",
isshow: (this.$checkPermi(['safety_hazard:table:list']) || this.$checkPermi([
'safety_hazard:questionnaire:list'
])),
title_icon: {
color: '#fff',
size: '22',
@ -247,12 +266,17 @@
data: [{
title: "检查表",
path: "/pages/zhixing/jianchabiao",
isshow: this.$checkPermi(['safety_hazard:table:list'])
}, {
title: "调查问卷",
path: "/pages/zhixing/wenjuan",
isshow: this.$checkPermi(['safety_hazard:questionnaire:list'])
}]
}, {
title: "统计报表",
isshow: (this.$checkPermi(['safety_hazard:statistic:progress']) || this.$checkPermi([
'safety_hazard:statistic:issue'
]) || this.$checkPermi(['safety_hazard:statistic:score'])),
title_icon: {
color: '#fff',
size: '22',
@ -261,17 +285,21 @@
data: [{
title: "进度",
path: "/pages/tongji/jindu",
isshow: this.$checkPermi(['safety_hazard:statistic:progress'])
}, {
title: "主要问题",
path: "/pages/tongji/zhuyaowenti",
isshow: this.$checkPermi(['safety_hazard:statistic:issue'])
}, {
title: "分数统计",
path: "/pages/tongji/fenshutj",
isshow: this.$checkPermi(['safety_hazard:statistic:score'])
}
]
}, {
title: "标准库",
isshow: this.$checkPermi(['safety_hazard:table:list']),
title_icon: {
color: '#fff',
size: '22',
@ -280,6 +308,7 @@
data: [{
title: "检查表标准",
path: "/pages/biaozhunku/jcbbiaozhun",
isshow: this.$checkPermi(['safety_hazard:table:list'])
}
]

View File

@ -111,6 +111,11 @@
"style": {
"navigationBarTitleText": "项目信息"
}
}, {
"path": "pages/xiangmu/yezhudanwei",
"style": {
"navigationBarTitleText": "业主单位"
}
}, {
"path": "pages/xiangmu/addxiangmu",
"style": {

View File

@ -55,15 +55,19 @@
</view>
<view style="margin-top: 20px; margin-bottom: 10px;">
<u-button style="width:100px; float: left; margin-left:10px;" type="success" icon="plus-circle" text="添加合同"
@click="addhetong()" size="small"></u-button>
@click="addhetong()" size="small" v-if="$checkPermi(['safety_hazard:contract:add'])"></u-button>
<u-button style="width:100px; float: left;margin-left: 20px;" type="primary" icon="edit-pen" text="编辑合同"
:disabled="activenum!=1" @click="uphetong()" size="small"></u-button>
:disabled="activenum!=1" @click="uphetong()" size="small"
v-if="$checkPermi(['safety_hazard:contract:edit'])"></u-button>
<u-button style="width:100px; float: left;margin-left: 20px;" type="error" icon="trash" text="删除合同"
:disabled="activenum==0" @click="shanchuhetong()" size="small"></u-button>
:disabled="activenum==0" @click="shanchuhetong()" size="small"
v-if="$checkPermi(['safety_hazard:contract:remove'])"></u-button>
<u-button style="width:100px; float: left;margin-left: 20px;" type="success" icon="play-circle" text="启动"
:disabled="activenum!=1" @click="qidong()" size="small"></u-button>
:disabled="activenum!=1" @click="qidong()" size="small"
v-if="$checkPermi(['safety_hazard:project:status'])"></u-button>
<u-button style="width:100px; float: left;margin-left: 20px;" type="warning" icon="error-circle" text="完结"
:disabled="activenum!=1" @click="wanjie()" size="small"></u-button>
:disabled="activenum!=1" @click="wanjie()" size="small"
v-if="$checkPermi(['safety_hazard:project:status'])"></u-button>
</view>
</view>
<view class="zhixing_center">
@ -114,7 +118,7 @@
:delshow="false" /> -->
<csr-uni-data-select style="width: 400px;" :filterable="true" v-model="formdata.customerCompanyId"
placeholder="选择委托单位" dataKey="label" dataValue="value" :localdata="wtdwlist" @change="addwtdwchange"
:clear="false"></csr-uni-data-select>
:clear="false" :disabled="formdata.contractId"></csr-uni-data-select>
</view>
<!-- <view v-else class="querybox_title"> {{activeitem.projectName}}</view> -->
</view>
@ -361,6 +365,7 @@
},
chaxunqy() {
//
this.getlistinfo()
},
@ -620,6 +625,7 @@
//
this.tableData = [];
this.clearSelection(); //
// debugger
getcontractlist(this.queryParams).then((res) => {
//debugger
this.tableData = res.rows || [];
@ -690,7 +696,7 @@
.querybox_title {
width: 100px;
font-size: 13px;
text-align: right;
// text-align: right;
justify-content: end;
}
}

View File

@ -15,8 +15,8 @@
<view>{{projectname}}</view>
</view>
<view style="margin-right: 15px; margin-bottom: 10px;">
<u-button v-if="tableData.length>0" type="primary" icon="arrow-downward" size="small" text="导出"
@click="daochu()"></u-button>
<u-button v-if="tableData.length>0&&$checkPermi(['safety_hazard:suggestion:export'])" type="primary"
icon="arrow-downward" size="small" text="导出" @click="daochu()"></u-button>
</view>
</view>
<u-table row-key="createTime" rowHeight="60" customClass="mewtable2" ref="pageTable" :scrollX="true"
@ -78,7 +78,8 @@
<u-table-column prop="" width="150" label="操作" align="center" headerAlign="center">
<template #default=" { row, index }">
<u-button type="primary" icon="edit-pen" text="编辑" size="small" v-if="!row.editshow"
<u-button type="primary" icon="edit-pen" text="编辑" size="small"
v-if="!row.editshow&&$checkPermi(['safety_hazard:suggestion:edit'])"
@click="bianji(row,index)"></u-button>
<view v-else style="display: flex; flex-direction: row; justify-content: space-around;">

View File

@ -9,16 +9,16 @@
:rules="rules"> -->
<u-form ref="form" labelPosition="left" labelWidth="0" :model="formData" :rules="rules">
<u-form-item prop="username" name="username">
<u-form-item prop="username" name="username" :borderBottom="false">
<u-input border="surround" v-model="formData.username" placeholder="请输入用户名" clearable />
</u-form-item>
<u-form-item prop="password" name="password">
<u-form-item prop="password" name="password" :borderBottom="false">
<u-input border="surround" password v-model="formData.password" placeholder="请输入密码"
passwordVisibilityToggle />
</u-form-item>
<view style="display: flex; flex-direction: row; justify-content: space-between;">
<u-form-item prop="code" name="code" style="width:50%">
<u-form-item prop="code" name="code" style="width:50%" :borderBottom="false">
<u-input border="surround" v-model="formData.code" placeholder="请输入验证码" />
</u-form-item>
<img :show-loading="true" :src="codeUrl" style="width: 40%; height:40px; margin-top:20rpx; margin-left: 1%;"
@ -126,11 +126,15 @@
// uni.redirectTo({
// url: "/pages/admin/home"
// })
userStore.setparentmenutitle('执行');
userStore.setparentmenutitle('检查表');
// userStore.setparentmenutitle('');
// userStore.setparentmenutitle('');
// uni.redirectTo({
// url: "/pages/zhixing/jianchabiao"
// })
uni.redirectTo({
url: "/pages/zhixing/jianchabiao"
url: "/pages/xiangmu/listindex"
})
console.log("555", "/pages/xiangmu/listindex")
}).catch((error) => {
this.$modal.msgError("个人信息获取失败!")

View File

@ -336,7 +336,7 @@
}
}
}
if (column.prop === 'riskLevel') {
if (column.prop === 'customerCompany3') {
//
const currentValue = row[column.prop]
let startIndex = rowIndex

View File

@ -14,7 +14,7 @@
<view class="querybox_title">项目状态</view>
<csr-uni-data-select style="width: 400px;" :multiple="true" :filterable="false"
v-model="queryParams.statusList" placeholder="选择项目状态" dataKey="label" dataValue="value"
:localdata="zhuangtailist" @change="xmztchange" :clear="true"></csr-uni-data-select>
:localdata="zhuangtailist" @change="xmztchange" :clear="false"></csr-uni-data-select>
</view>
</uni-col>
<uni-col :xs="24" :sm="6" :md="6">
@ -73,19 +73,24 @@
</view>
<view style="margin-top: 20px; margin-bottom: 10px;">
<u-button style="width:100px; float: left; margin-left:10px;" type="success" icon="plus-circle" text="添加项目"
@click="openright()" size="small"></u-button>
@click="openright()" size="small" v-if="$checkPermi(['safety_hazard:project:add'])"></u-button>
<u-button style="width:100px; float: left;margin-left: 20px;" type="primary" icon="edit-pen" text="编辑项目"
:disabled="activenum!=1" @click="upxiangmu()" size="small"></u-button>
:disabled="activenum!=1" @click="upxiangmu()" size="small"
v-if="$checkPermi(['safety_hazard:project:edit'])"></u-button>
<u-button style="width:100px; float: left;margin-left: 20px;" type="error" icon="trash" text="删除项目"
:disabled="activenum==0" @click="shanchujiancha()" size="small"></u-button>
:disabled="activenum==0" @click="shanchujiancha()" size="small"
v-if="$checkPermi(['safety_hazard:project:remove'])"></u-button>
<u-button style="width:100px; float: left;margin-left: 20px;" type="success" icon="play-circle" text="启动"
:disabled="activenum!=1" @click="qidong()" size="small"></u-button>
:disabled="activenum!=1" @click="qidong()" size="small"
v-if="$checkPermi(['safety_hazard:project:status'])"></u-button>
<u-button style="width:100px; float: left;margin-left: 20px;" type="warning" icon="error-circle" text="完结"
:disabled="activenum!=1" @click="wanjie()" size="small"></u-button>
:disabled="activenum!=1" @click="wanjie()" size="small"
v-if="$checkPermi(['safety_hazard:project:status'])"></u-button>
<u-button style="width:100px; float: left;margin-left: 20px;" type="primary" icon="list-dot" text="查看评价表"
:disabled="activenum!=1" @click="pingjia()" size="small"></u-button>
<u-button style="width:100px; float: left;margin-left: 20px;" type="success" icon="list-dot" text="查看处理建议"
:disabled="activenum!=1" @click="chulijianyi()" size="small"></u-button>
:disabled="activenum!=1" @click="chulijianyi()" size="small"
v-if="$checkPermi(['safety_hazard:suggestion:list'])"></u-button>
</view>
</view>
@ -118,6 +123,10 @@
</template>
</u-table-column>
</u-table>
<!--
<u-pagination v-model="queryParams.pageNum" :total="queryParams.total" :page-size="queryParams.pageSize" simple
style="float: right; margin-top:20px;"></u-pagination> -->
@ -359,8 +368,9 @@
imgurlslist: [],
tableData: [],
queryParams: {
// pageNum: 1,
// pageSize: 10,
pageNum: 1,
pageSize: 50,
total: 0,
projectNo: '', //
customerLevel: null, //
customerName: '', //-
@ -557,8 +567,8 @@
// debugger
},
qidong() {
//
setsafety_hazardprojectstatus(this.activeitem.contractId, '1').then((res) => {
//
setsafety_hazardprojectstatus(this.activeitem.projectId, '1').then((res) => {
// debugger
this.$modal.msgSuccess("启动成功!");
setTimeout(() => {
@ -569,7 +579,7 @@
},
wanjie() {
//
setsafety_hazardprojectstatus(this.activeitem.contractId, '2').then((res) => {
setsafety_hazardprojectstatus(this.activeitem.projectId, '2').then((res) => {
this.$modal.msgSuccess("完结成功!");
setTimeout(() => {
this.getlistinfo(); //
@ -593,7 +603,7 @@
this.pjmodaltitle = '非火灾高危单位';
}
this.yjprojectname = true;
this.pjmodalshow = true;
});
},
@ -867,6 +877,7 @@
getprojectlist(this.queryParams).then((res) => {
// debugger
this.tableData = res.rows || [];
this.queryParams.total = res.total;
})
},

View File

@ -0,0 +1,480 @@
<template>
<view class="zhixing-container" style="margin: 20rpx;margin-top: 220rpx; min-height: 300px; ">
<view class="zhixing_top" style="display: flex; flex-direction: column;">
<view style="display: flex; flex-direction: row;margin-bottom: 10px; margin-left: 10px;">
<view class="querybox" style=" margin-right:20px;">
<view class="querybox_title" style="display: flex; flex-direction: row;">
<view style="color: #ca4341; margin-right:5px;">*</view>
<view>制单人</view>
</view>
<u-input @change="chaxunqy()" v-model="queryParams.createBy" clearable placeholder="请输入制单人"></u-input>
</view>
<view class="querybox">
<u-button style="width:100px; float: left;margin-left: 20px;" type="warning" icon="reload" text="重置"
@click="resetqy()" size="small"></u-button>
<u-button style="width:100px; float: left;margin-left:30px;" type="primary" icon="search" text="查询"
@click="chaxunqy()" size="small"></u-button>
</view>
</view>
</view>
<view class="zhixing_center">
<u-table row-key="createTime" rowHeight="150" customClass="mewtable2" ref="pageTable" :scrollX="true"
:data="tableData" :ellipsis="false" height="550" :border="true" style="width:100%">
<!-- :span-method="spanMethodWithColspan" -->
<u-table-column type="index" fixed width="55" label="序号" align="center" headerAlign="center"></u-table-column>
<u-table-column prop="name1" align="center" width="150" label="专业" headerAlign="center">
<template #default="{ row, index }">
{{row.name1}}
</template>
</u-table-column>
<u-table-column prop="name2" width="200" align="center" label="单项" headerAlign="center">
<template #default="{ row, index }">
{{row.name2}}
</template>
</u-table-column>
<u-table-column prop="name3" align="center" label="子项" headerAlign="center">
<template #default="{ row, index }">
{{row.name3}}
</template>
</u-table-column>
<u-table-column prop="name4" width="200" align="center" label="要素" headerAlign="center">
<template #default="{ row, index }">
{{row.name4}}
</template>
</u-table-column>
<u-table-column prop="riskLevel" width="80" align="center" label="风险等级" headerAlign="center">
<template #default="{ row, index }">
<u-tag v-if="row.riskLevel" :text="row.riskLevel=='1'?'A':row.riskLevel=='2'?'B':row.riskLevel=='3'?'C':''"
:type="row.riskLevel=='1'?'error':row.riskLevel=='2'?'warning':row.riskLevel=='3'?'success':''"
size="mini"></u-tag>
</template>
</u-table-column>
<u-table-column prop="createBy" width="80" label="制单" align="center" headerAlign="center" />
<u-table-column prop="createTime" width="180" label="创建时间" align="center" headerAlign="center">
<template #default=" { row, index }">
{{row.createTime?$dayjs(row.createTime).format("YYYY-MM-DD HH:mm"):''}}
</template>
</u-table-column>
</u-table>
</view>
<!-- <LandScape style="width:1000px; height: 100%;" v-if="qianzishow" /> -->
<UniMenu />
</view>
</template>
<script>
import {
getsafety_hazardInfo,
getexecutionprojectlist
} from "@/apis/zhixing"
import {
getthstatus
} from "@/apis/hetong"
import {
getstandardchecktablelist
} from "@/apis/biaozhunku"
import {
setsafety_hazardcompanystatus,
getsysCtcNo,
getcustomerCompanyIdinfo,
getcompanylist,
getcompanytreeselect,
addsafety_hazardcompany,
upsafety_hazardcompany,
delsafety_hazardcompany
} from "@/apis/yezhudanwei"
import {
getToken,
setToken,
removeToken
} from '@/utils/auth'
import {
parseObjectToArray
} from "@/utils/util"
import UniMenu from '@/components/uni-menu/uni-menu.vue'
import comboxMore from '@/components/wl-combox-more/combox-more.vue'
import useUserStore from '@/store/user';
import CustomPicker from '@/components/custom-search-picker/index.vue';
import AddEditnr from '@/pages/zhixing/addwenjuan.vue';
import LandScape from '@/components/signature/landscape.vue';
export default {
components: {
UniMenu,
comboxMore,
CustomPicker,
AddEditnr,
LandScape
},
data() {
return {
// upurl: import.meta.env.VITE_APP_BASE_PRE + '/safety_hazard/table/img',
// httpurl: import.meta.env.VITE_APP_BASE_PRE,
xmpickerVisible: false,
addxmpickerVisible: false,
xththlist: [],
yjdwlist: [],
contractId: '',
qianziimg: '',
qiaziimgnum: 0,
rowitem: null,
sjnum: 0,
isedit: false,
modaltitle: '添加调查问卷',
pjmodaltitle: '非火灾高危单位',
pjmodalshow: false,
pjtableInfolist: [],
imgboxshow: false,
imgurlslist: [],
tableData: [],
queryParams: {
createBy: '',
},
addshow: false,
infolist: [],
activeitem: null,
activenum: 0,
qianzishow: false,
addxmdwlist: [],
activenumlist: [],
xmdwlist: [
// {
// projectId: 0,
// projectNo: "001",
// customerCompany3Name: "",
// lablename: "001",
// }, {
// projectId: 1,
// projectNo: "002",
// customerCompany3Name: "",
// lablename: "002",
// },
],
}
},
computed: {
nick() {
// debugger
// return userStore.username
const userStore = useUserStore();
return userStore.name
},
imageSrc() {
const userStore = useUserStore();
return userStore.avatar
},
username() {
// debugger
// return userStore.username
const userStore = useUserStore();
return userStore.username
},
avatar() {
//debugger
const userStore = useUserStore();
return userStore.avatar
},
windowHeight() {
return uni.getSystemInfoSync().windowHeight - 50
}
},
// //
// onBackPress() {
// //debugger
// uni.redirectTo({
// url: '/pages/index/index'
// });
// // uniapponBackPress
// return true;
// },
onShow() {
this.getlistinfo()
// this.getxmdwlist(); //
const userStore = useUserStore();
userStore.setparentmenutitle('项目');
userStore.setchildrenmenutitle('业主单位');
},
onLoad() {
// this.getUser()
},
methods: {
parseObjectToArray,
chaxunqy() {
//
this.getlistinfo()
},
resetqy() {
//
this.queryParams = {
createBy: '',
};
this.getlistinfo(); //
},
hideKeyboard() {
uni.hideKeyboard()
},
changeyjdw(e) {
//
if (!e) {
this.queryParams.contractId = null;
}
this.getlistinfo(); // //
},
getlistinfo() {
//
this.tableData = [];
getcompanytreeselect(this.queryParams).then((res) => {
//debugger
this.tableData = res.data || [];
})
},
//
spanMethodWithColspan({
row,
column,
rowIndex,
columnIndex
}) {
if (column.prop === 'customerCompany2') {
//
const currentValue = row[column.prop]
let startIndex = rowIndex
let endIndex = rowIndex
//console.log('currentValue', this.tableData)
//
while (startIndex > 0 && this.tableData[startIndex - 1][column.prop] === currentValue) {
startIndex--
}
//
while (endIndex < this.tableData.length - 1 && this.tableData[endIndex + 1][column.prop] === currentValue) {
endIndex++
}
const spanCount = endIndex - startIndex + 1
if (spanCount > 1) {
if (rowIndex === startIndex) {
//
return {
rowspan: spanCount,
colspan: 1
}
} else {
//
return {
rowspan: 0,
colspan: 0
}
}
}
}
if (column.prop === 'sysCtcNo') {
//
const currentValue = row[column.prop]
let startIndex = rowIndex
let endIndex = rowIndex
//console.log('currentValue', this.tableData)
//
while (startIndex > 0 && this.tableData[startIndex - 1][column.prop] === currentValue) {
startIndex--
}
//
while (endIndex < this.tableData.length - 1 && this.tableData[endIndex + 1][column.prop] === currentValue) {
endIndex++
}
const spanCount = endIndex - startIndex + 1
if (spanCount > 1) {
if (rowIndex === startIndex) {
//
return {
rowspan: spanCount,
colspan: 1
}
} else {
//
return {
rowspan: 0,
colspan: 0
}
}
}
}
if (column.prop === 'riskLevel') {
//
const currentValue = row[column.prop]
let startIndex = rowIndex
let endIndex = rowIndex
//console.log('currentValue', this.tableData)
//
while (startIndex > 0 && this.tableData[startIndex - 1][column.prop] === currentValue) {
startIndex--
}
//
while (endIndex < this.tableData.length - 1 && this.tableData[endIndex + 1][column.prop] === currentValue) {
endIndex++
}
const spanCount = endIndex - startIndex + 1
if (spanCount > 1) {
if (rowIndex === startIndex) {
//
return {
rowspan: spanCount,
colspan: 1
}
} else {
//
return {
rowspan: 0,
colspan: 0
}
}
}
}
return {
rowspan: 1,
colspan: 1
}
},
}
}
</script>
<style lang="scss" scoped>
.zhixing_top {
width: 100%;
display: flex;
flex-direction: column;
}
.querybox {
display: flex;
flex-direction: row;
align-items: center;
.querybox_title {
font-size: 13px;
text-align: right;
justify-content: end;
}
}
::v-deep .infotable {
.xincellclass {}
.u-table-header {
z-index: 0;
}
.u-table-cell {
.u-table-cell_content {
padding: 0rpx 16rpx 0rpx 16rpx;
white-space: normal;
text-align: left;
}
}
}
::v-deep .uni-table {
// tr:first-child th:nth-of-type(1) {
// /* */
// .uni-table-checkbox {
// display: none !important;
// }
// //
// }
.frisytr {
.uni-table-checkbox {
display: none !important;
}
}
.checkbox__inner {
z-index: 0 !important;
}
}
.wenjuanadbox {
display: flex;
flex-direction: column;
.querybox1 {
display: flex;
flex-direction: row;
// align-items: center;
justify-content: space-between;
.querybox_title {
justify-content: end;
}
}
}
::v-deep .mewtable2 {
.u-table__header {
.u-checkbox {
// display: none !important;
visibility: hidden !important;
}
.u-table__cell {
//justify-content: center !important;
min-height: 50px !important;
}
.u-table__rows {
//border-bottom: 1px solid #dadbde !important;
::v-deep .u-table__cell {
//justify-content: center !important;
// min-height: 50px !important;
height: auto !important;
}
}
}
.u-table__body {
.u-table__rows {
border-bottom: 1px solid #dadbde !important;
.u-table__cell {
z-index: 0 !important;
}
}
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@ -197,7 +197,7 @@
<view style="display: flex; margin-bottom: 30px; flex-direction: row; justify-content: space-around;">
<u-button type="error" :disabled="!formdata.checkTableId" text="删除" @click="sahnchu()"
style="width: 20%; margin-top: 100rpx;"></u-button>
style="width: 20%; margin-top: 100rpx;" v-if="$checkPermi(['safety_hazard:table:remove'])"></u-button>
<u-button type="primary" text="保存并关闭" @click="baocun()" style="width: 20%; margin-top: 100rpx;"></u-button>
<u-button type="success" text="保存并添加" @click="baocunbtj()" style="width: 20%; margin-top: 100rpx;"></u-button>
</view>

View File

@ -209,7 +209,9 @@
<view style="width: 100%; display: flex; padding-bottom:50px; flex-direction: row; justify-content: space-around;">
<!-- <u-button type="primary" text="关闭" @click="baocun()" style="width: 20%; margin-top: 100rpx;"></u-button> -->
<u-button type="success" text="保存" @click="baocun()" style="width: 20%; margin-top: 100rpx;"></u-button>
<u-button type="success"
v-if="(formdata.questionnaireId&&$checkPermi(['safety_hazard:questionnaire:edit']))||!formdata.questionnaireId"
text="保存" @click="baocun()" style="width: 20%; margin-top: 100rpx;"></u-button>
</view>

View File

@ -10,6 +10,10 @@
<csr-uni-data-select :filterable="true" v-model="contractId" placeholder="请选择系统合同号" dataKey="label"
dataValue="value" :localdata="xththlist" @change="changexthth" :clear="false"
style="width: 400px;"></csr-uni-data-select>
<!-- <u-select v-model="contractId" :list="xththlist" keyName="label" valueName="value" placeholder="请选择系统合同号"
style="width: 400px;" @change="changexthth"></u-select> -->
</view>
<view class="querybox">
<view class="querybox_title" style="display: flex; flex-direction: row;">
@ -33,13 +37,16 @@
<u-button style="width:100px; float: left;margin-left: 20px;" type="primary" icon="edit-pen" text="编辑检查点"
:disabled="activenum!=1||!isbutclick" @click="upjiancha()" size="small"></u-button> -->
<u-button style="width:100px; float: left;margin-left: 20px;" type="error" icon="trash" text="删除检查点"
:disabled="activenum==0||!isbutclick" @click="shanchujiancha()" size="small"></u-button>
:disabled="activenum==0||!isbutclick" @click="shanchujiancha()" size="small"
v-if="$checkPermi(['safety_hazard:table:remove'])"></u-button>
<u-button style="width:100px; float: left;margin-left: 20px;" type="warning" icon="info-circle" text="变更日志"
@click="biangenls()" :disabled="activenum!=1||!isbutclick" size="small"></u-button>
@click="biangenls()" :disabled="activenum!=1||!isbutclick" size="small"
v-if="$checkPermi(['safety_hazard:log:query'])"></u-button>
<u-button style="width:100px; float: left;margin-left: 20px;" type="primary" icon="list-dot" text="评价表"
:disabled="!queryParams.projectId" @click="pingjia()" size="small"></u-button>
<u-button style="width:100px; float: left; margin-left:10px;" type="success" icon="plus-circle" text="生成处理建议"
:disabled="!queryParams.projectId" @click="addjianyi()" size="small"></u-button>
:disabled="!queryParams.projectId" @click="addjianyi()" size="small"
v-if="$checkPermi(['safety_hazard:suggestion:add'])"></u-button>
</view>
</view>
@ -223,7 +230,12 @@ width: 100%;align-items: left; border-top:1px solid #eee;">
getloginfo,
delsafety_hazard,
getcheckTableIdtree,
getexecutionprojectlist
getexecutionprojectlist,
setprojectcurrent,
setcontractcurrent,
getprojectcurrent,
getcontractcurrent
} from "@/apis/zhixing"
import {
@ -653,18 +665,36 @@ width: 100%;align-items: left; border-top:1px solid #eee;">
//
//debugger
// this.contractId = e.value;
this.queryParams.projectname = '';
this.queryParams.projectId = '';
this.getxmdwlist();
//
if (e) {
setcontractcurrent(this.contractId).then((res) => {
//
this.userStore.setxtht(e.value, e.label);
});
}
},
changexmbh(e) {
//
//debugger
this.queryParams.projectname = e.lablename;
this.queryParams.projectId = e.projectId;
if (e) {
this.queryParams.projectname = e.lablename;
this.queryParams.projectId = e.projectId;
}
this.qingchu();
if (e) {
setprojectcurrent(this.queryParams.projectId).then((res) => {
//
this.userStore.setproject(e.projectId, e.lablename);
});
}
},
xmhandleConfirm(result) {
//
@ -840,8 +870,23 @@ width: 100%;align-items: left; border-top:1px solid #eee;">
this.xththlist = res.data ? this.parseObjectToArray(res.data) : [];
if (this.xththlist.length > 0) {
// debugger
this.contractId = this.xththlist[0].value;
this.getxmdwlist(); //
getcontractcurrent().then((res2) => {
//
// debugger
if (res2.data) {
this.contractId = res2.data.contractId;
this.getxmdwlist(); //
//
this.userStore.setxtht(res2.data.contractId, res2.data.sysCtcNo);
} else {
this.contractId = this.xththlist[0].value;
this.getxmdwlist(); //
setcontractcurrent(this.contractId).then((res) => {
//
this.userStore.setxtht(this.xththlist[0].value, this.xththlist[0].label);
});
}
});
}
})
},
@ -860,14 +905,46 @@ width: 100%;align-items: left; border-top:1px solid #eee;">
this.xmpickerConfig.options = res.data.projects || [];
if (this.xmdwlist.length > 0) {
//debugger
this.queryParams.projectId = this.xmdwlist[0].projectId;
this.queryParams.projectname = this.xmdwlist[0].lablename;
this.xmpickerConfig.value = this.xmdwlist[0];
// this.xmpickerConfig.value = this.xmdwlist.filter(item => res.data.areaIds.includes(item.value));
// if (this.contractId == this.userStore.xththid) {
//
getprojectcurrent().then((res2) => {
//
// debugger
if (res2.data) {
if (this.contractId == res2.data.contractId) {
//
this.queryParams.projectId = res2.data.projectId;
this.queryParams.projectname = res2.data.projectNo + `${res2.data.name}`;
this.xmpickerConfig.value = res2.data.projectId;
this.userStore.setproject(this.xmdwlist[0].projectId, res2.data.projectNo +
`${res2.data.name}`);
} else {
this.queryParams.projectId = this.xmdwlist[0].projectId;
this.queryParams.projectname = this.xmdwlist[0].lablename;
this.xmpickerConfig.value = this.xmdwlist[0];
setprojectcurrent(this.queryParams.projectId).then((res) => {
//
this.userStore.setproject(this.xmdwlist[0].projectId, this.xmdwlist[0].lablename);
});
}
} else {
this.queryParams.projectId = this.xmdwlist[0].projectId;
this.queryParams.projectname = this.xmdwlist[0].lablename;
this.xmpickerConfig.value = this.xmdwlist[0];
setprojectcurrent(this.queryParams.projectId).then((res) => {
//
this.userStore.setproject(this.xmdwlist[0].projectId, this.xmdwlist[0].lablename);
});
}
this.getlistinfo(); //
});
} else {
this.getlistinfo(); //
}
this.getlistinfo(); //
})
},

View File

@ -18,8 +18,8 @@
<view>项目编号</view>
</view>
<csr-uni-data-select :filterable="true" v-model="queryParams.projectId" placeholder="请选择项目编号"
dataKey="lablename" dataValue="projectId" :localdata="xmpickerConfig.options" @change="changexmbh"
:clear="false" style="width: 400px;"></csr-uni-data-select>
dataKey="lablename" dataValue="projectId" :localdata="xmpickerConfig.options" :clear="false"
style="width: 400px;"></csr-uni-data-select>
</view>
@ -31,11 +31,12 @@
</view>
<view style="margin-top: 20px; margin-bottom: 10px;">
<u-button style="width:100px; float: left; margin-left:10px;" type="success" icon="plus-circle" text="添加问卷"
@click="addwenjuan()" size="small"></u-button>
@click="addwenjuan()" size="small" v-if="$checkPermi(['safety_hazard:questionnaire:add'])"></u-button>
<!-- <u-button style="width:100px; float: left;margin-left: 20px;" type="primary" icon="edit-pen" text="编辑问卷"
:disabled="activenum!=1" @click="upwenjuan()" size="small"></u-button> -->
<u-button style="width:100px; float: left;margin-left: 20px;" type="error" icon="trash" text="删除问卷"
:disabled="activenum==0" @click="shanchujiancha()" size="small"></u-button>
:disabled="activenum==0" @click="shanchujiancha()" size="small"
v-if="$checkPermi(['safety_hazard:questionnaire:remove'])"></u-button>
<u-button style="width:100px; float: left;margin-left: 20px;" type="primary" icon="list-dot" text="评价表"
:disabled="activenum!=1" @click="pingjia()" size="small"></u-button>
</view>
@ -84,6 +85,9 @@
<u-table-column type="selection" fixed width="55" align="center" headerAlign="center"></u-table-column>
<u-table-column prop="projectNo" width="180" label="项目编号" headerAlign="center">
<template #default="{ row, index }">
<!-- <u-text :text="row.projectNo" v-if="$checkPermi(['safety_hazard:questionnaire:edit'])" type="primary"
decoration="underline" @click="upedit(row)"></u-text>
<view v-else>{{row.projectNo}}</view> -->
<u-text :text="row.projectNo" type="primary" decoration="underline" @click="upedit(row)"></u-text>
</template>
</u-table-column>
@ -239,22 +243,22 @@
<u-toast ref="uToast"></u-toast>
<uni-drawer ref="showright" mode="right" :width="550" :mask-click="true">
<scroll-view scroll-y="true" style="height: 100%;">
<AddEditnr style="width: 100%;" :objitem="rowitem" :sjnum="sjnum" @sahnchuevent="sahnchuevent"
@righteventclose="closeright" @shaunxian="getlistinfo()" @qianziclick="qianzishow=true" :qiaziimg="qianziimg"
:qiaziimgnum="qiaziimgnum" />
<AddEditnr style="width: 100%;" :objitem="rowitem" :sjnum="sjnum" @righteventclose="closeright"
@shaunxian="getlistinfo()" @qianziclick="qianzishow=true" :qiaziimg="qianziimg" :qiaziimgnum="qiaziimgnum" />
</scroll-view>
</uni-drawer>
<u-modal content="" :closeOnClickOverlay="true" title="手写签名" confirmText="关闭" width="1000px" :show="qianzishow"
@confirm="() => qianzishow = false">
<view class="slot-content" style="width: 100%;">
<!-- <scroll-view scroll-y="true" style="height: 300px; ">
</scroll-view> -->
<LandScape style="width:900px; height:500px;" @onConfirm="qianziConfirm" />
<next-modal :show="qianzishow" confirmText="关闭" :showCancel="false" @confirm="qianzishow=false" width="900px">
<!--注意插槽的使用的优先级大于next-modal组件的props的值-->
<view slot="title">
<view style="text-align: center;padding:20rpx"><text>手写签名</text></view>
</view>
</u-modal>
<!-- <LandScape style="width:1000px; height: 100%;" v-if="qianzishow" /> -->
<!-- <template #content><view style="text-align: center;"><text>hello你好这是next-modal组件的内容next-modal是一个轻量级的组件没有其他依赖请放心使用</text></view></template> -->
<!--自定义content内容-->
<view slot="content">
<LandScape style="width:98%; height:500px; margin: 0 auto;" @onConfirm="qianziConfirm" />
</view>
</next-modal>
<UniMenu />
</view>
</template>
@ -262,7 +266,12 @@
<script>
import {
getsafety_hazardInfo,
getexecutionprojectlist
getexecutionprojectlist,
setprojectcurrent,
setcontractcurrent,
getprojectcurrent,
getcontractcurrent
} from "@/apis/zhixing"
import {
getthstatus
@ -304,6 +313,7 @@
return {
// upurl: import.meta.env.VITE_APP_BASE_PRE + '/safety_hazard/table/img',
// httpurl: import.meta.env.VITE_APP_BASE_PRE,
userStore: useUserStore(),
upurl: 'http://219.146.89.198:19388' + '/safety_hazard/table/img',
httpurl: 'http://219.146.89.198:19388',
xmpickerVisible: false,
@ -492,14 +502,17 @@
changexthth(e) {
//
//debugger
// if(e){
// }
// this.contractId = e.value;
this.queryParams.projectname = '';
this.queryParams.projectId = '';
this.getxmdwlist();
//
if (e) {
setcontractcurrent(this.contractId).then((res) => {
//
this.userStore.setxtht(e.value, e.label);
});
}
},
getxthtxlist() {
//
@ -508,8 +521,26 @@
this.xththlist = res.data ? this.parseObjectToArray(res.data) : [];
if (this.xththlist.length > 0) {
// debugger
this.contractId = this.xththlist[0].value;
this.getxmdwlist(); //
// this.contractId = this.xththlist[0].value;
// this.getxmdwlist(); //
// debugger
getcontractcurrent().then((res2) => {
//
// debugger
if (res2.data) {
this.contractId = res2.data.contractId;
this.getxmdwlist(); //
//
this.userStore.setxtht(res2.data.contractId, res2.data.sysCtcNo);
} else {
this.contractId = this.xththlist[0].value;
this.getxmdwlist(); //
setcontractcurrent(this.contractId).then((res) => {
//
this.userStore.setxtht(this.xththlist[0].value, this.xththlist[0].label);
});
}
});
}
})
},
@ -772,13 +803,48 @@
this.xmpickerConfig.options = res.data.projects || [];
if (this.xmdwlist.length > 0) {
//debugger
this.queryParams.projectId = this.xmdwlist[0].projectId;
this.queryParams.projectname = this.xmdwlist[0].lablename;
// this.xmpickerConfig.value = this.xmdwlist[0].projectId;
// this.queryParams.projectId = this.xmdwlist[0].projectId;
// this.queryParams.projectname = this.xmdwlist[0].lablename;
getprojectcurrent().then((res2) => {
//
// debugger
if (res2.data) {
if (this.contractId == res2.data.contractId) {
//
this.queryParams.projectId = res2.data.projectId;
this.queryParams.projectname = res2.data.projectNo + `${res2.data.name}`;
this.userStore.setproject(this.xmdwlist[0].projectId, res2.data.projectNo +
`${res2.data.name}`);
} else {
this.queryParams.projectId = this.xmdwlist[0].projectId;
this.queryParams.projectname = this.xmdwlist[0].lablename;
setprojectcurrent(this.queryParams.projectId).then((res) => {
//
this.userStore.setproject(this.xmdwlist[0].projectId, this.xmdwlist[0].lablename);
});
}
} else {
this.queryParams.projectId = this.xmdwlist[0].projectId;
this.queryParams.projectname = this.xmdwlist[0].lablename;
setprojectcurrent(this.queryParams.projectId).then((res) => {
//
this.userStore.setproject(this.xmdwlist[0].projectId, this.xmdwlist[0].lablename);
});
}
this.getlistinfo(); //
});
} else {
this.getlistinfo(); //
}
this.getlistinfo(); //
// this.getlistinfo(); //
})
},
clickcell(row, column, cell, event) {
@ -910,4 +976,15 @@
}
}
.qztkbox {
width: 90%;
position: fixed;
z-index: 10000;
left: 5%;
top: 10%;
display: flex;
flex-direction: column;
background: #fff;
}
</style>

View File

@ -25,6 +25,10 @@ interface userInfoStoreInt {
urlip: string
urlpro: string
allurl: string
xththid: string
xththstr: string
projectid: string
projectname: string
}
// 创建小仓库
@ -46,7 +50,11 @@ export default defineStore(
childrenmenutitle: '',
urlip: '',
urlpro: '',
allurl: ''
allurl: '',
xththid: '',
xththstr: '',
projectid: '',
projectname: ''
})
//debugger
userInfo.value.token = getToken()
@ -63,6 +71,10 @@ export default defineStore(
userInfo.value.urlip = storage.get(constant.urlip)
userInfo.value.urlpro = storage.get(constant.urlpro)
userInfo.value.allurl = storage.get(constant.allurl)
userInfo.value.xththstr = storage.get(constant.xththstr)
userInfo.value.xththid = storage.get(constant.xththid)
userInfo.value.projectid = storage.get(constant.projectid)
userInfo.value.projectname = storage.get(constant.projectname)
const token = computed(() => {
// debugger
@ -106,6 +118,19 @@ export default defineStore(
const allurl = computed(() => {
return userInfo.value.allurl
})
const xththid = computed(() => {
return userInfo.value.xththid
})
const xththstr = computed(() => {
return userInfo.value.xththstr
})
const projectid = computed(() => {
return userInfo.value.projectid
})
const projectname = computed(() => {
return userInfo.value.projectname
})
const parentmenutitle = computed(() => {
return userInfo.value.parentmenutitle
@ -118,6 +143,19 @@ export default defineStore(
userInfo.value.allurl = allurl
storage.set(constant.allurl, allurl)
}
function setxtht(xththid: any, xththstr: any) {
userInfo.value.xththid = xththid
userInfo.value.xththstr = xththstr
storage.set(constant.xththid, xththid)
storage.set(constant.xththstr, xththstr)
}
function setproject(projectid: any, projectname: any) {
userInfo.value.projectid = projectid
userInfo.value.projectname = projectname
storage.set(constant.projectid, projectid)
storage.set(constant.projectname, projectname)
}
function seturlip(urlip: any) {
userInfo.value.urlip = urlip
storage.set(constant.urlip, urlip)
@ -256,7 +294,11 @@ export default defineStore(
childrenmenutitle: '',
urlip: '',
urlpro: '',
allurl: ''
allurl: '',
xththid: '',
xththstr: '',
projectid: '',
projectname: ''
}
uni.clearStorageSync()
goToPage({
@ -300,7 +342,13 @@ export default defineStore(
seturlip,
seturlpro,
setallurl,
allurl
allurl,
setxtht,
xththid,
xththstr,
projectid,
projectname,
setproject
}
},
{

View File

@ -0,0 +1,26 @@
## 1.1.22024-12-10
- 修改文档
## 1.1.12023-07-10
- 修复不完全选中状态在清除所有选项时不重置问题
## 1.1.02023-07-10
- 重写checkbox解决与colorui样式冲突问题
- 父级添加子级未全选状态,更直观了解选中数据情况
- 样式优化,提取文件内样式变量
- 代码体积优化
- 文档更新
## 1.0.62023-06-28
- 文档更新
## 1.0.52023-06-28
- 修复重置搜索框时不展示数据
- 新增异步懒加载节点(点击名称加载子节点)
## 1.0.42023-06-27
- 修复微信小程序下点击两次选择框才能打开弹窗问题
## 1.0.32023-05-29
- 文档更新
## 1.0.22023-05-29
- 文档更新
- 添加 `select-change` 事件,返回选中数据完整信息
## 1.0.12023-05-29
- 文档更新
## 1.0.02023-05-25
- 基础功能完善

View File

@ -0,0 +1,906 @@
<template>
<view :class="['select-list', { disabled }, { active: selectList.length }]" @click="open">
<view class="left">
<view v-if="selectList.length" class="select-items">
<view class="select-item" v-for="item in selectedListBaseinfo" :key="item[dataValue]">
<view class="name">
<text>{{ item[dataLabel] }}</text>
</view>
<view v-if="!disabled && !item.disabled" class="close" @click.stop="removeSelectedItem(item)">
<uni-icons type="closeempty" size="16" color="#999"></uni-icons>
</view>
</view>
</view>
<view v-else style="color: #6a6a6a" class="no-data">
<text>{{ placeholder }}</text>
</view>
</view>
<view class="right">
<uni-icons v-if="!selectList.length || !clearable" type="bottom" size="14" color="#999"></uni-icons>
<view @click.stop>
<uni-icons v-if="selectList.length && clearable" type="clear" size="24" color="#c0c4cc"
@click="clearSelectList"></uni-icons>
</view>
</view>
</view>
<uni-popup ref="popup" :animation="animation" :is-mask-click="isMaskClick"
:mask-background-color="maskBackgroundColor" :background-color="backgroundColor" :safe-area="safeArea" type="bottom"
@change="change" @maskClick="maskClick">
<view class="popup-content" :style="{ height: contentHeight }">
<view class="title">
<view v-if="mutiple && canSelectAll" class="left" @click="handleSelectAll">
<text>{{ isSelectedAll ? '取消全选' : '全选' }}</text>
</view>
<view class="center">
<text>{{ placeholder }}</text>
</view>
<view class="right" :style="{ color: confirmTextColor }" @click="close">
<text>{{ confirmText }}</text>
</view>
</view>
<view v-if="search" class="search-box">
<uni-easyinput :maxlength="-1" prefixIcon="search" placeholder="搜索" v-model="searchStr" confirm-type="search"
@confirm="handleSearch(false)" @clear="handleSearch(true)">
</uni-easyinput>
<button type="primary" size="mini" class="search-btn" @click="handleSearch(false)">
搜索
</button>
</view>
<view v-if="treeData.length" class="select-content">
<scroll-view class="scroll-view-box" :scroll-top="scrollTop" scroll-y="true" @touchmove.stop>
<view v-if="!filterTreeData.length" class="no-data center">
<text>暂无数据</text>
</view>
<data-select-item v-for="item in filterTreeData" :key="item[dataValue]" :node="item" :dataLabel="dataLabel"
:dataValue="dataValue" :dataChildren="dataChildren" :choseParent="choseParent" :border="border"
:linkage="linkage" :lazyLoadChildren="lazyLoadChildren"></data-select-item>
<view class="sentry" />
</scroll-view>
</view>
<view v-else class="no-data center">
<text>暂无数据</text>
</view>
</view>
</uni-popup>
</template>
<script lang="ts" setup>
import { ref, computed, watch, onMounted, nextTick, provide } from 'vue'
import dataSelectItem from './data-select-item.vue'
import { isString, paging } from './utils'
const props = defineProps({
canSelectAll: {
type: Boolean,
default: false
},
safeArea: {
type: Boolean,
default: true
},
search: {
type: Boolean,
default: false
},
clearResetSearch: {
type: Boolean,
default: false
},
animation: {
type: Boolean,
default: true
},
'is-mask-click': {
type: Boolean,
default: true
},
'mask-background-color': {
type: String,
default: 'rgba(0,0,0,0.4)'
},
'background-color': {
type: String,
default: 'none'
},
'safe-area': {
type: Boolean,
default: true
},
choseParent: {
type: Boolean,
default: true
},
placeholder: {
type: String,
default: '请选择'
},
confirmText: {
type: String,
default: '完成'
},
confirmTextColor: {
type: String,
default: '#007aff'
},
listData: {
type: Array,
default: () => []
},
dataLabel: {
type: String,
default: 'name'
},
dataValue: {
type: String,
default: 'id'
},
dataChildren: {
type: String,
default: 'children'
},
linkage: {
type: Boolean,
default: false
},
removeLinkage: {
type: Boolean,
default: true
},
clearable: {
type: Boolean,
default: false
},
mutiple: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
showChildren: {
type: Boolean,
default: true
},
border: {
type: Boolean,
default: false
},
lazyLoadChildren: {
type: Boolean,
default: false
},
load: {
type: Function,
default: function () { }
},
modelValue: {
type: [Array, String],
default: () => []
}
})
const emits = defineEmits([
'update:modelValue',
'change',
'maskClick',
'select-change',
'removeSelect',
'xuanzechange'
])
const contentHeight = ref('500px')
const treeData = ref([])
const filterTreeData = ref([])
const clearTimerList = ref([])
const selectedListBaseinfo = ref([])
const showPopup = ref(false)
const isSelectedAll = ref(false)
const scrollTop = ref(0)
const searchStr = ref('')
const popup = ref<any>(null)
const partCheckedSet = new Set()
provide('nodeFn', {
nodeClick: handleNodeClick,
nameClick: handleHideChildren,
loadNode: props.load,
initData: initData,
addNode: addNode
})
const selectList = computed(() => {
const newVal = props.modelValue === null ? '' : props.modelValue
return isString(newVal)
? newVal.length
? newVal.split(',')
: []
: newVal.map((item : any) => item.toString())
})
onMounted(() => {
getContentHeight(uni.getSystemInfoSync())
})
function getContentHeight({ screenHeight } : { screenHeight : number }) {
contentHeight.value = `${Math.floor(screenHeight * 0.7)}px`
}
watch(
() => props.listData,
(newVal : any[]) => {
if (newVal) {
treeData.value = initData(newVal)
const ids = props.modelValue
? Array.isArray(props.modelValue)
? props.modelValue
: props.modelValue.split(',')
: []
changeStatus(treeData.value, ids, true)
filterTreeData.value.length && changeStatus(filterTreeData.value, ids)
if (showPopup.value) {
resetClearTimerList()
renderTree(treeData.value)
}
}
},
{ immediate: true, deep: true }
)
watch(
() => props.modelValue,
(newVal : any[] | string) => {
const ids = newVal
? Array.isArray(newVal)
? newVal
: newVal.split(',')
: []
changeStatus(treeData.value, ids, true)
filterTreeData.value.length && changeStatus(filterTreeData.value, ids)
},
{ immediate: true }
)
//
function goTop() {
scrollTop.val = 10
nextTick(() => {
scrollTop.value = 0
})
}
//
function handleSearch(isClear = false) {
resetClearTimerList()
if (isClear) {
//
if (props.clearResetSearch) {
renderTree(treeData.value)
}
} else {
renderTree(searchValue(searchStr.value, treeData.value))
}
goTop()
uni.hideKeyboard()
}
//
function searchValue(str : any, arr : any[]) {
const res : any = []
arr.forEach((item) => {
if (item.visible) {
if (
item[props.dataLabel]
.toString()
.toLowerCase()
.indexOf(str.toLowerCase()) > -1
) {
res.push(item)
} else {
if (item[props.dataChildren]?.length) {
const data = searchValue(str, item[props.dataChildren])
if (data?.length) {
if (str && !item.showChildren && item[props.dataChildren]?.length) {
item.showChildren = true
}
res.push({
...item,
[props.dataChildren]: data
})
}
}
}
}
})
return res
}
//
async function open() {
// disaled
if (props.disabled) return
showPopup.value = true
popup.value.open()
renderTree(treeData.value)
}
//
function close() {
popup.value.close()
}
//
function change(data : any) {
if (!data.show) {
resetClearTimerList()
searchStr.value = ''
showPopup.value = false
}
emits('change', data)
}
//
function maskClick() {
emits('maskClick')
}
//
function initData(arr : any[], parentVisible ?: undefined | boolean) {
if (!Array.isArray(arr)) return []
const res = []
for (let i = 0; i < arr.length; i++) {
const obj : any = {
[props.dataLabel]: arr[i][props.dataLabel],
[props.dataValue]: arr[i][props.dataValue],
'code': arr[i]['code'] || '',
'deptId': arr[i]['deptId'] || '',
'level': arr[i]['level'] || '',
'id': arr[i]['id'] || '',
'parentId': arr[i]['parentId'] || '',
}
obj.checked = selectList.value.includes(arr[i][props.dataValue].toString())
obj.disabled = Boolean(arr[i].disabled)
//
obj.partChecked = Boolean(
arr[i].partChecked === undefined ? false : arr[i].partChecked
)
obj.partChecked && obj.partCheckedSet.add(obj[props.dataValue])
!obj.partChecked && (isSelectedAll.value = false)
const parentVisibleState =
parentVisible === undefined ? true : parentVisible
const curVisibleState =
arr[i].visible === undefined ? true : Boolean(arr[i].visible)
if (parentVisibleState === curVisibleState) {
obj.visible = parentVisibleState
} else if (!parentVisibleState || !curVisibleState) {
obj.visible = false
} else {
obj.visible = true
}
obj.showChildren =
'showChildren' in arr[i] && arr[i].showChildren != undefined
? arr[i].showChildren
: props.showChildren
if (arr[i].visible && !arr[i].disabled && !arr[i].checked) {
isSelectedAll.value = false
}
if (arr[i][props.dataChildren]?.length) {
obj[props.dataChildren] = initData(
arr[i][props.dataChildren],
obj.visible
)
}
res.push(obj)
}
return res
}
function addNode(node : any, children : any[]) {
getReflectNode(node, treeData.value)[props.dataChildren] = children
handleHideChildren(node)
}
//
function resetClearTimerList() {
const list = [...clearTimerList.value]
clearTimerList.value = []
list.forEach((fn) => fn())
}
//
function renderTree(arr : any[]) {
const pagingArr = paging(arr)
filterTreeData.value = pagingArr?.[0] || []
lazyRenderList(pagingArr, 1)
}
//
function lazyRenderList(arr : any[], startIndex : number) {
for (let i = startIndex; i < arr.length; i++) {
let timer : any = null
timer = setTimeout(() => {
filterTreeData.value.push(...arr[i])
}, i * 500)
clearTimerList.push(() => clearTimeout(timer))
}
}
// dataValue
function changeStatus(list : any[], ids : any[] | string, needEmit = false) {
const arr = [...list]
let flag = true
needEmit && (selectedListBaseinfo.value = [])
while (arr.length) {
const item = arr.shift()
if (ids.includes(item[props.dataValue].toString())) {
item.checked = true
//
item.partChecked = false
partCheckedSet.delete(item[props.dataValue])
needEmit && selectedListBaseinfo.value.push(item)
} else {
item.checked = false
if (item.visible && !item.disabled) {
flag = false
}
if (partCheckedSet.has(item[props.dataValue])) {
// filtertreedata
item.partChecked = true
} else {
item.partChecked = false
}
}
if (item[props.dataChildren]?.length) {
arr.push(...item[props.dataChildren])
}
}
isSelectedAll.value = flag
needEmit && emits('select-change', [...selectedListBaseinfo.value])
}
//
function removeSelectedItem(node : any) {
isSelectedAll.value = false
if (props.linkage) {
handleNodeClick(node, false)
emits('removeSelect', node)
} else {
const emitData = selectList.value.filter(
(item : any) => item !== node[props.dataValue].toString()
)
emits('removeSelect', node)
emits(
'update:modelValue',
isString(props.modelValue) ? emitData.join(',') : emitData
)
}
}
//
function getReflectNode(node : any, arr : any[]) {
const array = [...arr]
while (array.length) {
const item = array.shift()
if (item[props.dataValue] === node[props.dataValue]) {
return item
}
if (item[props.dataChildren]?.length) {
array.push(...item[props.dataChildren])
}
}
return {}
}
//
function getChildren(node : any) {
if (!node[props.dataChildren]?.length) return []
const res = node[props.dataChildren].reduce((pre : any, val : any) => {
if (val.visible) {
return [...pre, val]
}
return pre
}, [])
for (let i = 0; i < node[props.dataChildren].length; i++) {
res.push(...getChildren(node[props.dataChildren][i]))
}
return res
}
//
function getParentNode(target : any, arr : any[]) {
let res : any[] = []
for (let i = 0; i < arr.length; i++) {
if (arr[i][props.dataValue] === target[props.dataValue]) {
return true
}
if (arr[i][props.dataChildren]?.length) {
const childRes = getParentNode(target, arr[i][props.dataChildren])
if (typeof childRes === 'boolean' && childRes) {
res = [arr[i]]
} else if (Array.isArray(childRes) && childRes.length) {
res = [...childRes, arr[i]]
}
}
}
return res
}
// checkbox
function handleNodeClick(data : any, status : boolean | undefined) {
// debugger
const node = getReflectNode(data, treeData.value)
node.checked = typeof status === 'boolean' ? status : !node.checked
node.partChecked = false
partCheckedSet.delete(node[props.dataValue])
//
if (!props.mutiple) {
let emitData : any[] = []
if (node.checked) {
emitData = [node[props.dataValue].toString()]
}
emits(
'update:modelValue',
isString(props.modelValue) ? emitData.join(',') : emitData
)
emits(
'xuanzechange',
node
)
} else {
//
if (!props.linkage) {
//
let emitData = null
if (node.checked) {
emitData = Array.from(
new Set([...selectList.value, node[props.dataValue].toString()])
)
} else {
emitData = selectList.value.filter(
(id : number | string) => id !== node[props.dataValue].toString()
)
}
emits(
'update:modelValue',
isString(props.modelValue) ? emitData.join(',') : emitData
)
} else {
//
let emitData = [...selectList.value]
const parentNodes : any = getParentNode(node, treeData.value)
const childrenVal = getChildren(node).filter(
(item : any) => !item.disabled
)
if (node.checked) {
//
emitData = Array.from(
new Set([...emitData, node[props.dataValue].toString()])
)
if (childrenVal.length) {
emitData = Array.from(
new Set([
...emitData,
...childrenVal.map((item : any) =>
item[props.dataValue].toString()
)
])
)
//
childrenVal.forEach((childNode : any) => {
childNode.partChecked = false
partCheckedSet.delete(childNode[props.dataValue])
})
}
if (parentNodes.length) {
let flag = false
//
while (parentNodes.length) {
const item = parentNodes.shift()
if (!item.disabled) {
if (flag) {
//
item.partChecked = true
partCheckedSet.add(item[props.dataValue])
} else {
const allChecked = item[props.dataChildren]
.filter((node : any) => node.visible && !node.disabled)
.every((node : any) => node.checked)
if (allChecked) {
item.checked = true
item.partChecked = false
partCheckedSet.delete(item[props.dataValue])
emitData = Array.from(
new Set([...emitData, item[props.dataValue].toString()])
)
} else {
item.partChecked = true
partCheckedSet.add(item[props.dataValue])
flag = true
}
}
}
}
}
} else {
//
emitData = emitData.filter(
(id) => id !== node[props.dataValue].toString()
)
if (childrenVal.length) {
//
childrenVal.forEach((childNode : any) => {
emitData = emitData.filter(
(id) => id !== childNode[props.dataValue].toString()
)
})
}
if (parentNodes.length) {
parentNodes.forEach((parentNode : any) => {
if (emitData.includes(parentNode[props.dataValue].toString())) {
parentNode.checked = false
}
emitData = emitData.filter(
(id) => id !== parentNode[props.dataValue].toString()
)
const hasChecked = parentNode[props.dataChildren]
.filter((node : any) => node.visible && !node.disabled)
.some((node : any) => node.checked || node.partChecked)
parentNode.partChecked = hasChecked
if (hasChecked) {
partCheckedSet.add(parentNode[props.dataValue])
} else {
partCheckedSet.delete(parentNode[props.dataValue])
}
})
}
}
emits(
'update:modelValue',
isString(props.modelValue) ? emitData.join(',') : emitData
)
}
}
}
//
function handleHideChildren(node : any) {
const status = !node.showChildren
getReflectNode(node, treeData.value).showChildren = status
getReflectNode(node, filterTreeData.value).showChildren = status
}
//
function handleSelectAll() {
isSelectedAll.value = !isSelectedAll.value
if (isSelectedAll.value) {
if (!props.mutiple) {
uni.showToast({
title: '单选模式下不能全选',
icon: 'none',
duration: 1000
})
return
}
let emitData : any[] = []
treeData.value.forEach((item : any) => {
if (item.visible || (item.disabled && item.checked)) {
emitData = Array.from(
new Set([...emitData, item[props.dataValue].toString()])
)
if (item[props.dataChildren]?.length) {
emitData = Array.from(
new Set([
...emitData,
...getChildren(item)
.filter(
(item : any) =>
!item.disabled || (item.disabled && item.checked)
)
.map((item : any) => item[props.dataValue].toString())
])
)
}
}
})
emits(
'update:modelValue',
isString(props.modelValue) ? emitData.join(',') : emitData
)
} else {
clearSelectList()
}
}
//
function clearSelectList() {
if (props.disabled) return
partCheckedSet.clear()
const emitData : any[] = []
selectedListBaseinfo.value.forEach((node : any) => {
if (node.visible && node.checked && node.disabled) {
emitData.push(node[props.dataValue])
}
})
emits(
'update:modelValue',
isString(props.modelValue) ? emitData.join(',') : emitData
)
}
</script>
<style lang="scss" scoped>
$primary-color: #007aff;
$col-sm: 4px;
$col-base: 8px;
$col-lg: 12px;
$row-sm: 5px;
$row-base: 10px;
$row-lg: 15px;
$radius-sm: 3px;
$radius-base: 6px;
$uni-border-color: #999;
.select-list {
padding-left: $row-base;
min-height: 35px;
border: 1px solid #e5e5e5;
border-radius: $radius-sm;
display: flex;
justify-content: space-between;
align-items: center;
&.active {
padding: calc(#{$col-sm} / 2) 0 calc(#{$col-sm} / 2) $row-base;
}
.left {
flex: 1;
.select-items {
display: flex;
flex-wrap: wrap;
}
.select-item {
margin: $col-sm $row-base $col-sm 0;
padding: $col-sm $row-sm;
max-width: auto;
height: auto;
background-color: #eaeaea;
border-radius: $radius-sm;
color: #333;
display: flex;
align-items: center;
.name {
flex: 1;
padding-right: $row-base;
font-size: 14px;
}
.close {
width: 18px;
height: 18px;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
}
}
}
.right {
margin-right: $row-sm;
display: flex;
justify-content: flex-end;
align-items: center;
}
&.disabled {
background-color: #f5f7fa;
.left {
.select-item {
.name {
padding: 0;
}
}
}
}
}
.popup-content {
flex: 1;
background-color: #fff;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
display: flex;
flex-direction: column;
.title {
padding: $col-base 3rem;
border-bottom: 1px solid $uni-border-color;
font-size: 14px;
display: flex;
justify-content: space-between;
position: relative;
.left {
position: absolute;
left: 10px;
}
.center {
flex: 1;
text-align: center;
}
.right {
position: absolute;
right: 10px;
}
}
.search-box {
margin: $col-base $row-base 0;
background-color: #fff;
display: flex;
align-items: center;
.search-btn {
margin-left: $row-base;
height: 35px;
line-height: 35px;
}
}
.select-content {
margin: $col-base $row-base;
flex: 1;
overflow: hidden;
position: relative;
}
.scroll-view-box {
touch-action: none;
flex: 1;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.sentry {
height: 48px;
}
}
.no-data {
width: auto;
color: #999;
font-size: 12px;
}
.no-data.center {
text-align: center;
}
</style>

View File

@ -0,0 +1,285 @@
<template>
<view
class="customthree-tree-select-content"
:class="{
border: border && node[dataChildren] && node[dataChildren].length && node.showChildren
}"
:style="{ marginLeft: `${level ? 14 : 0}px` }"
>
<view v-if="node.visible" class="custom-tree-select-item">
<view class="item-content">
<view class="left" @click.stop="handleNameClick(node)">
<view class="icon-group">
<view
v-if="node[dataChildren] && node[dataChildren].length"
:class="['right-icon', { active: node.showChildren }]"
>
<uni-icons type="right" size="14" color="#333"></uni-icons>
</view>
<view v-else class="smallcircle-filled">
<uni-icons class="smallcircle-filled-icon" type="smallcircle-filled" size="10" color="#333"></uni-icons>
</view>
</view>
<view v-if="loadingArr.includes(node[props.dataValue].toString())" class="loading-icon-box">
<uni-icons class="loading-icon" type="spinner-cycle" size="14" color="#333"></uni-icons>
</view>
<view class="name" :style="node.disabled ? 'color: #999' : ''">
<text>{{ node[dataLabel] }}</text>
</view>
</view>
<view
v-if="
choseParent ||
(!choseParent && !node[dataChildren]) ||
(!choseParent && node[dataChildren] && !node[dataChildren].length)
"
:class="['check-box', { disabled: node.disabled }]"
@click.stop="!node.disabled && nodeClick(node)"
>
<view v-if="!node.checked && node.partChecked && linkage" class="part-checked"></view>
<uni-icons
v-if="node.checked"
type="checkmarkempty"
size="18"
:color="node.disabled ? '#333' : '#007aff'"
></uni-icons>
</view>
</view>
</view>
<view v-if="node.showChildren && node[dataChildren] && node[dataChildren].length">
<data-select-item
v-for="item in listData"
:key="item[dataValue]"
:node="item"
:dataLabel="dataLabel"
:dataValue="dataValue"
:dataChildren="dataChildren"
:choseParent="choseParent"
:lazyLoadChildren="lazyLoadChildren"
:border="border"
:linkage="linkage"
:level="level + 1"
></data-select-item>
</view>
</view>
</template>
<script lang="ts" setup>
import dataSelectItem from './data-select-item.vue'
import { paging } from './utils'
import { ref, inject, watchEffect } from 'vue'
const { nodeClick, nameClick, loadNode, initData, addNode } = inject('nodeFn')
const props = defineProps({
node: {
type: Object,
default: () => ({})
},
choseParent: {
type: Boolean,
default: true
},
dataLabel: {
type: String,
default: 'name'
},
dataValue: {
type: String,
default: 'value'
},
dataChildren: {
type: String,
default: 'children'
},
border: {
type: Boolean,
default: false
},
linkage: {
type: Boolean,
default: false
},
lazyLoadChildren: {
type: Boolean,
default: false
},
level: {
type: Number,
default: 0
}
})
const listData = ref([])
const clearTimerList = ref([])
const loadingArr = ref([])
watchEffect(() => {
if (props.node.showChildren && props.node[props.dataChildren] && props.node[props.dataChildren].length) {
resetClearTimerList()
renderTree(props.node[props.dataChildren])
}
})
//
function resetClearTimerList() {
const list = [...clearTimerList.value]
clearTimerList.value = []
list.forEach((fn) => fn())
}
//
function renderTree(arr: any[]) {
const pagingArr = paging(arr)
listData.value = pagingArr?.[0] || []
lazyRenderList(pagingArr, 1)
}
//
function lazyRenderList(arr: any[], startIndex: number) {
for (let i = startIndex; i < arr.length; i++) {
let timer: any = null
timer = setTimeout(() => {
listData.value.push(...arr[i])
}, i * 500)
clearTimerList.push(() => clearTimeout(timer))
}
}
//
function handleNameClick(node: any) {
if (!node.visible) return
if (!node[props.dataChildren]?.length && props.lazyLoadChildren) {
loadingArr.value.push(node[props.dataValue].toString())
loadNode(node)
.then((res: any) => {
addNode(node, initData(res, node.visible))
})
.finally(() => {
loadingArr.value = []
})
} else {
nameClick(node)
}
}
</script>
<style lang="scss" scoped>
$primary-color: #007aff;
$col-sm: 4px;
$col-base: 8px;
$col-lg: 12px;
$row-sm: 5px;
$row-base: 10px;
$row-lg: 15px;
$radius-sm: 3px;
$radius-base: 6px;
$border-color: #c8c7cc;
.customthree-tree-select-content {
&.border {
border-left: 1px solid $border-color;
}
::v-deep .uni-checkbox-input {
margin: 0 !important;
}
.item-content {
margin: 0 0 $col-lg;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
&::after {
content: '';
position: absolute;
top: 0;
left: 0;
bottom: 0;
width: 3px;
background-color: #fff;
transform: translateX(-2px);
z-index: 1;
}
.left {
flex: 1;
display: flex;
align-items: center;
.right-icon {
transition: 0.15s ease;
&.active {
transform: rotate(90deg);
}
}
.smallcircle-filled {
width: 14px;
height: 13.6px;
display: flex;
align-items: center;
.smallcircle-filled-icon {
transform-origin: center;
transform: scale(0.55);
}
}
.loading-icon-box {
margin-right: $row-sm;
width: 14px;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
.loading-icon {
transform-origin: center;
animation: rotating infinite 0.2s ease;
}
}
.name {
flex: 1;
}
}
}
.check-box {
margin: 0;
padding: 0;
box-sizing: border-box;
width: 23.6px;
height: 23.6px;
border: 1px solid $border-color;
border-radius: $radius-sm;
display: flex;
justify-content: center;
align-items: center;
&.disabled {
background-color: rgb(225, 225, 225);
}
.part-checked {
width: 60%;
height: 2px;
background-color: $primary-color;
}
}
}
@keyframes rotating {
from {
transform: rotate(0);
}
to {
transform: rotate(360deg);
}
}
</style>

View File

@ -0,0 +1,17 @@
export function isString(data: any) {
return typeof data === 'string'
}
// 分页
export function paging(data: any[], PAGENUM = 50) {
if (!Array.isArray(data) || !data.length) return data
const pages: any[] = []
data.forEach((item, index) => {
const i = Math.floor(index / PAGENUM)
if (!pages[i]) {
pages[i] = []
}
pages[i].push(item)
})
return pages
}

View File

@ -0,0 +1,85 @@
{
"id": "customthree-tree-select",
"displayName": "customthree-tree-select树形选择器支持v-model vue3版本",
"version": "1.1.2",
"description": "树形选择器基于uni-uiv-model绑定数据父级可选、数据回显、移除选项",
"keywords": [
"custom",
"tree-select",
"选择器",
"树形选择器"
],
"repository": "",
"engines": {
"HBuilderX": "^3.8.3"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"Vue": {
"vue2": "n",
"vue3": "y"
},
"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",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}

View File

@ -0,0 +1,240 @@
# customthree-tree-select 使用指南
**提示:** 使用该插件前确保你已经导入 `uni-popup` `uni-icons` `uni-easyinput` 插件。
**有问题可以加 QQ 群297080738**
## 优势
💪:基于 `uni-popup``uni-icons``uni-easyinput` 插件进行开发,默认样式与 `uni-easyinput` 样式对标。
⚡:全面支持懒加载应对大量数据。
🚀v-model 绑定数据、数据回显、移除选项。
⚙ :提供更多配置项。
📦:开箱即用。
## Props
| 属性名 | 类型 | 默认值 | 说明 |
| :--------------------: | :-----------------: | :-------------: | :----------------------------------------------------------: |
| canSelectAll | Boolean | false | 开启一键全选功能 |
| clearResetSearch | Boolean | false | 设置为 `true` 并且搜索之后,点击输入框清除按钮,会清空搜索内容并且会直接重置整个弹窗内树形选择器内容,默认情况下只有清除之后再次进行查询才会重置选择器 |
| animation | Boolean | ture | 是否开启弹窗动画 |
| is-mask-click | Boolean | true | 点击遮罩关闭弹窗 |
| mask-background-color | String | rgba(0,0,0,0.4) | 蒙版颜色,建议使用 rgba 颜色值 |
| background-color | String | none | 主窗口背景色 |
| safe-area | Boolean | true | 是否适配底部安全区 |
| **choseParent** | **Boolean** | **true** | **父节点是否可选** |
| **linkage** | **Boolean** | **false** | **父子节点是否联动** |
| placeholder | String | 请选择 | 空状态信息提示、弹窗标题 |
| confirmText | String | 完成 | 确定按钮文字 |
| confirmTextColor | String | #007aff | 确定按钮文字颜色 |
| listData | Array | - | 展示的数据 |
| **dataLabel** | **String** | **name** | **listData 中对应数据的 label** |
| **dataValue** | **String** | **id** | **listData 中对应数据的 value** |
| **dataChildren** | **String** | **children** | **listData 中对应数据的 children** |
| clearable | Boolean | false | 是否显示清除按钮,点击清除所有已选项 |
| **mutiple** | **Boolean** | **false** | **是否可以多选** |
| **disabled** | **Boolean** | **false** | **是否允许修改** |
| search | Boolean | false | 是否可以搜索(常用于数据较多的情况) |
| showChildren | Boolean | true | 默认展开(数据内部 showChildren 属性优先级更高,可以设置全局收起,单独展开某一条数据) |
| border | Boolean | false | 显示引导线 |
| load | Function | function(){} | lazyLoadChildren 设置为true 后,点击某个节点发送请求获取子节点数据,用法见下方异步懒加载示例 |
| lazyLoadChildren | Boolean | false | 是否开启异步懒加载节点 |
| **v-model/modelValue** | **Array \| String** | **[ ]** | **已选择的值,通过 v-model 进行绑定例如v-model="formData.selectedList" 根据你绑定数据的类型自动返回相同类型的数据String 类型通过 `,` 进行分隔** |
## Events
| 事件名称 | 说明 | 返回值 |
| ----------------- | ------------------------ | ------------------------------------------- |
| change | 弹窗组件状态发生变化触发 | e={show: true false,type:当前模式} |
| maskClick | 点击遮罩层触发 | |
| update:modelValue | 选中数据或取消选中时触发 | 以数组形式返回已选择数据的 dataValue 对应值 |
| select-change | 选中数据或取消选中时触发 | 以数组形式返回选中数据完整信息 |
| removeSelect | 从选择框内删除元素时触发 | |
## 基础使用示例
```vue
<template>
<customthree-tree-select :listData="listData" v-model="formData.selectedArr" />
<customthree-tree-select :listData="listData" v-model="formData.selectedString" />
</template>
<script setup>
import { reactive } from 'vue'
const formData = reactive({
selectedArr: [],
selectedString: ''
})
const listData = [
{
id: 1,
name: '城市1',
children: [
{
id: 3,
name: '街道1',
children: [
{
id: 4,
name: '小区1'
}
]
}
]
},
{
id: 2,
name: '城市2',
children: [
{
id: 6,
name: '街道2'
}
]
}
]
</script>
```
## 禁用某些选项,或隐藏某些选项
```vue
<template>
<customthree-tree-select
mutiple
linkage
clearable
search
dataLabel="text"
dataValue="value"
:listData="listData"
v-model="formData.selected"
></custom-tree-select>
</template>
<script setup>
import { reactive } from 'vue'
const formData = reactive({
selected: ''
})
const listData = [
{
id: 1,
name: '城市1',
children: [
{
id: 3,
name: '街道1',
disabled: true
children: [
{
id: 4,
name: '小区1'
}
]
}
]
},
{
id: 2,
name: '城市2',
children: [
{
id: 6,
name: '街道2',
visible: false
}
]
}
]
</script>
```
## 异步懒加载
```vue
<template>
<view class="content">
<customthree-tree-select
search
linkage
clearable
clearResetSearch
border
mutiple
lazyLoadChildren
canSelectAll
:showChildren="false"
:listData="listData"
:load="loadNode"
dataLabel="text"
dataValue="value"
v-model="selectedStr"
></customthree-tree-select>
</view>
</template>
<script>
export default {
data() {
return {
selectedStr: '',
listData: [
{
value: '0',
text: '测试懒加载'
},
{
value: '1',
text: '城市1',
children: [
{
value: '1-1',
text: '街道1',
disabled: true
}
]
}
]
}
},
methods: {
loadNode(node) {
return new Promise((resolve) => {
setTimeout(() => {
const item = this.listData.find((item) => item.value === node.value)
if (item) {
resolve([
{
value: '0-1',
text: '懒加载子元素'
}
])
}
resolve([])
}, 500)
})
}
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
</style>
```

View File

@ -0,0 +1,12 @@
## 1.0.52024-09-14
更新说明
## 1.0.42023-12-08
增加弹层宽度可配置
## 1.0.32023-12-08
更新使用事件说明
## 1.0.22023-06-15
增加自定义插槽使用说明
## 1.0.12023-06-14
增加插件使用说明
## 1.0.02023-06-12
初始化next-modal

View File

@ -0,0 +1,275 @@
<template>
<view class="next-modal" @touchmove.stop.prevent="bindTouchmove" :class="{'next-modal--show':isOpen}">
<view class="next-modal__mask" @click="clickMask"></view>
<view :style="width ? 'width:'+ width : ''" class="next-modal__container">
<template v-if="$slots.title">
<slot name="title" />
</template>
<template v-else>
<view class="next-modal__header" v-if="title.length > 0">{{title}}</view>
</template>
<view class="next-modal__content" :class="content ? 'next-modal--padding' : ''">
<template v-if="$slots.default || $slots.content">
<view><slot name="content" /></view>
<view><slot /></view>
</template>
<template v-else>
<view :style="{textAlign:align}">
<text class="modal-content">{{content}}</text>
</view>
</template>
</view>
<view class="next-modal__footer">
<template v-if="$slots.footer">
<slot name="footer" />
</template>
<template v-else>
<view v-if="showCancel" class="next-modal__footer-left" @click="clickLeft" :style="{color:cancelColor}"
hover-class="next-modal__footer-hover" :hover-start-time="20" :hover-stay-time="70">
{{cancelText}}
</view>
<view class="next-modal__footer-right" @click="clickRight" :style="{color:confirmColor}"
hover-class="next-modal__footer-hover" :hover-start-time="20" :hover-stay-time="70">
{{confirmText}}
</view>
</template>
</view>
</view>
</view>
</template>
<script>
export default {
name: 'next-modal',
props: {
title: { //
type: String,
default: ''
},
content: String, //
align: {
type: String,
default: 'left'
},
cancelText: { //""
type: String,
default: '取消'
},
cancelColor: { //
type: String,
default: '#333333'
},
confirmText: { //""
type: String,
default: '确定'
},
confirmColor: { //
type: String,
default: '#f0ad4e'
},
showCancel: { // true
type: [Boolean, String],
default: true
},
show: { //
type: [Boolean, String],
default: false
},
autoClose: { //
type: [Boolean, String],
default: true
},
width: {
type: String
}
},
data() {
return {
isOpen: false
}
},
created() {
this.$watch(() => this.show, (val) => {
this.isOpen = val
})
},
methods: {
bindTouchmove() {},
clickLeft() {
setTimeout(() => {
this.$emit('cancel')
}, 200)
},
clickRight() {
setTimeout(() => {
this.$emit('confirm')
}, 200)
},
clickMask() {
if (this.autoClose) {
this.closeModal()
}
},
closeModal() {
this.showAnimation = false
this.isOpen = false
this.$emit('close')
}
}
}
</script>
<style lang="scss">
$bg-color-mask: rgba(0, 0, 0, 0.5); //
$bg-color-hover: #f1f1f1; //
.next-modal {
position: fixed;
visibility: hidden;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 1000;
transition: visibility 200ms ease-in;
&.next-modal--show {
visibility: visible;
}
&__header {
position: relative;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding: 18upx 24upx;
line-height: 1.5;
color: #333;
font-size: 32upx;
text-align: center;
&::after {
content: " ";
position: absolute;
left: 0;
bottom: 0;
right: 0;
height: 1px;
border-top: 1px solid #e5e5e5;
transform-origin: 0 0;
transform: scaleY(.5);
}
}
&__container {
position: absolute;
z-index: 999;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition: transform 0.3s;
width: 540upx;
border-radius: 20upx;
background-color: #fff;
overflow: hidden;
opacity: 0;
transition: opacity 200ms ease-in;
}
&__content {
position: relative;
color: #333;
font-size: 28upx;
box-sizing: border-box;
line-height: 1.5;
&::after {
content: " ";
position: absolute;
left: 0;
bottom: -1px;
right: 0;
height: 1px;
border-bottom: 1px solid #e5e5e5;
transform-origin: 0 0;
transform: scaleY(.5);
}
}
&__footer {
position: relative;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #333;
font-size: 32upx;
display: flex;
flex-direction: row;
&-left,
&-right {
position: relative;
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
height: 88upx;
font-size: 28upx;
line-height: 88upx;
text-align: center;
background-color: #fff;
color: #333;
}
&-right {
color: #007aff;
}
&-left::after {
content: " ";
position: absolute;
right: -1px;
top: 0;
width: 1px;
bottom: 0;
border-right: 1px solid #e5e5e5;
transform-origin: 0 0;
transform: scaleX(.5);
}
&-hover {
background-color: $bg-color-hover;
}
}
&__mask {
display: block;
position: absolute;
z-index: 998;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: $bg-color-mask;
opacity: 0;
transition: opacity 200ms ease-in;
&.next-modal--show {
opacity: 1;
}
}
&--padding {
padding: 32upx 24upx;
min-height: 90upx;
}
&--show {
.next-modal__container,
.next-modal__mask {
opacity: 1;
}
}
}
</style>

View File

@ -0,0 +1,79 @@
{
"id": "next-modal",
"displayName": "next-modal(vue2 vue3多端通用)轻量modal弹层",
"version": "1.0.5",
"description": "modal弹层自定义弹层轻量弹层",
"keywords": [
"modal",
"next-modal",
"弹层",
"自定义弹层"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.1"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"npmurl": "",
"type": "component-vue"
},
"uni_modules": {
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y",
"alipay": "n"
},
"client": {
"App": {
"app-vue": "n",
"app-nvue": "n"
},
"H5-mobile": {
"Safari": "n",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "n",
"Edge": "n",
"Firefox": "n",
"Safari": "n"
},
"小程序": {
"微信": "y",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u"
},
"快应用": {
"华为": "n",
"联盟": "n"
},
"Vue": {
"vue2": "y",
"vue3": "y"
}
}
}
}
}

View File

@ -0,0 +1,341 @@
## next-modal --modal弹层
> 遇到问题或有建议可以加入QQ群(<font color=#f00>455948571</font>)反馈
> 如果觉得组件不错,<font color=#f00>给五星鼓励鼓励</font>咯!
### 如果有使用问题请加群
注意如果插件问题请务必给一个完整的复现demo谢谢配合
[点击链接加入群聊前端开发uniapp插件](https://qm.qq.com/q/S1bJzQfJAG)
### 预览
***
| 功能预览 |
| :----------------------------------------------------------------: |
| ![](https://lixueshiaa.github.io/webtest/www/static/next-modal.gif)|
## 使用
>[从uniapp插件市场导入](https://ext.dcloud.net.cn/plugin?name=next-modal)
### vue3 使用实例
```html
<template>
<view style="font-size: 16px;color: #666;padding: 10px"><text>基本用法</text></view>
<button size="mini" class="btn" @click="modalBasicShow=true">打开</button>
<view style="font-size: 16px;color: #666;padding: 10px"><text>自定义插槽基本用法</text></view>
<button size="mini" class="btn" @click="opencustom">打开</button>
<next-modal
:show="modalBasicShow"
content="感谢你使用next-modal组件"
title="提示"
@close="modalBasicShow=false"
@cancel="modalBasicShow=false"
@confirm="modalBasicShow=false"
/>
<next-modal
@close="close"
@cancel="cancel"
@confirm="confirm"
:show="modalCustomShow"
:title="modalTitle"
:content="modalContent"
>
<!--注意插槽的使用的优先级大于next-modal组件的props的值-->
<template #title><view style="text-align: center;padding:20rpx"><text>自定义标题-提示</text></view></template>
<!-- <template #content><view style="text-align: center;"><text>hello你好这是next-modal组件的内容next-modal是一个轻量级的组件没有其他依赖请放心使用</text></view></template> -->
<!--自定义content内容-->
<template #content>
<u--form
labelPosition="left"
:model="userInfo"
ref="form1"
labelWidth="80"
>
<u-form-item
label="姓名"
prop="name"
:borderBottom="false"
>
<u--input
v-model="userInfo.name"
border="none"
placeholder="请输入姓名"
></u--input>
</u-form-item>
<u-form-item
label="手机号码"
prop="phone"
:borderBottom="false"
>
<u--input
v-model="userInfo.phone"
border="none"
placeholder="请输入手机号码"
></u--input>
</u-form-item>
</u--form>
</template>
<!--自定义footer内容-->
<template #footer>
<view style="display: flex;padding: 20rpx;justify-content: space-around;width:100%">
<u-button @click="modalCustomShow=false" :customStyle="{margin: '0 10rpx'}">取消</u-button>
<u-button @click="reject" :customStyle="{margin: '0 10rpx'}" type="warning">拒绝</u-button>
<u-button @click="allow" :customStyle="{margin: '0 10rpx'}" type="primary">通过</u-button>
</view>
</template>
</next-modal>
</template>
```
```js
<script lang="ts">
import { ref } from 'vue'
export default {
setup() {
const modalCustomShow = ref(false)
const modalBasicShow = ref(false)
const modalTitle = ref('提示')
const modalContent = ref('hello你好这是next-modal组件的内容')
const userInfo = ref({})
function openbasic() {
}
function opencustom() {
modalCustomShow.value = true
}
function close() {
modalCustomShow.value = false
}
function cancel() {
modalCustomShow.value = false
}
function confirm() {
modalCustomShow.value = false
}
function reject() {
uni.showModal({
title: '确定要进行拒绝操作',
success: (res) => {
if (res.confirm) {
modalCustomShow.value = false
}
}
})
}
function allow() {
uni.showModal({
title: '确定要进行通过操作',
success: (res) => {
if (res.confirm) {
modalCustomShow.value = false
}
}
})
}
return {
userInfo,
modalCustomShow,
openbasic,
opencustom,
modalBasicShow,
modalTitle,
modalContent,
close,
cancel,
confirm,
reject,
allow
}
}
}
</script>
<style lang="scss">
.btn {
box-sizing: border-box;
flex: 1;
margin: 0 20rpx;
background-color: #f0ad4e;
color:#fff;
}
</style>
```
### vue2 使用实例
```html
<template>
<view style="font-size: 16px;color: #666;padding: 10px"><text>基本用法</text></view>
<button size="mini" class="btn" @click="modalBasicShow=true">打开</button>
<view style="font-size: 16px;color: #666;padding: 10px"><text>自定义插槽基本用法</text></view>
<button size="mini" class="btn" @click="opencustom">打开</button>
<next-modal
:show="modalBasicShow"
content="感谢你使用next-modal组件"
title="提示"
@close="modalBasicShow=false"
@cancel="modalBasicShow=false"
@confirm="modalBasicShow=false"
/>
<next-modal
@close="close"
@cancel="cancel"
@confirm="confirm"
:show="modalCustomShow"
:title="modalTitle"
:content="modalContent"
>
<!--注意插槽的使用的优先级大于next-modal组件的props的值-->
<view slot="title"><view style="text-align: center;padding:20rpx"><text>自定义标题-提示</text></view></view>
<!-- <template #content><view style="text-align: center;"><text>hello你好这是next-modal组件的内容next-modal是一个轻量级的组件没有其他依赖请放心使用</text></view></template> -->
<!--自定义content内容-->
<view slot="content">
<u--form
labelPosition="left"
:model="userInfo"
ref="form1"
labelWidth="80"
>
<u-form-item
label="姓名"
prop="name"
:borderBottom="false"
>
<u--input
v-model="userInfo.name"
border="none"
placeholder="请输入姓名"
></u--input>
</u-form-item>
<u-form-item
label="手机号码"
prop="phone"
:borderBottom="false"
>
<u--input
v-model="userInfo.phone"
border="none"
placeholder="请输入手机号码"
></u--input>
</u-form-item>
</u--form>
</view>
<!--自定义footer内容-->
<view slot="footer">
<view style="display: flex;padding: 20rpx;justify-content: space-around;width:100%">
<u-button @click="modalCustomShow=false" :customStyle="{margin: '0 10rpx'}">取消</u-button>
<u-button @click="reject" :customStyle="{margin: '0 10rpx'}" type="warning">拒绝</u-button>
<u-button @click="allow" :customStyle="{margin: '0 10rpx'}" type="primary">通过</u-button>
</view>
</view>
</next-modal>
</template>
```
```js
<script>
export default {
data: () => {
return {
modalCustomShow: false,
modalBasicShow: false,
modalTitle: '提示',
modalContent: 'hello你好这是next-modal组件的内容',
userInfo: {}
}
},
methods: {
openbasic() {
},
opencustom() {
this.modalCustomShow = true
},
close() {
this.modalCustomShow = true
},
cancel() {
this.modalCustomShow = true
},
confirm() {
this.modalCustomShow = true
},
reject() {
uni.showModal({
title: '确定要进行拒绝操作',
success: (res) => {
if (res.confirm) {
this.modalCustomShow = true
}
}
})
},
allow() {
uni.showModal({
title: '确定要进行通过操作',
success: (res) => {
if (res.confirm) {
this.modalCustomShow = true
}
}
})
}
}
}
</script>
<style lang="scss">
.btn {
box-sizing: border-box;
flex: 1;
margin: 0 20rpx;
background-color: #f0ad4e;
color:#fff;
}
</style>
```
## 参数
### next-search-more Props
可选参数属性列表
|参数名 |说明 |类型 |是否必填 |默认值 |可选值 |
|---- |---- |---- |---- |---- |---- |
|title |弹层标题 |String |否 |'' |- |
|content |弹层内容 |String |否 |'' |- |
|align |弹层内容的对齐方式 |String |否 |left |- |
|cancelText |取消按钮的文字,默认为"取消" |String |否 |取消 |- |
|cancelColor | 取消按钮文字颜色 |String |否 |#333333 |- |
|confirmText |确定按钮的文字,默认为"确定" |String |否 |确定 |- |
|confirmColor | 确认按钮文字颜色 |String |否 |#f0ad4e |- |
|showCancel| 是否显示取消按钮,默认为 true |Boolean |否 |true |false |
|show| 显示弹层 |Boolean |否 |false |true |
|autoClose| 点击遮罩是否自动关闭弹窗 |Boolean |否 |true |false |
|width| 弹层内容宽度(只支持字符串,必须要带单位) |String |否 |- |- |
## Slot 插槽
(注意: 插槽的优先级大于组件的props配置的值)
|名称 |说明 |参数 |
|---- |---- |---- |
|title |title插槽 |无 |
|content |content插槽 |无 |
|footer |footer插槽 |无 |
|default |default插槽 |无 |
# Event 事件
|事件名 |说明 |类型 |回调参数 |
|---- |---- |---- |---- |
|confirm|确认的回调事件 |emit |- |
|cancel|取消的回调事件 |emit |- |

View File

@ -11,7 +11,11 @@ const constant = {
childrenmenutitle: 'vuex_childrenmenutitle',
urlip: 'vuex_urlip',
urlpro: 'vuex_urlpro',
allurl: 'vuex_allurl'
allurl: 'vuex_allurl',
xththid: 'vuex_xththid',
xththstr: 'vuex_xththstr',
projectid: 'vuex_projectid',
projectname: 'vuex_projectname'
}
export default constant

View File

@ -16,7 +16,11 @@ let storageNodeKeys = [
constant.childrenmenutitle,
constant.urlip,
constant.urlpro,
constant.allurl
constant.allurl,
constant.xththid,
constant.xththstr,
constant.projectid,
constant.projectname
]
const storage = {

View File

@ -370,6 +370,7 @@ export const downloadBinaryFile = (url: any) => {
let headers = {
Bearerauth: 'Bearer ' + getToken()
}
//console.log('下载地址:', JSON.stringify(url))
uni.downloadFile({
url: url, //下载地址
header: headers,