From b2d15258cb0b0ff8c35458e48c6412b6f6b6a8c0 Mon Sep 17 00:00:00 2001 From: LiuJiaNan <liujianan@zcloudchina.com> Date: Thu, 4 Jul 2024 17:57:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=89=E9=99=90=E7=A9=BA=E9=97=B4=E4=BD=9C?= =?UTF-8?q?=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/index.js | 15 +- components/other-select/index.vue | 32 +- pages.json | 14 +- .../confined_space/apply.vue | 391 +++--- .../confined_space/index.vue | 14 +- pages/eight_assignments/index.vue | 22 +- .../select_corp_info.vue} | 24 +- pages/eight_assignments/select_department.vue | 88 ++ .../select_review_personnel.vue | 131 +++ pages/index/index.vue | 27 +- pages/login/login.vue | 4 +- static/icon-apps/app_icons6.png | Bin 0 -> 8317 bytes static/icon-apps/i1.png | Bin 0 -> 7656 bytes static/icon-apps/i10.png | Bin 0 -> 8761 bytes static/icon-apps/i11.png | Bin 0 -> 8754 bytes static/icon-apps/i2.png | Bin 0 -> 9060 bytes static/icon-apps/i3.png | Bin 0 -> 9863 bytes static/icon-apps/i4.png | Bin 0 -> 8736 bytes static/icon-apps/i5.png | Bin 0 -> 7538 bytes static/icon-apps/i6.png | Bin 0 -> 8112 bytes static/icon-apps/i7.png | Bin 0 -> 8382 bytes static/icon-apps/i8.png | Bin 0 -> 8873 bytes static/icon-apps/i9.png | Bin 0 -> 7210 bytes uni_modules/next-search-more/changelog.md | 20 + .../next-search-more/next-search-more.vue | 239 ++++ uni_modules/next-search-more/package.json | 79 ++ uni_modules/next-search-more/readme.md | 215 ++++ uni_modules/next-tree/changelog.md | 173 +++ .../components/next-tree/next-tree.vue | 1043 +++++++++++++++++ .../next-tree/components/next-tree/style.css | 272 +++++ uni_modules/next-tree/package.json | 84 ++ uni_modules/next-tree/readme.md | 843 +++++++++++++ utils/request.js | 10 +- utils/submitHomeworkProcess.js | 76 ++ 34 files changed, 3586 insertions(+), 230 deletions(-) rename pages/{selete_corp_info/index.vue => eight_assignments/select_corp_info.vue} (70%) create mode 100644 pages/eight_assignments/select_department.vue create mode 100644 pages/eight_assignments/select_review_personnel.vue create mode 100644 static/icon-apps/app_icons6.png create mode 100644 static/icon-apps/i1.png create mode 100644 static/icon-apps/i10.png create mode 100644 static/icon-apps/i11.png create mode 100644 static/icon-apps/i2.png create mode 100644 static/icon-apps/i3.png create mode 100644 static/icon-apps/i4.png create mode 100644 static/icon-apps/i5.png create mode 100644 static/icon-apps/i6.png create mode 100644 static/icon-apps/i7.png create mode 100644 static/icon-apps/i8.png create mode 100644 static/icon-apps/i9.png create mode 100644 uni_modules/next-search-more/changelog.md create mode 100644 uni_modules/next-search-more/components/next-search-more/next-search-more.vue create mode 100644 uni_modules/next-search-more/package.json create mode 100644 uni_modules/next-search-more/readme.md create mode 100644 uni_modules/next-tree/changelog.md create mode 100644 uni_modules/next-tree/components/next-tree/next-tree.vue create mode 100644 uni_modules/next-tree/components/next-tree/style.css create mode 100644 uni_modules/next-tree/package.json create mode 100644 uni_modules/next-tree/readme.md create mode 100644 utils/submitHomeworkProcess.js diff --git a/api/index.js b/api/index.js index 58d22f3..4482ffa 100644 --- a/api/index.js +++ b/api/index.js @@ -33,10 +33,17 @@ export const setCertificateInformationEditPost = (params) => post("/app/specialU export const getDeptTree = (params) => post("/api/department/listzTree", params) //用户信息 export const getEMPLOYMENTAPPLYMANAGEMENTID = (params) => post("/app/user/getEMPLOYMENTAPPLYMANAGEMENTID", params) //获取EMPLOYMENTAPPLYMANAGEMENTID -export const getCorpInfoList = (params) => post("/department/getPreventCrop", params) //获取公司列表 -export const getConfinedSpaceSelectList = (params) => post("/app/gfLimitSpace/listAllSpace", { + +// 以下接口八项作业流程使用 +export const getCorpInfoList = (params) => post("/app/util/getCorp", params) //获取公司列表 +export const getConfinedSpaceSelectList = (params) => post("/app/Task/getAllToDoList", { loading: false, ...params }) //获取受限空间名称选择列表 -export const getOtherAssignmentsSelectList = (params) => post("/app/eightwork/list", params) //关联的其他特殊作业及安全作业票编号选择列表 -export const getRiskIdentificationResultsSelectList = (params) => post("/app/eightwork/getInfo", params) //风险辨识结果选择列表 +export const getOtherAssignmentsSelectList = (params) => post("/app/Task/getAllUnEndList", params) //关联的其他特殊作业及安全作业票编号选择列表 +export const getRiskIdentificationResultsSelectList = (params) => post("/app/eightWork/getInfo", params) //风险辨识结果选择列表 +export const setTaskSave = (params) => post("/app/Task/init", params) //八项作业、隐患整改、安全环保检查任务保存更新接口 +export const getCurrentNextOperation = (params) => post("/app/Task/getSupplementInfo", params) //获取当前任务的下一步操作 +export const getDepartmentTree = (params) => post("/app/util/getDepartmentTree", params) //获取部门树 +export const getUserList = (params) => post("/app/util/getUserList", params) //获取人员 +// 结束 diff --git a/components/other-select/index.vue b/components/other-select/index.vue index 23e9b27..859f354 100644 --- a/components/other-select/index.vue +++ b/components/other-select/index.vue @@ -5,7 +5,7 @@ <u-checkbox-group v-model="selectValue" placement="column"> <u-checkbox :customStyle="{marginBottom: '8px'}" v-for="(item, index) in list" :key="index" :label="type === 'assignments' ? item.CHECK_NO : item.NAME" - :value="type === 'assignments' ? item.CHECK_NO : item.NAME"> + :name="type === 'assignments' ? item.CHECK_NO : item.NAME"> </u-checkbox> </u-checkbox-group> <view class="button_group_placeholder"></view> @@ -29,17 +29,14 @@ visible: { type: Boolean, required: true, - default: false }, value: { type: String, required: true, - default: '' }, type: { type: String, required: true, - default: '' } }, data() { @@ -51,7 +48,10 @@ watch: { visible: { handler(newValue) { - if (newValue) this.getData() + if (newValue) { + this.selectValue = this.value.split(',') + this.getData() + } }, immediate: true } @@ -60,7 +60,7 @@ async getData() { if (this.type === 'assignments') { const resData = await getOtherAssignmentsSelectList() - this.list = resData.varList + this.list = resData.list } else if (this.type === 'identification') { const resData = await getRiskIdentificationResultsSelectList({ vectors: JSON.stringify(['accidentType']) @@ -69,17 +69,19 @@ } }, close() { + this.selectValue = [] this.$emit('update:visible', false) }, determine() { - const value = [] - for (let i = 0; i < this.selectValue.length; i++) { - if (this.value.indexOf(this.selectValue[i]) === -1) { - value.push(this.selectValue[i]) - } - } - this.value && value.unshift(this.value) - const emitValue = value.join(',') + // const value = [] + // for (let i = 0; i < this.selectValue.length; i++) { + // if (this.value.indexOf(this.selectValue[i]) === -1) { + // value.push(this.selectValue[i]) + // } + // } + // this.value && value.unshift(this.value) + // const emitValue = value.join(',') + const emitValue = this.selectValue.join(',') this.$emit('input', emitValue) this.close() } @@ -107,4 +109,4 @@ right: 0; } } -</style> \ No newline at end of file +</style> diff --git a/pages.json b/pages.json index 8a9df44..a3c5e2e 100644 --- a/pages.json +++ b/pages.json @@ -175,7 +175,7 @@ } }, { - "path": "pages/selete_corp_info/index", + "path": "pages/eight_assignments/select_corp_info", "style": { "navigationBarTitleText": "选择分公司" } @@ -197,6 +197,18 @@ "style": { "navigationBarTitleText": "位置定位" } + }, + { + "path": "pages/eight_assignments/select_review_personnel", + "style": { + "navigationBarTitleText": "选择审核人员" + } + }, + { + "path": "pages/eight_assignments/select_department", + "style": { + "navigationBarTitleText": "选择部门" + } } ], "globalStyle": { diff --git a/pages/eight_assignments/confined_space/apply.vue b/pages/eight_assignments/confined_space/apply.vue index 0d79121..e73a63c 100644 --- a/pages/eight_assignments/confined_space/apply.vue +++ b/pages/eight_assignments/confined_space/apply.vue @@ -1,173 +1,234 @@ <template> - <view class="content"> - <view class="card"> - <u--form labelPosition="left" :model="form" :rules="rules" ref="formRef" labelWidth="140px"> - <u-form-item label="申请单位" prop="APPLY_DEPARTMENT_NAME" borderBottom required> - <u--input v-model="form.APPLY_DEPARTMENT_NAME" border="none" readonly /> - </u-form-item> - <u-form-item label="申请人" prop="APPLY_USER_NAME" borderBottom required> - <u--input v-model="form.APPLY_USER_NAME" border="none" readonly /> - </u-form-item> - <u-form-item label="作业分公司" prop="CORP_NAME" borderBottom required> - <u--input v-model="form.CORP_NAME" border="none" readonly /> - </u-form-item> - <u-form-item label="受限空间所属单位" prop="BELONG_CORP" borderBottom required> - <u--input v-model="form.BELONG_CORP" border="none" /> - </u-form-item> - <u-form-item label="受限空间名称" prop="LIMITSPACE_NAME" borderBottom required - @click="fnSingleChoiceClick('LIMITSPACE_NAME')"> - <u--input v-model="form.LIMITSPACE_NAME" border="none" readonly /> - </u-form-item> - <u-form-item label="受限空间内原有介质名称" prop="MEDIUM_NAME" borderBottom required> - <u--input v-model="form.MEDIUM_NAME" border="none" /> - </u-form-item> - <u-form-item label="作业内容" prop="WORK_CONTENT" borderBottom required labelPosition="top"> - <u--textarea v-model="form.WORK_CONTENT" border="none" autoHeight /> - </u-form-item> - <u-form-item label="作业开始时间" prop="WORK_START_DATE" borderBottom required - @click="fnDateTimePickerClick('WORK_START_DATE')"> - <u--input v-model="form.WORK_START_DATE" border="none" readonly /> - </u-form-item> - <u-form-item label="作业结束时间" prop="WORK_END_DATE" borderBottom required - @click="fnDateTimePickerClick('WORK_END_DATE')"> - <u--input v-model="form.WORK_END_DATE" border="none" readonly /> - </u-form-item> - <u-form-item label="地点坐标" borderBottom required> - <u-button type="primary" size="small" text="定位" :customStyle="{width:'100upx',margin:0}" - @click="fnLocation" /> - </u-form-item> - <u-form-item label="经度" prop="WORK_LONGITUDE" borderBottom required> - <u--input v-model="form.WORK_LONGITUDE" border="none" readonly /> - </u-form-item> - <u-form-item label="纬度" prop="WORK_LATITUDE" borderBottom required> - <u--input v-model="form.WORK_LATITUDE" border="none" readonly /> - </u-form-item> - <u-form-item label="作业人" prop="WORK_USER" borderBottom required> - <u--input v-model="form.WORK_USER" border="none" /> - </u-form-item> - <u-form-item label="关联的其他特殊作业及安全作业票编号" prop="SPECIAL_WORK" borderBottom required labelPosition="top" - labelWidth="auto"> - <u-button type="primary" size="mini" text="选择其它" - :customStyle="{position: 'absolute',top: '-46upx',right: '20upx',width: '150upx'}" - @click="otherAssignmentsShow = true" /> - <u--textarea v-model="form.SPECIAL_WORK" border="none" autoHeight maxlength="-1" /> - </u-form-item> - <u-form-item label="风险辨识结果" prop="RISK_IDENTIFICATION" borderBottom required labelPosition="top" - labelWidth="auto"> - <u-button type="primary" size="mini" text="选择其它" - :customStyle="{position: 'absolute',top: '-46upx',right: '20upx',width: '150upx'}" - @click="otherIdentificationShow = true" /> - <u--textarea v-model="form.RISK_IDENTIFICATION" border="none" autoHeight maxlength="-1" /> - </u-form-item> - </u--form> - </view> - <u-picker :show="picker.show" :columns="picker.columns" :keyName="picker.key" :key="picker.type" - @confirm="fnSingleChoiceConfirm" @cancel="fnSingleChoiceCancel" /> - <u-datetime-picker :show="datetimePicker.show" v-model="datetimePicker.value" :mode="datetimePicker.mode" - :minDate="datetimePicker.min" :key="datetimePicker.type" @confirm="fnDateTimePickerConfirm" - @cancel="fnDateTimePickerCancel" /> - <other-select :visible.sync="otherAssignmentsShow" v-model="form.SPECIAL_WORK" type="assignments" /> - <other-select :visible.sync="otherIdentificationShow" v-model="form.RISK_IDENTIFICATION" type="identification" /> - </view> + <view class="content"> + <view class="card"> + <u-form labelPosition="left" :model="form" :rules="rules" ref="formRef" labelWidth="140px"> + <u-form-item label="申请单位" prop="APPLY_DEPARTMENT_NAME" borderBottom required> + <u-input v-model="form.APPLY_DEPARTMENT_NAME" border="none" readonly/> + </u-form-item> + <u-form-item label="申请人" prop="APPLY_USER_NAME" borderBottom required> + <u-input v-model="form.APPLY_USER_NAME" border="none" readonly/> + </u-form-item> + <u-form-item label="作业分公司" prop="CORP_NAME" borderBottom required> + <u-input v-model="form.CORP_NAME" border="none" readonly/> + </u-form-item> + <u-form-item label="受限空间所属单位" prop="BELONG_CORP" borderBottom required> + <u-input v-model="form.BELONG_CORP" border="none"/> + </u-form-item> + <u-form-item label="受限空间名称" prop="LIMITSPACE_NAME" borderBottom required + @click="fnSingleChoiceClick('LIMITSPACE_NAME')"> + <u-input v-model="form.LIMITSPACE_NAME" border="none" readonly/> + <u-icon name="arrow-right"></u-icon> + </u-form-item> + <u-form-item label="受限空间内原有介质名称" prop="MEDIUM_NAME" borderBottom required> + <u-input v-model="form.MEDIUM_NAME" border="none"/> + </u-form-item> + <u-form-item label="作业内容" prop="WORK_CONTENT" borderBottom required labelPosition="top"> + <u-textarea v-model="form.WORK_CONTENT" border="none" autoHeight/> + </u-form-item> + <u-form-item label="作业开始时间" prop="WORK_START_DATE" borderBottom required + @click="fnDateTimePickerClick('WORK_START_DATE')"> + <u-input v-model="form.WORK_START_DATE" border="none" readonly/> + <u-icon name="arrow-right"></u-icon> + </u-form-item> + <u-form-item label="作业结束时间" prop="WORK_END_DATE" borderBottom required + @click="fnDateTimePickerClick('WORK_END_DATE')"> + <u-input v-model="form.WORK_END_DATE" border="none" readonly/> + <u-icon name="arrow-right"></u-icon> + </u-form-item> + <u-form-item label="地点坐标" borderBottom required> + <u-button type="primary" size="small" text="定位" :customStyle="{width:'100upx',margin:0}" + @click="fnLocation"/> + </u-form-item> + <u-form-item label="经度" prop="WORK_LONGITUDE" borderBottom required> + <u-input v-model="form.WORK_LONGITUDE" border="none" readonly/> + </u-form-item> + <u-form-item label="纬度" prop="WORK_LATITUDE" borderBottom required> + <u-input v-model="form.WORK_LATITUDE" border="none" readonly/> + </u-form-item> + <u-form-item label="作业人" prop="WORK_USER" borderBottom required> + <u-input v-model="form.WORK_USER" border="none"/> + </u-form-item> + <u-form-item label="关联的其他特殊作业及安全作业票编号" prop="SPECIAL_WORK" borderBottom required + labelPosition="top" labelWidth="auto"> + <u-button type="primary" size="mini" text="选择其它" + :customStyle="{position: 'absolute',top: '-46upx',right: '20upx',width: '150upx'}" + @click="otherAssignmentsShow = true"/> + <u-textarea v-model="form.SPECIAL_WORK" border="none" autoHeight maxlength="-1"/> + </u-form-item> + <u-form-item label="风险辨识结果" prop="RISK_IDENTIFICATION" borderBottom required labelPosition="top" + labelWidth="auto"> + <u-button type="primary" size="mini" text="选择其它" + :customStyle="{position: 'absolute',top: '-46upx',right: '20upx',width: '150upx'}" + @click="otherIdentificationShow = true"/> + <u-textarea v-model="form.RISK_IDENTIFICATION" border="none" autoHeight maxlength="-1"/> + </u-form-item> + </u-form> + <view class="mt-10"> + <u-button type="primary" text="下一步" @click="$u.debounce(fnSubmit, 1000,true)"/> + </view> + </view> + <u-picker :show="picker.show" :columns="picker.columns" :keyName="picker.key" :key="picker.type" + @confirm="fnSingleChoiceConfirm" @cancel="fnSingleChoiceCancel"/> + <u-datetime-picker :show="dateTimePicker.show" v-model="dateTimePicker.value" :mode="dateTimePicker.mode" + :minDate="dateTimePicker.min" :key="dateTimePicker.type" @confirm="fnDateTimePickerConfirm" + @cancel="fnDateTimePickerCancel"/> + <other-select :visible.sync="otherAssignmentsShow" v-model="form.SPECIAL_WORK" type="assignments"/> + <other-select :visible.sync="otherIdentificationShow" v-model="form.RISK_IDENTIFICATION" type="identification"/> + </view> </template> <script> - import { - getConfinedSpaceSelectList - } from '../../../api/index' - import OtherSelect from '@/components/other-select/index.vue'; +import {getConfinedSpaceSelectList} from '../../../api/index' +import OtherSelect from '@/components/other-select/index.vue'; +import {setSubmitForm} from "@/utils/submitHomeworkProcess"; - export default { - components: { - OtherSelect - }, - data() { - return { - form: { - APPLY_DEPARTMENT_ID: this.$store.getters.getUserInfo.DEPARTMENT_ID, - APPLY_DEPARTMENT_NAME: this.$store.getters.getUserInfo.DEPARTMENT_NAME, - APPLY_USER_ID: this.$store.getters.getUserInfo.USER_ID, - APPLY_USER_NAME: this.$store.getters.getUserInfo.NAME, - BELONG_CORP: '', - LIMITSPACE_NAME: '', - LIMITSPACE_ID: '', - MEDIUM_NAME: '', - WORK_CONTENT: '', - WORK_START_DATE: '', - WORK_END_DATE: '', - WORK_LONGITUDE: '', - WORK_LATITUDE: '', - WORK_USER: '', - SPECIAL_WORK: '', - }, - rules: {}, - picker: { - show: false, - columns: [], - key: 'NAME', - type: '' - }, - datetimePicker: { - show: false, - value: Number(new Date()), - min: new Date().getTime(), - mode: 'datetime', - type: '' - }, - otherAssignmentsShow: false, - otherIdentificationShow: false, - } - }, - onLoad(options) { - this.form.CORP_ID = options.CORPINFO_ID - this.form.CORP_NAME = options.CORP_NAME - }, - methods: { - async fnGetConfinedSpaceSelectList() { - const resData = await getConfinedSpaceSelectList() - this.picker.columns = [resData.varList] - }, - fnSingleChoiceClick(event) { - this.picker.type = event - if (event === 'LIMITSPACE_NAME') this.fnGetConfinedSpaceSelectList() - this.picker.show = true - }, - fnSingleChoiceConfirm(event) { - if (this.picker.type === 'LIMITSPACE_NAME') { - this.form.LIMITSPACE_ID = event.value[0].LIMITSPACE_ID - this.form.LIMITSPACE_NAME = event.value[0].NAME - } - this.fnSingleChoiceCancel() - }, - fnSingleChoiceCancel() { - this.picker.show = false - }, - fnDateTimePickerClick(event) { - this.datetimePicker.type = event - this.datetimePicker.value = Number(new Date(this.form[event])) || Number(new Date()) - this.datetimePicker.show = true - }, - fnDateTimePickerConfirm(event) { - this.form[this.datetimePicker.type] = uni.$u.timeFormat(event.value, 'yyyy-mm-dd hh:MM') - this.fnDateTimePickerCancel() - }, - fnDateTimePickerCancel() { - this.datetimePicker.show = false - }, - fnLocation() { - uni.navigateTo({ - url: '/pages/map/index', - events: { - acceptLocationData: (event) => { - this.form.WORK_LONGITUDE = event.data.longitue; - this.form.WORK_LATITUDE = event.data.latitude; - } - }, - }) - } - } - } +export default { + components: { + OtherSelect + }, + data() { + return { + formItems: [ + {name: '申请单位', key_name: 'APPLY_DEPARTMENT_NAME', key_id: 'APPLY_DEPARTMENT_ID', type: 0}, + {name: '申请人', key_name: 'APPLY_USER_NAME', key_id: 'APPLY_USER_ID', type: 0}, + {name: '作业分公司', key_name: 'CORP_NAME', key_id: 'CORP_ID', type: 0}, + {name: '受限空间所属单位', key_name: 'BELONG_CORP', type: 0}, + {name: '受限空间名称', key_name: 'LIMITSPACE_NAME', key_id: 'LIMITSPACE_ID', type: 0}, + {name: '受限空间内原有介质名称', key_name: 'MEDIUM_NAME', type: 0}, + {name: '作业内容', key_name: 'WORK_CONTENT', type: 0}, + {name: '作业开始时间', key_name: 'WORK_START_DATE', type: 0}, + {name: '作业结束时间', key_name: 'WORK_END_DATE', type: 0}, + {name: '经度', key_name: 'WORK_LONGITUDE', type: 0}, + {name: '纬度', key_name: 'WORK_LATITUDE', type: 0}, + {name: '作业人', key_name: 'WORK_USER', type: 0}, + {name: '关联的其他特殊作业及安全作业票编号', key_name: 'SPECIAL_WORK', type: 0}, + {name: '风险辨识结果', key_name: 'RISK_IDENTIFICATION', type: 0}, + ], + form: { + APPLY_DEPARTMENT_ID: this.$store.getters.getUserInfo.DEPARTMENT_ID, + APPLY_DEPARTMENT_NAME: this.$store.getters.getUserInfo.DEPARTMENT_NAME, + APPLY_USER_ID: this.$store.getters.getUserInfo.USER_ID, + APPLY_USER_NAME: this.$store.getters.getUserInfo.NAME, + CORP_ID: '', + CORP_NAME: '', + BELONG_CORP: '', + LIMITSPACE_NAME: '', + LIMITSPACE_ID: '', + MEDIUM_NAME: '', + WORK_CONTENT: '', + WORK_START_DATE: '', + WORK_END_DATE: '', + WORK_LONGITUDE: '1', + WORK_LATITUDE: '2', + WORK_USER: '', + SPECIAL_WORK: '', + RISK_IDENTIFICATION: '', + }, + rules: { + APPLY_DEPARTMENT_ID: [{type: 'string', required: true, message: '请选择申请单位', trigger: 'blur'}], + APPLY_DEPARTMENT_NAME: [{type: 'string', required: true, message: '请选择申请人', trigger: 'blur'}], + APPLY_USER_NAME: [{type: 'string', required: true, message: '请选择申请人', trigger: 'blur'}], + CORP_NAME: [{type: 'string', required: true, message: '请选择作业分公司', trigger: 'blur'}], + BELONG_CORP: [{type: 'string', required: true, message: '请输入受限空间所属单位', trigger: 'blur'}], + // LIMITSPACE_NAME: [{type: 'string', required: true, message: '请选择受限空间名称', trigger: 'blur'}], + MEDIUM_NAME: [{type: 'string', required: true, message: '请输入受限空间内原有介质名称', trigger: 'blur'}], + WORK_CONTENT: [{type: 'string', required: true, message: '请输入作业内容', trigger: 'blur'}], + WORK_START_DATE: [{type: 'string', required: true, message: '请选择作业开始时间', trigger: 'blur'}], + WORK_END_DATE: [{type: 'string', required: true, message: '请选择作业结束时间', trigger: 'blur'}], + WORK_LONGITUDE: [{type: 'string', required: true, message: '请选择经度', trigger: 'blur'}], + WORK_LATITUDE: [{type: 'string', required: true, message: '请选择纬度', trigger: 'blur'}], + WORK_USER: [{type: 'string', required: true, message: '请输入作业人', trigger: 'blur'}], + SPECIAL_WORK: [{ + type: 'string', + required: true, + message: '请输入关联的其他特殊作业及安全作业票编号', + trigger: 'blur' + }], + RISK_IDENTIFICATION: [{type: 'string', required: true, message: '请输入风险辨识结果', trigger: 'blur'}], + }, + picker: { + show: false, + columns: [], + key: 'NAME', + type: 'picker' + }, + dateTimePicker: { + show: false, + value: Number(new Date()), + min: new Date().getTime(), + mode: 'datetime', + type: 'datetime-picker' + }, + otherAssignmentsShow: false, + otherIdentificationShow: false, + } + }, + onLoad(options) { + this.form.CORP_ID = options.CORPINFO_ID + this.form.CORP_NAME = options.CORP_NAME + }, + methods: { + async fnGetConfinedSpaceSelectList() { + const resData = await getConfinedSpaceSelectList({TYPE: 2}) + this.picker.columns = [resData.list.list] + }, + fnSingleChoiceClick(event) { + this.picker.type = event + if (event === 'LIMITSPACE_NAME') this.fnGetConfinedSpaceSelectList() + this.picker.show = true + }, + fnSingleChoiceConfirm(event) { + if (this.picker.type === 'LIMITSPACE_NAME') { + this.form.LIMITSPACE_ID = event.value[0].LIMITSPACE_ID + this.form.LIMITSPACE_NAME = event.value[0].NAME + } + this.fnSingleChoiceCancel() + }, + fnSingleChoiceCancel() { + this.picker.show = false + }, + fnDateTimePickerClick(event) { + this.dateTimePicker.type = event + this.dateTimePicker.value = Number(new Date(this.form[event])) || Number(new Date()) + this.dateTimePicker.show = true + }, + fnDateTimePickerConfirm(event) { + this.form[this.dateTimePicker.type] = uni.$u.timeFormat(event.value, 'yyyy-mm-dd hh:MM') + this.fnDateTimePickerCancel() + }, + fnDateTimePickerCancel() { + this.dateTimePicker.show = false + }, + fnLocation() { + uni.navigateTo({ + url: '/pages/map/index', + events: { + acceptLocationData: (event) => { + this.form.WORK_LONGITUDE = event.data.longitue; + this.form.WORK_LATITUDE = event.data.latitude; + } + }, + }) + }, + async fnSubmit() { + try { + await this.$refs.formRef.validate() + try { + await setSubmitForm({ + form: this.form, + formItems: this.formItems, + TYPE: 'confinedSpace', + CORP_ID: this.form.CORP_ID + }) + } catch { + } + } catch { + uni.$u.toast('请补全必填项') + } + } + } +} </script> <style> -</style> \ No newline at end of file +</style> diff --git a/pages/eight_assignments/confined_space/index.vue b/pages/eight_assignments/confined_space/index.vue index 0d9f0eb..d111ff0 100644 --- a/pages/eight_assignments/confined_space/index.vue +++ b/pages/eight_assignments/confined_space/index.vue @@ -19,20 +19,20 @@ return { baseList: [ { - img: require('../../../static/icon-apps/app_icons.png'), + img: require('../../../static/icon-apps/i9.png'), title: '申请', - url: '/pages/selete_corp_info/index', + url: '/pages/eight_assignments/select_corp_info', params: { type: 'confined_space' } }, { - img: require('../../../static/icon-apps/app_icons.png'), + img: require('../../../static/icon-apps/i10.png'), title: '待办', url: '/pages/eight_assignments/confined_space/index' }, { - img: require('../../../static/icon-apps/app_icons.png'), + img: require('../../../static/icon-apps/i11.png'), title: '已办', url: '/pages/eight_assignments/confined_space/index' }, @@ -63,8 +63,8 @@ margin-top: 20upx; image { - width: 136upx; - height: 136upx; + width: 110upx; + height: 110upx; } .text { @@ -74,4 +74,4 @@ } } } -</style> \ No newline at end of file +</style> diff --git a/pages/eight_assignments/index.vue b/pages/eight_assignments/index.vue index 4e52857..e4322d8 100644 --- a/pages/eight_assignments/index.vue +++ b/pages/eight_assignments/index.vue @@ -19,42 +19,42 @@ return { baseList: [ { - img: require('../../static/icon-apps/app_icons.png'), + img: require('../../static/icon-apps/i1.png'), title: '受限空间安全作业', url: '/pages/eight_assignments/confined_space/index' }, { - img: require('../../static/icon-apps/app_icons.png'), + img: require('../../static/icon-apps/i2.png'), title: '盲板抽堵作业', url: '/pages/electronic_work_card/index' }, { - img: require('../../static/icon-apps/app_icons.png'), + img: require('../../static/icon-apps/i3.png'), title: '动土作业', url: '/pages/electronic_work_card/index' }, { - img: require('../../static/icon-apps/app_icons.png'), + img: require('../../static/icon-apps/i4.png'), title: '高处作业', url: '/pages/electronic_work_card/index' }, { - img: require('../../static/icon-apps/app_icons.png'), + img: require('../../static/icon-apps/i5.png'), title: '吊装作业', url: '/pages/electronic_work_card/index' }, { - img: require('../../static/icon-apps/app_icons.png'), + img: require('../../static/icon-apps/i6.png'), title: '临时用电作业', url: '/pages/electronic_work_card/index' }, { - img: require('../../static/icon-apps/app_icons.png'), + img: require('../../static/icon-apps/i7.png'), title: '动火作业', url: '/pages/electronic_work_card/index' }, { - img: require('../../static/icon-apps/app_icons.png'), + img: require('../../static/icon-apps/i8.png'), title: '断路作业', url: '/pages/electronic_work_card/index' }, @@ -84,8 +84,8 @@ margin-top: 20upx; image { - width: 136upx; - height: 136upx; + width: 110upx; + height: 110upx; } .text { @@ -95,4 +95,4 @@ } } } -</style> \ No newline at end of file +</style> diff --git a/pages/selete_corp_info/index.vue b/pages/eight_assignments/select_corp_info.vue similarity index 70% rename from pages/selete_corp_info/index.vue rename to pages/eight_assignments/select_corp_info.vue index 0019eac..63e2f03 100644 --- a/pages/selete_corp_info/index.vue +++ b/pages/eight_assignments/select_corp_info.vue @@ -1,9 +1,9 @@ <template> <view class="content"> <view class="card"> - <u-radio-group v-model="selete_corp" placement="column"> - <u-radio :customStyle="{marginBottom: '20upx'}" v-for="(item, index) in list" :key="item.CORPINFO_ID" - :label="item.CORP_NAME" :name="item.CORPINFO_ID"> + <u-radio-group v-model="select_corp" placement="column"> + <u-radio :customStyle="{marginBottom: '20rpx'}" v-for="item in list" :key="item.CORPINFO_ID" + :label="item.NAME" :name="item.CORPINFO_ID"> </u-radio> </u-radio-group> <view class="button_placeholder"></view> @@ -17,14 +17,14 @@ <script> import { getCorpInfoList - } from '../../api/index' + } from '../../api' export default { data() { return { type: '', list: [], - selete_corp: '' + select_corp: '' } }, onLoad(options) { @@ -34,10 +34,10 @@ methods: { async fnGetData() { const resData = await getCorpInfoList() - this.list = resData.data + this.list = resData.list.corpInfoDos }, fnConfirm() { - if (!this.selete_corp) { + if (!this.select_corp) { uni.$u.toast('请选择作业分公司') return; } @@ -47,13 +47,13 @@ 'default': '/pages/eight_assignments/confined_space/apply' } } - const url = urlByTypeMap[this.type][this.selete_corp] ?? urlByTypeMap[this.type].default + const url = urlByTypeMap[this.type][this.select_corp] ?? urlByTypeMap[this.type].default let params = {} for (let i = 0; i < this.list.length; i++) { - if (this.list[i].CORPINFO_ID === this.selete_corp) { + if (this.list[i].CORPINFO_ID === this.select_corp) { params = { CORPINFO_ID: this.list[i].CORPINFO_ID, - CORP_NAME: this.list[i].CORP_NAME, + CORP_NAME: this.list[i].NAME, } break } @@ -70,7 +70,7 @@ <style scoped lang="scss"> .button_placeholder { - height: 100upx; + height: 100rpx; } .button { @@ -79,4 +79,4 @@ left: 0; right: 0; } -</style> \ No newline at end of file +</style> diff --git a/pages/eight_assignments/select_department.vue b/pages/eight_assignments/select_department.vue new file mode 100644 index 0000000..9ba034c --- /dev/null +++ b/pages/eight_assignments/select_department.vue @@ -0,0 +1,88 @@ +<template> + <view> + <u-modal :show="modelShow" title="选择所属端" showCancelButton cancelText="返回" @cancel="fnModalCancel" + @confirm="fnModalConfirm"> + <u-radio-group v-model="type" placement="column"> + <u-radio :customStyle="{marginBottom: '8px'}" label="企业端" name="0"/> + <u-radio :customStyle="{marginBottom: '8px'}" label="监管端" name="1"/> + <u-radio :customStyle="{marginBottom: '8px'}" label="相关方端" name="2"/> + </u-radio-group> + </u-modal> + <next-tree + v-if="!modelShow" + uiMode="page" + ref="nextTreeRef" + checkStrictly + funcMode="radio" + selectParent + :ifSearch="false" + :treeData="treeData" + themeColor="#2a56f7" + page-height="92vh" + labelKey="DEPARTMENT_NAME" + valueKey="DEPARTMENT_ID" + childrenKey="nodes" + @change="fnTreeChange" + > + <template #fixedBottomBar> + <view style="padding: 20upx;margin-bottom: 20upx;"> + <u-button type="primary" text="确定" @click="fnTreeConfirm"/> + </view> + </template> + </next-tree> + </view> +</template> + +<script> +import {getDepartmentTree} from "@/api"; + +export default { + data() { + return { + modelShow: true, + type: '', + CORP_ID: '', + treeData:[], + treeSelectData:[] + } + }, + onLoad(query) { + this.CORP_ID = query.CORP_ID + }, + methods: { + fnModalCancel() { + uni.navigateBack() + }, + fnModalConfirm() { + if (!this.type) { + uni.$u.toast('请选择所属端') + return + } + this.modelShow = false + this.fnGetDepartmentTree() + }, + async fnGetDepartmentTree() { + let CORP_ID = '' + if (this.type === '0') CORP_ID = this.CORP_ID + if (this.type === '2') CORP_ID = this.$store.getters.getUserInfo.CORPINFO_ID + let resData = await getDepartmentTree({TYPE: this.type, CORP_ID}) + this.treeData = resData.tree.tree + }, + fnTreeChange(event){ + this.treeSelectData = event + }, + fnTreeConfirm(){ + this.getOpenerEventChannel().emit("confirm", { + DEPARTMENT_NAME: this.treeSelectData[0].DEPARTMENT_NAME, + DEPARTMENT_ID: this.treeSelectData[0].DEPARTMENT_ID, + TYPE: this.type + }); + uni.navigateBack(); + } + }, +} +</script> + +<style scoped lang="scss"> + +</style> diff --git a/pages/eight_assignments/select_review_personnel.vue b/pages/eight_assignments/select_review_personnel.vue new file mode 100644 index 0000000..59d5def --- /dev/null +++ b/pages/eight_assignments/select_review_personnel.vue @@ -0,0 +1,131 @@ +<template> + <view> + <view class="content"> + <view class="card"> + <u-form labelPosition="left" :model="form" :rules="rules" ref="formRef" labelWidth="140px"> + <u-form-item v-for="(item, index) in list" :key="index" :label="item.name" :prop="item.key_name" + borderBottom :required="item.isRequired === '1'" @click="fnSelect(item)"> + <u-input v-model="form[item.key_name]" border="none" readonly/> + <u-icon name="arrow-right"></u-icon> + </u-form-item> + </u-form> + <view class="mt-10"> + <u-button type="primary" text="下一步" @click="$u.debounce(fnSubmit, 1000,true)"/> + </view> + </view> + </view> + <u-picker :show="picker.show" :columns="picker.columns" keyName="NAME" + :key="picker.currentColumnKey" @confirm="fnPickerConfirm" @cancel="fnPickerCancel"/> + </view> +</template> + +<script> +import {getUserList} from "@/api"; +import {setPersonnelForm} from "@/utils/submitHomeworkProcess"; + +export default { + data() { + return { + taskId: '', + CORP_ID: '', + TYPE: '', + list: [], + form: {}, + rules: {}, + picker: { + show: false, + columnsAll: {}, + columns: [], + currentColumnKey: '', + currentName: '', + currentId: '', + } + } + }, + onLoad() { + const eventChannel = this.getOpenerEventChannel(); + eventChannel.on('nextNodes', (data) => { + this.list = data.nextNodes + this.taskId = data.taskId + this.CORP_ID = data.CORP_ID + this.TYPE = data.TYPE + this.fnInitFormAndRules() + }) + }, + methods: { + fnInitFormAndRules() { + this.list.forEach((item) => { + this.$set(this.form, item.key_name, '') + this.$set(this.form, item.key_id, '') + this.$set(this.rules, item.key_name, [{ + required: item.isRequired === '1', + message: item.name + '不能为空', + trigger: 'blur', + }]) + }) + }, + fnSelect({key_name, key_id, type, value}) { + if (type === '1') { + this.fnSelectDepartment(key_name, key_id, value) + return + } + if (type === '0') { + // 弹出选择人员 + this.fnSelectUser(key_name, key_id, value) + } + }, + fnSelectDepartment(key_name, key_id, value) { + uni.navigateTo({ + url: `/pages/eight_assignments/select_department?CORP_ID=${this.CORP_ID}`, + events: { + confirm: (event) => { + this.form[key_name] = event.DEPARTMENT_NAME + this.form[key_id] = event.DEPARTMENT_ID + this.form[value + '_USER_ID'] = '' + this.form[value + '_USER_NAME'] = '' + this.fnGetUserList(event, value) + } + }, + }) + }, + async fnGetUserList({DEPARTMENT_ID, TYPE}, value) { + let resData = await getUserList({DEPARTMENT_ID, TYPE}) + this.$set(this.picker.columnsAll, value, [resData.list.list]) + }, + fnSelectUser(key_name, key_id, value) { + this.picker.currentName = key_name + this.picker.currentId = key_id + this.picker.currentColumnKey = value + this.picker.columns = this.picker.columnsAll[this.picker.currentColumnKey] + if (!this.picker.columnsAll[this.picker.currentColumnKey]) { + uni.$u.toast('没有选择部门或当前部门没有人员') + return + } + this.picker.show = true + }, + fnPickerConfirm(event) { + this.form[this.picker.currentId] = event.value[0].USER_ID + this.form[this.picker.currentName] = event.value[0].NAME + this.fnPickerCancel() + }, + fnPickerCancel() { + this.picker.show = false + }, + async fnSubmit() { + try { + await this.$refs.formRef.validate() + try { + await setPersonnelForm({form: this.form,list:this.list, taskId: this.taskId, CORP_ID: this.CORP_ID, TYPE: this.TYPE}) + } catch { + } + } catch { + uni.$u.toast('请补全必填项') + } + } + }, +} +</script> + +<style scoped lang="scss"> + +</style> diff --git a/pages/index/index.vue b/pages/index/index.vue index 300467b..2b4a8b1 100644 --- a/pages/index/index.vue +++ b/pages/index/index.vue @@ -16,14 +16,16 @@ </view> </view> <view class="home-apps"> - <view class="home-apps-item" v-for="(item,index) in baseList" :key="index" @click="fnNavigator(index)"> - <view class="home-apps-item-img"> - <image :src="item.img" mode=""></image> + <template v-for="(item,index) in baseList"> + <view class="home-apps-item" :key="index" v-if="fnIsShow(index)" @click="fnNavigator(index)"> + <view class="home-apps-item-img"> + <image :src="item.img" mode=""></image> + </view> + <view class="text"> + <text>{{ item.title }}</text> + </view> </view> - <view class="text"> - <text>{{ item.title }}</text> - </view> - </view> + </template> </view> <u-modal :show="updateVersion.modalShow" title="温馨提示" :showConfirmButton="updateVersion.showConfirmButton" :showCancelButton="updateVersion.showCancelButton" :confirmText="updateVersion.confirmText" :cancelText="updateVersion.cancelText" @@ -70,13 +72,18 @@ export default { url: '/pages/employed_by/index' }, { - img: require('../../static/icon-apps/app_icons5.png'), + img: require('../../static/icon-apps/app_icons6.png'), title: '高危作业', url: '/pages/eight_assignments/index' }, ], } }, + computed: { + userInfo() { + return this.$store.getters.getUserInfo + } + }, onLoad() { this.fnUpdateVersion(false) }, @@ -109,6 +116,10 @@ export default { } }); }, + fnIsShow(index){ + if(index === 5) return !!this.userInfo.CORPINFO_ID + return true + }, fnNavigator(e) { uni.$u.route({ url: this.baseList[e].url diff --git a/pages/login/login.vue b/pages/login/login.vue index 6dac197..3b27015 100644 --- a/pages/login/login.vue +++ b/pages/login/login.vue @@ -36,8 +36,8 @@ export default { return { publicKey: 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2zCyUYSD0pNrbtaYdvGfHfWoRV+fo/2N9O2PLLz/jZvMkigkq4eAq4JO+Ek0wDHI9WxP6iTSLYCHhIOs9CQTPvyldJFm8riZtQZlBTD8Plkb3rjrgwTqbBi3w3+HKYdkSvGFXJIdSOPbpXnj5BzN8vlVaybs24R/vpUzG9178lwIDAQAB', form: { - userName: '', - userPwd: '' + userName: '14730797906', + userPwd: 'Aa@123456789' } } }, diff --git a/static/icon-apps/app_icons6.png b/static/icon-apps/app_icons6.png new file mode 100644 index 0000000000000000000000000000000000000000..14d581e2de6776cb4f5eb6c59ff9ac040602c134 GIT binary patch literal 8317 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 P9|Wi=YlF)btzQ2hl-ZrN literal 0 HcmV?d00001 diff --git a/static/icon-apps/i1.png b/static/icon-apps/i1.png new file mode 100644 index 0000000000000000000000000000000000000000..e554051987ceef7b2c800cd4fb85aa1a4951b583 GIT binary patch literal 7656 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 literal 0 HcmV?d00001 diff --git a/static/icon-apps/i10.png b/static/icon-apps/i10.png new file mode 100644 index 0000000000000000000000000000000000000000..c80f00c8cc7ae4d8c7ffafedbf563cf86482a4f3 GIT binary patch literal 8761 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 literal 0 HcmV?d00001 diff --git a/static/icon-apps/i11.png b/static/icon-apps/i11.png new file mode 100644 index 0000000000000000000000000000000000000000..b50446c4ea40670e53c4d5679fc90ea3a2953459 GIT binary patch literal 8754 zcmaKSWmr`2-u2MkjZ%YjcSsB^N(&OwJ;K1i(A^*{B?Hpk-5mnb-BJ?L-Sz5u&i_2` zhxfeuy7s=~T5J8{Uf=HhSxrR&2a^&L007`9zLC}VGg|+7!RV-ezOx`p<Ua$2lbnvz zdwWYKR})7IfRwqtsRgYf#Kg)%!@|Ve-QkCY7yy982-ehb(ot3tHM56sn*7CZx<R0S z*Z_c-q#M-4%*Mir*3`lZY$pypZs`Ehg3ZN&+5*bl%1{{#Yw#NnM~n9!Dw<{<HfAE` zKuHN&F*nga0uT!)6IwTjtsP9%O&s_yUC}@DzuR0u+J8ZuY{Y^8la!9K8m)}IqXn%1 zryz$J55EAdkO(J_ARoVo2s<q=H;*tEw=fqE9|w=1C_lF-FE8!CAK;&8j^>u48nW{L zj`e3H4zzZ1f{Jo+xw^V?y7F<_J6dt^h=_=Aar1KV@^bt^aKPN{oJ`y}>|pf&D9BpC z%pAc`C$PO8?O#O`Q+sD8ap0d!|EB~9^gpt8uz$DdPs6y}OrTsmoZNp)`Uj}2{QrkS zApb$boHQ){H{buKFig`OYQd#p0kd~@H2ZUKmh^u^K}BU8Eliy39X0LkZU5<_nzg-? zJ<Qr3N-HDtw`(G_%-Uc(b9+}9%fC3v%A$&PFeei`GYdsoao`^nPB7S9R8B;eM?_FY znon3(o`*+HUPPXcUtUI5h*wTlj#o%d_8+dSy_qw_!p`X*uKE9RW&SJouN@%JKapiE z9KkLY=JJmA5ZZs0EeihcxrqE%y?=Af|9dV{|CP)2CmF84hx>mW_CH&H9Q1ekAM5^E z{Kxzjc7Gi2_{Z7?TWlo&0Cl#atdyqP;<5oovc6WL#I=_5W!#aIXh|A!b*ODG{v^Ve zpu)ld+P9k6w5G@=_@N^RaDuesR0qp%6H-zy{Y^lcvfr6y*Ue;sk^a_*$kGFoy0o55 zy9{Y66<WtD?w5O<J1efM8b4>c(u+0soM%e3kJFyh4<&b2fG2pVSse`(E4NOY_s<Ve zSP`NtTH0mrqF&C36qgRC{T8;ZzZUNCbmyeAt-jXZ5${`&=x_CWqPdH(4~JYxnlZIL z$9OE=w>Eri>*suHLZ4@DBe-*54=D$`A55Gtn~vW1b$DZA7Ib!m@*K8eR`4;m4)?lu zdb|2^Ud@A<Ps_;FIBy0ld96mXPT`TB(P({`cwsS~T(1=+Y49RB@o_cku6^qoco?3^ z=vK(`$%R)M^2NcC8S_f^ZI9ZjjhqkcsmdL-kp133n{<PL?9pH8_C|~i9Zvf>sN5T3 zGwy3rFb#yah@(NDA<*5tipY|}0mCDI$I$D^`Hc=m{ZfR;mw6`l$pJl`KPHZ)z9$uE z*fzyGuK&bxp@s|j&Ix&X4*4|SX}`mz5fx@V8$N2=$820rqG7WJ@-zR4O6cxoK-lia z5_)~EB3U`WXS90yBv#O|`ngU%P~H%V&aJ^Hc%Bnu3(L(JYn%S6{IlA7X!Glw*b?a1 z=;d81jZ{A-^>xQllLr*xt)u7aeM5XmNW<zcgmanWF^W6@qkqPP;b&yVX)8aTy}D}` z^O~Z>iVly(cl)!PVOqiab{;zSxK)p9*X5tv?5w!Enl6VrGF(PQT4vqXTIY?Rn<#Wr zKfYK;-gWy-W)667?vP^%!}?A<vElTO;wHs6`+OR^2aCZtsdL^>cScGPEg|>EhMy%% z{51)2^fH>1?>!w>8-Ul(4>MereNnHUV$x%7-#)KXX-X2I)9QfC*cVy4W>;YbXU8K7 z`|b66RS|dLU(5(~Nm106yD;_64~7Q^56)LCAMr2wx|rE@=e-IGm}(9}uZ>o8hW%pV z!KOrHu9-EX9uZz!(N^W>oeL{QP}^<nSP>*+dE#8Gd48)%o}b@-90PuenVwT{L$(ER zmI@@^uhcy5y`a9`pBkH2LIn=Rp<!egR?&$&e>z7>SNtd<jNm7bQI%Yixed=*MV={F zrb{7?8%w@#Nf2xGJ-)H=y-vk)bV$)8BqED{{HmJlcHn9l*W@(*h@F#n$_EO+;#0qk z9C@XI`s|qtUJgyyb9OieZNAQAKH9S}EIsSgU8R8r6%mm2#b%f!kaP}6o-HNV(<7kB z*Kr3X_)2t}e>RKwb?5s&{0gZA9>{#oWR&BDKAvaRN2T{X@y=KGG8%Bvl*py!_GM8I z@7pcX8DG1fFnTR5`^YyQ1aqkqQyRvgJ#l6-yC?Wv&YY(UoLCe+li>GLAVokvBC|GR zsoShcSq5|_p6EL1<nyy|yUzFWvla;xN#;9FcMfqMuX{dfVJl)3CBsG?waDGu$VOvU zc~_}<Ok_QL2@Z7lTNA7<jSJmVkq>U%PX`&&>*NW0AT)p(Hq{&siV_wzA_Atk*=BOj z82jzobFL~TsK$y0SYt`!F@UtwYCeDt>yDI--=kk9ql9*`8Rz;1?dD`6?`SCJbk1uB z?3|(TTIr+~l3y}fN6G`_>4&Li{LWPlTHhBOcv<famzh^00Lgr9r|JxAT`a`7yOC)n z>G?x6z&qauJ|Jd!(X0h*T8?Y^xx=$&ri&nRo?~_Q6rYksiaT(n_hS`j08&1vH?CmX zU~4k`>%kBPoAOJf8dGFLSz-md=G!LSnVGharv5xVmicECMqm7jbK@u`h<rx0$>_c0 zog%sDNk>u%qz_E^)V~1fnN8{OH%HLbzt9u(<1fjdm89kP7~IY^w-j%SoyOZVFq8?s zn$1+LaBEsd+G(=3wWbB&>(R?IK+7~HD9%LQuoc>$!_R~?Z*a6z*jXiZSYg`pA5x^m zAw#}>zS|k6BTSP6<B;M2v_bFmibLV~@!C*5dQsaeR#sK9hRvQ1PF2?H+~^1;_~b(r zG^EoUpqZ~)H1P3epLmB*Uq;Q1jRKJ;yolUdQx2BWHy-QN7l%Z^6Bjj}zPYM#n^ZxO z+(7%_Cc9TY`6)Z}p&dSK!_jOx40U_n>yPq%%{8<XXRS_1r0}%eC%_kicf3HI@<~JH z2i(*z&zOa<6)=Vz1guieX9^Kh)asX8Rg_6a`VPZ-oe$@0QbrGmJP`}&;6#mCR-h{I zqmX1IXK$X*pupge>@OeP(^Y*uxa$*+-QW-VRt4oMD%yQiH1+5cqI>iD#)h_ucd+hl zYse~*56Ug|Cr3wV8}d7S<gCxSNM)bQtre*WH2`r0oH`pNNm*K&pAwLxSvlAa`sq~= zNhK<wt!IPLG^!$pbv3Jt?X=ZTR5lw)95(uU!P7Wdo!s%`(<21d3$IawNKJ!5Nn^Pm z-h2wBuv9{Qp;X{ziyb(foSB5)1>4#<CBY>P<8?q83I-9cN_oekZ|TVevzR~aBt|+l z53~pj>)t$Q;AN8Cl}O#bEqt#F_vR+BXB;6V<774lp`s5a+)9(`^$I8<N(GDb_$XM% zccm(xbdIJ{r2LZkUMG9aC+q(X(4~8mlc^<pN9XNp-iNNjmLNHqt?9Grlz*R9R3kJz z-&W@z0#?sOZM$AJz)8PS!YUh63wK8xoh+2qoaDns=*pqPmq5dStLO3%e~#f9!RAdV zE&IHij_LV|S|Sh>fTepwmfdZ=8gvRl%l$wMqW_(ooB37AAA(05D}p9!(YI^!Ld@?; zzZBKoryx}G!=(>XCuS&jXLu%ZuQ!iuho8!E<4aH`D+|hSn|hHm`1t7uPe#x+wl7}7 zmuiHnWAR$Fr}--dw}TTi!=qH9bwEsCBSk!8G#VlK8|Gvo>7W?Gdv%UNwaop<*L;IS z7F$g1AJu0ZR8+O2X2|l47svv?7_>*8G<{{neKC7a^LdYNKnO5NK1cyro5n$}=F6}F z(e1=mY+XCR2f6f7w$IeRc2+lAti}2_sO2hB=6_JW>@c(GC;fT7KAd4{8jjiwtNc-0 zuSxK8pnCiaIaS#5VKnrLU+`r^6?PV5d42tUxUnmiC`Q5<HwU@#q&|Ymn!Zv3B73ng z(YE$TAZx)}tW;O$<A52349(Hi*Q4+rvc%S`tx^K3uHwKL*s2EpNZM2fDS5H7cc_W- zKIQyG4Hok{<u>t4t#$Z4eZX-3aK&^L906O<m!xO0{3N{{KHoc%;?1m;^ut@E84r+W zD{Ly0gZB!p@74Q5H*Lp}!bI)@$9gTOL6ge&rqkoGRDq;Qq8f5#Q+JgZ<`&)(j}L03 zJ(li^p44KFzZFiLhWJ=FU}9>_cs>5KWgC8B+%MFiCi1YC{7gSx_iuirwmY93-rBvK z`Sq*A9Q@1txF;w68sRs;SRw+VmTck2OdAQcM~P$uk$2I+{htEXU%MLVM=Z-<+>2|^ z`l9A1sKycF=V|8nX|e>oSJaCN11=PH6p7)vUL-V)srHe}IyjimS00@cU8eHL&6I>; zCn9l=^)0M^pNTL-4n>wnBcS!AH5OcoTAmxj5SJ{hSuJOU+>Di*cEQz+!T}u51Df?2 zG&_Ntsc@wu-jDIYb$Ec#4(vJCiybdOtZ(_dm@t0r4O3a(l+|n5awJv_5(WVWsudoC zJyyXNe57;@4qIm4QKtv|H@Ga%y8VgSJ*BdA`a4M4ynFIB44CB_MJrxtPe|xkmNS{K zueM|O(qD_izE7fcs)gCQK(h&gW+-$VA(`DlC(I}C{DQaT;;P3+WjymY9z91a$I&)2 zjh3=e%(0BK)PuV@%acXt=_9=;80LGm`K}9k@wL6Nx_2q?VwXX$kO0go5iM0S`65z; zvx&>@b%AmCVNi`i1`<WV@+?^{4ef#W@$8{X50<jcT4EB;-5Nc<r=8}jA3oiCq_qQd z8c2_ju6_bgLL8Jt2d3l`-8FCrxoi>gh2ph`*Me6<w64?p;;vG&0!ttXkpYG0=&(0t zBX1zOWlDMu(hcjsMRj~H7_j(kxqryN&D4T9biWz5YCBwXGB{{*2sI2F^nxbSz{qZd zzDJ_Pd*=I1jVcu6@sjjgdc5$ggkuFQSnMvdpPSlt0;0Db`ErwRDYBG3a3uExv-XG! zha!V!(=BZ}bSq2!_?+6ZKUp=6p!No=kw)2tp@rGRI^hOfkSu?jT~iHuB7gWMG9=|M z`>oyU+q11X@lLK|%_ZksQqlLF2lVmXS<FcNhsv5aWhV+x<X=^rFg0FTcqL`G3sD{* zRPsaBs0TH4cXL17OE!C9vu8XM&BM$<U+}W_$StQyH>@tMBd^;+;|E8hA~w(+ek;Lp z(d6lBU{EDN91TcuC}S-$#tyiyX1!0Op=+<L#JIoeu$c<YvZ$DHk>n)f>T$4b06H;W zWBk2#4CJh<+=?e1{6_LRx3zX>v*CO;+Be3ma<d-HYi!-t@g*&K8HWh4`<cLmi0D$_ zeWk0uDSnZKCWAS0{<KnH>h{VJ#`j>uhB0cC3(qUr^$&^V;n>XG9{0&(z#ApTj&{V< z;s<Q?NTg7M#ARJ(hrM8RqLEAvh{$KXuvE!FW~Z)Kg&P!n!}J3DVWdpT_Q**ELnhpI z-_x;BzE_e3AY|99JitE}N}a)!NS>udM4o$`t4!)$Da|5MCCzGkG%8(<!zF47VV{`J z^L5eTg|AuTwn%0WKYvPCmXWp@*(4C9WGebl%|9WgY>8LLV%B9Hz1wEuREV^h3J%>7 z7o!2<7Pn(T)^+hG9*v;+vXw=zQbts`snk;U!LqLSg7KhJWEnDA0{2@2gaTJhdPG)^ zwT-lu1j0URGb|Ded^V5te2HCB-=_R1y}9S{R&_IJo*$_~<#a*JBV7ir9%!r)7DU|u zV0A$-!?yx(Dis7yQRZCtfMTttU5>>%mFPpM+xj_Y(3VIo?QN^!Xe1*^nX*o*CD^aG z7L1a-U{WP9fJ;8ZC;~TUNtZN}=QvJ4y=)dgX^V30N}3fimc4z`Xt90>eLIqyEf5CW z;Q}ixoCf-XMi{aWhY0o19yOHg1#4b?9Ug#XGcAN1##G<NKMYi{dmRhleM=I0*ta>f z^Jj9ASn2o`tTf;4y+Dj(8op9MIb_1M!NBZZ1Ka_JAY+H91^|<TCPiIP@oeuTS{EKd zNEe&k{Yl(82hqMr4{^m{lFOL0I9^WLu9r`R36{zNs*L9pxvh=w>Q}^zn9AeCje)}w zO%lHgmZ<%4lzk_&^OabUXwrNXCw2ndCDTOKlwax9p!1~20X?>WA38D7m`##Lpfq*c z@ou9zR59t(vX>1l>3)(2w{4_!dEbb=9M(smgC~k|8CWRZq#-9VvVgACz0KjM#_>hz z+gDgMMCEAs)2}G?U-W;QfX4CvzHJ-p+M_C|wfx%J`C+sJ*D@x3uHrma;*E;J`s0$G zCS!rPH3Na=)0nOKuAjg_w<VvYs-b}V#}VV-F~-p@RQ@|FKBzC_0?rHc0rYIybGDv! zV5A4HeO0H|$KoG`n-E7!jh2t4q%9O*`Eo={q^ecUB9jTpNyXBtjE=v2r_S>suzOYr zE62@AGG|97--QJ7q1Ehpr)1T?KArSAJ~dUSt1RN!Z}E&^_OYSP)<4v!gQjqGwxoQw z8%)+yt+<0X&>K$qKI=C9tz-_49*C$Lm?}4nkS09L=_BrUB1aV&Oy?G>Hr!U$K%#fP zc4AiRPIrc9*tVo9JmS6jX%*$V!x7IM{J{`vn0YL|CDv%Y%^>I7a5!3POvic<ZC^)t ztd5RXlcv_rvg-kewcWy5IMguT=4mxWp4L`XL+Waw5pKt$o_FIi*Ht;1n_fVcbh~XC z|HY826Na@?hyP*t(H6{G3_PR2OnT@~Kr1f|_hTc?%*80Q5C=TUIxFY8bpWYv`Sfm& z_A?pZ2iC@RMJGW{a^`3*>J5Zvr!cSWZUkQ*@2mYxTR9*8Qe(VDF?T9|Maa-@x%)EC z8gpjwgitnOmI0Hn`;9t>Y0b6_v4}*m5Px`_tfUtRVnL-}bAo#Fbk~ykdWj>Z?sVLv z@QrroQGJ@kYripX)5BMdmJ>L)ls-S=%)&L$RV>-kamGC5MwlC2h$*||Di;KC_QJ3E zrtP|Q&_{CGW;?!oG~%N!*E<RBCMM=LHe9|&e0d<82|oU9VzwR;VSmL|m6sP4$-rA? zDZVnMGnf8uFOYeJ>rR;{rSaqvpc%?wO(uwcs`NsD=)-UaVU+$<5CEI2;<Bq~5SvY; zq(F(7H4Rx*k#2Tuyt0mj*(O@RVLI57={uv`Whx5e18OZ=nXex?q|Qb8*&b_e?7~as zMd?cOTOq0ySbHS&QCCRXU}ivy#b#g`SCtJxphra@f?Sd1^FC{$TwA@HA3zTs>r`A1 zo&?4^faj~MRy5X^G%iiD(42H1esEha6X4C_e3#foM(T^v=bjI(MAzL~`%K7<AmU7u zoPw1*h@T`~Sa*@uU|1Ab1!&@2*cbNDpwxHm>(=}z{idx_VI+In&yFVT9OL)MWp}f; zjrd4Wz!<weM!bRwm1cPic<42eKvtA-<%ME)HO{+|>P0JWPrzX`3iHy}m2{PBJ!bS$ z#k&hPD&gWfvt5<Mq=bn3-iM*JY>^@FLx%@z2-IDI6*I9K?_;n-@ior$Tl)DukXw^f zlBpw{qY7|&nfHQ?H84@~uyfcJKdYE7&6Ii+n>llnUMzm}m7N$n9M%6DQ)#ztfUs^E zZf->yew|okYKb*A(i?rMU17tTw*2~;%sx6dW6M(o?2GT=(j`$cP2k+MKyseJpGvh) zgexFKO7$1)Ldfn-w%7Aijd@+gQl2g&!a9<t5YJ2g@$WKGxYU+-To~kR__#Ce!r^gR z?~s|2JpugtFE}t{hCxzRRV~rqS|kPW7V97?F{!X8;$bV(Gio&x0lf^N<VM`v7N=bh zhM+rt5O<UZjxMRt<>cplysO?@+SL@7>xAd*YF1Cd8WlfNe~)Ht%Fcsr0!GkIaY#8T zPa@jsj9PCi?RKVDUlqGP!Guces!PpG3{!F8w*4W5eoj-<rT3cfg|kNump@&5^eNm{ zrv38kTA$kyJehTX<cxv19)C!5m6V!u$$gI|(yh~O<E%l*(B~L;@3}oysz8R^0C!Od zHCBv2zR3@hAmk=(ozz(65#M`}>7AOwR6|zX;~|^td?l2fnAJu^BV+%NvtvwUkHRZ1 z5nteg9U6V}i)>eIY!yUQ<0P6RV{7AZNFaoO*XcfFb#9J_&8nxH=OJb}>-NoK&a6j_ zNVqv-|I+37H!aM)-XNL7QD+=ozeNwdI_vuJS26qgJRPy7$mrdYm(-Gn6WlMmlVVKw zGdkQF$VMR36#CR71X$LMuDTH}7l~Pd=cwITZmUpe+cai42a3P3Zpiq&*6!n2<L+EE zq{B=oNQug+w0*o~%h95=4RWCkacU~H-O!Q(5M^i1NrkammMxs$OUHEKw^S@W16yZn z)vt??Zw*X&Yydo3)=7A{N9J}YH7MvlG&Fi#xLgK1&p%fLuR4pSj5-L>%j!-Y^<;pI z%Km#;NjcV>`&V80^c7NzEP;!|CsL^^I^iFEijwn*luwrWnAYc(d|1c|jgiat_A^o0 zs<v4SQIadeMwzWvs}7Ai(ypQ$AWux}cyS3vOA{CizaTmG#YHxEiHR{pohL=)2_RbH zuT6C?O@diyRgWKV#AX`xDkwhBD4G^vOJ`Or*w$jxdm_b8ZB`Fv-YtTZ?`DvX{q*7L zAxowto@QEKx_zco6vF2m4GLBg4wKVn7MtRO7TgN7=X?%y$H*XWC*LBwi37}0H$|t; z1XO~B#a!{RHcsc5jrdhh*S$U-(bqRYd!KGA=MbFP55+GYA6locp;LhpOfhT{zx=*1 z1J3yHTaS`QnZ~YdKiRkb(oG%i0aO=}zg`jKoO8UH-bX5vWyZ=coRzVt^b0CMFbn84 zf}!(PdzGaUKQFPE?>q%!;q_X(;Nvgy_y=0Fhd!a^BOR#;6!c?=SZxM^hEBubDKc3V zW-FIX<wYW?v%PW-!(I=!O=ETk`$cZtrHKRjiy01=vq63b{0yI1%);f%UQV=k#-7Ax z7Rg*ZR@DzYCTEH3*B}qz8fmb9pEe!`#0ZxM@?)1-vs(BCqP&}f_|F!(7e0>ILu!AB za)z6k7z@~WJf|ge6MQNyB_Am4vQ1w@1CcTE%XL`uG{duWjgwg-1cgnV4Yzu`c!I|2 z)WAunY4g~ahYm_*2ps-uHo&zoT%f>@7g`F<SKe30^dQB9z}o(mzMAL;e&wbFxKBuM zEfGONZwlksHQ#^|-5MrkFaHR^69~O+t;Gq(%pa4NT(3+ebA#GA&8x<IB^fm6tc>OF zfA=$Fypj?d6#-#(u6=FtD1WOz-ddFy^r6!5wr5Ak$#r&x;&=3>06}8!#sYt4s+dx| z&I9WEDR^Q&!zEuP<MEz9VtgR**eW53a<Ld3^C@T!72h9fIAOY2iP|J?);`;Qx%6TK zq?k~sH-34W`Zc5FDBafRHXflE>7Jq6_oKhDkN-Vlkz8h+P5_~v>FK*(Zb?UT1zD&Y zRHw^A$~QOwRdU%O89RriDz-y*hlUR5k<(Pn6l34EZ%5aUe`um85Ecw?Ngr)qPLeEZ z6#e?nethJ`?{^T2Ehxtn<94t#cXjm*MR<_1Kt?d=SB3hyxNXWwJ$FX8J%UUVP9~t= zc=MD8hZ{7N>(!uQDbqh%VR(3@G$5B;=K~im5fq^LHdW_2r66%MIW72%9LD;3&F{sO z7;$oz`kV0$B1fn9oW|zV%2_~|d>(BSN!v&+5ei<r<d=M`R5MGS@4w+|lw?6W5<n4` zsio#?!}C+yB@qL~Iz|?ddVcibYSqR3lD*IG9y`u9xq>OW<ldBg&<%MeA-@0;0@)4u z;2Qi1>V$x`&iAVgv=Z1g{g8x%|B1)S&x2iwr~(ajnqz6w*?23|GeyD~d#Ic|*0$rP zpZ%-7TetJ+qm?59$qK5PLtCh0K|p;s`key?gaHTU0ziz)S_6$Rfu=F0EJ*-{j)ajc zC)=kyYXHg~6YnT)ZeIzt=gaan;4x^L_|4m)IhVG}tq2c1F8c@o;}t1dEY8a){X^S~ z*hA~IhoR;>Wxg~`m!!RXem6eTQhsZf6mSP=_l4Zaus6mm_eDu`N@va$pN~;k<|7Zc z8~563SKwML0Zyy_B@q+l^VXT|QXJ>hnNDp84l(Tu;YFJ^gPi4UZ=4c^$ffBx&iw~` zK7|qtY=i_8naX>@TTaMpfN^c708S<K*tl@WtFR>Pq>O&aogWucv^$koO08wTM(*2> zT$GO^!sZG6-wS^S`Y6n3Btge(I>g)7pQaRA_v?(19Qqd+eS$B&&<dX3d*>OF{+xR` zV^1nV!Qo<IGGzXV+tTyqIS==`F1@7{wj&AY1}lag`{!D67NG`%)z>a(10$lZTw=U( zo9(Qq6tB}w(z*j~MM&%QeddR2@%?Syo3mq$hj6}qfh(`Z#?iT%w<@%;Ufw2TFkAE7 zEKaIs?dzrL%Rhh|C~F=6Eap7X7V)XC)dA1pZd-Ss@5|2;6L0hHm#M)Vy(R|Vhnka3 zZo=6N6Y53g+Hd+ssh;l~5sgh@=^B6p;#W;+MWPyl;I2n9&FS__dt}FgSMUM~RAWse zm`;c8e7EYA#hlLC9OL0ob>8)s%J5CgsDY7h%9YB19)JZy_z{H}_Z6EOiGU~HCCvBY zX)xudYn<llLt&!e6YwDtM^mqz#dV|B-s!l>9S09F4lrd8MMYF2j4kyeVA`J^^KrAB z`8|@sIaI4Z683t7>Y7izliM-Uvj4&LYCb!|^|&eT%Y+gk=+9*z2%*}a*y^fQA-}lD zc6z$sDgn=Tf7vO23mA8#x4~z7T$+)^u6?P{U_WgCb9C3H1+R2@J$Q5h9S~QERQila zO%76zl!*(ix1Sl9V+)NkaDA)0)%9Lu3&NLH{R@V%n>P5y1rb4S-{vFB12!z$-NgL0 z#V!)Nc6;h}@oMhEM3mk2jkkB%@zPg_(KHnhnxtkn5AtUb04dh75Pu{8!~!13$gL;o ze;slftA@<YfWYMB(gWa3Ctn)Ad5ujAdyVlXPwcpo5UUq}9EhP(gn)T5Bj-nssz%Oj z9^0juEeGZGr(pLBM+v_~BG-^s3rE?@Mc|tU1jF07V>fipO?L}&+tGl{pLDSO0&z!w z00vqCgue<E3GVS`MXq*^>2TDNci%Z?+2TLq@ArE$c|UFcKxI}rIiL~^)i}6*#>`|! mh;`Lb^Hs0;_N?lM02r7U0)@z=k^lXRLs3pewp`jc;Qs&w^J^mj literal 0 HcmV?d00001 diff --git a/static/icon-apps/i2.png b/static/icon-apps/i2.png new file mode 100644 index 0000000000000000000000000000000000000000..700886b3bb08f30bc1da20820128f806e446f5e1 GIT binary patch literal 9060 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 literal 0 HcmV?d00001 diff --git a/static/icon-apps/i3.png b/static/icon-apps/i3.png new file mode 100644 index 0000000000000000000000000000000000000000..87f1ba60e86055768e655ceee056513bc202d745 GIT binary patch literal 9863 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 I%bAD%A6JSgB>(^b literal 0 HcmV?d00001 diff --git a/static/icon-apps/i4.png b/static/icon-apps/i4.png new file mode 100644 index 0000000000000000000000000000000000000000..565453544915cb00d286b1dcdfade394e2e60b16 GIT binary patch literal 8736 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 XD<@>LH@W=Z|7^fibd*0RT8I4~FVYDZ literal 0 HcmV?d00001 diff --git a/static/icon-apps/i5.png b/static/icon-apps/i5.png new file mode 100644 index 0000000000000000000000000000000000000000..bff4090bc93f551ffd46391079d48492b0f65ac0 GIT binary patch literal 7538 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 VO=Qmh@#in7uGTHhCUyJR{{pGch1~!E literal 0 HcmV?d00001 diff --git a/static/icon-apps/i6.png b/static/icon-apps/i6.png new file mode 100644 index 0000000000000000000000000000000000000000..29ccb09b763a6e4b3a1fdbc57d35c67f44897181 GIT binary patch literal 8112 zcmaKRWmJ@J-|f)djl@WaATmQU<j^1>F(A?n0}MHINU3y((g@N>mvnbYNq0AhAbIe4 zpa1io59c}eTK9d$+I#=v+F!19hpMT{6X4R~0ssI4MFkm+$I<%ng=1qrey1fZ(H{pI zq^u57)4>wyZsKeKfSNm)S^yOhCRP?27AEGNPW=|5000^r9HxWRQBj7NIUrt|{KdTV zKsY|K0RT}64@VO-TMH!6)WQmGFUEA-*vbTin~O2M;a35vI7(Ys!xg-oEi}DUVP;;o zX2Rx765>En56Ghc!UAam^g!6zyFfg|nEs^;d7S^<=4Jx^3xc#2WBQ+@bX3%U(hklR zK>n8kTxMWCexRW6ORxYhpRn)?AP)#E#0?VS2J>=(1t5GN2oDeN-w)GcG-q>5h=z>Z zzhgbF#F(s+NJj`ax4XOhOLyLv4$fBGU}0flZV(SQ4-eNPg3HCz9%<siW$(iLkAjSa zi<vXr5eav&2mVzwF?Dc7iZMNA`adNg9RDM0@AB_9JvNNn!^Dvr{1WuHq<?@aD*t~d z0`VWT3sS@4fAjr+3cJ8O9WA&uEL<F1oy{H(&XW0WC`X92vxN!L!5QY@VE0cK)vO(m z4ldRXjzDSYzg-gsvcG}bn>)C>JpUI*MFpa0?}9Y3H?vTb5o3B(c?pM`Lj(kPp<pSn z5U-GoEEp^+CnYV-C(Q$f^78UYN%PC`{KJ)TFmpv%*dzbpn*T3X_`h=h+5zGC7+J=` z8SZ9bF6Zok0RF3N2>ie2BJf}J{>?T2@3{#6S1$KsGTeU;_y0QVf3_YS^mqCn>pm|2 zV}1+!N5?xqTDu}@@D~6;2UL`S!aU{{418nswGt(^T`!eKS$O+5yw9FKH9`+m0Ah#6 z*|`OwYd<Z(mdnaYk_ywUxRqYys_x<{o}QA>cbc)_k}cLJueQPC`Z*<wABPQwwgbS7 zEDBPj3OtI`aYOQ#jaJM1ewRxw$Bmbd@|XU*x!cW0es@d0m+qs&t>;b-%s#uaCt}uX zmej*&ul1+LPE&hY6GWZ~f*R1e4n#W|JhQ%HSEHkB$&F_0#O&Vp#9hqIjWcGlWHFEL z-;L|_VmrR3IceZ&&%|W+K;-Z2ct5OQm@psa{a*ewlfTFKqV&VK_}SQoJad*$<2prC zcB#Xb5IH9<&>kN!E$e_qU=TC3<lbTx$j^Y&BR^kNahBw-Uk#7WSO*0^Z!gCd5fs-5 zT*=mC^0;1g+-q-C!ec+r_^7@6ibCKgnkn*bRvD)VD{b>n-OBd5n`&mr>a~K@{ZlX7 zxe(nWjGpKGQ&g~5YwW%Zft|6zz8C15?~p3+{wJd$M{_EJ4h2eTf6A6=08?l~@7#_E z#MOnqmymS}eu-@~?c!qK0tpC-8~>2(e#jJ8X&4n{&l9`pKVw2MJ8?w))gkRZbFt~Z z>|r!)cHdA>bZr05*Apv@QKsz$otAB(Y@7KjwY{71<wdlF#zS%N{_Z>c?J1b$#qa#$ z*FmwrwZvBF(oYU<N2!R!$rOhj<S_^>3Rz}$+>s?HQ5RyS#>5X%>o?<=p_Fb?o)g=r zQ&v%1f+G%cMt>NfoNcpn7gBogwc{2D%^<gYn?A(LxFps-+ReKwo`@O*(M4OwVs0)g zBLNS+dZxL%sbSyQYDZ98TZ5YGQ}s2^p`$9?tNhj+UHRDPOS%(drt1sYbcM`D>T8Fi z&is2Dp3()a;s;uFPiR%!ALW~;bf3yM<KxSlT#zf~iul4TY|`nm(&=AE)?<J-S3_or zbNlJ&og!E(GwyzvhTWEmnq&Bm3{UEqA8Mj}mpQ-Gx0--9G`n8M`jt(&$@SUd`1(#! zX3wu^1<^SMG6g@J^3UBh_wF?K@Jiy!;i+!i)s=Cjc`%Wl&(or^c*S{fE<Kxa-y>dG zQ6IpJ=o`^7-r3hftRl*xd`GMVei>Z|+ua?q)UKr8<ALN6Tj;IFUfI0PqIELQ-oB** zm5g$5Z?dyK!4~s!WsDJCGjRJrw-+91@5x2@A&&GVxROAsHUOWvCRe2G^&EMOPD7fi z-5=j8<!$S0A?jT!LHA~zCXl<0CNdC@7DX;nhBPmw!hf8!1H$1-ScI@bN0ZB#rl#&c zB{WXs5Q=@trLK&j8%Gg<Y=1x53U~2zamocohFCt-ySU%SE%Y177#Zpg7V?QCYS^eo zOXWSVf>@M86=4xhsu<OsBMMpr0kIrKh9aF<<ndmM$RB87KQ@?vx?Z6|r{RprnT+ZS zyw>F7`*^-r<F#f)GDiAZL_$TppTfrJ$=x#)VAxb4J7Oj%93{tW9P)~xi|tZ6y*h0m z;N}I#VF;E#vCVQhZ=zfIdEt3HCW!xpea~F?V*F$btu7d=T>be#M0Z1!gqX=7J$=nj z+GFZ(195~*L0=&3Tzgwu;_`ne+0rQE*Ne)=*K^bc<gj~25H}lmXxR`#^;)b8jJR5$ z166(D6#(7cjdI2>KUT+`nS+qX?ZMCKZY2gsmFI^_r(H2I8xG|mYx_t(i(L8rj3n$P z?Z*lz6nqc?6l|s(8d1}#tVi1P=kj?vs+|(z9!m&aU73obr(%xfth-f@Vk^C#w6u-t zQRHV5Q7K}_tqF@SV#Tisi**Z$Q!O}v6x0#3fi`v=zYYYSHt*G3C6!$M`UCat@!?zJ zSa3bwy5a2_Ba0@qm^h9F1l!`?8TCgH$0RT~&(XLtXXln?dzH#_Fym$)NdEYZO&Vu> z!}nqQ+2EE_p-CIdBu$6ft5D#_Uyk0nqfmjM_-$T51<bu9D%5KxA=>Aw;q#(i%+>oN zi5F?~_{T#LsWe3@#X=f#2B-z_>Zj@>ZBMk1r5+0BQ0`OKX71~0oYuMee&zd9|Lh3s zRy>!UvSq7PIOKE*v8+OPf3B3BI<y_D@EEz`bepP_uVKMHwib!t4O)E|cofbBR4bXT z8L3+_l_<r;FoQ~>j0;s|oFn40WH3HRP3Y;#2Ec^33S5h->J75hZW7P6GqNoc&V*(K z3a8PR>sUgE*gs}d_OI&5&wu7S=@j|!5K+TYn1sF>i!=HyC2*7A{uc;b!bicDXBqMb zcR=#l<Xi$!c#X6$YtIpu!#Brd<``m^d!|0f%5$1pZ!^J{eq*34md#2M23EqcywRVw z&|Is1E*EB>N4q_kRqkbTIn~-9_vOVlj>Ocx7YJu?xik?I2pBXm=ZK^k8(=s8PTTk$ z=zbIFPd4G{2f1fUXgvo?KJ??pCZ$6aa2k7X{geo_$3d_#64!F9NLb@K1o*H!4|sN& zJAbmJN9=cgBiS4E<{MRAz^8%YY7EjgP^_tPpA3E+7B$XK7HYp0O=)jRzhd8(lYoT6 zwWH?@^(+wM7D1;x<af|d{8;+WmMaQhh>MdNs?t_q-<z#aSB7X(7PTe~tU=uHzC;_+ zyqv-*n&<p*1}fAR+a$6yr6+7il%dr481m9N{0?AfxB`}W=(r=ZeX>6}ak}s5O4KVk z(;(Bvpjexm4}ucX9VFT$Dg6p)`VHCWX)&{b3ESy@Ht%HRDMKn=SP)5Z&KU!Ge|}nE ztCg*LUzr(UKe!)X8H!H~<eeihm!a2){a`J^N_Ri=*>ub{95vq{jG^^l0n91C#v^D( zRzd)=k`}#Z6=Jm%WN~0);f*`=`jBR+_W@#Fs~jxn(F3GR9Ib}gKF3zcd~TZ+5<@^r zz~OYVVGQ$k?4?_1U)*^|*!8vbU|A^j($|2)-X3%nS^@#AWmB}He&{e27%Jq0$s*%d zGl>BB$qV$neE4f)u`<_ERc16f#R@^ctU6>;IyTPHSFWmx(CieUzcPNl!!|Y^Tl}E$ z+-Cj02(CH9GU1@q>`+yQ&LZ#p8dX40^deMFhtAMwXHaaRVPDPsGB5Y+l7rZ0%d&p4 z(2b4VD#3fB%lXA=q)7#RK{MB|m?{x~kbpHP3|tGS$qa~N5?V73rDdbUnaL5JynpNS z41w?`d0TEv3PO!CJyE+hgVxX|&J^^aVpehmoQ-=3RnQhsl#H?AsW(O~P5Q!*qvw_> z=FHnM3!F2Odn6<tnv9L>swA0lYMv|@(#mv4{S;u?+Q#n0n^Dc(WMRrF2<!ObhHBBP zU~HE^hC#ZV+=e}<E^wwaunxl~1*`pPsVuX0&%z{j##PPxA(iUJ8&kXeo$}@9YPV<u zru8qgKf^n17ZP8XC*?c6>#@?|`dDH5BxGpp6{*$wjEryxIJ+wJoeWQ4Bu|uzUBVX{ zdH^N#O$lB#)C!JW$uy@Wff?@)(E@~yK1F$2a`Yy|&F2Wf#VDS=o|~34z^@)NA-G3? zl_UPKxfXpBu^Y;`4!*6gDhb`z#YY%Ja=W0FG*r>HBu~1vYX~cl(o=`yZPr=A*{Xd5 z8!1ts=wvX~^hik2JZqjVtM*ho>L-BqEL)HQx?(G@L?LSC*O{~yl6DXEYme%4dQC7y zp`-cmW*%3DlXo!X0LH)L&lVt%GBtutQ<{{ZS57XK=ojCaiPCdhAFI6qOhEUS?U>!S zsqYcx4z@E2E-4NCqpyEWh6M|bh&yk$1j{hIe=WPvA3ur4E?IxJRA*>cOrh9T?9yu` zgoonU*Y#zlhdn_sLCA58#B=Z6xj43^>daDeaeetLQPC+TN`!e-NWz<nV_>kv14UaQ z3O%&o7c`4B)c?m8_E!RqGnNJO)xCDK=1aHqhoV8u=NHpY@YCbPRDw#bQX|R&G#I;l zf^J=HpN2F!ositMj>+3^@wH{xvp?Jr<;>%+tpzEZ%i3@gPjT^lL!*4poWvz?IQGSQ zTkG4F21|B)mnn_qC6+>a5yi@VjM`1b6_(YgeQ9n}WVG@4Y@&CU4vUN$MWhEF4m?Zg zF3~brhNfLJP*pvwsx;aP^Hn(ei0k(DFgp3{S2-!~88_$s2tS2Vk`Nn7{-vHg1F+nP zRQuav;7u*|YTSz_u<=ixq~U3hls3&Z8B3W|3vePmB%TpW96Hul3Ug8F-4zY4qLxKX z!m4Ofa)SYQhNK9M-E;#bZwR!N-fRX0AJXBb%ZTK#DzJx@wiR4Kz=gP^DO^)@=O5`x zgyc<YhZQwAUOIng%cX-scRPrUwNka+v}|RZdeC5{xbZeB@A1sV<)R;8f+wS-Wzhxs zY{OA@bJeih;i#DJdl><L(3|F*@nLl7J7rx*5vm~(NRY2mH9?PLx7ODnQo_hMoA?Ol ztmm?Y!b+7HjifhSwAmT>#&+_FRf3&tpDD6ReemxNoY=)0X5s#L$%fd6`(^MNlA>$z zz^}W|N@4A>z#+oeLBiMxu0bn^hX6>_c{rS<BqWGKbpxkF8#%n%f}Lg+r|OiOC^DzV z-5xd-X2X|iClZu}CZ8oPh(qm3f7#Tki>2`#^O&5dle;n;r27oIxm|bj3Sow$>!iMq z$fElcFv*rR*fGXI2cBg3v^O%L%AhFuOk(uxeFPI!le<_!4Ntxtv(LWHe_`zpv2uzK zCaFv)d^J&FBZkFMD1RrO;VbE0eAf3Z_*@mHE+=$NfiXn-<Dwu97UOcAogH;9*h77u zWq!GkWb3pW^W4x;pA<GKs$!x=Tw{%%ocR!cxfR$?_VnFIQ-xDp!yc0=>KH*>yd%Fd zX=Q$TV|XWhb_C_)eI;6iZagZunagOec{M2{W@3aTF8CX2&v?0z!=8{?0M;N>rMTI$ zxXvup%cZ(O&HuL2J=!3o|2I4$CMu|chLoR_a$9O*aE*@44bg7{l~1fYbi~hNf$_Tw zj8%}0Ac^IQi00>YfzTae%bhxDh@GZj`1y@^kKgxigIOu!jZ;W}H?N7OtKXU(y|xYW z_u5YB$Nn^ka3sp8)Ih_4<y?}G6#pn%Wb&}X5Ybr~ma%rbM;^Jr+rX~zb)caHs$9Qv zB(3$P@nvRI?!HPJjb=*m8cV6b0kL^;Jp{X>@2&py3m)%{N5TO2!P&DGABfl=Q8uFX zU;V=fvIZ%T@dwYo?6tHz5hlvsDHwfQjG0z+9%}UjYQ};I$Num_N5j~C_SA4)=tdQ< zw&SFlJEbFy8+%Z9Y>+^ZyBHvdZ_=2JS=*uahU~(!dx;K%x<?mdB45(!4l8wufs>&J z0F8f<Yh4rF&CdjNeL-g~Q;oo!K~0H7cw*<NVtVc8)&S!GVYW@08m~#f)L8U&`gl5h zbsxN3@+X1zl%SVq{2Y|q=N_7FJ*?14(kJ9qWh0H^8D6cwhR#91TAy(3M!(@7knUBP z0k}mwnEdRGpH@Y&+6<H%Si{~yA~RG4O-_E&<OkP`sMj#Aa^65kzfC||uVOi$?xfGn z3G9dl9ywZ7j*y+f6S{Fan1#PoHHFXpIf!t-_S|3RS}n%XJhXXey8*sCYN}8a%uUls zt<m8a(Zr;?xEoIayhoRJAx7B<H=RN6a<ao?Tsr}0)qjugT}w(QdQb7Hmpw%#CdD)2 zg|SUMMm1dU<hfYyehhHu{KtWE=0{N+(Q(sVVdH|3g(l%Kzo|_#y6~z){Ac({^r+4^ zs^jhhpG0)XvPf52Oy!bzCbpeQu*UY(=~|p66&*n}SYb0ppEH6c&a4IY{MsXsXr4?f z{d%1t-nOX7FlUj*f(=X8mOY=Gim2-baJj_KSseQP2Z1kZ?<=@2G_o16X!@A&2!FeA zu-ld4s7Y+N4LhpaicsS+v>mMLz2zen`F8gVg&AVdWWr@UQ(sYLzDaT*i7EvbL3`WH zG$nBdHAyA{vWAyQ_KwIRE2DJM2H89{h)Ux!d_Qv3={H&OZ&<4OriQU7zM+UMVW{Yo z$WV*^dVRkzT{DlbBE+)u40_zo+1WYE0u>(A;W~AdA&E>5FJMx|puLZYD_=zd0;6 zR<Q)wcz4V`(fiJp7^fgl%5e1dD#iC2HoJ+|FdHOIZs*2zX#FumxyI6aTFoUpY+QU^ zn=7bx^BBI%ZzHZ5myqq+)~azrypiE&Jm48rW2c63Z}#ayu?(BrC9kQtxa5g#Z8n%5 zgR^D;eaxBSO*-U(u;7kOK#?<+g)eDXd7x5XxWv4*Z0vsG+SF-$o%P__m7BoJhf(k1 za|C)oNsZL#uUP`SHuN++k1yCehNDPtryrPaessNkd*9t5+$hVUz@PJz(px%w<7wM` zv0u+h;S6QMTsM^g$|z(xQ5e|UBINzYo{BPnIanz*DC10>eWC32ha+|r9VqOZ-_?%r z1e9rPghSV6Xum7x`qsK-{eF1eD#1VpeYZsOqC)u76|fZ$XC@XfK$}L2>s^Y*nTgC3 zpNg<wPgYA1cx9z-VFd3e_gwge<tuc>Had2_R@p4=Kl+*cNmcp}^Hof9j@NV$ubx2W z-_750u@b$^ep9uRXn{X35N~A|wVo6;uP6#___mxr9~uvbUW!pAM?XY!It27og3MoF z^&2I>Yo<6Wep%Gj4-oxqK>OZ;p%d#hOUMkN^q+B+0W1tjP!g+231OsTOsq^`a#(ze zBL{oTanF^hlC@aS;6U%3K+DDCZ_yB8FF1wpC5&2vCp$SH7LWD47b{6Eva;D<!)8(K zja!9w5|zIAr+lHsKY03Xckhp6WRYs4ztxL}t1uGOO0@>2-)f0-=2em;wuiUh4<`E@ zGz}XxcV@jqww=5{>m7p)FQjF{<}&uLtGP>p%wLPGZcp3pWZ5!aIGdh28&2_uZPa=N z6(rr^4wWt>_h#u<M?`|W89B*Hez~L8<mzntu4m3#Hqg=NdA~X)qvmueY%ADfMmNH7 zl_`~=574aqAcsg9Ci?EVP}$3@S6w<s{U%Oz!h6c6*6tI!WF#M<^4Ivbog|z1df@z7 z<d%a-ZVMU6HGYU9G85&dMH5~@;e&?B;%`Vrc%kcR!#KMVA3P9ZpK1bX03H!z&f6Q- z|320A66q7la&AC0;B4jx_Pf(iNvS+f^h;bJE(aHE_FWbGkK2}`=;q8X3CaoIEO7dg zKB>-S-`7XcvzbjYL|AS7u<nB~6fvSeYX?O0w5+7a1zd-}+s@Y)TAVm8zrd-y02(Yd zuMzp`Tz!)mE;Uo5Wg&dk22okAKakaolZ@0QkTgbcx#mMePl|cbhBj^k2$;}F$6=jq zb0I!I`!|ybzV5i4#NV~(p9a)yf4d1PF0;jWm99bV{->FK+wUp5Xhb2L{RgE}%uj0k zdWIPR=~h*H%_0ivX5+91^EsMdNKsw4J`DCc#er{H(I{+(xB0mEdgc_bX$M*R*rn5$ zprW_0tGFAn?y@EkK@r<`-JW+(&NLlPRA!`Y`3aiiFlo1f%Aht;%8g_Q;)R@r1deFj zS0n(?K{)C-8(l%P)}R?%7hqgtVQ33z)YNenDS&L<|KM<Gcw#B`BOW6LMf-W*o7|nE z(BtJwZownG9sG>BIGBMZxh7Aye{5}9p~zwov{DjXn<@uXy931Y%Ng}M?O?&#O9@~j zPejCgd1?JHhV_{=xBBC=P2$$ZGT#oWGKj+>rSf$(!^f9>#*Qz8;jW`aH`m!Gyxa;A z<0x;4LSdhV@LeUG3I}qBKb0QY)o6zYlFbi<0A^77$X|T6`79!M);RFgLg1Nriv;`a z0op6^TNR_$>reVBDO|6KpE8tvefk?CeN)eC$@>O?t~ahFB$cZ}K-)U=MayW8eID;_ z>PrV<sH9#ToyMl<wA&)0(SpavA~D`Ckz-Vc>*sB=19jWNwBAU=-fyvPoXvWo^%i77 z4M|~r0$;b;dd2V0`Nz9{qps2+B0u7~_TxUwsB5ptJW$3&z~Q0ghbWWJ6km$0GgIz0 z<szQLpQIS>NTQmJ>I0auX)|rv`wr{3O9solORSdQC7L#S80;8?6RE#So$#XHHS7m+ zVm<w7AGm>ClMjQD!uWp@<ss0s`T0E3id99-UM12Cx+r~`vMik2XnV@gUK@a7;f)n^ z`<r|8t<z?mrJ={d)W-||$vzFW4@KdZtxGla$0Lfz1}?bgscM_DB@4t~n8U&`LmhsO z0IDd?Zp;;d{Lc85m+`*noOp_CTO0S?@{|1bsYhw=x>L$V4X2ao4mA-V4IEUg4grO= z_K}9W{k(5YM;_k}NlJh84dp>D#Jtd_vff)hd+Mpo;y$3?t1&QAk02qk;n~GN@=a9p zVnZTaMBn(BFM7@xUanMk->Dg34PuNGXz8;Rhs)OJHy3zR`d+umHosZ^F0y>_Hiwb) znYI$uH7>npNQNC%Lr=?IQ-m1`9iH9fw`wN}d!{%I6K5lyCJ%S_-mXzY<oIx%xUh+; z{y6uVxN||x_qK`&f{Q%qF_Nz(LZrgDK_8bq_7?Y54<C+2-%m7iCIX6uO2NGIpV|79 zpL<00r#OGA5e;`Ji8r`nXgclNz+h}RT_Cc@13!!V6>z<{7VAGzK;SG(<AEkKS$=X& zQ(U(wj_B_G7_@eIx7iL$RhqZKu8JyMrxq9})_eJua2L&+@ke)R|NW}e_T{n8Re;4z zru!k|x_ALv8fIKD!99#mh!j8wFS274zACnOli_pN!t{RoX2!Kxn#qRkpg<hnmjHT0 zI_9o_@w)4W;jP8!LgNfq!_iwTAQN-KL|kT=8>Czu9+tUp`EAzgewNX&p+U&i7sshp ztbK;l;6fRGdRy+vd!X#q67Q++!`-^S*Svch?x05#P?flRZr$d&n%%gM*5_)B2BeWZ ze2z>`%5)vhNltS;{1Hh%At3<xgWwN<TMIBwN*GPE7A}Qa?;hi$Hz1xgTD?1n`zpxY zY`3c-u{;5;*!aF}8L(dZqEs^uwEiWqutll=fiXP(qxQ(%7&nva<+}&Ble+M4LJbce z-fn8XOC~clt<`mzB;s>cZtnF~kTzFSrL*3@URoEk61%;`n?9iB+pX*iDUH-AjqJgk ziki7XXzn#Q?hJP%FL}7F{%FrR&J^=G3tC(~*_<*e^3Xes*cq)s_>`9Jk8k(9p8vI3 zrG2opIIcMWkeq~O!#C*DP>2uzpsd{LJ^8w_g4T7)7uCF0dPhH#`IFbGeI-<w_f<Zn z3I`F_F8NnajHi~HlFEJREC}XU(0sSNg&B~B1pe$efb*`KvnSo1x{UJXJ{53lpn zswCo)P+ou3OedAj!N?Q$H@t`P@6@f-S}Mj<rQv7U8WhuDxF%2t7n0@XDXJ_AU{ftX zXd8oL3_pxv5$6ti*aS|NU|Ga47N8JUlctTw1nUZhXUJ&~`0pu3*M4cfP#}q51(l)} zsApNDw;7W`;p7Eiw7e<6lytAJZGkbG{|dWgK!lqGiX=hW4LwneFPcuLni*PeT~Q>n z=N%P6%<GFOmz+r{5gFzyyP<ro2!6>LNXAm00N;8&FK$)|VOw28&XRgn#)FYR3ZQ?w W8E0`}#^LWjbVXTJnQv0Yf&T{_1`($K literal 0 HcmV?d00001 diff --git a/static/icon-apps/i7.png b/static/icon-apps/i7.png new file mode 100644 index 0000000000000000000000000000000000000000..4bd9b37c724810e038d9bf24b24ead247a2b8c15 GIT binary patch literal 8382 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 literal 0 HcmV?d00001 diff --git a/static/icon-apps/i8.png b/static/icon-apps/i8.png new file mode 100644 index 0000000000000000000000000000000000000000..993bf41eac446f80b5f1bf091abc26f99ad339ae GIT binary patch literal 8873 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 DCKs)@ literal 0 HcmV?d00001 diff --git a/static/icon-apps/i9.png b/static/icon-apps/i9.png new file mode 100644 index 0000000000000000000000000000000000000000..20e98f2646cd57b285d0fe9a994dcd6c76606974 GIT binary patch literal 7210 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 literal 0 HcmV?d00001 diff --git a/uni_modules/next-search-more/changelog.md b/uni_modules/next-search-more/changelog.md new file mode 100644 index 0000000..69512e2 --- /dev/null +++ b/uni_modules/next-search-more/changelog.md @@ -0,0 +1,20 @@ +## 1.0.9(2023-07-06) +增加clear时,同事发送input事件 +## 1.0.8(2023-06-16) +更新修复input事件 +## 1.0.7(2023-06-15) +增加输入事件 +## 1.0.6(2023-06-09) +增加demo +## 1.0.5(2023-06-09) +更新more插槽的使用说明 +## 1.0.4(2023-06-09) +修复mode=more模式下input事件 +## 1.0.3(2023-06-08) +更改模式 +## 1.0.2(2023-06-08) +更改说明文件模式 +## 1.0.1(2023-06-08) +更新说明 +## 1.0.0(2023-06-08) +初始化next-search-more diff --git a/uni_modules/next-search-more/components/next-search-more/next-search-more.vue b/uni_modules/next-search-more/components/next-search-more/next-search-more.vue new file mode 100644 index 0000000..47b4e4a --- /dev/null +++ b/uni_modules/next-search-more/components/next-search-more/next-search-more.vue @@ -0,0 +1,239 @@ +<template> + <view class="next-search-more"> + <view class="search" :style="{ backgroundColor: backgroundColor }"> + <view class="content" :style="{ 'border-radius': radius + 'px', border: border }"> + <view class="content-box" :class="{ center: mode === 'center' }"> + <text class="icon icon-search"></text> + <input class="input" :class="{ center: !active && mode === 'center' }" :focus="isFocus" :placeholder="placeholder" v-model="inputVal" @input="input" @focus="focus" @blur="blur" /> + <text v-if="isDelShow" class="icon icon-del" @click="clear"></text> + </view> + <view v-show="(active && isFixedSearchBtn && button === 'inside') || (isDelShow && button === 'inside')" class="searchBtn" @click="search">搜索</view> + </view> + <template v-if="mode === 'common' || mode ==='center'"> + <view v-if="button === 'outside'" class="button" :class="{ active: isFixedSearchBtn || active }" @click="search"> + <view class="button-item">{{ !isFixedSearchBtn ? searchName : '搜索' }}</view> + </view> + </template> + <template v-else-if="mode === 'more'"> + <view class="button active" @click="selectMore"> + <view class="button-item"><text class="icon icon-more"></text></view> + </view> + </template> + </view> + <view class="more-container-parent"> + <view v-if="mode === 'more' && showMore" class="more-container"> + <slot name="more"></slot> + </view> + </view> + </view> +</template> + +<script> +export default { + props: { + mode: { + type: String, + default: 'common' + }, + button: { + type: String, + default: 'outside' + }, + isFixedSearchBtn: { + type: Boolean, + default: true + }, + radius: { + type: String, + default: '60' + }, + placeholder: { + type: String, + default: '请输入搜索内容' + }, + backgroundColor: { + type: String, + default: '#fff' + }, + showMore: { + type: Boolean, + default: false + }, + border: { type: String, default: '1px #f5f5f5 solid' } + + }, + data() { + return { + active: false, + inputVal: '', + searchName: '取消', + isDelShow: false, + isFocus: false, + timer: 0 + }; + }, + methods: { + focus() { + this.active = true; + }, + blur() { + this.isFocus = false; + if (!this.inputVal) { + this.active = false; + } + }, + input() { + clearInterval(this.timer) + this.timer = setTimeout(() => { + this.$emit('input', this.inputVal); + }, 500) + }, + clear() { + this.inputVal = ''; + this.active = false; + this.$emit('input', this.inputVal); + this.$emit('search', ''); + }, + getFocus() { + this.isFocus = true; + }, + search() { + if (!this.inputVal) return; + this.$emit('search', this.inputVal); + }, + selectMore() { + this.$emit('moreClick') + } + }, + created() { + this.$watch(() => this.inputVal, (newVal) => { + if (newVal) { + this.searchName = '搜索'; + this.isDelShow = true; + } else { + this.searchName = '取消'; + this.isDelShow = false; + } + }) + } +}; +</script> + +<style lang="scss" scoped> +.next-search-more { + .search { + display: flex; + width: 100%; + border-bottom: 1px #f5f5f5 solid; + box-sizing: border-box; + padding: 15upx; + font-size: $uni-font-size-base; + background: #fff; + .content { + display: flex; + align-items: center; + width: 100%; + height: 60upx; + border: 1px #ccc solid; + background: #fff; + overflow: hidden; + transition: all 0.2s linear; + border-radius: 30px; + + .content-box { + width: 100%; + display: flex; + align-items: center; + &.center { + justify-content: center; + } + .icon { + padding: 0 15upx; + &.icon-del { + font-size: 38upx; + } + } + .input { + width: 100%; + max-width: 100%; + line-height: 60upx; + height: 60upx; + transition: all 0.2s linear; + &.center { + width: 200upx; + } + &.sub { + // position: absolute; + width: auto; + color: grey; + } + } + } + .searchBtn { + height: 100%; + flex-shrink: 0; + padding: 0 30upx; + background: $uni-color-success; + line-height: 60upx; + color: #fff; + border-left: 1px #ccc solid; + transition: all 0.3s; + } + } + + .button { + display: flex; + align-items: center; + justify-content: center; + position: relative; + flex-shrink: 0; + width: 0; + transition: all 0.2s linear; + white-space: nowrap; + overflow: hidden; + &.active { + padding-left: 15upx; + width: 100upx; + } + .icon-more { + font-size: 48upx; + } + } + } + .more-container-parent { + flex-shrink: 0; + width: 100%; + // position: fixed; + // position: sticky; + z-index: 997; + flex-wrap: nowrap; + display: flex; + flex-direction: row; + position: relative; + flex-direction: column; + .more-container { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: auto; + background-color: #ffffff; + padding: 20rpx; + border-radius: 0 0 30rpx 30rpx; + box-sizing: border-box; + overflow: hidden; + } + } +} + +@font-face { + font-family: 'iconfont'; + src: url('https://at.alicdn.com/t/c/font_4110624_nikfg21uyk8.ttf?t=1686190660183') format('truetype'); +} +.icon { + font-family: iconfont; + font-size: 32upx; + font-style: normal; + color: #999; +} +</style> diff --git a/uni_modules/next-search-more/package.json b/uni_modules/next-search-more/package.json new file mode 100644 index 0000000..f0f64e2 --- /dev/null +++ b/uni_modules/next-search-more/package.json @@ -0,0 +1,79 @@ +{ + "id": "next-search-more", + "displayName": "next-search-more(vue2 vue3多端通用)搜索框组合、搜索下拉框组件全端可用", + "version": "1.0.9", + "description": "搜索下拉框,支持多种展示形式,可以结合第三方组件一起使用,可自定义", + "keywords": [ + "远程搜索", + "组合搜索", + "配置搜索", + "自定义搜索", + "搜索下拉框" +], + "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" + }, + "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" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/next-search-more/readme.md b/uni_modules/next-search-more/readme.md new file mode 100644 index 0000000..b418bae --- /dev/null +++ b/uni_modules/next-search-more/readme.md @@ -0,0 +1,215 @@ + +## next-search-more --搜索更多,搜索下拉,search-more + +> 遇到问题或有建议可以加入QQ群(<font color=#f00>455948571</font>)反馈 +> 如果觉得组件不错,<font color=#f00>给五星鼓励鼓励</font>咯! + + +## 使用 + +>[从uniapp插件市场导入](https://ext.dcloud.net.cn/plugin?name=next-search-more) + +```html +<template> + <view class="index"> + <view style="padding: 10px 0;background-color:#000000;color: #fff;font-size: 13px;"><text>1. mode=more模式</text></view> + <next-search-more mode="more" :showMore="showMore" @moreClick="moreClick"> + <!--以下demo你可以借助第三方的插件实现你想要的任何复杂功能--> + <template #more> + <u--form labelWidth="80" labelAlign="right"> + <u-form-item label="radio:"> + <u-radio-group v-model="searchForm.radio" placement="row"> + <u-radio v-for="(item, index) in optionslist" :key="index" :label="item.name" :name="item.name" /> + </u-radio-group> + </u-form-item> + <u-form-item label="checkbox:"> + <u-checkbox-group v-model="searchForm.checkbox" placement="row"> + <u-checkbox v-for="(item, index) in optionslist" :key="index" :label="item.name" :name="item.name" /> + </u-checkbox-group> + </u-form-item> + <u-form-item label="rate:"> + <u-rate :count="5" v-model="searchForm.rate" /> + </u-form-item> + <u-form-item label="switch:"> + <u-switch v-model="searchForm.switch"></u-switch> + </u-form-item> + <u-form-item label="other:"> + <next-search-select + :multiple="false" + :list="options" + label-key="projectName" + value-key="id" + placeholder=" 请选择报备项目" + title="选择报备项目" + v-model:value="searchForm.projectId" + @search="searchFunc" + @change="changeCallback" + clearable + ></next-search-select> + </u-form-item> + <view class="flex-row"> + <u-button @click="cancel" :customStyle="{margin: '10rpx'}" text="取消"></u-button> + <u-button @click="comfirm" :customStyle="{margin: '10rpx'}" type="primary" text="确定"></u-button> + </view> + </u--form> + </template> + </next-search-more> + <view style="padding: 10px 0;background-color:#000000;color: #fff;font-size: 13px;"><text>2. mode=common;button=outside模式</text></view> + <next-search-more mode="common" button="outside" /> + <view style="padding: 10px 0;background-color:#000000;color: #fff;font-size: 13px;"><text>3. mode=common;button=inside模式</text></view> + <next-search-more mode="common" button="inside" /> + <view style="padding: 10px 0;background-color:#000000;color: #fff;font-size: 13px;"><text>4. mode=center;button=outside模式</text></view> + <next-search-more mode="center" button="outside" /> + <view style="padding: 10px 0;background-color:#000000;color: #fff;font-size: 13px;"><text>5. mode=center;button=inside模式</text></view> + <next-search-more mode="center" button="inside" /> + <view style="padding: 10px 0;background-color:#000000;color: #fff;font-size: 13px;"><text>6. mode=center;button=inside;isFixedSearchBtn=false模式</text></view> + <next-search-more mode="center" button="inside" :isFixedSearchBtn="false" /> + <view class="content-block"><text>全站ICON图标海量下载iconfont图标大全,为你优选-包图网,全站ICON图标海量下载iconfont图标大全,为你优选-包图网</text></view> + </view> +</template> +``` + +### vue3 + ts 使用 + +```js +<script lang="ts"> +import { ref, nextTick, toRefs, toRaw, unref, reactive } from 'vue' + +export default { + setup() { + const showMore = ref(false) + const searchForm = reactive({ + radio: '', + checkbox: '', + rate: 3, + switch: false, + projectId: '' + }) + let dataLength = 0 + const options = ref<any>([]) + const optionslist = ref([{ + name: '苹果', + disabled: false + }, + { + name: '香蕉', + }, + { + name: '橙子', + } + ]) + function cancel () { + showMore.value = false + } + function comfirm () { + showMore.value = false + } + function moreClick () { + showMore.value = !unref(showMore) + } + function searchFunc(val?) { + console.log("搜索的关键字:", val) + uni.showLoading({ + title: '请稍后...', + icon: 'none' + }) + // 模拟ajax请求 + setTimeout(() => { + options.value = [] + dataLength = 0 + if (dataLength < 40) { + for (let i = 0; i < 40; i++) { + options.value.push({ + id: `id-${val ? val + '-' : ''}${dataLength + i}`, + projectName: `项目item-${val ? val + '-' : ''}${dataLength + i}`, + ohterKey: `test-${i}` + }) + } + dataLength = unref(options).length + } + uni.hideLoading() + }, 1000) + } + function changeCallback(item) { + console.log("选中的item:", item) + } + searchFunc() + return { + showMore, + moreClick, + optionslist, + searchForm, + searchFunc, + options, + changeCallback, + comfirm, + cancel + } + } +} +</script> +<style lang="scss"> + + .flex-row { + display: flex; + justify-content: space-around; + } + .content-block { + border-radius: 20rpx; + border: 1rpx solid #ccc; + margin: 20rpx; + padding: 20rpx; + } +</style> +<style lang="scss"> +page { + background: #ccc; +} +</style> + + +``` +### vue2 同样支持,在这里不再写demo + +### 组件按需加载 +如果不需要组件全局加载,而已把组件拷贝到项目的components目录下,单独引入进来使用即可达到按需加载的效果 +### 预览 + +*** + +| 功能预览 | | 项目中应用演示 | +| :--------------------------------------------------------------------------:| | :-----------------------------------------------------------------------------:| +|  | |  | + + +## 参数 + + +### next-search-more Props + +可选参数属性列表 + +|参数名 |说明 |类型 |是否必填 |默认值 |可选值 | +|---- |---- |---- |---- |---- |---- | +|mode |模式mode,支持common模式 center模式 more模式 |String |否 |common |center,more| +|button |搜索按钮的模式,支持outside模式 inside模式 |String |否 |outside |inside | +|isFixedSearchBtn |是否固定搜索按钮 |Boolean |否 |true |false | +|radius |搜索控件的radius |String, Number |否 |60 |- | +|placeholder | placeholder |String |否 |请输入搜索内容 |- | +|backgroundColor |搜索控件的背景颜色 |String |否 |#fff |- | +|showMore | mode=more模式下,用于控制打开下拉弹层 |Boolean |否 |false |true | +|border| border |String |否 |1px #f5f5f5 solid |- | + + +# Event 事件 +|事件名 |说明 |类型 |回调参数 | +|---- |---- |---- |---- | +|input |搜索框输入事件 |emit |- | +|search|搜索触发的事件 |emit |- | +|moreClick|更多按钮点击触发事件 |emit |- | + +## Slot 插槽 + +|名称 |说明 |参数 | +|---- |---- |---- | +|more |more插槽,在mode=more模式下用于存放下拉框内容 |无 | diff --git a/uni_modules/next-tree/changelog.md b/uni_modules/next-tree/changelog.md new file mode 100644 index 0000000..0e31f4b --- /dev/null +++ b/uni_modules/next-tree/changelog.md @@ -0,0 +1,173 @@ +## 1.8.9(2024-06-28) +完善说明文件 +## 1.8.8(2024-06-21) +更新插件 +## 1.8.7(2024-05-08) +fix bug +## 1.8.6(2024-04-07) +功能更新 +## 1.8.5(2024-04-07) +修复bug +## 1.8.3(2024-04-06) +update +## 1.8.2(2024-04-06) +update +## 1.8.1(2024-04-06) +fix bug +## 1.8.0(2024-04-03) +优化 +## 1.7.9(2024-04-03) +优化编辑tree功能 +## 1.7.8(2024-04-02) +超集功能上线 +## 1.7.7(2024-03-26) +增加expandedMode=singe +## 1.7.6(2024-02-27) +修复特殊字符的处理方法 +## 1.7.5(2024-02-26) +增加无子节点的父节点配置 +## 1.7.4(2024-02-05) +修复vue2,语法使用问题 +## 1.7.3(2024-02-05) +修复vue2,插槽不显示bug +## 1.7.2(2024-02-05) +优化大数据的性能 +## 1.7.1(2024-01-25) +优化功能说明 +## 1.7.0(2024-01-24) +增加expandedKeys默认展开项目,配置 +## 1.6.9(2024-01-23) +增加change事件 +## 1.6.8(2024-01-22) +搜索模式下,不再响应展开收起逻辑 +## 1.6.7(2024-01-04) +修复异步加载节点搜索展示bug +## 1.6.6(2023-12-29) +修复next-tree异步加载节点关闭bug +## 1.6.5(2023-12-21) +fix bug +## 1.6.4(2023-12-21) +fix bug +## 1.6.3(2023-12-21) +更新vue2版本说明文档 +## 1.6.2(2023-12-21) +修复说明文档 +## 1.6.1(2023-12-18) +增加empty插槽 +## 1.6.0(2023-12-18) +增加empty插槽 +## 1.5.9(2023-12-15) +修改说明文件 +## 1.5.8(2023-12-15) +修复changeVerify函数单选时,返回参数bug +## 1.5.7(2023-12-14) +修复checkStrictlyModel === 'strong'的bug +## 1.5.6(2023-12-13) +代码优化 +## 1.5.5(2023-12-13) +优化changeVerify的使用 +## 1.5.4(2023-12-12) +修复提示层级问题 +## 1.5.3(2023-12-12) +优化uiMode=page模式下的使用 +## 1.5.2(2023-12-11) +增加uiMode配置,实现页面模式展示 +## 1.5.1(2023-12-06) +更新说明 +## 1.5.0(2023-12-06) +更新插件使用注意事项 +## 1.4.9(2023-12-01) +增加topBar插槽 +## 1.4.8(2023-11-30) +增加changeVerify验证函数,实现change的各种控制 +## 1.4.7(2023-11-30) +增加弹层容器高度可配置 +## 1.4.6(2023-11-28) +修复bug +## 1.4.5(2023-11-28) +修复disabled是,需要显示灰色不可操作 +## 1.4.4(2023-11-28) +增加说明 +## 1.4.3(2023-11-28) +增加主题配置 +## 1.4.2(2023-11-28) +增加异步加载时,子节点说明 +## 1.4.1(2023-11-27) +修复说明bug +## 1.4.0(2023-11-27) +next-tree 全面说明文档 +## 1.3.6(2023-11-27) +增加远程加载loadData,全面实现全功能覆盖 +## 1.3.5(2023-11-27) +增加title的定义 +## 1.3.4(2023-11-27) +增加title支持自定义定制 +## 1.3.3(2023-11-21) +增加搜索模式searchModel=depHighlight模式,从属高亮显示模式 +## 1.3.2(2023-11-20) +修复valueKey设置bug +## 1.3.1(2023-11-17) +增加说明文件,和demo +## 1.3.0(2023-11-17) +修复clear时不支持关联模式的设置 +## 1.2.9(2023-11-17) +增加checkStrictlyModel模式设置,强关联,和弱关联 +## 1.2.8(2023-11-16) +增加next-tree的辅助线模式 +## 1.2.7(2023-11-16) +优化next-tree +## 1.2.6(2023-11-16) +修复搜索时,隐藏未打开的数据 +## 1.2.5(2023-11-16) +修复搜索无法点击,和级联半选不生效问题 +## 1.2.4(2023-11-16) +更新新功能插件使用说明 +## 1.2.3(2023-11-16) +增加插槽模式,只是高ui要求定制 +## 1.2.2(2023-11-15) +修复checkStrictly配置下,子关联父的选择状态 +## 1.2.1(2023-11-15) +增加半选提示功能配置showHalfCheckedTips +## 1.2.0(2023-11-14) +修复disabled配置状态下,父子级联,不需要改变disabled设置项的选择状态 +## 1.1.9(2023-11-13) +增强大数据量体验交互,增加筛选搜索模式 +## 1.1.8(2023-11-13) +增加清除clear和取消cancel事件 +## 1.1.7(2023-11-08) +更新next-tree插件功能清单说明 +## 1.1.6(2023-11-07) +update说明文档 +## 1.1.5(2023-11-07) +update +## 1.1.4(2023-11-07) +更新readme.md说明 +## 1.1.3(2023-11-07) +更新说明demo +## 1.1.2(2023-11-07) +增加子节点按需渲染演示demo +## 1.1.1(2023-11-07) +增加清空功能 +## 1.1.0(2023-11-07) +增加子孙节点按需渲染,扩展本插件支持大数据量渲染; +## 1.0.9(2023-10-26) +增加文件说明 +## 1.0.8(2023-09-14) +增加禁用节点属性配置disabledKey +## 1.0.7(2023-09-06) +增加checkStrictly,实现父子节点关联 +## 1.0.6(2023-09-06) +更新vue2使用过程视图不更新的技术说明 +## 1.0.5(2023-09-06) +修复说明文档 +## 1.0.4(2023-06-19) +修改demo +## 1.0.3(2023-06-19) +更新vue2的使用demo +## 1.0.2(2023-06-19) +修复说明文档 + +## 1.0.1(2023-05-10) +更新说明文件 +## 1.0.0(2023-05-09) +初始化项目 diff --git a/uni_modules/next-tree/components/next-tree/next-tree.vue b/uni_modules/next-tree/components/next-tree/next-tree.vue new file mode 100644 index 0000000..6a65f6c --- /dev/null +++ b/uni_modules/next-tree/components/next-tree/next-tree.vue @@ -0,0 +1,1043 @@ +<template> + <view class="next-tree"> + <view class="next-tree-mask" v-if="uiMode === 'popup'" :class="{'show':showTree}" @tap="_cancel"></view> + <view class="next-tree-cnt" :style="{top: top, height: pageHeight}" :class="{'show':showTree, 'next-tree-cnt-page': uiMode === 'page'}"> + <view v-if="_showTreeBar" class="next-tree-bar"> + <view class="next-tree-bar-cancel" :style="{'color':cancelColor}" hover-class="hover-c" @tap="_cancel">取消</view> + <view class="next-tree-bar-title" :style="{'color':titleColor}">{{customTitle}}</view> + <view class="next-tree-bar-btns"> + <view v-if="['checkbox', 'radio'].indexOf(funcMode) !== -1" class="next-tree-bar-cancel" :style="{'color':cancelColor}" hover-class="hover-c" @tap="_clear">清空</view> + <view v-else-if="funcMode === 'edit'" class="next-tree-bar-cancel" :style="{'color':cancelColor}" hover-class="hover-c" @tap="_revert">还原</view> + <view class="btn-divid"></view> + <view class="next-tree-bar-confirm" :style="{'color':_themeColor}" hover-class="hover-c" @tap="_confirm">确定</view> + </view> + </view> + <!-- #ifdef APP-PLUS--> + <view class="next-tree-view" :style="'top:'+(_showTreeBar?'72rpx':'0rpx')"> + <!-- #endif--> + <!-- #ifdef H5--> + <view class="next-tree-view" style="top: 72rpx"> + <!-- #endif--> + <next-search-more v-if="ifSearch" @search="onSearch" mode="center" placeholder="请输入关键字" :isFixedSearchBtn="false" /> + <slot name="topBar"></slot> + <scroll-view class="next-tree-view-sc" :scroll-y="true"> + <view v-if="_treeList.length"> + <block v-for="(item, index) in _treeList" :key="index"> + <view class="next-tree-item-block" v-if="item.show"> + <view class="next-tree-item" :style="[{ + paddingLeft: item.rank*15 + 'px', + zIndex: item.rank*-1 +50 + }]" + :class="{ + border: border === true, + show: item.show, + last: item.lastRank, + showchild: item.showChild, + open: item.open, + disabled: item.disabled === true + }"> + <block v-if="showAuxiliaryLine"> + <template v-if="item.rank > 1"> + <view :key="i" v-for="i in (item.rank - 1)" :style="{left: (6 * (2*i - 1) + 3 * (i - 1)) + 'px'}" class="parent-horizontal-line"></view> + </template> + <view class="left-line"> + <view v-if="item.lastRank" class="horizontal-line"></view> + </view> + </block> + <view class="next-tree-label" @tap.stop="_treeItemTap(item, index)"> + <image class="next-tree-icon" :src="item.lastRank ? lastIcon : item.showChild ? currentIcon : defaultIcon"></image> + <input @click.stop @tap.stop class="label-input" placeholder="请输入" v-if="funcMode === 'edit' && item.status === 'edit'" v-model="item.name" /> + <rich-text :nodes="getNodes(item.ouputText)" :selectable="false" v-else-if="ifSearch && searchModel==='depHighlight' && keywords"></rich-text> + <slot v-else-if="$slots.label" name="label" :data="_getLabelSlotData(item)"></slot> + <rich-text v-else-if="item.checked && !item.disabled" :nodes="getThemeNodes(item.name)"></rich-text> + <text v-else>{{item.name}}</text> + </view> + <template v-if="['checkbox', 'radio'].indexOf(funcMode) !== -1"> + <view class="next-tree-check" @tap.stop="_treeItemSelect(item, index)" v-if="selectParent === true ? true : item.lastRank"> + <view class="next-tree-check-yes" v-if="item.checked" :class="{'radio':!multiple}" :style="{'border-color': item.disabled ? '#ccc' : _themeColor, 'background-color': item.disabled ? '#ccc' : _themeColor}"> + <view class="next-tree-check-yes-b" :style="{'background-color':item.disabled ? '#ccc' : _themeColor}"> + <text v-if="item.checked" class="icon-text">✔</text> + </view> + </view> + <view class="next-tree-check-no" v-else :class="{'radio':!multiple}" :style="{'border-color': item.disabled ? '#ccc' : _themeColor}"> + <text v-if="showHalfChecked(item) && showHalfCheckedTips" :style="{'color': item.disabled ? '#ccc' : _themeColor, 'font-weight': 'blod', 'font-size': '10px'}" class="icon-text">一</text> + </view> + </view> + </template> + <template v-else-if="funcMode === 'edit'"> + <text v-if="item.status === 'loading'" :style="{'color': '#ccc'}" class="iconfont-loading icon-btn"></text> + <view v-else> + <text @click="_complete(item)" v-if="item.status === 'edit'" :style="{'color': item.disabled ? '#ccc' : _themeColor}" class="iconfont icon-btn"></text> + <template v-else> + <text @click="_editItem(item)" :style="{'color': item.disabled ? '#ccc' : _themeColor}" class="iconfont icon-btn"></text> + <text @click="_addSubItem(item)" :style="{'color': item.disabled ? '#ccc' : '#333'}" class="iconfont icon-btn"></text> + <text @click="_addSameItem(item)" :style="{'color': item.disabled ? '#ccc' : '#333'}" class="iconfont icon-btn"></text> + </template> + <text @click="_delItem(item)" :style="{'color': item.disabled ? '#ccc' : '#ff4d4f'}" class="iconfont icon-btn"></text> + </view> + + </template> + </view> + </view> + </block> + </view> + <view v-else> + <slot v-if="$slots.empty" name="empty"></slot> + <view class="empty" v-else><text>暂无数据</text></view> + </view> + <view v-if="ifSearch" style="height: 80rpx"></view> + <slot name="bottomBar"></slot> + </scroll-view> + </view> + </view> + <view class="fixed-bottom-bar"><slot name="fixedBottomBar"></slot></view> + </view> +</template> + +<script> +export default { + name: "next-tree", + props: { + uiMode: { + type: String, + default: 'popup' // popup(弹窗), page(页面) + }, + funcMode: { + type: String, + default: 'radio' // display(展示模式), edit(编辑模式), checkbox(多选模式), radio(单选模式) + }, + treeData: { + type: Array, + default: function() { + return [] + } + }, + valueKey: { + type: String, + default: 'id' + }, + labelKey: { + type: String, + default: 'label' + }, + disabledKey: { + type: String, + default: 'disabled' + }, + childrenKey: { + type: String, + default: 'children' + }, + title: { + type: [String, Function], + default: '' + }, + selectParent: { //是否可以选父级 + type: Boolean, + default: false + }, + foldAll: { //折叠时关闭所有已经打开的子集,再次打开时需要一级一级打开 + type: Boolean, + default: false + }, + themeColor: { // 主题颜色 + type: String, + default: '#f9ae3d' // #f9ae3d + }, + cancelColor: { // 取消按钮颜色 + type: String, + default: '' // #757575 + }, + titleColor: { // 标题颜色 + type: String, + default: '' // #757575 + }, + currentIcon: { // 展开时候的ic + type: String, + default: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAABRCAYAAACqj0o2AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoV2luZG93cykiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MEQ0QTM0MzQ1Q0RBMTFFOUE0MjY4NzI1Njc1RjI1ODIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MEQ0QTM0MzU1Q0RBMTFFOUE0MjY4NzI1Njc1RjI1ODIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDowRDRBMzQzMjVDREExMUU5QTQyNjg3MjU2NzVGMjU4MiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDowRDRBMzQzMzVDREExMUU5QTQyNjg3MjU2NzVGMjU4MiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PidwepsAAAK0SURBVHja7JxbTsJAFIYHww7ciStgCeoGvGxAiOsgURegoL5720AXYLiIr0aJviq3Zx3PhIEnKG3ndtr+f3KixrSUj/ZjzjClIqUUiFm2gAAQAREQEUAEREAERAQQAREQAREBREAEREBEEqa67h9RFDWllDv0awWYlqlQHmu1WjMRRMoV1QFttA12y3xRtdNczq8EsE4/f8FumX2q77ROvNXk8UGMEKdUz6tYJHljaZAbuyUH+UR1to5BEohTuqwPCeS4pAA/qY6o/kyHOAMCeRK3owJnj+rH1jjxhqpVsstaebCz6TmnHWyXyY+xHjSBWBY/bvSgadtXBj9u9KCN3rnIfkzkQVsTEEX0Y2IP2oKo/HhMICcFAThUcwVZNGU6FdbX/XURzkbVF4+ybGhjPrFdgP66QdXNurGtSdk6Xdb9nAJ8oDo3OQlsQZzkdPw41ONBo6vI5scDefRjZg+6gpg3Pxp50CXEvPjR2IOuIXL3oxUPuobI3Y9WPOgDIlc/WvOgL4iL/vqFCcD7LH0xB4hj7cfQ/fWH9qCT+FhG0tN+DBk1PzjOM0SVllixcsBT1AvYc/kAPhc0hRg/3uvxoCgKRN9+dOrBUBB9+9GpB0NC9OVH5x4MDdG1H714kANEV3705kEOEBf9dcPi/lQnsuvLg1wgSu3Ha0v7Uh4MMgUXeuG71H407a+VBy9CPQkOdw+MtB+nGbd/D+FBbhBNxo9SjwcngJjNj0E9yBFiFj8G9SBXiGn8GNyDnCEm8SMLD3KHGOdHNh7kDjHOj2w8mAeIi/5arX+c6b/fxHz9oADEdGdjR/fXCw/OOB5oVfCOgnepz8IB14PMw03jCmTE+QBx5z0gAmKSqK9OUF+hcAeIhu/QYr4Qie8rjW83hhMBERARQAREQAREBBABERCLnH8BBgA+TQI7U4t53AAAAABJRU5ErkJggg==' + }, + defaultIcon: { // 折叠时候的ic + type: String, + default: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFEAAABRCAYAAACqj0o2AAACE0lEQVR4Xu3c200DMRCF4XEltJAOkEugA+ggpUAHoQMqiFMCdEAJUMEiS4mEELlIO7bPOeN9i6K1rG/952myyea1WiCtXmEuYBPR4RBMxInoIOCwhOtJLKVszWyXc/5y2BvNEq6I+/3+kFK6M7OHnPM7jcLKjbZAvD/uaZtzflm5P4rbWyJWgDcze1LPuzVihfxUz7sH4ilJ2bx7Isrm3RtRMu8RiHJ5j0SUyXs0okTeCIj0eSMh0uaNhkiZNyIiXd7IiDR5oyNS5M2ACJ83EyJs3myIkHkzIsLlzYwIkzc7IkTeCojD81ZCHJa3GuKQvBURu+etjNgtb3XELnlHQGyedyTEZnlHQ2ySd0RE97wjI7rlHR3RJe+JeIrbLOecD6ePpZQ6W1kn2epo4MUrPOKyLN8ppYq1+y1VStncOjIdGnFZlo+U0uOtWOeOY2TE12Ouq//pEA7xXL7XfvcufR8K0Svfv6CREN3yDYfYIt9QiK3yjYTYLF95xB75SiP2ylcZsVu+cogj8pVCHJWvEuKwfOkREfKlRkTJlxkRJl86RMR8qRBR82VChM0XHpEhX2hElnyREWnyhUNkzBcKkTVfJETafIcjKuQ7FFEl35GIMvl2R1TMtyuiar49EWXzbY5oZpv/hibXTF2h3+s60FRKeT6+3TjMS3nrA3ZFRD8xrfY3ER1kJ+JEdBBwWGKeRAfEH1wS5WFZSDB/AAAAAElFTkSuQmCC' + }, + lastIcon: { // 没有子集的ic + type: String, + default: '' + }, + border: { // 是否有分割线 + type: Boolean, + default: false + }, + checkStrictly: { // 只有在funcMode为checkbox状态下生效; 状态下节点选择完全受控(父子节点选中状态不再关联) + type: Boolean, + default: false + }, + checkStrictlyModel: { // 关联模式 weak: 弱关联;strong: 强关联 + type: String, + default: 'weak' + }, + showHalfCheckedTips: { // 只有在funcMode为checkbox, checkStrictly为false状态下生效; 父子节点选中状态不再关联,显示半选提示 + type: Boolean, + default: true + }, + ifSearch: { // 是否开启search模式 + type:Boolean, + default: true + }, + searchModel: { // 搜索模式配置 + type: String, + default:'common' // depHighlight: 从属高亮;common: 一般;remote:远程 + }, + showAuxiliaryLine: { // 辅助线模式 + type:Boolean, + default: false + }, + loadData: { + type: Function + }, + height: { + type: Number, + default: 500 + }, + changeVerify: { + type: Function + }, + expandedKeys: { // (Controlled) Specifies the keys of the expanded treeNodes + type: Array, + default: () => ([]) + }, + expandedMode: { // common: 一般模式;singe: 单一模式; + type: String, + default: 'common' + }, + pageHeight:{ + type: String, + default: '100%' + }, + }, + data() { + return { + showTree: false, + treeList: [], + currentTreeData: [], + selectIndex: -1, + keywords: '', + nodeInitContrl: {}, + top: '', + initNum: 1 + } + }, + computed: { + _showTreeBar() { + return this.uiMode === 'popup' + }, + _themeColor() { + return this.themeColor || '#f9ae3d' + }, + _treeList () { + if(this.ifSearch && this.keywords) { + return this.treeList.filter(item => { + return (item.name && item.name.indexOf(this.keywords) !== -1) + }).map(item => { + const o = JSON.parse(JSON.stringify(item)); + if(o.showChild === false) { + o.showChild = true; + } + if(o.show === false) { + o.show = true; + } + return o + }) + } else { + return this.treeList + } + }, + customTitle() { + if(typeof this.title === 'function') { + return this.title(this._getCheckedParams()); + } else { + return this.title + } + }, + multiple() { + if(this.funcMode === 'checkbox') { + return true + } else if(this.funcMode === 'radio') { + return false + } else { + return true + } + } + }, + methods: { + _show() { + this.showTree = true + }, + _hide() { + this.showTree = false + }, + _cancel() { + this._hide() + this.$emit("cancel", ''); + }, + _confirm() { + // 处理所选数据 + let rt = this._getCheckedParams(); + this._hide() + + this.$emit("confirm", rt); + }, + _getLabelSlotData(item) { + const _it = this.getItemFromTreeData(this.currentTreeData, item.id); + const it = Object.assign({}, _it); + delete it[this.childrenKey]; + return it + }, + _getCheckedParams() { + // 处理所选数据 + let rt = [], + obj = {}; + this.treeList.forEach((v, i) => { + if (this.treeList[i].checked) { + obj = {} + obj.parents = this.treeList[i].parents + obj = Object.assign(obj, this.treeList[i].source) + // 移除子元素 + // delete obj.children + rt.push(obj) + } + }); + return rt; + }, + _addSubItem(item) { + if(item.disabled) return; + const it = Object.assign({}, item); + if(item.lastRank) { + item.lastRank = false; + item.showChild = true; + } + this.$nextTick(() => { + this.initNum++; + const parentId = item.parentId.concat([]); + const parents = item.parents.concat([]); + parentId.push(item.id); + parents.push(item); + it.disabled = false; + it.rank = it.rank + 1; + it.id = `next-tree-${this.initNum}`; + it.parentId = [...parentId]; + it.parents = [...parents]; + it.show = true; + it.showChild = false; + it.open = false; + it.name = ''; + it.status = 'edit'; + it.source = {}; + it.hideArr = []; + it.lastRank = true; + let index = -1; + for (let i = this.treeList.length - 1; i >= 0; i--) { + if(this.treeList[i].id === item.id) { + index = i; + break; + } + } + if(index !== -1) { + this.treeList.splice(index + 1, 0, it); + } + }) + }, + _addSameItem(item) { + if(item.disabled) return; + const it = Object.assign({}, item); + let index = -1; + for (let i = this.treeList.length - 1; i >= 0; i--) { + if(this.treeList[i].id === item.id || this.treeList[i].parentId.indexOf(item.id) !== -1) { + index = i; + break; + } + } + this.initNum++; + it.id = `next-tree-${this.initNum}`; + it.source = {}; + it.hideArr = []; + it.name = ""; + it.status = 'edit'; + if(index !== -1) { + this.treeList.splice(index + 1, 0, it); + } + }, + async _complete(item) { + if (item.name) { + item.status = 'loading'; + if(item.operateCallback) { + await item.operateCallback('complete', item); + await this.$nextTick(); + } + item.status = ''; + } else { + uni.showToast({ + title: '请先完善内容', + icon: 'none' + }) + } + }, + _editItem(item) { + if(item.disabled) return; + item.status = 'edit'; + }, + _revert() { + this.uiModeInit(); + }, + async _delItem(item) { + if(item.disabled) return; + item.status = 'loading'; + if(item.operateCallback) { + await item.operateCallback('delete', item); + await this.$nextTick(); + } + this.delItemFunc(item); + }, + delItemFunc(item) { + const id = item && item.id ? item.id : ''; + const ids = []; + this.treeList.map((it, index) => { + if(it.id === id) { + ids.push(index); + } else if(it.parentId.indexOf(id) !== -1) { + ids.push(index); + } + }); + ids.sort((a, b) => b - a); + ids.forEach(index => { + this.treeList.splice(index, 1); + }); + }, + checkedFunc(values, state = true) { + if(values instanceof Array) { + values.map(id => { + const item = this.treeList.find(it => it.id === id); + if(item) { + item.checked = !!state + } + }) + } else { + const _item = this.treeList.find(it => it.id === values); + if(_item) { + _item.checked = !!state + } + } + }, + getRenderTreeList(list = [], rank = 0, parentId = [], parents = []) { + const treeList = []; + list.forEach(item => { + const halfChecked = this.getHalfCheckedFormTreeData(item); + let ouputText = ''; + if(this.searchModel === 'depHighlight') { + if(parents && parents.length) { + ouputText = parents.map(item => item[this.labelKey]).join(' > '); + ouputText = ouputText + ' > ' + item[this.labelKey]; + } else { + ouputText = item[this.labelKey]; + } + } + const bool1 = this.expandedKeys.indexOf(item[this.valueKey]) !== -1; + const len = parentId.length; + const bool2 = len > 0 ? this.expandedKeys.indexOf(parentId[len - 1]) !== -1 : bool1; + treeList.push({ + id: item[this.valueKey], + name: item[this.labelKey], + source: item, + parentId, // 父级id数组 + parents, // 父级id数组 + rank, // 层级 + showChild: bool1, //子级是否显示 + open: bool1, //是否打开 + show: (bool1 || bool2) || rank === 0, // 自身是否显示 + hideArr: [], + ouputText, + orChecked: item.checked ? item.checked : false, + checked: item.checked ? item.checked : false, + halfChecked, + disabled: this.disabledKey && item[this.disabledKey] === true, + status: '', + operateCallback: (typeof item.operateCallback) === 'function' ? item.operateCallback : undefined + }) + if(bool1) { + this.nodeInitContrl[item[this.valueKey]] = true; + } else { + this.nodeInitContrl[item[this.valueKey]] = undefined; + } + if ( + (Array.isArray(item[this.childrenKey]) && item[this.childrenKey].length > 0) || + (this.loadData && Array.isArray(item[this.childrenKey]) &&item[this.childrenKey].length === 0) + ) { + let parentid = [...parentId], + parentArr = [...parents], + childrenid = []; + delete parentArr.children + parentid.push(item[this.valueKey]); + parentArr.push({ + [this.valueKey]: item[this.valueKey], + [this.labelKey]: item[this.labelKey], + }) + } else if(item[this.childrenKey] === null) { + treeList[treeList.length - 1].lastRank = false; + } else { + treeList[treeList.length - 1].lastRank = true; + } + }) + return treeList; + }, + //扁平化树结构 + _renderTreeList(list = [], rank = 0, parentId = [], parents = []) { + list.forEach(item => { + const halfChecked = this.getHalfCheckedFormTreeData(item); + let ouputText = ''; + if(this.searchModel === 'depHighlight') { + if(parents && parents.length) { + ouputText = parents.map(item => item[this.labelKey]).join(' > '); + ouputText = ouputText + ' > ' + item[this.labelKey]; + } else { + ouputText = item[this.labelKey]; + } + } + const bool1 = this.expandedKeys.indexOf(item[this.valueKey]) !== -1; + const len = parentId.length; + const bool2 = len > 0 ? this.expandedKeys.indexOf(parentId[len - 1]) !== -1 : bool1; + this.treeList.push({ + id: item[this.valueKey], + name: item[this.labelKey], + source: item, + parentId, // 父级id数组 + parents, // 父级id数组 + rank, // 层级 + showChild: bool1, //子级是否显示 + open: bool1, //是否打开 + show: (bool1 || bool2) || rank === 0, // 自身是否显示 + hideArr: [], + ouputText, + orChecked: item.checked ? item.checked : false, + checked: item.checked ? item.checked : false, + halfChecked, + disabled: this.disabledKey && item[this.disabledKey] === true, + status: '', + operateCallback: (typeof item.operateCallback) === 'function' ? item.operateCallback : undefined + }) + if(bool1) { + this.nodeInitContrl[item[this.valueKey]] = true; + } else { + this.nodeInitContrl[item[this.valueKey]] = undefined; + } + if ( + (Array.isArray(item[this.childrenKey]) && item[this.childrenKey].length > 0) || + (this.loadData && Array.isArray(item[this.childrenKey]) &&item[this.childrenKey].length === 0) + ) { + let parentid = [...parentId], + parentArr = [...parents], + childrenid = []; + delete parentArr.children + parentid.push(item[this.valueKey]); + parentArr.push({ + [this.valueKey]: item[this.valueKey], + [this.labelKey]: item[this.labelKey], + }) + this._renderTreeList(item[this.childrenKey], rank + 1, parentid, parentArr); + } else if(item[this.childrenKey] === null) { + this.treeList[this.treeList.length - 1].lastRank = false; + } else { + this.treeList[this.treeList.length - 1].lastRank = true; + } + }) + }, + // 处理默认选择 + _defaultSelect() { + this.treeList.forEach((v, i) => { + if (v.checked) { + this.treeList.forEach((v2, i2) => { + if (v.parentId.toString().indexOf(v2.parentId.toString()) >= 0) { + v2.show = true + if (v.parentId.includes(v2.id)) { + v2.showChild = true; + v2.open = true; + } + } + }) + } + }) + }, + // 点击 + async _treeItemTap(item, _index) { + const index = this.treeList.findIndex(it =>it.id === item.id); + if (item.lastRank === true) { + if (item.disabled === true) return + if (['checkbox', 'radio'].indexOf(this.funcMode) === -1) return + //点击最后一级时触发事件 + this.treeList[index].checked = !this.treeList[index].checked; + + if(this.changeVerify && (typeof this.changeVerify === 'function')) { + const current = Object.assign({}, item.source); + current.checked = item.checked; + const tip = this.changeVerify(current, this.multiple ? this._getCheckedParams() : [current]); + if(tip) { + this.treeList[index].checked = !this.treeList[index].checked; + uni.showToast({ + title: tip, + icon: 'none' + }); + return + } + }; + this.treeList[index].halfChecked = false; + if(this.multiple && !this.checkStrictly && this.showHalfCheckedTips) { + this.updateHalfChecked(index); + } else if(this.multiple && this.checkStrictly) { + this.updateParentChecked(index); + } + this._fixMultiple(index); + this.$emit("change", this._getCheckedParams()); + return; + } else if(this.ifSearch && this.keywords) { + // 搜索模式下不处理展开收起逻辑 + return + } + // loadData实现 + const isLoadData = this.loadData && !this.nodeInitContrl[item.id]; + if(isLoadData) { + uni && uni.showLoading({ title: "请稍后..." }); + const newChild = await this.loadData({$type: 'nodeLoad', source: this.treeList[index].source}); + // 为了保证treeData数据的完整性,异步加载的数据需要添加到treeData上; + const treeItem = this.getItemFromTreeData(this.currentTreeData, item.id); + treeItem[this.childrenKey] = newChild && newChild.length ? newChild : undefined; + const parentId = item.parentId || []; + const lists = this.getRenderTreeList(newChild || [], item.rank + 1, parentId.concat([item.id]), [{[this.valueKey]: item[this.valueKey],[this.labelKey]: item[this.labelKey]}]); + this.nodeInitContrl[item.id] = true; + this.treeList.splice(index+1, 0, ...lists); + } + const childLen = this.treeList.filter(it => it.parentId.includes(item.id)).length; + if(!isLoadData && childLen > 50) { + uni && uni.showLoading({ title: "请稍后..." }); + } + let list = this.treeList; + let id = item.id; + item.showChild = !item.showChild; + item.open = item.showChild ? true : !item.open; + list.forEach((childItem, i) => { + if (item.showChild === false) { + //隐藏所有子级 + if (!childItem.parentId.includes(id)) { + return; + } else { + if (!this.foldAll) { + if (childItem.lastRank !== true && !childItem.open) { + childItem.showChild = false; + } + // 为隐藏的内容添加一个标记 + if (childItem.show) { + childItem.hideArr[item.rank] = id + } + } else { + if (childItem.lastRank !== true) { + childItem.showChild = false; + } + } + childItem.show = false; + } + } else { + // 打开子集 + if (childItem.parentId[childItem.parentId.length - 1] === id) { + childItem.show = true; + } + + // 打开被隐藏的子集 + if (childItem.parentId.includes(id) && !this.foldAll) { + if (childItem.hideArr[item.rank] === id) { + childItem.show = true; + if (childItem.open && childItem.showChild) { + childItem.showChild = true + } else { + childItem.showChild = false + } + childItem.hideArr[item.rank] = null + } + } else if(this.expandedMode === 'singe' && !childItem.parentId.includes(id)) { + if (childItem.id !== id) { + const bool1 = item.parentId.some(id => { + return (childItem.parentId && childItem.parentId.indexOf(id) !== -1) || childItem.rank === 0; + }); + const childItemParentId = [...childItem.parentId]; + const _id = childItemParentId ? childItemParentId.pop() : ''; + const nodeList = [item, { parentId: childItemParentId.length ? childItemParentId : [] }]; + if(!childItem.lastRank) { + if(item.parentId.indexOf(childItem.id) === -1) { + childItem.showChild = false; + } + + if(!bool1 && !this.isSiblingNode([item, childItem])) { + childItem.show = false; + } else if(childItem.rank !== 0 && _id !== id && this.isSiblingNode(nodeList)) { + childItem.show = false; + } else if (childItem.rank !== 0 && _id !== id && !this.isSiblingNode(nodeList) && this.isParentSiblingNode(nodeList)) { + childItem.show = false; + } + } else { + if(!this.isSiblingNode([item, childItem]) && !bool1) { + childItem.show = false; + } else if(_id !== id && this.isSiblingNode(nodeList)) { + childItem.show = false; + } else if (_id !== id && !this.isSiblingNode(nodeList) && this.isParentSiblingNode(nodeList)) { + childItem.show = false; + } + } + } + } + } + }); + setTimeout(() => { + uni && uni.hideLoading() + }) + }, + isSiblingNode(targetArr = []) { + const target1 = targetArr && targetArr.length ? targetArr[0] : {}; + let target1Id = ''; + if(target1.parentId && target1.parentId.length) { + target1Id = target1.parentId[target1.parentId.length - 1] + } + return targetArr.every(item => { + if(item && item.parentId && item.parentId.length) { + return target1Id === item.parentId[item.parentId.length - 1] + } else { + return target1Id === '' + } + }) + }, + isParentSiblingNode(targetArr = []) { + const target1 = targetArr && targetArr.length ? targetArr[0] : {}; + let target1Id = ''; + if(target1.parentId && target1.parentId.length) { + target1Id = target1.parentId[target1.parentId.length - 1] + } + return targetArr.every(item => { + if(item && item.parentId && item.parentId.length) { + return item.parentId.some(id => id === target1Id) && target1Id !== ''; + } else { + return target1Id === ''; + } + }) + }, + getThemeNodes(text) { + const _text = (text || '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const regex = new RegExp(`(${text || ''})`, 'gi'); + return text ? text.replace(regex, `<span style="color: ${this._themeColor}">$1</span>`) : ''; + }, + getNodes(ouputText) { + if(this.keywords && ouputText) { + const key = (this.keywords || '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + const regex = new RegExp(`(${key})`, 'gi'); + return ouputText.replace(regex, `<span style="color: ${this._themeColor}">$1</span>`); + } + return ouputText + }, + getHalfCheckedFormTreeData(item) { + if (this.checkStrictly) { + return false; + } else if (!this.showHalfCheckedTips) { + return false + } else { + if(item[this.childrenKey] && item[this.childrenKey].length) { + return item[this.childrenKey].some(it => { + if(it.checked === true) { + return true; + } else if(it[this.childrenKey] && it[this.childrenKey].length) { + return this.getHalfCheckedFormTreeData(it); + } else { + return false; + }; + }); + } else { + return false; + } + } + }, + getItemFromTreeData(treeData, id) { + if(id) { + let item = null; + (treeData || []).some(it => { + if(it[this.valueKey] === id) { + item = it + return true + } else if(it[this.childrenKey] && it[this.childrenKey].length) { + item = this.getItemFromTreeData(it[this.childrenKey], id) + return !!item + } else { + return false + } + }); + return item + }; + return null + }, + _treeItemSelect(item, _index) { + const index = this.treeList.findIndex(it =>it.id === item.id); + if (item.disabled === true) return + this.treeList[index].checked = !this.treeList[index].checked; + + if(this.changeVerify && (typeof this.changeVerify === 'function')) { + const current = Object.assign({}, item.source); + current.checked = item.checked; + const tip = this.changeVerify(current, this.multiple ? this._getCheckedParams() : [current]); + if(tip) { + this.treeList[index].checked = !this.treeList[index].checked; + uni.showToast({ + title: tip, + icon: 'none' + }); + return + } + }; + this.treeList[index].halfChecked = false; + if (this.multiple && this.checkStrictly) { + if(!item.lastRank) { + const source = item.source || {}; + const children = source[this.childrenKey] || []; + const checkedKeyList = this.getChildrenKeys(children); + this.treeList.forEach((v, i) => { + if(checkedKeyList.indexOf(v.id) !== -1) { + if(this.checkStrictlyModel === 'weak') { + if(!this.treeList[i].disabled) { + this.treeList[i].checked = this.treeList[index].checked + } + } else if(this.checkStrictlyModel === 'strong') { + this.treeList[i].checked = this.treeList[index].checked + } + } + }) + } + this.updateParentChecked(index) + } else if(this.multiple && !this.checkStrictly && this.showHalfCheckedTips) { + this.updateHalfChecked(index); + } else { + this._fixMultiple(index); + } + + this.$emit("change", this._getCheckedParams()); + }, + updateParentChecked(index) { + const parentId = (this.treeList[index].parentId || []).concat([]).reverse(); + if(parentId && parentId.length) { + parentId.map(id => { + const parentTreeDataItem = this.getItemFromTreeData(this.currentTreeData, id); + const childrenIds = (parentTreeDataItem[this.childrenKey] || []).map(item => item[this.valueKey]); + const bool = this.treeList + .filter(it => childrenIds.indexOf(it.id) !== -1) + .every(it => it.checked === true); + + const _bool = this.treeList + .filter(it => childrenIds.indexOf(it.id) !== -1) + .every(it => it.checked === false); + + const parentItem = this.treeList.find(it => it.id === id); + if(parentItem) { + if (this.checkStrictlyModel === 'weak') { + if(bool && !parentItem.disabled) { + parentItem.checked = true; + } else if(_bool && !parentItem.disabled) { + parentItem.checked = false; + } + } else if(this.checkStrictlyModel === 'strong') { + if(bool) { + parentItem.checked = true; + } else { + parentItem.checked = false; + } + } + } + }) + } + }, + updateHalfChecked(index) { + const _parentId = this.treeList[index].parentId || []; + const parentId = _parentId.concat([]).reverse(); + if(parentId && parentId.length) { + parentId.map(id => { + const parentTreeDataItem = this.getItemFromTreeData(this.currentTreeData, id); + const childrenIds = (parentTreeDataItem[this.childrenKey] || []).map(item => item[this.valueKey]); + + const bool = this.treeList + .filter(it => childrenIds.indexOf(it.id) !== -1) + .every(it => it.checked === false && it.halfChecked === false); + + const _bool = this.treeList + .filter(it => childrenIds.indexOf(it.id) !== -1) + .some(it => it.checked === true || it.halfChecked === true); + + const parentItem = this.treeList.find(it => it.id === id); + if(parentItem) { + if(!parentItem.checked) { + if(bool) { + parentItem.halfChecked = false + } else if (_bool) { + parentItem.halfChecked = true + } else { + parentItem.halfChecked = false + } + } + } + }) + } + if(this.treeList[index].checked == false) { + const source = this.treeList[index].source || {}; + const children = source[this.childrenKey] || []; + const checkedKeyList = this.getChildrenKeys(children); + const bool = this.treeList.filter(item => checkedKeyList.indexOf(item.id) !== -1).some(item => item.checked); + if(bool) { + this.treeList[index].halfChecked = true; + } + } + }, + showHalfChecked(item) { + if(this.multiple && !this.checkStrictly && item.halfChecked === true) { + return true + } else { + return false + } + }, + getChildrenKeys(children) { + let keys = []; + (children || []).map(item => { + keys.push(item[this.valueKey]) + if (item[this.childrenKey] && item[this.childrenKey].length) { + keys = keys.concat(this.getChildrenKeys(item[this.childrenKey])) + } + }) + return keys + }, + // 处理单选多选 + _fixMultiple(index) { + if (!this.multiple) { + // 如果是单选 + this.treeList.forEach((v, i) => { + if (i != index) { + this.treeList[i].checked = false + } else { + this.treeList[i].checked = true + } + }) + } + }, + // 重置数据 + _reTreeList() { + this.treeList.forEach((v, i) => { + this.treeList[i].checked = v.orChecked + }) + }, + _initTree(){ + this.treeList.length = 0; + if(this.loadData) { + this.currentTreeData = JSON.parse(JSON.stringify(this.treeData)); + } else { + this.currentTreeData = this.treeData; + } + this._renderTreeList(this.currentTreeData); + this.$nextTick(() => { + this._defaultSelect(); + }) + }, + _clear() { + this.treeList.map(item => { + if(this.multiple && this.checkStrictly) { + if(this.checkStrictlyModel === 'strong') { + item.checked = false; + } else if(this.checkStrictlyModel === 'weak') { + if(!item.disabled) { + item.checked = false; + }; + } else { + item.checked = false; + } + } else { + if(!item.disabled) { + item.checked = false; + } + }; + + item.halfChecked = false; + }) + this.$emit("change", this._getCheckedParams()); + this.$emit("clear"); + }, + async onSearch(val) { + if(this.searchModel === 'remote') { + if(this.loadData) { + if(val) { + const newChild = await this.loadData({$type: 'remoteSearch', source: val}); + const lists = this.getRenderTreeList(newChild); + this.treeList = [...lists]; + } else { + this._initTree(); + } + } else { + uni.showToast({ + title: "使用远程搜索模式,需要配置loadData函数;", + icon: 'none' + }) + } + } else { + this.keywords = val; + } + }, + initUiModePopup(watched) { + uni.getSystemInfo({ + success: (res) => { + this.top = (res.windowHeight - this.height) + 'px'; + } + }); + watched && watched(); + watched = this.$watch(() => this.showTree, (bool) => { + if(bool) { + this._initTree(); + } else { + this.$nextTick(() => { + setTimeout(() => { + this.treeList.length = 0; + this.nodeInitContrl = {}; + }) + }) + } + }, {immediate: true}); + }, + initUiModePage(watched) { + this.top = '0px'; + watched && watched(); + watched = this.$watch(() => this.treeData, () => { + this.treeList.length = 0; + this.nodeInitContrl = {}; + this.$nextTick(() => { + this._initTree(); + }); + }, {immediate: true, deep: true}) + this.$nextTick(() => { + this.showTree = true; + }); + }, + uiModeInit() { + let watched = null; + if(this.uiMode === 'popup') { + this.initUiModePopup(watched); + } else if (this.uiMode === 'page') { + this.initUiModePage(watched); + } else { + this.initUiModePopup(watched); + } + } + }, + mounted() { + console.log('----------next-tree组件完成挂载demo------------') + this.uiModeInit(); + } +} +</script> + +<style scoped> +@import "./style.css"; +</style> diff --git a/uni_modules/next-tree/components/next-tree/style.css b/uni_modules/next-tree/components/next-tree/style.css new file mode 100644 index 0000000..3ae61fc --- /dev/null +++ b/uni_modules/next-tree/components/next-tree/style.css @@ -0,0 +1,272 @@ +@font-face { + font-family: 'iconfont'; + src: url('//at.alicdn.com/t/c/font_4110624_qs48wckazsh.ttf?t=1712479573821') format('truetype'); +} +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.iconfont { + font-family: iconfont; + font-style: normal; +} +.iconfont-loading { + font-family: iconfont; + display: inline-block; + font-style: normal; + animation: spin 1s linear infinite; +} +.next-tree-mask { + position: fixed; + top: 0rpx; + right: 0rpx; + bottom: 0rpx; + left: 0rpx; + z-index: 997; + background-color: rgba(0, 0, 0, 0.6); + opacity: 0; + transition: all 0.3s ease; + visibility: hidden; +} +.next-tree-mask.show { + visibility: visible; + opacity: 1; +} +.next-tree-cnt { + position: fixed; + top: 0rpx; + right: 0rpx; + bottom: 0rpx; + left: 0rpx; + z-index: 997; + top: 360rpx; + transition: all 0.3s ease; + transform: translateY(100%); +} +.next-tree-cnt.next-tree-cnt-page { + transition: none; +} +.next-tree-cnt.show { + transform: translateY(0); +} +.next-tree-bar { + background-color: #fff; + height: 72rpx; + padding-left: 20rpx; + padding-right: 20rpx; + display: flex; + justify-content: space-between; + align-items: center; + box-sizing: border-box; + border-bottom-width: 1rpx !important; + border-bottom-style: solid; + border-bottom-color: #f5f5f5; + font-size: 32rpx; + color: #757575; + line-height: 1; +} +.next-tree-bar-btns { + display: inline-block; + display: flex; + flex-direction: row; +} +.btn-divid { + display: inline-block; + width: 1px; + margin: 0 10px; + background-color: #ccc; +} +.next-tree-bar-confirm { + color: #f9ae3d; +} +.next-tree-view { + position: absolute; + top: 0rpx; + right: 0rpx; + bottom: 0rpx; + left: 0rpx; + top: 72rpx; + background-color: #fff; + padding-top: 20rpx; + padding-right: 20rpx; + padding-bottom: 20rpx; + padding-left: 20rpx; +} +.next-tree-view-sc { + height: 100%; + overflow: hidden; +} +.next-tree-view-sc .empty { + text-align: center; + color: #757575; + padding: 30rpx; +} +.next-tree-item-block { + +} +.next-tree-item { + display: flex; + justify-content: space-between; + align-items: center; + font-size: 26rpx; + color: #757575; + line-height: 1; + height: 0; + opacity: 0; + transition: 0.2s; + position: relative; + overflow: hidden; +} +.next-tree-item .icon-btn { + font-size: 30rpx; + margin-right: 20rpx; +} +.next-tree-item .left-line { + position: relative; + width: 1rpx; + height: 100%; + box-sizing: border-box; +} +.next-tree-item .left-line::before { + position: absolute; + content: ""; + width: 1rpx; + height: 100%; + background-color: rgba(204,204,204,0.9); + box-sizing: border-box; + + left: -18rpx; +} +.next-tree-item .parent-horizontal-line { + width: 1rpx; + height: 100%; + position: absolute; + top: 0; + left: 0rpx; + box-sizing: border-box; + background-color: rgba(204,204,204,0.9); +} +.next-tree-item .left-line .horizontal-line { + width: 20rpx; + height: 1rpx; + position: absolute; + top: 40rpx; + left: 0rpx; + background-color: rgba(204,204,204,0.9); + box-sizing: border-box; +} + +.next-tree-item.show { + min-height: 80rpx; + margin-top: 10rpx; + height: 100%; + opacity: 1; +} +.next-tree-item.showchild:before { + transform: rotate(90deg); +} +.next-tree-item.border { + border-bottom: 1rpx solid rgba(204,204,204,0.2); +} +.next-tree-item.last:before { + opacity: 0; +} +.next-tree-item.disabled { + color: #ccc!important; +} + +.next-tree-icon { + width: 26rpx; + height: 26rpx; + margin-right: 8rpx; +} +.next-tree-label { + flex: 1; + display: flex; + align-items: center; + height: 100%; + line-height: 1.2; +} +.next-tree-label .label-input { + border: 1rpx solid #f0f0f0; + border-radius: 10rpx; + width: 100%; + padding: 12rpx 18rpx; + margin-right: 30rpx; +} +.next-tree-check { + width: 40px; + height: 40px; + display: flex; + justify-content: center; + align-items: center; +} +.next-tree-check-yes, +.next-tree-check-no { + width: 20px; + height: 20px; + border-top-left-radius: 20%; + border-top-right-radius: 20%; + border-bottom-right-radius: 20%; + border-bottom-left-radius: 20%; + border-top-width: 1rpx; + border-left-width: 1rpx; + border-bottom-width: 1rpx; + border-right-width: 1rpx; + border-style: solid; + border-color: #f9ae3d; + display: flex; + justify-content: center; + align-items: center; + box-sizing: border-box; +} +.next-tree-check-yes-b { + border-top-left-radius: 20%; + border-top-right-radius: 20%; + border-bottom-right-radius: 20%; + border-bottom-left-radius: 20%; + background-color: #f9ae3d; + color: #fff; +} +.next-tree-check-yes-b .icon-text { + font-size: 14px; + font-weight: normal; + font-family: uicon-iconfont; + display: flex; + flex-direction: row; + align-items: center; +} +.next-tree-check .radio { + border-top-left-radius: 50%; + border-top-right-radius: 50%; + border-bottom-right-radius: 50%; + border-bottom-left-radius: 50%; +} +.next-tree-check .radio .next-tree-check-yes-b { + border-top-left-radius: 50%; + border-top-right-radius: 50%; + border-bottom-right-radius: 50%; + border-bottom-left-radius: 50%; +} + +.next-tree-item.disabled .next-tree-check-no { + color: #ccc!important; +} +.next-tree-item.disabled .next-tree-check-yes-b { + background-color: #ccc!important; +} +.hover-c { + opacity: 0.6; +} + +.fixed-bottom-bar { + border-top: 1px solid #ccc; + position: fixed; + bottom: 0rpx; + left: 0rpx; + right: 0rpx; + z-index: 998; +} + + diff --git a/uni_modules/next-tree/package.json b/uni_modules/next-tree/package.json new file mode 100644 index 0000000..3a0280a --- /dev/null +++ b/uni_modules/next-tree/package.json @@ -0,0 +1,84 @@ +{ + "id": "next-tree", + "displayName": "next-tree(超强树选择器、树组件、树插件、无限级联树、单选树、多选树、自定义样式树、树形选择器)", + "version": "1.8.9", + "description": "next-tree 弹窗树形选择器,支持多选,支持大数据, 无限级联,单选,父子级级联,远程/ajax加载,子节点增量/异步渲染,自定义样式定制,具名插槽等;支持h5/小程序/APP,全端通用", + "keywords": [ + "树选择", + "tree", + "弹窗树选择器", + "多选树", + "单选树" +], +"engines": { + }, +"dcloudext": { + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "修改版本说明", + "permissions": "无" + }, + "npmurl": "", + "type": "component-vue" + }, + "uni_modules": { + "dependencies": ["next-search-more"], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y", + "alipay": "n" + }, + "client": { + "Vue": { + "vue2": "y", + "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": "n", + "Edge": "y", + "Firefox": "y", + "Safari": "u" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "u", + "QQ": "y", + "钉钉": "y", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/next-tree/readme.md b/uni_modules/next-tree/readme.md new file mode 100644 index 0000000..3d6d61d --- /dev/null +++ b/uni_modules/next-tree/readme.md @@ -0,0 +1,843 @@ + +## next-tree --下拉树 + +> 遇到问题或有建议可以加入QQ群(<font color=#f00>455948571</font>)反馈 +> 如果觉得组件不错,<font color=#f00>给五星鼓励鼓励</font>咯! + +## 亮点功能说明(打造你不得不用的好插件) + +### 本插件自1.5.0版本后支持一下功能 + + > 1.大数据量渲染(本插件智能判断,如果子孙集数据量大于50时,会响应等待渲染视图;) + > 2.子节点按需渲染(自动启用,无需配置) + > 3.父子级联选择设置 + > 4.单选多选设置 + > 5.父节点是否可选设置 + > 6.回显默认选中值 + > 7.不可选项disabled设置 + > 8.增强大数据量体验交互,增加筛选搜索模式 + > 9.增强样式定制,提供自定义插槽,实现高要求样式定制 + > 10.增加辅助线模式,外观更加精美 + > 11.支持动态配置title + > 12.支持搜索模式searchModel=depHighlight模式,从属高亮显示模式 + > 13.支持异步加载子节点,ajax加载子节点 + > 14.增加可配置主题,自由定制插件主题颜色 + > 15.支持动态校验,可以进行提示控制校验 + > 16.支持页面模式/弹层模式,可以进行单页面展示或者弹层展示 + > 17.支持半选提示状态显示 + > 18.支持展开项expandedKeys配置 + > 19.全面支持vue2/vue3 + > 20.增加无子节点的父节点配置支持(当item[childrenKey]为null时,代表无子节点的父节点) + > 21.终极支持超数据量使用,增加展开模式配置单链路配置使用expandedMode=singe,使得ui组件使用进一步不在限制与数据量 + > 22.功能模式再次增强,支持单选tree,多选tree,编辑tree,展示tree; + +## 注意 + +### 作者不介意你对组件源码进行改造使用,为了开源更加高效,谢谢你的配合;为了节省不必要的沟通浪费,以下情况请不要再反馈给作者,请自行解决; +### 在这感各位的理解,我支持开源,但是作者时间有限;谢谢各位的配合;在这里期望我写的小小插件能为你提供便捷; + + > 1.如果你对源码进行了修改使用,请不需要对作者做任何的反馈,作者确实没有空陪你做技术分析解答; + > 2.如果你引入插件,连插件是否有正常被uniapp框架识别解析都不清楚,请你换个插件使用; + > 3.如果你引入插件,针对自己项目进行功能改造的,请自行仔细阅读源码并了解其原理,自行改造;这里作者不愿意浪费过多时间进行技术解答; + > 4.如果你不想进行全局加载next-tree,需要按需加载;next-tree中有相关依赖的组件,需要你自行在组件内部单独引入;依赖组件可以在package.json中找到; + > 5.理论上作者不再解决由于本地开发环境问题所导致的插件使用问题,请自行到uniapp官网学习解决; + +## 使用 +### 超集功能即将不对外开源; + +>[从uniapp插件市场导入](https://ext.dcloud.net.cn/plugin?name=next-tree) + +## 关注作者的动态 +[点击进入主页,关注作者](https://ask.dcloud.net.cn/people/ponder_7464) + +## 关注作者其他开源 + +npm开源包:[npm](https://www.npmjs.com/~lixueshiaa); +github开源项目:[github](https://github.com/lixueshiaa); + + +```html +<template> + <view style="padding:10px;color: #333;font-weight: 500;"> + <view style="padding: 10px 0"><text>1、设置单选和父级不可选</text></view> + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(false, false)">设置</button> + <view style="padding: 10px 0"><text>2、设置多选和父级不可选</text></view> + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(true, false)">设置</button> + <view style="padding: 10px 0"><text>3、设置单选和父级可选</text></view> + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(false, true)">设置</button> + <view style="padding: 10px 0"><text>4、设置多选和父级可选</text></view> + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(true, true)" >设置</button> + <view style="padding: 10px 0"><text>4、设置多选和父级可选和父级关联子级选择</text></view> + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(true, true, true)" >设置</button> + <view style="padding: 10px 0"><text>5、设置默认回显(默认选中: '上海-2', '黄埔区-35')</text></view> + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="echoDefault()" >设置</button> + <!-- 异步加载demo --> + <view style="padding: 10px 0"><text>6、异步加载渲染demo</text></view> + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="openTree()" >设置</button> + </view> + + <!-- 异步加载demo --> + <next-tree :selectParent="false" :checkStrictly="true" funcMode="checkbox" ref="nextTreeAsyncRef" :treeData="asyncTreeData" :loadData="loadData" /> + + <next-tree :expandedKeys="['3','3-1']" :changeVerify="changeVerify" :title="getTitle" ref="nextTreeRef" :checkStrictly="checkStrictly" :selectParent="selectParent" :funcMode="funcMode" :treeData="treeData" @cancel="oncancel" @confirm="onconfirm"> + <!-- label插槽示意代码 --> + <!-- <template #label="{data: {id, label, iconSrc, prev, post}}"> + <view class="line-block"> + <image class="img" v-if="iconSrc" :src="iconSrc"></image> + <text space="nbsp" v-if="prev">{{prev}} </text><text>{{label}}</text><text space="nbsp" v-if="post"> {{post}}</text> + </view> + </template> --> + <!-- <template #topBar> + <view style="color: #666;padding:5px;"><text style="font-size: 12px;">历史记录</text></view> + <view style="display: flex;justify-content: space-between;padding-bottom: 10px;border-bottom: 1rpx solid #f0f0f0;"> + <button @click="checkedFunc('1-3-3-4')" :style="'background-color:'+ (activeId === '1-3-3-4' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">北京区-4</button> + <button @click="checkedFunc('3-1-2')" :style="'background-color:'+ (activeId === '3-1-2' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">海珠区-2</button> + <button @click="checkedFunc('3-1-6')" :style="'background-color:'+ (activeId === '3-1-6' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">海珠区-5</button> + </view> + </template> --> + </next-tree> +</template> +``` + +### vue3 + ts 使用 + +```ts +<script setup lang="ts"> +import { ref, unref } from 'vue' +import nextTree from '@/components/next-tree/next-tree.vue' + +const funcMode = ref('radio'); +const selectParent = ref(false) +const nextTreeRef = ref() +const nextTreeAsyncRef = ref() +const activeId = ref('') + +const localData: any = { + 'a1': [{id: 'a1-1', label: 'a1-1'}, {id: 'a1-2', label: 'a1-2',children: [] },{id: 'a1-3', label: 'a1-3'}], + 'b1': [{id: 'b1-1', label: 'b1-1',children: []}, {id: 'b1-2', label: 'b1-2'},{id: 'b1-3', label: 'b1-3'}], + 'c1': [{id: 'c1-1', label: 'c1-1'}, {id: 'c1-2', label: 'c1-2'},{id: 'c1-3', label: 'c1-3',children: []}], + 'a1-2': [{id: 'a1-2-1', label: 'a1-2-1'}, {id: 'a1-2-2', label: 'a1-2-2'}], + 'b1-1': [{id: 'b1-1-1', label: 'b1-1-1'}, {id: 'b1-1-2', label: 'b1-1-2'}], + 'c1-3': [{id: 'c1-3-1', label: 'c1-3-1'}, {id: 'c1-3-2', label: 'c1-3-2'}] +} + +const checkStrictly = ref(false) +const asyncTreeData = ref([{id: 'a1', label: 'a1', children: []},{id: 'b1', label: 'b1', children: []},{id: 'c1', label: 'c1', children: []}]) +const treeData = ref([ + {id: '1', label: '北京'}, + {id: '2', label: '上海', children: [ + {id: '2-1', label: '上海-1'}, + {id: '2-2', label: '上海-2'}, + {id: '2-3', label: '上海-3'}, + ] }, + {id: '3', label: '广州', children: [ + {id: '3-1', label: '海珠区', children: [ + {id: '3-1-1', label: '海珠区-1'}, + {id: '3-1-2', label: '海珠区-2'}, + {id: '3-1-4', label: '海珠区-3'}, + {id: '3-1-5', label: '海珠区-4'}, + {id: '3-1-6', label: '海珠区-5'}, + {id: '3-1-7', label: '海珠区-6'}, + {id: '3-1-8', label: '海珠区-7'}, + {id: '3-1-9', label: '海珠区-8'}, + {id: '3-1-10', label: '海珠区-9'}, + {id: '3-1-11', label: '海珠区-10'}, + ]}, + {id: '3-2', label: '番禺区', children: [ + {id: '3-2-1', label: '番禺区-1'}, + {id: '3-2-2', label: '番禺区-2'}, + {id: '3-2-4', label: '番禺区-3', children: null}, // 注意: 当childrenKey的值设为null,代表无子节点的父节点 + {id: '3-2-5', label: '番禺区-4'}, + {id: '3-2-6', label: '番禺区-5'}, + {id: '3-2-7', label: '番禺区-6'}, + {id: '3-2-8', label: '番禺区-7'}, + {id: '3-2-9', label: '番禺区-8'}, + {id: '3-2-10', label: '番禺区-9'}, + {id: '3-2-11', label: '番禺区-10'}, + ]}, + {id: '3-3', label: '黄埔区', children: [ + {id: '3-3-1', label: '黄埔区-1'}, + {id: '3-3-2', label: '黄埔区-2'}, + {id: '3-3-3', label: '黄埔区-3'}, + {id: '3-3-4', label: '黄埔区-4'}, + {id: '3-3-5', label: '黄埔区-5'}, + {id: '3-3-6', label: '黄埔区-6'}, + {id: '3-3-7', label: '黄埔区-7'}, + {id: '3-3-8', label: '黄埔区-8'}, + {id: '3-3-9', label: '黄埔区-9'}, + {id: '3-3-10', label: '黄埔区-10'}, + {id: '3-3-12', label: '黄埔区-11'}, + {id: '3-3-13', label: '黄埔区-12'}, + {id: '3-3-13', label: '黄埔区-13'}, + {id: '3-3-14', label: '黄埔区-14'}, + {id: '3-3-15', label: '黄埔区-15'}, + {id: '3-3-16', label: '黄埔区-16'}, + {id: '3-3-17', label: '黄埔区-17'}, + {id: '3-3-18', label: '黄埔区-18'}, + {id: '3-3-19', label: '黄埔区-19'}, + {id: '3-3-20', label: '黄埔区-20'}, + {id: '3-3-21', label: '黄埔区-21'}, + {id: '3-3-22', label: '黄埔区-22'}, + {id: '3-3-23', label: '黄埔区-23'}, + {id: '3-3-24', label: '黄埔区-24'}, + {id: '3-3-25', label: '黄埔区-25'}, + {id: '3-3-26', label: '黄埔区-26'}, + {id: '3-3-27', label: '黄埔区-27'}, + {id: '3-3-28', label: '黄埔区-28'}, + {id: '3-3-29', label: '黄埔区-29'}, + {id: '3-3-30', label: '黄埔区-30'}, + {id: '3-3-31', label: '黄埔区-31'}, + {id: '3-3-32', label: '黄埔区-32'}, + {id: '3-3-33', label: '黄埔区-33'}, + {id: '3-3-34', label: '黄埔区-34'}, + {id: '3-3-35', label: '黄埔区-35'}, + {id: '3-3-36', label: '黄埔区-36'}, + + ]}, + ], + }]) +function getTitle(checked) { + return `已选:${checked.length}项` +} +function itemclick (_multiple, _selectParent, _checkStrictly = false) { + funcMode.value = _multiple ? 'checkbox' : 'radio'; + selectParent.value = _selectParent + checkStrictly.value = _checkStrictly + unref(nextTreeRef).showTree = true +} +function checkedFunc(id) { + if(unref(activeId) === id) { + activeId.value = ''; + unref(nextTreeRef).checkedFunc(id, false) + } else { + activeId.value = id; + unref(nextTreeRef).checkedFunc(id) + } +} +function changeVerify(current, chooseList) { + // 注意:返回非空字符串会阻止原有行为,并提示返回的字符串 + // 如果函数体不做return返回值,即验证通过,控件正常处理业务 + console.log('当前变化的数据', current) + console.log('已选择的数据', chooseList) + if(chooseList && chooseList.length > 4) { + + return '最多可以选择4个节点' + } +} +function openTree() { + unref(nextTreeAsyncRef).showTree = true +} +function echoDefault () { + const selectIds = ['2-1','3-3-35'] + checkedTreeData(unref(treeData), selectIds) + console.log('treeData的数据:', unref(treeData)) + funcMode.value = 'checkbox' + unref(nextTreeRef).showTree = true +} +function loadData(data) { + const type = data.$type; // 加载类型 + const source = data.source // 源数据 + // 同步实现的代码处理方式 + + if (type === 'nodeLoad') { + const nodeItem = source; + // 同步实现的代码处理方式 + // 如果期望子集节点中还存在孙子节点可以打开,请在初始化数据的时候,初始化个空数组的子节点配置值{[this.childrenKey]: []} + + // if(nodeItem && localData[nodeItem.id]) { + // return localData[nodeItem.id] + // } else { + // return [] + // } + + // 异步的代码实现方式 + // 如果期望子集节点中还存在孙子节点可以打开,请在初始化数据的时候,初始化个空数组的子节点配置值{[this.childrenKey]: []} + + return new Promise((resolve, reject) => { + setTimeout(() => { + if(nodeItem && localData[nodeItem.id]) { + return resolve(localData[nodeItem.id]) + } else { + return resolve([]) + } + }, 1000) + }) + } else if(type === 'remoteSearch') { // searchModel=remote的时候,会在loadData函数中返回type参数供做业务处理 + // ...doing + } + +} + +function checkedTreeData (treeData, selectIds) { + treeData.map(item => { + if (selectIds.indexOf(item.id) !== -1) { + item.checked = true + } else { + item.checked = false + } + if (item.children && item.children.length) { + checkedTreeData(item.children, selectIds) + } + }) +} +function oncancel() { + // 清除treeData的选中状态 + checkedTreeData(unref(treeData), []) +} +function onconfirm(list) { + console.log('选中项的数量列表list:', list) +} +</script> +<style lang="scss"> + .line-block { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + .img { + width: 40rpx; + height: 40rpx; + border-radius: 10rpx; + margin: 0 20rpx; + } + } +</style> + +``` + +### vue2 使用 +```html +<template> + <view> + <view style="padding:10px;color: #333;font-weight: 500;"> + <view style="padding: 10px 0"><text>1、设置单选和父级不可选</text></view> + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(false, false)">设置</button> + <view style="padding: 10px 0"><text>2、设置多选和父级不可选</text></view> + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(true, false)">设置</button> + <view style="padding: 10px 0"><text>3、设置单选和父级可选</text></view> + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(false, true)">设置</button> + <view style="padding: 10px 0"><text>4、设置多选和父级可选</text></view> + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(true, true)" >设置</button> + <view style="padding: 10px 0"><text>4、设置多选和父级可选和父级关联子级选择</text></view> + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="itemclick(true, true, true)" >设置</button> + <view style="padding: 10px 0"><text>5、设置默认回显(默认选中: '上海-2', '黄埔区-35')</text></view> + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="echoDefault()" >设置</button> + <!-- 异步加载demo --> + <view style="padding: 10px 0"><text>6、异步加载渲染demo</text></view> + <button style="width: 100%;background-color: #f9ae3d;color:#fff" size="mini" @click="openTree()" >设置</button> + </view> + <!-- 异步加载demo --> + <next-tree :selectParent="false" :checkStrictly="true" funcMode="checkbox" ref="nextTreeAsyncRef" :treeData="asyncTreeData" :loadData="loadData" /> + + <next-tree :expandedKeys="['3','3-1']" :changeVerify="changeVerify" :title="getTitle" ref="nextTreeRef" :checkStrictly="checkStrictly" :selectParent="selectParent" :funcMode="funcMode" :treeData="treeData" @cancel="oncancel" @confirm="onconfirm"> + <!-- label插槽示意代码 --> + <!-- <template v-slot:label="{data}"> + <view class="line-block"> + <image class="img" v-if="data.iconSrc" :src="data.iconSrc"></image> + <text space="nbsp" v-if="data.prev">{{data.prev}} </text><text>{{data.label}}</text><text space="nbsp" v-if="data.post"> {{data.post}}</text> + </view> + </template> --> + <!-- <template #topBar> + <view style="color: #666;padding:5px;"><text style="font-size: 12px;">历史记录</text></view> + <view style="display: flex;justify-content: space-between;padding-bottom: 10px;border-bottom: 1rpx solid #f0f0f0;"> + <button @click="checkedFunc('1-3-3-4')" :style="'background-color:'+ (activeId === '1-3-3-4' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">北京区-4</button> + <button @click="checkedFunc('3-1-2')" :style="'background-color:'+ (activeId === '3-1-2' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">海珠区-2</button> + <button @click="checkedFunc('3-1-6')" :style="'background-color:'+ (activeId === '3-1-6' ? '#f9ae3d' : '#ccc') + ';color:#fff;margin: 5px'" size="mini">海珠区-5</button> + </view> + </template> --> + </next-tree> + </view> +</template> +``` + +```js +<script> +let self = null; +export default { + data () { + return { + funcMode: 'radio', + selectParent: false, + checkStrictly: false, + activeId: '', + localData:{ + 'a1': [{id: 'a1-1', label: 'a1-1'}, {id: 'a1-2', label: 'a1-2',children: [] },{id: 'a1-3', label: 'a1-3'}], + 'b1': [{id: 'b1-1', label: 'b1-1',children: []}, {id: 'b1-2', label: 'b1-2'},{id: 'b1-3', label: 'b1-3'}], + 'c1': [{id: 'c1-1', label: 'c1-1'}, {id: 'c1-2', label: 'c1-2'},{id: 'c1-3', label: 'c1-3',children: []}], + 'a1-2': [{id: 'a1-2-1', label: 'a1-2-1'}, {id: 'a1-2-2', label: 'a1-2-2'}], + 'b1-1': [{id: 'b1-1-1', label: 'b1-1-1'}, {id: 'b1-1-2', label: 'b1-1-2'}], + 'c1-3': [{id: 'c1-3-1', label: 'c1-3-1'}, {id: 'c1-3-2', label: 'c1-3-2'}] + }, + asyncTreeData: [{id: 'a1', label: 'a1', children: []},{id: 'b1', label: 'b1', children: []},{id: 'c1', label: 'c1', children: []}], + treeData: [ + {id: '1', label: '北京', checked: false}, + {id: '2', label: '上海', checked: false, children: [ + {id: '2-1', label: '上海-1', checked: false}, + {id: '2-2', label: '上海-2', checked: false}, + {id: '2-3', label: '上海-3', checked: false}, + ] }, + {id: '3', label: '广州', children: [ + {id: '3-1', label: '海珠区', checked: false, children: [ + {id: '3-1-1', label: '海珠区-1', checked: false, disabled: true}, + {id: '3-1-2', label: '海珠区-2', checked: false}, + {id: '3-1-4', label: '海珠区-3', checked: false}, + {id: '3-1-5', label: '海珠区-4', checked: false}, + {id: '3-1-6', label: '海珠区-5', checked: false}, + {id: '3-1-7', label: '海珠区-6', checked: false}, + {id: '3-1-8', label: '海珠区-7', checked: false}, + {id: '3-1-9', label: '海珠区-8', checked: false}, + {id: '3-1-10', label: '海珠区-9', checked: false}, + {id: '3-1-11', label: '海珠区-10', checked: false}, + ]}, + {id: '3-2', label: '番禺区', checked: false, children: [ + {id: '3-2-1', label: '番禺区-1', checked: false}, + {id: '3-2-2', label: '番禺区-2', checked: false}, + {id: '3-2-4', label: '番禺区-3', checked: false}, + {id: '3-2-5', label: '番禺区-4', checked: false}, + {id: '3-2-6', label: '番禺区-5', checked: false}, + {id: '3-2-7', label: '番禺区-6', checked: false}, + {id: '3-2-8', label: '番禺区-7', checked: false}, + {id: '3-2-9', label: '番禺区-8', checked: false}, + {id: '3-2-10', label: '番禺区-9', checked: false}, + {id: '3-2-11', label: '番禺区-10', checked: false}, + ]}, + {id: '3-3', label: '黄埔区', checked: false, children: [ + {id: '3-3-1', label: '黄埔区-1', checked: false}, + {id: '3-3-2', label: '黄埔区-2', checked: false}, + {id: '3-3-3', label: '黄埔区-3', checked: false}, + {id: '3-3-4', label: '黄埔区-4', checked: false}, + {id: '3-3-5', label: '黄埔区-5', checked: false}, + {id: '3-3-6', label: '黄埔区-6', checked: false}, + {id: '3-3-7', label: '黄埔区-7', checked: false}, + {id: '3-3-8', label: '黄埔区-8', checked: false}, + {id: '3-3-9', label: '黄埔区-9', checked: false}, + {id: '3-3-10', label: '黄埔区-10', checked: false}, + {id: '3-3-12', label: '黄埔区-11', checked: false}, + {id: '3-3-13', label: '黄埔区-12', checked: false}, + {id: '3-3-13', label: '黄埔区-13', checked: false}, + {id: '3-3-14', label: '黄埔区-14', checked: false}, + {id: '3-3-15', label: '黄埔区-15', checked: false}, + {id: '3-3-16', label: '黄埔区-16', checked: false}, + {id: '3-3-17', label: '黄埔区-17', checked: false}, + {id: '3-3-18', label: '黄埔区-18', checked: false}, + {id: '3-3-19', label: '黄埔区-19', checked: false}, + {id: '3-3-20', label: '黄埔区-20', checked: false}, + {id: '3-3-21', label: '黄埔区-21', checked: false}, + {id: '3-3-22', label: '黄埔区-22', checked: false}, + {id: '3-3-23', label: '黄埔区-23', checked: false}, + {id: '3-3-24', label: '黄埔区-24', checked: false}, + {id: '3-3-25', label: '黄埔区-25', checked: false}, + {id: '3-3-26', label: '黄埔区-26', checked: false}, + {id: '3-3-27', label: '黄埔区-27', checked: false}, + {id: '3-3-28', label: '黄埔区-28', checked: false}, + {id: '3-3-29', label: '黄埔区-29', checked: false}, + {id: '3-3-30', label: '黄埔区-30', checked: false}, + {id: '3-3-31', label: '黄埔区-31', checked: false}, + {id: '3-3-32', label: '黄埔区-32', checked: false}, + {id: '3-3-33', label: '黄埔区-33', checked: false}, + {id: '3-3-34', label: '黄埔区-34', checked: false}, + {id: '3-3-35', label: '黄埔区-35', checked: false}, + {id: '3-3-36', label: '黄埔区-36', checked: false}, + ]}, + ], + }] + } + }, + methods: { + openTree: function() { + this.$refs.nextTreeAsyncRef.showTree = true + }, + changeVerify: function(current, chooseList) { + // 注意:返回非空字符串会阻止原有行为,并提示返回的字符串 + // 如果函数体不做return返回值,即验证通过,控件正常处理业务 + console.log('当前变化的数据', current) + console.log('已选择的数据', chooseList) + if(chooseList && chooseList.length > 4) { + + return '最多可以选择4个节点' + } + }, + checkedFunc: function(id) { + if(this.activeId === id) { + this.activeId = ''; + this.$refs.nextTreeRef.checkedFunc(id, false) + } else { + this.activeId = id; + this.$refs.nextTreeRef.checkedFunc(id) + } + }, + function loadData(data) { + const type = data.$type; // 加载类型 + const source = data.source // 源数据 + // 同步实现的代码处理方式 + + if (type === 'nodeLoad') { + const nodeItem = source; + // 同步实现的代码处理方式 可以返回单个子节点的集合也可以返回子孙节点的集合 + // 如果期望子集节点中还存在孙子节点可以打开,请在初始化数据的时候,初始化个空数组的子节点配置值{[this.childrenKey]: []} + + // if(nodeItem && this.localData[nodeItem.id]) { + // return this.localData[nodeItem.id] + // } else { + // return [] + // } + // 异步的代码实现方式 可以返回单个子节点的集合也可以返回子孙节点的集合 + // 如果期望子集节点中还存在孙子节点可以打开,请在初始化数据的时候,初始化个空数组的子节点配置值{[this.childrenKey]: []} + return new Promise((resolve, reject) => { + setTimeout(() => { + if(nodeItem && self.localData[nodeItem.id]) { + return resolve(self.localData[nodeItem.id]) + } else { + return resolve([]) + } + }, 1000) + }) + } else if(type === 'remoteSearch') { // searchModel=remote的时候,会在loadData函数中返回type参数供做业务处理 + // ...doing + } + + }, + + getTitle: function(checked) { + return `已选:${checked.length}项` + }, + echoDefault: function() { + const selectIds = ['2-1','3-3-35'] + this.checkedTreeData(this.treeData, selectIds) + console.log('treeData的数据:', this.treeData) + this.funcMode = 'checkbox' + this.$refs.nextTreeRef.showTree = true + }, + itemclick: function(_multiple, _selectParent, _checkStrictly = false) { + this.funcMode = _multiple ? 'checkbox' : 'radio' + this.selectParent = _selectParent + this.checkStrictly = _checkStrictly + this.$refs.nextTreeRef.showTree = true + }, + checkedTreeData: function(treeData, selectIds) { + // 注意 vue2当数据深嵌套时,如果没有在treeData里面初始化checked属性,那在改变数据的时候直接将checked属性赋值为true,这时候ui界面有可能不会更新, + // 这时候建议使用this.$set去更新checked属性值,或者在初始化this.treeData的时候初始化checked属性 + (treeData || []).map(item => { + if (selectIds.indexOf(item.id) !== -1) { + item.checked = true + } else { + item.checked = false + } + if (item.children && item.children.length) { + this.checkedTreeData(item.children, selectIds) + } + }) + }, + onconfirm: function(list) { + console.log('选中项的数量列表list:', list) + }, + oncancel: function() { + // 清除treeData的选中状态 + this.checkedTreeData(this.treeData, []) + } + }, + created() { + self = this + } +} +</script> +<style lang="scss"> + .line-block { + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + .img { + width: 40rpx; + height: 40rpx; + border-radius: 10rpx; + margin: 0 20rpx; + } + } +</style> + +``` + +### 个性化自定义样式渲染 + +如果你的需求对样式需求比较高,请使用插槽模式渲染,本组件提供label插槽供你自定义定制; + +```js +<script> +// 提供参考一组自定义渲染数据demo,treeData如下; +const treeData = [ + {id: '1', label: '北京', prev: 'PonderNext-', iconSrc: 'https://img95.699pic.com/xsj/03/fg/hj.jpg%21/fh/300', children: [ + {id: '1-3-3-1', label: '北京区-1', prev: '前置-'}, + {id: '1-3-3-2', label: '北京区-2', post: '-后置'}, + {id: '1-3-3-3', label: '北京区-3', post: '-后置', prev: '前置-'}, + {id: '1-3-3-4', label: '北京区-4'}, + {id: '1-3-3-5', label: '北京区-5'}, + {id: '1-3-3-6', label: '北京区-6'}, + {id: '1-3-3-7', label: '北京区-7'}, + {id: '1-3-3-8', label: '北京区-8'}, + {id: '1-3-3-9', label: '北京区-9'}, + {id: '1-3-3-10', label: '北京区-10'}, + {id: '1-3-3-12', label: '北京区-11'}, + {id: '1-3-3-13', label: '北京区-12'}, + {id: '1-3-3-13', label: '北京区-13'}, + {id: '1-3-3-14', label: '北京区-14'}, + {id: '1-3-3-15', label: '北京区-15'}, + {id: '1-3-3-16', label: '北京区-16'}, + {id: '1-3-3-17', label: '北京区-17'}, + {id: '1-3-3-18', label: '北京区-18'}, + {id: '1-3-3-19', label: '北京区-19'}, + {id: '1-3-3-20', label: '北京区-20'}, + {id: '1-3-3-21', label: '北京区-21'}, + {id: '1-3-3-22', label: '北京区-22'}, + {id: '1-3-3-23', label: '北京区-23'}, + {id: '1-3-3-24', label: '北京区-24'}, + {id: '1-3-3-25', label: '北京区-25'}, + {id: '1-3-3-26', label: '北京区-26'}, + {id: '1-3-3-27', label: '北京区-27'}, + {id: '1-3-3-28', label: '北京区-28'}, + {id: '1-3-3-29', label: '北京区-29'}, + {id: '1-1-3-3-30', label: '北京区-30'}, + {id: '1-3-3-31', label: '北京区-31'}, + {id: '1-3-3-32', label: '北京区-32'}, + {id: '1-3-3-33', label: '北京区-33'}, + {id: '1-3-3-34', label: '北京区-34'}, + {id: '1-3-3-35', label: '北京区-35'}, + {id: '1-3-3-36', label: '北京区-36'}, + {id: '1-3-3-37', label: '北京区-37'}, + {id: '1-3-3-38', label: '北京区-38'}, + {id: '1-3-3-39', label: '北京区-39'}, + {id: '1-3-3-40', label: '北京区-40'}, + {id: '1-3-3-41', label: '北京区-41'}, + {id: '1-3-3-42', label: '北京区-42'}, + {id: '1-3-3-43', label: '北京区-43'}, + {id: '1-3-3-44', label: '北京区-44'}, + {id: '1-3-3-45', label: '北京区-45'}, + {id: '1-3-3-46', label: '北京区-46'}, + {id: '1-3-3-47', label: '北京区-47'}, + {id: '1-3-3-48', label: '北京区-48'}, + {id: '1-3-3-49', label: '北京区-49'}, + {id: '1-3-3-50', label: '北京区-50'}, + {id: '1-3-3-51', label: '北京区-51'}, + {id: '1-3-3-52', label: '北京区-52'}, + {id: '1-3-3-53', label: '北京区-53'}, + {id: '1-3-3-54', label: '北京区-54'}, + ]}, + {id: '2', label: '上海', prev: 'PonderNext-', iconSrc: 'https://img95.699pic.com/xsj/0g/hb/tc.jpg%21/fh/300', children: [ + {id: '2-1', label: '上海-1', iconSrc: 'https://img1.baidu.com/it/u=1997340124,765201109&fm=253&fmt=auto&app=120&f=JPEG?w=285&h=285'}, + {id: '2-2', label: '上海-2', iconSrc: 'https://img1.baidu.com/it/u=1997340124,765201109&fm=253&fmt=auto&app=120&f=JPEG?w=285&h=285'}, + {id: '2-3', label: '上海-3', iconSrc: 'https://img1.baidu.com/it/u=1997340124,765201109&fm=253&fmt=auto&app=120&f=JPEG?w=285&h=285'}, + ] }, + {id: '3', label: '广州', prev: 'PonderNext-', iconSrc: 'https://storage-public.zhaopin.cn/user/avatar/1589350028141684980/d00a1afa-e3ec-40a5-a68e-aef1f684b189.jpg', children: [ + {id: '3-1', label: '海珠区', iconSrc: 'https://img95.699pic.com/xsj/0u/f3/5h.jpg%21/fh/300', children: [ + {id: '3-1-1', label: '海珠区-1', disabled: true}, + {id: '3-1-2', label: '海珠区-2', post: '-后置', prev: '前置-'}, + {id: '3-1-4', label: '海珠区-3', post: '-后置',}, + {id: '3-1-5', label: '海珠区-4', children: [ + { id: '3-1-5-1', label: '海珠区-4-200号'}, + { id: '3-1-5-2', label: '海珠区-4-201号', children: [ + { id: '3-1-5-1-1', label: '海珠区-4-200号-2'}, + { id: '3-1-5-2-1', label: '海珠区-4-201号-3'}, + ]}, + ]}, + {id: '3-1-6', label: '海珠区-5'}, + {id: '3-1-7', label: '海珠区-6'}, + {id: '3-1-8', label: '海珠区-7', post: '-后置',}, + {id: '3-1-9', label: '海珠区-8'}, + {id: '3-1-10', label: '海珠区-9'}, + {id: '3-1-11', label: '海珠区-10'}, + {id: '3-1-1', label: '海珠区-11', disabled: true}, + {id: '3-1-2', label: '海珠区-12'}, + {id: '3-1-4', label: '海珠区-13'}, + {id: '3-1-5', label: '海珠区-14'}, + {id: '3-1-6', label: '海珠区-15'}, + {id: '3-1-7', label: '海珠区-16'}, + {id: '3-1-8', label: '海珠区-17'}, + {id: '3-1-9', label: '海珠区-18'}, + {id: '3-1-10', label: '海珠区-19', prev: '前置-'}, + {id: '3-1-11', label: '海珠区-20'}, + {id: '3-1-1', label: '海珠区-21', disabled: true}, + {id: '3-1-2', label: '海珠区-22'}, + {id: '3-1-4', label: '海珠区-23'}, + {id: '3-1-5', label: '海珠区-24'}, + {id: '3-1-6', label: '海珠区-25'}, + {id: '3-1-7', label: '海珠区-26'}, + {id: '3-1-8', label: '海珠区-27'}, + {id: '3-1-9', label: '海珠区-28'}, + {id: '3-1-10', label: '海珠区-29'}, + {id: '3-1-11', label: '海珠区-30'}, + {id: '3-1-1', label: '海珠区-31', disabled: true}, + {id: '3-1-2', label: '海珠区-32'}, + {id: '3-1-4', label: '海珠区-33'}, + {id: '3-1-5', label: '海珠区-34'}, + {id: '3-1-6', label: '海珠区-35'}, + {id: '3-1-7', label: '海珠区-36'}, + {id: '3-1-8', label: '海珠区-37'}, + {id: '3-1-9', label: '海珠区-38'}, + {id: '3-1-10', label: '海珠区-39'}, + {id: '3-1-11', label: '海珠区-40'}, + {id: '3-1-1', label: '海珠区-41', disabled: true}, + {id: '3-1-2', label: '海珠区-42'}, + {id: '3-1-4', label: '海珠区-43'}, + {id: '3-1-5', label: '海珠区-44'}, + {id: '3-1-6', label: '海珠区-45'}, + {id: '3-1-7', label: '海珠区-46'}, + {id: '3-1-8', label: '海珠区-47'}, + {id: '3-1-9', label: '海珠区-48'}, + {id: '3-1-10', label: '海珠区-49'}, + {id: '3-1-11', label: '海珠区-50'}, + {id: '3-1-11', label: '海珠区-51'}, + ]}, + {id: '3-2', label: '番禺区', iconSrc: 'https://img1.baidu.com/it/u=931648192,3196263841&fm=253&fmt=auto&app=120&f=JPEG?w=285&h=285', disabled: true, checked: true, children: [ + {id: '3-2-1', label: '番禺区-1'}, + {id: '3-2-2', label: '番禺区-2'}, + {id: '3-2-4', label: '番禺区-3'}, + {id: '3-2-5', label: '番禺区-4'}, + {id: '3-2-6', label: '番禺区-5'}, + {id: '3-2-7', label: '番禺区-6'}, + {id: '3-2-8', label: '番禺区-7'}, + {id: '3-2-9', label: '番禺区-8'}, + {id: '3-2-10', label: '番禺区-9'}, + {id: '3-2-11', label: '番禺区-10'}, + ]}, + {id: '3-3', label: '黄埔区', iconSrc: 'https://img.jiaoyubao.cn/43423/20210423113959473-20210423114005024.jpeg', children: [ + {id: '3-3-1', label: '黄埔区-1'}, + {id: '3-3-2', label: '黄埔区-2'}, + {id: '3-3-3', label: '黄埔区-3'}, + {id: '3-3-4', label: '黄埔区-4'}, + {id: '3-3-5', label: '黄埔区-5'}, + {id: '3-3-6', label: '黄埔区-6'}, + {id: '3-3-7', label: '黄埔区-7'}, + {id: '3-3-8', label: '黄埔区-8'}, + {id: '3-3-9', label: '黄埔区-9'}, + {id: '3-3-10', label: '黄埔区-10'}, + {id: '3-3-12', label: '黄埔区-11'}, + {id: '3-3-13', label: '黄埔区-12'}, + {id: '3-3-13', label: '黄埔区-13'}, + {id: '3-3-14', label: '黄埔区-14'}, + {id: '3-3-15', label: '黄埔区-15'}, + {id: '3-3-16', label: '黄埔区-16'}, + {id: '3-3-17', label: '黄埔区-17'}, + {id: '3-3-18', label: '黄埔区-18'}, + {id: '3-3-19', label: '黄埔区-19'}, + {id: '3-3-20', label: '黄埔区-20'}, + {id: '3-3-21', label: '黄埔区-21'}, + {id: '3-3-22', label: '黄埔区-22'}, + {id: '3-3-23', label: '黄埔区-23'}, + {id: '3-3-24', label: '黄埔区-24'}, + {id: '3-3-25', label: '黄埔区-25'}, + {id: '3-3-26', label: '黄埔区-26'}, + {id: '3-3-27', label: '黄埔区-27'}, + {id: '3-3-28', label: '黄埔区-28'}, + {id: '3-3-29', label: '黄埔区-29'}, + {id: '3-3-30', label: '黄埔区-30'}, + {id: '3-3-31', label: '黄埔区-31'}, + {id: '3-3-32', label: '黄埔区-32'}, + {id: '3-3-33', label: '黄埔区-33'}, + {id: '3-3-34', label: '黄埔区-34'}, + {id: '3-3-35', label: '黄埔区-35'}, + {id: '3-3-36', label: '黄埔区-36'}, + {id: '3-3-37', label: '黄埔区-37'}, + {id: '3-3-38', label: '黄埔区-38'}, + {id: '3-3-39', label: '黄埔区-39'}, + {id: '3-3-40', label: '黄埔区-40'}, + {id: '3-3-41', label: '黄埔区-41'}, + {id: '3-3-42', label: '黄埔区-42'}, + {id: '3-3-43', label: '黄埔区-43'}, + {id: '3-3-44', label: '黄埔区-44'}, + {id: '3-3-45', label: '黄埔区-45'}, + {id: '3-3-46', label: '黄埔区-46'}, + {id: '3-3-47', label: '黄埔区-47'}, + {id: '3-3-48', label: '黄埔区-48'}, + {id: '3-3-49', label: '黄埔区-49'}, + {id: '3-3-50', label: '黄埔区-50'}, + {id: '3-3-51', label: '黄埔区-51'}, + {id: '3-3-52', label: '黄埔区-52'}, + {id: '3-3-53', label: '黄埔区-53'}, + {id: '3-3-54', label: '黄埔区-54'}, + ]}, + ], + }] +</script> +``` + +### 预览 +### +*** + +| 功能预览 | 父子级关联演示 | 全面支持大数据量,子孙节点ui按需渲染(按需渲染数据) | +| :------------------------------------------------------------------: | :------------------------------------------------------------------: | :------------------------------------------------------------------: | +|  |  |  | + + + +| 增强控件交互能力,增加筛选search模式,全面支持大数据量交互 | 超强的样式定制能力,满足你高精美组件的需求 | 打开精美的辅助线模式,让你的控件更加友好 | +| :------------------------------------------------------------------: | :------------------------------------------------------------------: | :------------------------------------------------------------------: | +|  |  |  | + + +| 增加搜索模式searchModel=depHighlight模式,从属高亮显示模式 | 支持异步加载子节点,子树集,ajax远程加载数据等 | 支持不同主题的切换,ui定制更简单 | +| :------------------------------------------------------------------: | :------------------------------------------------------------------: | :------------------------------------------------------------------: | +|  |  |  | + +| 增加验证函数和topBar插槽使得更加容易和组件进行交互 | 增加页面模式,支持整页ui展示模式 | 增加展开模式expandedMode配置,支持单链路展开,理论上支持几万数据量 | +| :------------------------------------------------------------------: | :------------------------------------------------------------------: | :------------------------------------------------------------------: | +| | |  | + + + +### 超集功能预览(增值功能) +### +| 实现tree的功能模式扩展,让你的tree组件实现可编辑态 | +| :--------------------------------------------------------------------: | +| | + +## 参数 +可选参数属性列表 + +|参数名 |说明 |类型 |是否必填 |默认值 |可选值 | +|---- |---- |---- |---- |---- |----------------------- | +|uiMode |ui表现方式;popup<弹窗>, page<页面>;默认是 popup |String |是 |popup |page | +|funcMode |功能模式配置;display<展示模式>, edit<编辑模式>,checkbox<多选模式>, radio<单选模式>;默认是 radio |String |是 |radio |dispaly,edit,checkbox | +|treeData |树源数据列表 |Array |是 |[] |- | +|valueKey |绑定value的键属性(项的唯一key标识) |String |否 |id |- | +|labelKey |用于显示的字段 |String |否 |label |- | +|disabledKey |禁用节点绑定属性 |String |否 |disabled |- | +|childrenKey |子节点绑定属性 (注意:当item[childrenKey]的值设为null时,代表是无下级数据的父节点,即非叶子节点) |String |否 |children |- | +|title | 弹出标题(如果是函数时会返回所选项的值作为回调参数如;title: (checked):String => {}) |String, Function |否 |'' |- | +|selectParent |作用于funcMode=display模式下;是否可以选父级 |Boolean |否 |false |true | +|foldAll| 折叠时关闭所有已经打开的子集,再次打开时需要一级一级打开 |Boolean |否 |false |true | +|themeColor |主题颜色 |String |否 |#f9ae3d |- | +|cancelColor |取消按钮颜色 |String |否 |#757575 |- | +|titleColor |标题颜色 |String |否 |#757575 |- | +|border |是否有分割线 |Boolean |否 |false |true | +|checkStrictly|作用于funcMode=checkbox模式下; 状态下节点选择完全受控(父子节点选中状态不再关联) |Boolean |否 |false |true | +|checkStrictlyModel|作用于funcMode=checkbox模式下;父子节点关联模式:strong:强关联(不再受限节点的disabled控制),weak:弱关联(节点关联受disabled控制) |String |是 |weak |strong | +|showHalfCheckedTips|作用于funcMode=checkbox模式下; checkStrictly为false的状态下生效;父子节点选中状态不再关联,是否展示半选提示; |Boolean |否 |false |true | +|ifSearch| 筛选search模式 |Boolean |否 |true |false | +|searchModel| 搜索模式配置 depHighlight: 从属高亮(显示层级并高亮显示);common: 一般;remote: 远程 |String |否 |common |depHighlight | +|showAuxiliaryLine| 是否打开辅助线 |Boolean |否 |false |true | +|loadData| 异步加载函数 (node):Promise([childData]) => {} // demo有说明 |Function |否 |- |- | +|height| 只在uiMode=popup时生效;弹层容器的高度,默认是500 |Number |否 |500 |- | +|changeVerify|作用于funcMode=display模式下; 验证函数 (current as any, chooseList as any []):String => {} // 验证函数会把当前控件的选择值作为参数返给函数体,demo有说明 |Function |否 |- |- | +|expandedKeys| (Controlled) Specifies the keys of the expanded treeNodes 展开配置项,格式为[valueKey] |Array |否 |[] |- | +|expandedMode| 展开模式配置: common: 一般模式;singe: 单一模式; |String |否 |common |singe | + + +# Event 事件 +|事件名 |说明 |类型 |回调参数 | +|---- |---- |---- |---- | +|confirm|菜单收起时返回的筛选结果 |emit |array | +|clear|点击清除按钮时触发 |emit |- | +|cancel|关闭弹层和点击取消时触发 |emit |- | +|change|选项改变时触发 |emit |array | + +## Slot 插槽 + +|名称 |说明 |参数 | +|---- |---- |---- | +|label |label插槽 |data(当前项对于treeData里面的数据) | +|topBar |topBar插槽 |----滚动区域顶部topBar插槽 | +|bottomBar |bottomBar插槽 |----滚动区域底部bottomBar插槽 | +|fixedBottomBar |fixedBottomBar插槽 |----固定在页面的底部,使用fixed进行定位 | +|empty |empty插槽 |----数据为空的插槽 | + diff --git a/utils/request.js b/utils/request.js index dc97da5..e72ff42 100644 --- a/utils/request.js +++ b/utils/request.js @@ -1,5 +1,5 @@ -// let requestPath = 'http://192.168.0.31:8992/qa-prevention-xgf/'; // 后台请求地址 -let requestPath = 'https://skqhdg.porthebei.com:9006/qa-prevention-xgf/'; // 后台请求地址 +let requestPath = 'http://192.168.0.99:8199/'; // 后台请求地址 +// let requestPath = 'https://skqhdg.porthebei.com:9006/qa-prevention-xgf/'; // 后台请求地址 // let requestPath = 'https://qgxgf.qhdsafety.com/qa-prevention-xgf/'; // 外网地址 import store from '../store/index' @@ -19,16 +19,16 @@ function post(url, data) { }, method: 'POST', header: { - 'Content-type': 'application/x-www-form-urlencoded' + 'Content-type': data?.postMethod || 'application/x-www-form-urlencoded' }, success: (res) => { if (res.statusCode != 200){ uni.showToast({ - title: '网络错误请重试,' +res.statusCode, + title: '网络错误请重试', icon: 'error', duration: 2000 }); - reject(err) + reject(res) } if (data && data.loading !== false) { uni.hideLoading(); diff --git a/utils/submitHomeworkProcess.js b/utils/submitHomeworkProcess.js new file mode 100644 index 0000000..9ccc01a --- /dev/null +++ b/utils/submitHomeworkProcess.js @@ -0,0 +1,76 @@ +import {getCurrentNextOperation, setTaskSave} from "../api/index"; + +// 处理表单数据 +const processFormData = (formData, formItems) => { + const form = [] + for (let i = 0; i < formItems.length; i++) { + const formItem = formItems[i] + form.push({ + ITEM: formItem.name, + ITEM_NAME: formItem.key_name, + ITEM_VALUE: formData[formItem.key_name], + FK_NAME: formItem.key_id || '', + FK_VALUE: formData[formItem.key_id] || '', + TYPE: formItem.type, + SORT: i + 1 + }) + } + return form +} +// 提交表单基础信息 +export const setSubmitForm = async ({form, formItems, TYPE, CORP_ID}) => { + const {taskIds} = await setTaskSave({ + data: [{form: processFormData(form, formItems)}], + TYPE, + postMethod: 'application/json', + }) + await resolveNextOperation(taskIds[0], CORP_ID, TYPE) +} +// 处理选择人员数据 +const processingSelectedPersonnelData = (formData, list) => { + const form = [] + for (let i = 0; i < list.length; i++) { + const item = list[i] + form.push({ + TYPE_NAME: item.desc, + TYPE: item.code, + DEPARTMENT_ID: list[i].type === '1' ? formData[item.key_id] : '', + DEPARTMENT_NAME: list[i].type === '1' ? formData[item.key_name] : '', + USER_ID: list[i].type === '0' ? formData[item.key_id] : '', + USER_NAME: list[i].type === '0' ? formData[item.key_name] : '', + isDepartment: list[i].type + }) + } + return form +} +// 提交人员信息 +export const setPersonnelForm = async ({form, list, taskId, CORP_ID, TYPE}) => { + await setTaskSave({ + data: [{jobs: processingSelectedPersonnelData(form, list), task: {EW_RU_TASK_ID: taskId}}], + postMethod: 'application/json', + }) + await resolveNextOperation(taskId, CORP_ID, TYPE) +} +// 决定下一步操作 EW_RU_TASK_ID当前任务id CORP_ID 选择的企业id TYPE作业类型 +const resolveNextOperation = async (EW_RU_TASK_ID, CORP_ID, TYPE) => { + const {info} = await getCurrentNextOperation({EW_RU_TASK_ID}) + // 选人 + if (info.chooseNextFlag === '1') { + uni.navigateTo({ + url: '/pages/eight_assignments/select_review_personnel', + success: ({eventChannel}) => { + eventChannel.emit('nextNodes', {nextNodes: info.nextNodes, taskId: EW_RU_TASK_ID, CORP_ID, TYPE}) + } + }) + return + } + // 填写安全措施 + if (info.completeFlag === '1') { + return + } + // 填写其它安全措施 + if (info.canAddFlag === '1') { + return + } + console.log('没有下一步了') +}