| 2024-12-23 | liukangdong | ![]() |
| 2024-12-23 | liukangdong | ![]() |
admin/src/views/Inspection/components/taskDetail.vue
@@ -1,5 +1,5 @@ <template> <GlobalWindow title="巡检任务详情" :showConfirm="false" :visible.sync="isShowModal"> <GlobalWindow title="巡检任务详情" width="800px" :showConfirm="false" :visible.sync="isShowModal"> <QueryForm v-model="filters" :query-form-config="queryFormConfig" @handleQuery="getDetail(1)" @clear="clear" /> <el-table v-loading="loading" :data="list" stripe> <el-table-column prop="pointName" label="巡检点名称" min-width="100" show-overflow-tooltip /> admin/src/views/Inspection/task.vue
@@ -5,7 +5,7 @@ <el-form-item label="计划名称" prop="planTitle"> <el-input v-model="searchForm.planTitle" placeholder="请输入计划名称" @keypress.enter.native="search"></el-input> </el-form-item> <el-form-item label="任务状态"> <el-form-item label="任务状态" prop="status"> <el-select v-model="searchForm.status" label="任务状态" filterable clearable> <el-option value="0" label="待开始"></el-option> <el-option value="1" label="进行中"></el-option> admin/src/views/contract/components/contractEdit.vue
@@ -1,12 +1,6 @@ <template> <GlobalWindow width="100%" :title="title" :withFooter="false" :visible.sync="visible" :confirm-working="isWorking" @confirm="confirm" @close="close"> <GlobalWindow width="100%" :title="title" :withFooter="false" :visible.sync="visible" :confirm-working="isWorking" @confirm="confirm" @close="close"> <div class="tabs fixed"> <div class="tab" :class="{ active: activeTabs === 0 }">1、基本信息</div> <div class="tab" :class="{ active: activeTabs === 1 }">2、费用条款</div> @@ -19,7 +13,8 @@ <div class="list"> <el-form-item label="合同类型" prop="type"> <el-select v-model="form.type" placeholder="请选择" @change="changeType"> <el-option v-for="(item, index) in types" :key="index" :value="item.value" :label="item.name"></el-option> <el-option v-for="(item, index) in types" :key="index" :value="item.value" :label="item.name"></el-option> </el-select> </el-form-item> <el-form-item label="合同编号" prop="code"> @@ -27,21 +22,26 @@ </el-form-item> <el-form-item label="经办人" prop="userId"> <el-select v-model="form.userId" filterable placeholder="请选择"> <el-option v-for="(item, index) in agentList" :key="index" :value="item.id" :label="item.realname"></el-option> <el-option v-for="(item, index) in agentList" :key="index" :value="item.id" :label="item.realname"></el-option> </el-select> </el-form-item> <el-form-item label="合同签订日期" prop="signDate"> <el-date-picker type="date" v-model="form.signDate" value-format="yyyy-MM-dd" :clearable="false" placeholder="请选择" /> <el-date-picker type="date" v-model="form.signDate" value-format="yyyy-MM-dd" :clearable="false" placeholder="请选择" /> </el-form-item> <el-form-item label="合同开始日期" prop="startDate"> <el-date-picker type="date" v-model="form.startDate" @change="getHouseData" :clearable="false" value-format="yyyy-MM-dd" placeholder="请选择" /> <el-date-picker type="date" v-model="form.startDate" @change="getHouseData" :clearable="false" value-format="yyyy-MM-dd" placeholder="请选择" /> </el-form-item> <el-form-item label="合同结束日期" prop="endDate"> <el-date-picker type="date" v-model="form.endDate" @change="getHouseData" :clearable="false" value-format="yyyy-MM-dd" placeholder="请选择" /> <el-date-picker type="date" v-model="form.endDate" @change="getHouseData" :clearable="false" value-format="yyyy-MM-dd" placeholder="请选择" /> </el-form-item> <el-form-item label="归属项目" prop="projectId"> <el-select v-model="form.projectId" @change="getHouseTree" placeholder="请选择"> <el-option v-for="(item, index) in projectList" :key="index" :value="item.id" :label="item.name"></el-option> <el-option v-for="(item, index) in projectList" :key="index" :value="item.id" :label="item.name"></el-option> </el-select> </el-form-item> <el-form-item label="结果取整(四舍五入)" prop="roundedUp"> @@ -52,7 +52,8 @@ </el-form-item> <el-form-item label="所属公司" prop="companyId"> <el-select v-model="form.companyId" placeholder="请选择"> <el-option v-for="(item, index) in comparyList" :key="index" :value="item.id" :label="item.name"></el-option> <el-option v-for="(item, index) in comparyList" :key="index" :value="item.id" :label="item.name"></el-option> </el-select> </el-form-item> </div> @@ -65,24 +66,21 @@ </el-form-item> <el-form-item label="联系人" prop="memberId"> <el-select v-model="form.memberId" placeholder="请选择"> <el-option v-for="(item, index) in contactsList" :key="index" :value="item.id" :label="item.name"></el-option> <el-option v-for="(item, index) in contactsList" :key="index" :value="item.id" :label="item.name"></el-option> </el-select> <!-- <el-input v-model="form.memberName" readonly placeholder="请点击选择租客" />--> <!-- <el-input v-model="form.memberName" readonly placeholder="请点击选择租客" />--> </el-form-item> </div> </el-form> </div> <div class="main_house"> <div class="title">请选择房源</div> <el-tree :data="houseList" show-checkbox node-key="idd" @check="checkHouseRoom" :default-expanded-keys="ids" :default-checked-keys="ids" :props="{ children: 'projectDataVOList', label: 'name' }"> <span class="custom-tree-node" style="width: 100%; display: flex; align-items: center; justify-content: space-between;" slot-scope="{ node, data }"> <el-tree :data="houseList" show-checkbox node-key="idd" @check="checkHouseRoom" :default-expanded-keys="ids" :default-checked-keys="ids" :props="{ children: 'projectDataVOList', label: 'name' }"> <span class="custom-tree-node" style="width: 100%; display: flex; align-items: center; justify-content: space-between;" slot-scope="{ node, data }"> <span>{{ data.name }}</span> <span style="color: #2080f7;" v-if="data.lv === 3"> {{ data.area }}㎡ @@ -113,8 +111,12 @@ </div> <div v-show="activeTabs === 1"> <div class="tabs cost_tabs"> <div class="tab" :class="{ active: cactiveTabs === 0 }" @click="ctabsClick(0)" v-if="[0,2].includes(form.type)">租赁条款</div> <div class="tab" :class="{ active: cactiveTabs === 1 }" @click="ctabsClick(1)" v-if="[0,1].includes(form.type)">物业条款</div> <div class="tab" :class="{ active: cactiveTabs === 0 }" @click="ctabsClick(0)" v-if="[0, 2].includes(form.type)"> 租赁条款 </div> <div class="tab" :class="{ active: cactiveTabs === 1 }" @click="ctabsClick(1)" v-if="[0, 1].includes(form.type)"> 物业条款 </div> </div> <!-- 租赁条款 --> <div v-show="cactiveTabs === 0"> @@ -128,7 +130,8 @@ </el-form-item> <el-form-item label="付款方式" prop="zlPayType"> <el-select v-model="form.zlPayType" @change="changePayType" placeholder="请选择"> <el-option v-for="(item, index) in payMethods" :key="index" :value="item.value" :label="item.name"></el-option> <el-option v-for="(item, index) in payMethods" :key="index" :value="item.value" :label="item.name"></el-option> </el-select> </el-form-item> <el-form-item label="免租期" prop="zlDate"> @@ -141,18 +144,22 @@ <el-button type="text" size="medium" @click="addZl">增加</el-button> </div> <div class="list"> <div style="width: 100%; display: flex; flex-wrap: wrap;" v-for="(zlDetailList, index) in form.zlDetailList" :key="index"> <div style="width: 100%; display: flex; flex-wrap: wrap;" v-for="(zlDetailList, index) in form.zlDetailList" :key="index"> <el-form-item label="起始日期" :prop="'zlDetailList.' + index + '.time'" :rules="{ required: true, message: '请选择', trigger: 'blur' }"> <el-date-picker type="daterange" v-model="zlDetailList.time" @change="getDate1($event, index)" value-format="yyyy-MM-dd" placeholder="请选择" /> <el-date-picker type="daterange" v-model="zlDetailList.time" @change="getDate1($event, index)" value-format="yyyy-MM-dd" placeholder="请选择" /> </el-form-item> <el-form-item label="合同单价" :prop="'zlDetailList.' + index + '.price'" :rules="{ required: true, message: '请输入', trigger: 'blur' }"> <el-input placeholder="请输入" v-model="zlDetailList.price" @input="clearzl" class="input-with-select"> <el-select v-model="zlDetailList.circleType" @change="clearzl" style="width: 150px;" slot="append" placeholder="请选择"> <el-option v-for="(item, index) in unitOps" :key="index" :value="item.value" :label="item.name"></el-option> <el-select v-model="zlDetailList.circleType" @change="clearzl" style="width: 150px;" slot="append" placeholder="请选择"> <el-option v-for="(item, index) in unitOps" :key="index" :value="item.value" :label="item.name"></el-option> </el-select> </el-input> </el-form-item> @@ -161,7 +168,8 @@ }"> <div style="display: flex; align-items: center; justify-content: space-between;"> <el-input v-model="zlDetailList.advanceDays" @input="clearzl" placeholder="请输入" v-trim /> <el-link :underline="false" type="danger" @click="deleZl(index)" style="margin-left: 20px; flex-shrink: 0;">删除</el-link> <el-link :underline="false" type="danger" @click="deleZl(index)" style="margin-left: 20px; flex-shrink: 0;">删除</el-link> </div> </el-form-item> </div> @@ -185,24 +193,24 @@ </el-table-column> <el-table-column label="期数" align="center" show-overflow-tooltip> <template slot-scope="{row}"> <el-tag type="success" v-if="row.sortnum > 0">{{row.sortnum}}</el-tag> <el-tag type="success" v-if="row.sortnum > 0">{{ row.sortnum }}</el-tag> </template> </el-table-column> <el-table-column label="区间" align="center" show-overflow-tooltip> <template slot-scope="{row}"> {{row.startDate}} ~ {{row.endDate}} {{ row.startDate }} ~ {{ row.endDate }} </template> </el-table-column> <el-table-column prop="planPayDate" label="付款日" align="center" show-overflow-tooltip /> <el-table-column label="应收" align="center" show-overflow-tooltip> <template slot-scope="{row}"> {{row.receivableFee}}元 {{ row.receivableFee }}元 </template> </el-table-column> </el-table> <div class="total"> <span>总计</span> <div>费用应收总计:{{zlPrice}}元,押金应收总计:{{form.zlDeposit}}元</div> <div>费用应收总计:{{ zlPrice }}元,押金应收总计:{{ form.zlDeposit }}元</div> </div> </div> <!-- 物业条款 --> @@ -217,7 +225,8 @@ </el-form-item> <el-form-item label="付款方式" prop="wyPayType"> <el-select v-model="form.wyPayType" @change="changePayType1" placeholder="请选择"> <el-option v-for="(item, index) in payMethods" :key="index" :value="item.value" :label="item.name"></el-option> <el-option v-for="(item, index) in payMethods" :key="index" :value="item.value" :label="item.name"></el-option> </el-select> </el-form-item> <el-form-item label="免租期" prop="wyDate"> @@ -230,18 +239,22 @@ <el-button type="text" size="medium" @click="addWy">增加</el-button> </div> <div class="list"> <div style="width: 100%; display: flex; flex-wrap: wrap;" v-for="(wyDetailList, index) in form.wyDetailList" :key="index"> <div style="width: 100%; display: flex; flex-wrap: wrap;" v-for="(wyDetailList, index) in form.wyDetailList" :key="index"> <el-form-item label="起始日期" :prop="'wyDetailList.' + index + '.time'" :rules="{ required: true, message: '请输入', trigger: 'blur' }"> <el-date-picker type="daterange" v-model="wyDetailList.time" @change="getDate2($event, index)" value-format="yyyy-MM-dd" placeholder="请选择" /> <el-date-picker type="daterange" v-model="wyDetailList.time" @change="getDate2($event, index)" value-format="yyyy-MM-dd" placeholder="请选择" /> </el-form-item> <el-form-item label="合同单价" :prop="'wyDetailList.' + index + '.price'" :rules="{ required: true, message: '请输入', trigger: 'blur' }"> <el-input placeholder="请输入" @input="clearwy" v-model="wyDetailList.price"> <el-select v-model="wyDetailList.circleType" @change="clearwy" style="width: 150px;" slot="append" placeholder="请选择"> <el-option v-for="(item, index) in unitOps1" :key="index" :value="item.value" :label="item.name"></el-option> <el-select v-model="wyDetailList.circleType" @change="clearwy" style="width: 150px;" slot="append" placeholder="请选择"> <el-option v-for="(item, index) in unitOps1" :key="index" :value="item.value" :label="item.name"></el-option> </el-select> </el-input> </el-form-item> @@ -250,7 +263,8 @@ }"> <div style="display: flex; align-items: center; justify-content: space-between;"> <el-input v-model="wyDetailList.advanceDays" @input="clearwy" placeholder="请输入" v-trim /> <el-link :underline="false" type="danger" @click="deleWy(index)" style="margin-left: 20px; flex-shrink: 0;">删除</el-link> <el-link :underline="false" type="danger" @click="deleWy(index)" style="margin-left: 20px; flex-shrink: 0;">删除</el-link> </div> </el-form-item> </div> @@ -274,32 +288,33 @@ </el-table-column> <el-table-column label="期数" align="center" show-overflow-tooltip> <template slot-scope="{row}"> <el-tag type="success" v-if="row.sortnum > 0">{{row.sortnum}}</el-tag> <el-tag type="success" v-if="row.sortnum > 0">{{ row.sortnum }}</el-tag> </template> </el-table-column> <el-table-column label="区间" align="center" show-overflow-tooltip> <template slot-scope="{row}"> {{row.startDate}} ~ {{row.endDate}} {{ row.startDate }} ~ {{ row.endDate }} </template> </el-table-column> <el-table-column prop="planPayDate" label="付款日" align="center" show-overflow-tooltip /> <el-table-column prop="receivableFee" label="应收" align="center" show-overflow-tooltip> <template slot-scope="{row}"> {{row.receivableFee}}元 {{ row.receivableFee }}元 </template> </el-table-column> </el-table> <div class="total"> <span>总计</span> <div>费用应收总计:{{wyPrice}}元,押金应收总计:{{form.wyDeposit}}元</div> <div>费用应收总计:{{ wyPrice }}元,押金应收总计:{{ form.wyDeposit }}元</div> </div> </div> </div> <div class="window__footer"> <slot name="footer"> <el-button @click="confirm" :loading="confirmWorking" type="primary">{{activeTabs === 0 ? '下一步' : '提交'}}</el-button> <el-button @click="confirm" :loading="confirmWorking" type="primary">{{ activeTabs === 0 ? '下一步' : '提交'}}</el-button> <slot name="btns" /> <el-button @click="close">{{activeTabs === 0 ? '返回' : '上一步'}}</el-button> <el-button @click="close">{{ activeTabs === 0 ? '返回' : '上一步' }}</el-button> </slot> </div> <!-- 选择租客 --> @@ -328,7 +343,7 @@ computed: { ...mapState(['userInfo']) }, data () { data() { return { title: '创建合同', activeTabs: 0, @@ -363,6 +378,7 @@ advanceDays: '' } ], wyDeposit: '', wyPayType: '', @@ -433,11 +449,12 @@ { name: '元/场', value: 6 }, ], houseLvThree: [] } }, methods: { open (title, target) { open(title, target) { this.title = title this.ids = [] this.houseList = [] @@ -486,7 +503,7 @@ // this.getHouseTree() }) }, changePayType (e) { changePayType(e) { if (e === 0) { this.unitOps = [ { name: '元/m²·天', value: 0 }, @@ -514,7 +531,7 @@ } this.clearzl() }, changePayType1 (e) { changePayType1(e) { if (e === 0) { this.unitOps1 = [ { name: '元/m²·天', value: 0 }, @@ -543,14 +560,14 @@ this.clearwy() }, // 获取联系人 getYwList () { getYwList() { ywList({ customerId: this.form.renterId }).then(res => { this.contactsList = res }) }, getHouseData () { getHouseData() { if (this.form.startDate && this.form.endDate) { this.getHouseTree() if (this.form.zlDetailList.length === 1) { @@ -565,33 +582,33 @@ } } }, changeType (e) { changeType(e) { if (e === 0 || e === 2) { this.cactiveTabs = 0 } else if (e === 0 || e === 1) { this.cactiveTabs = 1 } }, getDayTime (num) { const today = new Date(); const year = today.getFullYear(); const month = today.getMonth() + 1; const day = today.getDate(); getDayTime(num) { const today = new Date() const year = today.getFullYear() const month = today.getMonth() + 1 const day = today.getDate() if (!num) { return `${year}-${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day : day}`; return `${year}-${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day : day}` } else { return `${year + 1}-${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day - 1 : day - 1}`; return `${year + 1}-${month < 10 ? '0' + month : month}-${day < 10 ? '0' + day - 1 : day - 1}` } }, clearzl () { clearzl() { this.zlList = [] this.zlPrice = '' }, clearwy () { clearwy() { this.wyList = [] this.wyPrice = '' }, confirm () { confirm() { var that = this if (this.activeTabs === 0) { this.$refs.form.validate((valid) => { @@ -633,7 +650,7 @@ } } }, submit () { submit() { // 调用新建接口 this.isWorking = true create({ ...this.form }) @@ -646,26 +663,26 @@ this.isWorking = false }) }, getDate1 (e, index) { getDate1(e, index) { this.form.zlDetailList[index].startDate = e[0] this.form.zlDetailList[index].endDate = e[1] this.clearzl() }, getDate2 (e, index) { getDate2(e, index) { this.form.wyDetailList[index].startDate = e[0] this.form.wyDetailList[index].endDate = e[1] this.clearwy() }, checkHouseRoom (a, b) { checkHouseRoom(a, b) { this.ids = b.checkedKeys let arr = b.checkedKeys.map(item => { if (item.split('-')[0] == 3) { return Number(item.split('-')[1]) } }) this.form.roomIds = arr.filter(item => item !== undefined); this.form.roomIds = arr.filter(item => item !== undefined) }, getHouseTree () { getHouseTree() { tree({ startDate: this.form.startDate, endDate: this.form.endDate, @@ -681,14 +698,14 @@ }, addParamToArray(arr) { for (let i = 0; i < arr.length; i++) { const currentItem = arr[i].projectDataVOList; const currentItem = arr[i].projectDataVOList arr[i].idd = arr[i].lv + '-' + arr[i].id if (currentItem.length > 0) { this.addParamToArray(currentItem); this.addParamToArray(currentItem) } } }, generateZL () { generateZL() { getBillList({ ...this.form, billType: 0 }) .then(res => { let zlPrice = 0 @@ -703,7 +720,7 @@ this.zlList = arr }) }, generateWY () { generateWY() { getBillList({ ...this.form, billType: 1 }) .then(res => { this.wy = true @@ -719,7 +736,7 @@ this.wyList = arr }) }, addZl () { addZl() { this.form.zlDetailList.push({ circleType: 0, startDate: this.form.startDate, @@ -729,7 +746,7 @@ advanceDays: '' }) }, addWy () { addWy() { this.form.wyDetailList.push({ circleType: 0, startDate: this.form.startDate, @@ -749,62 +766,66 @@ this.form.wyDetailList.splice(index, 1) this.clearwy() }, getZLDate (e) { getZLDate(e) { this.form.zlFreeStartDate = e[0] this.form.zlFreeEndDate = e[1] this.clearzl() }, getWYDate (e) { getWYDate(e) { this.form.wyFreeStartDate = e[0] this.form.wyFreeEndDate = e[1] this.clearwy() }, getTenant (row) { getTenant(row) { this.form.renterId = row.id this.form.renterName = row.name this.form.memberId = '' this.form.memberName = '' this.getYwList() }, dele (imgaddr) { dele(imgaddr) { this.form.fileList.forEach((item, index) => { if (imgaddr === item.imgaddr) { this.form.fileList.splice(index, 1) } }) }, getUser () { getUser() { getUserList({}) .then(res => { this.agentList = res }) }, getProject () { getProject() { getProjectList({}) .then(res => { this.projectList = res this.projectList = res || [] if (this.projectList.length > 0) { this.$set(this.form, 'projectId', this.projectList[0].id) this.getHouseTree() } }) }, getCompany () { getCompany() { companyList({ type: 2 }) .then(res => { this.comparyList = res this.form.companyId = res[0].id }) }, tabsClick (val) { tabsClick(val) { this.activeTabs = val }, ctabsClick (val) { ctabsClick(val) { this.cactiveTabs = val }, handleRent () { handleRent() { this.$refs.MemberSearchRef.open() }, houseChange (e) { houseChange(e) { console.log(e) }, beforeUpload (file) { beforeUpload(file) { this.loadingInstance = Loading.service({ lock: true, text: 'Loading', @@ -812,14 +833,14 @@ background: 'rgba(0, 0, 0, 0.7)' }) }, uploadError () { uploadError() { this.$nextTick(() => { // 以服务的方式调用的 Loading 需要异步关闭 if (this.loadingInstance) { this.loadingInstance.close() } }) }, getDay () { getDay() { const now = new Date() const year = now.getFullYear() const month = now.getMonth() + 1 // 加1使其从1开始 @@ -827,9 +848,9 @@ const hours = now.getHours() const minutes = now.getMinutes() const seconds = now.getSeconds() return `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')} ${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`; return `${year}-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')} ${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}` }, uploadAvatarSuccess (file) { uploadAvatarSuccess(file) { this.$nextTick(() => { if (this.loadingInstance) { this.loadingInstance.close() @@ -838,7 +859,7 @@ const item = file.data[0] this.form.fileList.push({ ...item, fileurl: item.imgaddr, name: item.originname, userName: this.userInfo.realname, createTime: this.getDay() }) }, close () { close() { if (this.activeTabs === 0) { this.$emit('close') this.visible = false @@ -854,6 +875,7 @@ <style lang="scss" scoped> @import '@/assets/style/variables.scss'; .fixed { background: #ffffff; position: sticky; @@ -976,6 +998,7 @@ display: flex; align-items: center; justify-content: space-between; span { font-weight: 500; font-size: 14px; admin/src/views/project/components/OperaYwBuildingWindow.vue
@@ -89,7 +89,7 @@ }) }, methods: { open (title, target,type) { open(title, target, type) { this.title = title this.visible = true this.getProject() @@ -98,14 +98,14 @@ this.$nextTick(() => { this.$refs.form.resetFields() this.form[this.configData['field.id']] = null this.form.type=type this.form.type = type }) return } // 编辑 this.$nextTick(() => { console.log('----'); console.log('----') this.getDetail(target.id) }) }, @@ -117,6 +117,10 @@ getProject() { getProjectList({}).then(res => { this.projectList = res || [] if (this.projectList.length > 0) { this.$set(this.form, 'projectId', this.projectList[0].id) // this.changeProject(this.projectList[0].id) } }) } } admin/src/views/project/components/OperaYwRoomWindow.vue
@@ -101,6 +101,8 @@ this.title = title this.visible = true this.getProject() this.buildList = [] this.floorList = [] // 新建组织 if (target == null) { this.$nextTick(() => { @@ -115,8 +117,8 @@ this.getDetail(target.id) }) }, confirm () { if(!this.form.feeArea){ confirm() { if (!this.form.feeArea) { this.form.feeArea = this.form.rentArea } if (this.form.id == null || this.form.id === '') { @@ -143,6 +145,10 @@ getProject() { getProjectList({}).then(res => { this.projectList = res || [] if (this.projectList.length > 0) { this.$set(this.form, 'projectId', this.projectList[0].id) this.changeProject(this.projectList[0].id) } }) }, @@ -150,6 +156,9 @@ this.form.buildingId = '' getBuildList({ projectId: e }).then(res => { this.buildList = res || [] // if(this.buildList.length > 0){ // this.form.buildingId = this.buildList[0].id // } }) }, changeBuild(e) { admin/src/views/workorder/components/OperaYwWorkorderWindow.vue
@@ -140,7 +140,7 @@ this.visible = true this.getProject() this.getCate() // 新建 // 新建 if (target == null) { this.form = { id: null, @@ -192,7 +192,11 @@ }, getProject() { getProjectList({}).then(res => { this.projectList = res this.projectList = res || [] if(this.projectList.length > 0){ this.$set(this.form, 'projectId', this.projectList[0].id) this.getBuild(this.projectList[0].id) } }) }, getBuild(projectId) { @@ -200,7 +204,11 @@ this.$set(this.form, 'floorId', '') this.$set(this.form, 'roomId', '') getBuildList({ projectId }).then(res => { this.buildList = res this.buildList = res || [] // if(projectId && this.buildList.length > 0){ // this.$set(this.form, 'buildingId', this.buildList[0].id) // this.changeBuild(this.buildList[0].id) // } }) }, changeBuild(e) { admin/src/views/workorder/components/detail.vue
@@ -49,11 +49,21 @@ <div class="value" v-if="info.fileList == null || !info.fileList.length">无</div> <div class="value" v-if="info.fileList != null && info.fileList.length"> <div v-for="item in info.fileList" :key="item.id" style="display: inline;margin-right: 20px"> <video v-if="item.fileurlFull && item.fileurlFull.endsWith('.mp4')" ref="videoRef" controls preload="auto" style="width: 80px;height: 80px;object-fit: contain;" :src="item.fileurlFull" /> <el-image v-else-if="item.fileurlFull" style="width:80px; height: 80px" :src="item.fileurlFull" <!-- <video v-if="item.fileurlFull && item.fileurlFull.endsWith('.mp4')" ref="videoRef" controls preload="auto" style="width: 80px;height: 80px;object-fit: contain;" :src="item.fileurlFull" /> --> <el-image v-if="item.type == 0" style="width:80px; height: 80px" :src="item.fileurlFull" :preview-src-list="[item.fileurlFull]"> </el-image> </div> </div> </div> <div v-if="info.fileList && info.fileList.length > 0 && info.fileList.filter(i => i.type == 1).length > 0" class="item max"> <div class="la">问题视频</div> <div class="value"> <div v-for="item in info.fileList" :key="item.id" style="display: inline;margin-right: 20px"> <video v-if="item.type == 1" ref="videoRef" controls preload="auto" style="width: 240px;height: 160px;object-fit: contain;" :src="item.fileurlFull" /> </div> </div> </div> @@ -61,7 +71,7 @@ <div class="side"> <div class="title">工单流转记录</div> <div class="flow_list"> <div class="item" v-for="item,i in info.logList"> <div class="item" v-for="item, i in info.logList"> <div class="icon"> <div class="dian"></div> <div v-if="i < info.logList.length - 1" class="line"></div> @@ -76,7 +86,9 @@ </div> </div> </div> <div class="title">{{ info.dealStatus == 0 || info.dealStatus == 1 ? '工单处理' : '处理结果' }}</div> <div class="title" v-if="info.dealStatus == 2 || info.dealStatus == 0 || (info.dealStatus == 1 && info.dealUserId === userInfo.id)"> {{ info.dealStatus == 0 || info.dealStatus == 1 ? '工单处理' : '处理结果' }}</div> <el-form :model="param" ref="form" :rules="rules"> <template v-if="info.dealStatus == 0 || info.dealStatus == null"> <el-form-item label="处理方式" prop="dealType"> @@ -84,7 +96,7 @@ <el-radio v-model="param.dealType" :label="0">指派</el-radio> <el-radio v-model="param.dealType" :label="1">直接回复</el-radio> </div> </el-form-item> </el-form-item> <el-form-item v-if="param.dealType == 0" label="指派给" prop="dealUserId"> <el-select v-model="param.dealUserId" clearable filterable class="w400"> <el-option v-for="item in staffList" :label="item.realname" :value="item.id"></el-option> @@ -104,8 +116,8 @@ </el-form-item> <el-form-item label="现场图片"> <div class="file_list"> <el-upload class="avatar-uploader" :data="uploadData" :auto-upload="true" :action="uploadImgUrl" :show-file-list="false" :on-success="uploadAvatarSuccess" :on-error="uploadError" <el-upload class="avatar-uploader" :data="uploadData" :auto-upload="true" :action="uploadImgUrl" :show-file-list="false" :on-success="uploadAvatarSuccess" :on-error="uploadError" :before-upload="beforeUpload"> <div class="upload_wrap"> <i class="el-icon-plus avatar-uploader-icon"></i> @@ -223,8 +235,8 @@ const { id } = this detailById(id).then(res => { this.info = res if(this.info.dealStatus == 1){ this.$set(this.param, 'getDate',dayjs().format('YYYY-MM-DD HH:mm:ss') ) if (this.info.dealStatus == 1) { this.$set(this.param, 'getDate', dayjs().format('YYYY-MM-DD HH:mm:ss')) } }) }, @@ -316,13 +328,15 @@ } .primaryColor { border: 1px solid rgba(63, 126, 239,.2); background-color: rgba(63, 126, 239,.2); border: 1px solid rgba(63, 126, 239, .2); background-color: rgba(63, 126, 239, .2); } .green{ .green { background-color: rgba(83, 183, 148, .2); border: 1px solid rgba(83, 183, 148, .2); } .gray { color: #333333; background-color: rgba(128, 128, 128, .2); @@ -352,7 +366,8 @@ width: 100%; display: flex; align-items: center; .la{ .la { margin-bottom: 0; width: 72px; } @@ -362,38 +377,47 @@ width: 100%; } } .main_content{ .main_content { display: flex; .side{ .side { width: 370px; .title{ .title { font-size: 14px; } .flow_list{ .item{ .flow_list { .item { display: flex; .icon{ .icon { width: 28px; display: flex; flex-direction: column; align-items: center; .dian{ .dian { width: 12px; height: 12px; border-radius: 50%; background-color: #e89e42; } .line{ .line { width: 1px; height: 100%; background-color: #e89e42; } } .content{ .content { font-size: 12px; color: #999999; padding-bottom: 12px; .name{ .name { font-size: 13px; color: #333333; } h5/pages/index.vue
@@ -1,6 +1,6 @@ <template> <view class="main_app"> <view class="hone_name title">{{ userInfo.realname }},欢迎登录</view> <view class="hone_name title">{{ userInfo.realname }},欢迎登录~</view> <view class="home_con"> <image class="bg" src="@/static/home/home_bg.jpg" mode=""></image> <view class="h1">阜宁文体中心</view> @@ -24,14 +24,15 @@ </view> </template> <script> import { logoutPost } from '@/api' <script> import { logoutPost } from '@/api' export default { data() { return { userInfo: uni.getStorageSync('userInfo') || {}, list1: [ { list1: [{ name: '新增工单', url: '/pages/workOrder/edit', img: require('@/static/home/ic_xinzenggongdan@2x.png'), @@ -74,12 +75,15 @@ url: item.url }) }, loginOut() { logoutPost() this.$store.commit('empty') uni.redirectTo({ url: '/pages/login' }) loginOut() { logoutPost().then(res => { this.$store.commit('empty') setTimeout(() => { uni.redirectTo({ url: '/pages/login' }) }, 300) }) // window.location.href= 'https://zhcg.fnwtzx.com/fn_h5' }, h5/pages/login.vue
@@ -45,7 +45,7 @@ code: '' }, downTime: 0, code: '' code: '111' // code: '' } }, h5/pages/operation/device.vue
@@ -83,7 +83,8 @@ import { uploadUrl, ywDevicePost, ywDeviceCreate ywDeviceCreate, getPointRecordByCode } from '@/api' import dayjs from 'dayjs'; import { @@ -122,7 +123,7 @@ }, handleP() { const { param, param, fileList } = this ywDeviceCreate({ @@ -285,8 +286,19 @@ }, (decodeText, decodeResult) => { if (decodeText) { //这里decodeText就是通过扫描二维码得到的内容 this.$set(this.param, 'deviceCode', decodeText) this.stopScan(); //关闭扫码功能 this.$set(this.param, 'deviceCode', decodeText) this.stopScan(); //关闭扫码功能 getPointRecordByCode({ // taskId: this.id, pointCode: decodeText }).then(ress => { if (ress.data) { console.log('ress', ress.data); } else { this.showToast('未匹配到巡检点,请重新扫描') } }) } }, (err) => { h5/pages/polling/detail.vue
@@ -34,7 +34,10 @@ <view class="content"> <view class="head"> <view>{{item.pointName}}</view> <view class="status" :class="{ gray: item.status == 1 }">{{ item.status == 1 ? '已巡检' : '待巡检' }}</view> <view class="status" :class="{ gray: item.status == 1 }"> <image v-if="item.status == 1" src="@/static/plan_ic_finish@2x.png" class="icon" mode=""></image> <text>{{ item.status == 1 ? '已巡检' : '待巡检' }}</text> </view> </view> <template v-if="item.status == 1"> <view class="line"> @@ -43,7 +46,10 @@ </view> <view class="line"> <view class="la">巡检时间:</view> <view class="val">{{item.dealDate}}</view> <view class="val"> <text>{{item.dealDate}}</text> <text v-if="item.status == 1" class="detail">查看详情</text> </view> </view> </template> <view class="desc" v-else>{{item.content}}</view> @@ -100,11 +106,11 @@ }, onLoad(option) { this.id = option.id // this.getDetail() }, onShow() { this.getDetail() }, // onShow() { // this.getDetail() // }, methods: { openSc() { this.isScaning = true; @@ -164,7 +170,7 @@ this.info = res.data let time = new Date(res.data.startDate).getTime() console.log('res.data.startDate', new Date().getTime()); this.flag = new Date().getTime() > time this.flag = new Date().getTime() > time && (this.info.status == 0 || this.info.status == 1) }) ywPatrolTaskRecord({ capacity: 999, @@ -268,14 +274,15 @@ margin-bottom: 20rpx; .la { color: #666666; color: #666666; } } .list { height: calc(100vh - 720rpx); overflow: auto; height: calc(100vh - 490rpx); overflow: auto; padding-bottom: 160rpx; .item { width: 690rpx; height: 188rpx; @@ -288,7 +295,18 @@ margin-bottom: 20rpx; .line { margin-bottom: 10rpx; margin-bottom: 10rpx; width: 100%; .val{ display: flex; justify-content: space-between; align-items: center; flex: 1; .detail{ color: $primaryColor; font-size: 26rpx; } } } .icon { @@ -311,9 +329,19 @@ margin-bottom: 16rpx; .status { offset-anchor: 28rpx; font-size: 28rpx; color: $primaryColor; font-weight: 400; font-weight: 400; display: flex; align-items: center; .icon{ width: 40rpx; height: 40rpx; // border-radius: 50%; // overflow: hidden; background: none; } } .gray { h5/pages/polling/point.vue
@@ -31,7 +31,7 @@ <video v-if="item.type == 1" :src="item.fileurlFull" :controls="false"></video> </view> </view> <view class="desc">{{ info.dealInfo }}</view> <view v-if="info.dealInfo" class="desc">{{ info.dealInfo }}</view> <view class="line line_s"> <view class="la">巡检人:</view> <view class="val">{{ info.realname }}</view> @@ -78,11 +78,12 @@ </view> </view> <view class="label">处理说明</view> <textarea v-model="handleParam.dealInfo" placeholder="请填写处理说明" placeholder-class="placeholder9" /> <view class="label" style="margin-bottom: 10rpx;">处理说明</view> <textarea v-model="handleParam.dealInfo" :maxlength="-1" placeholder="请填写处理说明" placeholder-class="placeholder9" /> </view> </view> <view class="sub_btn" @click="onSubmit">确认巡检</view> <view v-if="info.status == 0" class="sub_btn" @click="onSubmit">确认巡检</view> <!-- --> <u-popup :show="showUpload" @close="showUpload = false" closeOnClickOverlay> <view class="sel_upload_wrap"> @@ -149,34 +150,38 @@ fileList, id } = this if (handleParam.dealStatus == 1) { return uni.showModal({ title: '温馨提示', content: '巡检结果异常,是否前往提交工单?', success: function(res) { if (res.confirm) { patrolData({ ...handleParam, multifileList: fileList, id, }).then(res => { this.showToast('操作成功') uni.navigateBack() }) patrolData({ ...handleParam, multifileList: fileList, id, }).then(res => { if (handleParam.dealStatus == 1) { return uni.showModal({ title: '温馨提示', content: '巡检结果异常,是否前往提交工单?', success: (res) => { if (res.confirm) { this.showToast('操作成功') setTimeout(() => { uni.redirectTo({ url: '/pages/workOrder/edit' }) }, 300) }else{ this.showToast('操作成功') setTimeout(() => { uni.navigateBack() }, 300) } } } }); } else { patrolData({ ...handleParam, multifileList: fileList, id, }).then(res => { }); } else { this.showToast('操作成功') uni.navigateBack() }) } setTimeout(() => { uni.navigateBack() }, 300) } }) }, getDetail() { const { @@ -360,10 +365,11 @@ } .sub_btn { position: fixed; bottom: 68rpx; left: 40rpx; // position: fixed; // bottom: 68rpx; // left: 40rpx; width: 670rpx; margin-top: 60rpx; height: 88rpx; background: $primaryColor; box-shadow: 0rpx 8rpx 20rpx 0rpx rgba(0, 104, 255, 0.3); @@ -417,7 +423,7 @@ textarea { box-sizing: border-box; width: 690rpx; min-height: 200rpx; min-height: 140rpx; background-color: #f7f7f7; font-size: 28rpx; color: #333333; h5/pages/polling/task.vue
@@ -44,13 +44,17 @@ <view class="line" @click="itemClick(item)">执行时间:{{ item.startDate.slice(11, 16) }} 至 {{ item.endDate.slice(11, 16) }}</view> <view class="line"> <view @click="itemClick(item)">完成情况:{{item.finishNum || 0}}/{{item.patrolNum}}</view> <view v-if="param.queryStatus == '0,1'" class="btn" @click="openSc(item)"> <view v-if="param.queryStatus == '0,1' && item.flag && (item.status == 0 || item.status == 1)" class="btn" @click="openSc(item)"> <image src="@/static/side/ic_saoma@2x.png" class="saoma" mode=""></image> <view>扫码巡检</view> </view> </view> </view> </view> <view v-if="list.length == 0" class="empty_wrap"> <image src="@/static/empty.png" mode=""></image> <view class="">暂无数据</view> </view> </view> </scroll-view> @@ -93,7 +97,9 @@ // activeItem: {} }; }, onLoad() { onShow() { this.page = 1 this.list = [] this.getList() }, methods: { @@ -184,7 +190,11 @@ page, capacity: 10 }).then(res => { this.list = [...this.list, ...res.data.records] this.list = [...this.list, ...res.data.records] this.list.forEach(item => { let time = new Date(item.startDate).getTime() item.flag = new Date().getTime() > time }) this.total = res.data.total }) } @@ -272,10 +282,11 @@ } .scroll_Y { height: calc(100vh - 230rpx); height: calc(100vh - 130rpx); } .list { .list { .item { display: flex; // height: 290rpx; h5/pages/workOrder/detail.vue
@@ -11,7 +11,12 @@ <view class="file_list"> <view class="file" v-for="(item,index) in info.fileList"> <image v-if="item.type == 0" :src="item.fileurlFull" mode="aspectFill"></image> <video v-if="item.type == 1" :src="item.fileurlFull" :controls="false"></video> <!-- <video v-if="item.type == 1" :src="item.fileurlFull" :controls="false"></video> --> <view v-if="item.type == 1" @click="videoClick(item)" class="video_wrap"> <video :src="item.fileurlFull" initial-time="0.01" :show-center-play-btn="false" :controls="false" class="video" :enable-progress-gesture="false" autoplay muted /> <image src="@/static/play.png" class="play" mode=""></image> </view> </view> </view> <view class="content"> @@ -23,7 +28,7 @@ <view class="la">上报人:</view> <view class="val">{{ info.creatorName }}{{info.creatorCompany ? '-' + info.creatorCompany : ''}}</view> </view> <view class="line" v-if="info.creatorPhone || info.creatorMobile"> <view class="line" v-if="info.creatorPhone || info.creatorMobile"> <view class="la">联系电话:</view> <view class="val">{{ info.creatorMobile || info.creatorPhone }}</view> </view> @@ -63,7 +68,7 @@ <image src="@/static/side/phoneed.png" class="icon"></image> <text>上报人</text> </view> <view class="btn active" @click="isShowHandle = true">去处理</view> <view class="btn active" @click="handleOpen">去处理</view> </view> <!-- --> <u-popup :show="showUpload" @close="showUpload = false" zIndex="10076" closeOnClickOverlay> @@ -74,8 +79,8 @@ </u-popup> <!-- --> <!-- 工单处理 --> <u-popup :show="isShowHandle" :round="10" :safeAreaInsetBottom="true" mode="bottom" closeable @close="isShowHandle = false"> <u-popup :show="isShowHandle" :round="10" :safeAreaInsetTop="true" :safeAreaInsetBottom="true" mode="bottom" closeable @close="isShowHandle = false"> <view class="appr_modal"> <view class="title">工单处理</view> <view class="df_sb"> @@ -118,13 +123,18 @@ <u-datetime-picker :minDate="new Date().getTime()" :show="isShowHandleDate" @confirm="confirmHandleDate" @cancel="isShowHandleDate = false" mode="datetime"></u-datetime-picker> <!-- --> <view v-if="videoPlay" class="video_app"> <video controls autoplay muted x5-video-player-type="h5" x5-video-player-fullscreen="true" id="myvideo" :src="videoUrl" @fullscreenchange="screenChange"></video> <view class="bg" @click="closeVideo"></view> </view> </view> </template> <script> import { uploadUrl, ywWorkorderD, ywWorkorderD, ywWorkorderDeal } from '@/api' import dayjs from 'dayjs'; @@ -135,10 +145,14 @@ info: {}, showUpload: false, isShowHandle: false, isShowHandleDate: false, isShowHandleDate: false, userInfo: uni.getStorageSync('userInfo') || {}, handleParam: {}, dealFileList: [] dealFileList: [], videoPlay: false, videoContext: null, videoUrl: '' }; }, onLoad(option) { @@ -147,25 +161,55 @@ this.getDetail() }, methods: { onSubmit() { const { handleParam, dealFileList, id } = this if (!handleParam.dealTime) return this.showToast('处理时间不能为空') ywWorkorderDeal({ ...handleParam, id, dealFileList }).then(res => { if(res.code == 200){ this.showToast('操作成功') uni.navigateBack() } handleOpen() { this.isShowHandle = true this.$set(this.handleParam, 'dealTime', dayjs().format('YYYY-MM-DD HH:mm:ss')); }, videoClick(item) { this.videoPlay = true; this.videoContext = uni.createVideoContext("myvideo", this); // this这个是实例对象 必传 this.videoUrl = item.fileurlFull; this.videoContext.requestFullScreen(); this.$nextTick(() => { this.videoContext.play(); }) }, handleCall() { const { info } = this uni.makePhoneCall({ phoneNumber: info.creatorMobile }); }, screenChange(e) { let fullScreen = e.detail.fullScreen // 值true为进入全屏,false为退出全屏 if (!fullScreen) { //退出全屏 this.videoPlay = false // 隐藏播放盒子 } }, closeVideo() { this.videoPlay = false this.videoContext = null }, onSubmit() { const { handleParam, dealFileList, id } = this if (!handleParam.dealTime) return this.showToast('处理时间不能为空') ywWorkorderDeal({ ...handleParam, id, dealFileList }).then(res => { if (res.code == 200) { this.showToast('操作成功') uni.navigateBack() } }) }, handleCall() { const { info } = this uni.makePhoneCall({ phoneNumber: info.creatorMobile }); }, getDetail() { ywWorkorderD(this.id).then(res => { @@ -323,7 +367,7 @@ image, video { width: 156rpx; width: 156rpx; height: 156rpx; } } @@ -488,28 +532,37 @@ display: flex; flex-wrap: wrap; margin-bottom: 30rpx; max-height: 362rpx; overflow-y: auto; margin-right: -30rpx; } .adduser_list_item_ipt1_upload { margin-top: 24rpx; width: 156rpx; height: 156rpx; margin-right: 24rpx; border: 2rpx solid #e5e5e5; margin-right: 22rpx; border: 1rpx solid #e5e5e5; background: #f7f7f7; color: #666666; font-size: 22rpx; box-sizing: border-box; display: flex; flex-direction: column; align-items: center; justify-content: center; position: relative; &:nth-of-type(4n) { margin-right: 0; } .close { position: absolute; right: -20rpx; top: -20rpx; z-index: 9999; background-color: #fff; } image { @@ -523,4 +576,46 @@ } } } .video_wrap { position: relative; border: 1px solid; width: 156rpx; height: 156rpx; border-radius: 4rpx; .play { width: 60rpx !important; height: 60rpx !important; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } } .video_app { overflow: hidden; position: fixed; left: 0; top: 0; width: 100vw; height: 100vh; display: flex; align-items: center; z-index: 9990; .bg { background-color: rgba(0, 0, 0, .6); position: absolute; width: 100%; height: 100%; z-index: -1; } video { width: 100%; height: 42vh; } } </style> h5/pages/workOrder/edit.vue
@@ -51,7 +51,7 @@ <u-icon class="close" size="20" name="close-circle-fill" color="red" @click="fileDel('fileList', i)"></u-icon> <image v-if="item.type == 0" :src="item.fileurlFull" mode="widthFix"></image> <video v-if="item.type == 1" :src="item.fileurlFull" :controls="false"></video> <video v-if="item.type == 1" :show-center-play-btn="false" :src="item.fileurlFull" :controls="false"></video> </view> </view> </view> @@ -116,7 +116,7 @@ showCate2: false, areaType: [ [{ name: '室内装修', name: '室内维修', id: 0 }, { @@ -431,7 +431,10 @@ position: absolute; right: -20rpx; top: -20rpx; z-index: 9999; z-index: 9999; background-color: #fff; border-radius: 50%; overflow: hidden; } image { h5/pages/workOrder/list.vue
@@ -32,7 +32,7 @@ <scroll-view scroll-y="true" class="scroll_Y" @scrolltolower="scrolltolower"> <view class="list"> <view class="item" v-for="item in list" @click="itemClick(item)"> <image v-if="item.dealStatus == 0" src="@/static/side/workordered.png" class="icon"></image> <image v-if="item.dealStatus == 0 || item.dealStatus == 1" src="@/static/side/workordered.png" class="icon"></image> <image v-else src="@/static/side/workorder.png" class="icon"></image> <view class="content"> <view class="name_wrap line"> @@ -216,7 +216,7 @@ } .scroll_Y{ height: calc(100vh - 320rpx); height: calc(100vh - 250rpx); } .list { .item { @@ -224,7 +224,7 @@ // height: 290rpx; padding: 30rpx 0; border-bottom: 2rpx solid #E5E5E5; .icon { width: 80rpx; height: 80rpx; h5/static/plan_ic_finish@2x.png
h5/static/play.png
h5/utils/config.js
@@ -1,6 +1,6 @@ // export const baseUrl = 'gateway_interface/' export const baseUrl = 'gateway_interface/' // export const baseUrl = 'http://192.168.0.173/gateway_interface/' export const baseUrl = 'https://zhcg.fnwtzx.com/gateway_interface/' // export const baseUrl = 'https://zhcg.fnwtzx.com/gateway_interface/' export const uploadAvatar = `${baseUrl}visitsAdmin/cloudService/web/public/uploadFtp.do` export const uploadUrl = `${baseUrl}visitsAdmin/cloudService/public/uploadBatch`