Initial commit

This commit is contained in:
lnljyang
2025-12-30 09:44:46 +08:00
commit 82b8d21506
147 changed files with 39113 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
/.idea/
/.hbuilderx/
/unpackage/dist/dev/
/unpackage/dist/build/
/node_modules/

65
App.vue Normal file
View File

@@ -0,0 +1,65 @@
<script>
import initApp from "@/utils/init.js"
export default {
options: {
styleIsolation: 'shared', // 解除样式隔离
},
onLaunch: function() {
initApp();
// console.log(uni.$u.props)
// console.log('App Launch')
try {
uni.hideTabbar({})
} catch (e) {
}
},
onShow: function() {
// console.log('App Show')
try {
uni.hideTabbar({})
} catch (e) {
}
},
onHide: function() {
// console.log('App Hide')
}
}
</script>
<style lang="less">
/*每个页面公共css */
.u-text {
.u-text__value {
font-size: 14px !important;
}
}
.u-button:after {
border: unset !important;
}
.u-button {
font-weight: bold;
}
.u-cell__body{
padding: 10px 0px !important;
}
.uni-scroll-view {
::-webkit-scrollbar {
width: 0;
height: 0;
background-color: transparent;
}
}
</style>
<style>
/**
* 设置页面安全区域
*/
page {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
</style>

36
README.en.md Normal file
View File

@@ -0,0 +1,36 @@
# 资产管理平台小程序
#### Description
{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**}
#### Software Architecture
Software architecture description
#### Installation
1. xxxx
2. xxxx
3. xxxx
#### Instructions
1. xxxx
2. xxxx
3. xxxx
#### Contribution
1. Fork the repository
2. Create Feat_xxx branch
3. Commit your code
4. Create Pull Request
#### Gitee Feature
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
4. The most valuable open source project [GVP](https://gitee.com/gvp)
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

39
README.md Normal file
View File

@@ -0,0 +1,39 @@
# 资产管理平台小程序
#### 介绍
{**以下是 Gitee 平台说明,您可以替换此简介**
Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN。专为开发者提供稳定、高效、安全的云端软件开发协作平台
无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)}
#### 软件架构
软件架构说明
#### 安装教程
1. xxxx
2. xxxx
3. xxxx
#### 使用说明
1. xxxx
2. xxxx
3. xxxx
#### 参与贡献
1. Fork 本仓库
2. 新建 Feat_xxx 分支
3. 提交代码
4. 新建 Pull Request
#### 特技
1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md
2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com)
3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目
4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目
5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help)
6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)

31
api/annualReview.js Normal file
View File

@@ -0,0 +1,31 @@
import axios from "@/utils/request";
export default {
queryTakePageList(params) {
return axios.post(`/vehicle/vehicleAnnualInspection/queryPageList`, params); // 年审列表
},
getTakeId(params) {
return axios.get(`/vehicle/vehicleAnnualInspection/getVoById`, params); // 年审详情
},
getAnnualInspectionStatusName(params) {
return axios.get(`/dic/queryByDicType`, {
dicType: "dic_annual_inspection_status",
}); // 字典数据
},
save(params) {
return axios.post(`/vehicle/vehicleAnnualInspection/save`, params); // add edit
},
queryIdNames(params) {
return axios.get(`/annualReviewServiceStation/queryIdNames`, params); // 年检服务站名称
},
getToDo(params) {
return axios.get(`/vehicle/vehicleAnnualInspection/getToDo`, params); // 年检服务站名称
},
//获取年审服务站列表
// queryStationPageList(params) {
// return axios.post(
// `/vehicle/annualInspectionServiceStation/queryPageList`,
// params
// ); // 年审列表
// },
};

47
api/audit.js Normal file
View File

@@ -0,0 +1,47 @@
import axios from "@/utils/request";
export default {
// queryAuditList(params) {
// return axios.post(`/truckRentTask/queryTakePageList`, params);
// },
//获取待我审批/getWaitApprovePageList
queryAuditList(params) {
return axios.get(`/contract/getWaitApprovePageList`, params);
},
//获取已审批
queryAuditedList(params) {
return axios.get(`/contract/getApprovedPageList`, params);
},
//审批历史记录
getFlowTaskHistoryList(params) {
return axios.get(`/flow/getFlowTaskHistoryList`, params);
},
getAuditId(params) {
return axios.get(`/contract/getById`, params);
},
//审批通过
approve(params) {
return axios.post(`/flow/approve`, params);
},
//审批驳回
reject(params) {
return axios.post(`/flow/reject`, params);
},
//审批流程回调业务
changeStatusByFlowTask(params) {
return axios.post(`/contract/changeStatusByFlowTask`, params);
},
//生成提车前应收款 ==yongyin
makeContractBill(params) {
return axios.post(`/contract/makeContractBill`, params);
},
getSalesManagerDic() {
return axios.get(`/dic/queryByDicType`, { dicType: "sales_manager" });
},
getAddress(params) {
return axios.post(`/baidumap/getAddress`, params);
},
};

0
api/dic.js Normal file
View File

23
api/examination.js Normal file
View File

@@ -0,0 +1,23 @@
import axios from "@/utils/request";
export default {
//考场
queryPage(params) {
return axios.get("/trainExam/queryPageListForCurrentUser",params);
},
//考试记录
examRecords(params) {
return axios.get("/trainExamRecord/queryPageListForDriver",params);
},
getExamPaper(params){
return axios.get("/trainExam/getVoById",params);
},
//获取考试后的试卷
getDoneExamPaper(params){
return axios.get("/trainExamRecord/queryVoById",params);
},
//提交交卷
rollIn(params){
return axios.post("/trainExamRecord/submitExam",params);
}
}

25
api/failure.js Normal file
View File

@@ -0,0 +1,25 @@
import axios from "@/utils/request";
export default {
queryPageList(params) {
return axios.get(`/run/failure/queryPageForWeixin`, params);
},
getTakeId(params) {
return axios.get(`/run/failure/getById`, params);
},
getMaintain(params) {
return axios.get(`/maintain/queryPage`, params); // 维修站信息
},
add(params){
return axios.post(`/run/failure/add`, params); // 添加
},
edit(params){
return axios.put(`/run/failure/edit`, params); // 修改
},
queryTruckRentInfo(params) {
return axios.get(`/contractRentTruck/queryTruckRentInfo`, params); // 查询单个车辆租赁信息
},
getMaintainanceList(params) {
return axios.get(`/maintain/queryPage`, params) // 查询维修站点分页
}
}

10
api/fault.js Normal file
View File

@@ -0,0 +1,10 @@
import axios from "@/utils/request";
export default {
addById(params) {
return axios.put(`/run/failure/mobileReport`, params);
},
queryPageList(params){
return axios.get("/run/failure/queryPage",params);
}
}

16
api/index.js Normal file
View File

@@ -0,0 +1,16 @@
/**
* url 映射
* @author WangLongFei/Alisdon <920124512@qq.com>
*/
const files = require.context('../api', false, /\.js$/);
const modules = {};
files.keys().forEach(key => {
if (key !== './index.js') {
modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default;
}
});
export default {
...modules
};

22
api/login.js Normal file
View File

@@ -0,0 +1,22 @@
import axios from "@/utils/request";
export default {
loginByPhoneForDriver(params) {
return axios.post(`/auth/loginByPhoneForDriver`, params);
},
loginDriver(params) {
return axios.post(`/auth/loginForDriver`, params);
},
loginUser(params) {
return axios.post(`/auth/login`, params);
},
logout() {
return axios.get(`/auth/logout`);
},
getUserInfo() {
return axios.get(`/auth/getLoginUserInfo`);
},
getUserMenu() {
return axios.get(`/menu/userMenu`);
},
};

32
api/maintainTodo.js Normal file
View File

@@ -0,0 +1,32 @@
import axios from "@/utils/request";
//保养待办接口
export default {
queryPageList(params) {
return axios.get(`/maintenanceAgent/queryPageList`, params);
},
add(params) {
return axios.put(`/maintenanceAgent/add`, params); //接口在车辆整备那边调用
},
edit(params) {
return axios.put(`/maintenanceAgent/edit`, params);
},
getById(params) {
return axios.get(`/maintenanceAgent/getAgentInfoById`, params);
},
//获取保养记录列表
getMaintainInfoByCarId(params) {
return axios.get(`/maintenanceAgent/getNewAgentItemInfoById`, params);
},
//查看保养记录
getRecords(params) {
return axios.get(`/maintenanceAgent/getAgentItemListByIds`, params);
},
getCostInfoByIds(params) {
return axios.post(`/maintenanceAgent/getAgentItemListByIdss`, params);
},
getPayeeType() {
return axios.get(`/dic/queryByDicType`, {
dicType: "dic_maintenance_payee_type",
}); // 字典数据 收款方类型
},
};

48
api/map.js Normal file
View File

@@ -0,0 +1,48 @@
import axios from "@/utils/request";
export default {
getHydrogenList(params) {
return axios.get(`/WechatLiteApp/Station/search`, params);
},
getVehicleMarkers(params) {
return axios.post(`/WechatLiteApp/Truck/list`, params);
},
getHydrogenStationMarkers(params) {
return axios.post(`/WechatLiteApp/Station/list`, params);
},
//车辆详情
getVehicleDetail(params) {
return axios.get(`/WechatLiteApp/Truck/info`, params);
},
//氢站详情
getHydrogenDetail(params) {
return axios.get(`/WechatLiteApp/Station/info`, params);
},
//获取下拉查询车牌号列表
getAllplateNumbere(params) {
return axios.get(`/WechatLiteApp/Truck/search`, params);
},
getAddress(params) {
return axios.post(`/baidumap/getAddress`, params);
},
getTruckInfoTree(params) {
return axios.get(`/WechatLiteApp/Truck/infoTree`, params);
},
getStationInfoTree() {
return axios.get(`/WechatLiteApp/Station/infoTree`);
},
getOrgsList() {
return axios.get(`/org/queryListByPid`);
},
getPlateAreaDic() {
return axios.get(`/dic/queryByDicType`, { dicType: "dic_plateArea" }); // 付款状态
},
getOwnDepartDic() {
return axios.get(`/dic/queryByDicType`, { dicType: "businessDepartment" }); // 业务部门
},
getHydrogenCoopDic() {
return axios.get(`/dic/queryByDicType`, {
dicType: "weappMap_cooperation",
}); // 合作状态
},
};

93
api/returnCar.js Normal file
View File

@@ -0,0 +1,93 @@
import axios from "@/utils/request";
export default {
queryTakePageList(params) {
return axios.post(`/truckRentTask/queryReturnPageList`, params); // 还车单列表
},
getTakeId(params) {
return axios.get(`/truckRentTask/getReturn`, params); // 还车单详情
},
getSalesManagerDic() {
return axios.get(`/dic/queryByDicType`, { dicType: "sales_manager" }); // 字典数据
},
getAddress(params) {
return axios.post(`/baidumap/getAddress`, params); // 百度地图 获取当前位置
},
addTake(params) {
return axios.post(`/truckRentTask/addReturn`, params); // 添加还车单
},
generateWordforReturn(params) {
return axios.post(`/truckRentTask/generateWordforReturn`, params); // 生成交车单确认文档
},
validateTruckByIds(params) {
return axios.get(`/contractRentTruck/validateTruckByIds`, params); // 验证车辆是否可用
},
getFormDataTemplate(params) {
return axios.get(`/truckRentTask/getFormDataTemplate`, params); // 获取表单数据模版
},
initiateSignature(params) {
return axios.post(`/truckRentTask/initiateSignature`, params); // 发起电子签章
},
getSignatureUrl(params) {
return axios.post(`/truckRentTask/getSignatureUrl`, params); // 获取电子签章签署链接
},
fileDownloadUrl(params) {
return axios.post(`/truckRentTask/fileDownloadUrl`, params); // 下载已签署文件
},
//查询二级科目id和名称列表
getQuerySubjectTowNames(params) {
return axios.get(`/finance/financeCostType/querySubjectTowNames`, params);
// return axios.get(`/dic/queryByDicType`, {
// dicType: "dic_returncar_money_item",
// }); // 字典数据
},
// 还车
startReturn(params) {
return axios.post(`/truckRentTask/startReturn`, params);
},
// 撤销还车
cancelReturn(params) {
return axios.post(`/truckRentTask/repealReturn`, params);
},
// 还车到达
sureReturn(params) {
return axios.post(`/truckRentTask/vehicleArrival`, params);
},
// 财务费用结算
financeCost(params) {
return axios.post(`/truckRentReturnCost/checkCostInfo`, params);
},
// 编辑费用核算信息
editCostInfo(params) {
return axios.post(`/truckRentReturnCost/editCostInfo`, params);
},
// 获取费用核算信息
getCostInfo(params) {
return axios.get(`/truckRentReturnCost/getCostInfoById`, params);
},
getCostDeps() {
return axios.get(`/dic/queryByDicType`, {
dicType: "settlement_department",
}); // 字典数据
},
// 停车场列表
getParkingPageList(params) {
return axios.get(`/parking/queryPageList`, params);
},
// 维修站列表
getFixPageList(params) {
return axios.get(`/maintain/getNames`, { params });
},
updateParking(params) {
return axios.post(`/truckRentTask/updateParkingInfo`, params); // 更新停车场信息
},
getLocationTypeList() {
return axios.get(`/dic/queryByDicType`, {
dicType: "return_location_type",
});
}, // 获取还车地点类型
clearSignInfo(params) {
return axios.post(`/truckRentTask/clearSignInfo`, params); // 清除签名信息
},
};

63
api/returnCost.js Normal file
View File

@@ -0,0 +1,63 @@
import axios from "@/utils/request";
export default {
queryPageList(params) {
return axios.post(`/truckRentReturnCost/getCostPageList`, params); // 还车单列表
},
getTakeId(params) {
return axios.get(`/truckRentTask/getReturn`, params); // 还车单详情
},
//查询二级科目id和名称列表
getQuerySubjectTowNames(params) {
return axios.get(`/finance/financeCostType/querySubjectTowNames`, params);
// return axios.get(`/dic/queryByDicType`, {
// dicType: "dic_returncar_money_item",
// }); // 字典数据
},
// 财务费用结算
financeCost(params) {
return axios.post(`/truckRentReturnCost/checkCostInfo`, params);
},
// 编辑费用核算信息
editCostInfo(params) {
return axios.post(`/truckRentReturnCost/editCostInfo`, params);
},
// 获取费用核算信息
getCostInfo(params) {
return axios.get(`/truckRentReturnCost/getCheckingCostInfoById`, params);
},
getCostDeps() {
return axios.get(`/dic/queryByDicType`, {
dicType: "settlement_department",
}); // 字典数据
},
//审批流程回调业务
changeStatusByFlowTask(params) {
return axios.post(`/truckRentReturnCost/changeStatusByFlowTask`, params);
},
//还车费用核算 财务费用结算(新)
financeSettleAccounts(params) {
return axios.post(`/truckRentReturnCost/financeSettleAccounts`, params);
},
// 获取待办数量
getCostToDo() {
return axios.get(`/truckRentReturnCost/getTodoCount`);
},
// 还车费用核算 车辆是否含有无忧包服务
getIsHasOKPack(params) {
return axios.get(`/truckRentReturnCost/hasOKPack`, params);
},
//审批通过后付款确认:记录当前人、状态和时间
paymentConfirm(params) {
// {
// "id": 0,
// "status": 0
// }
return axios.post(`/truckRentReturnCost/paymentConfirm`, params);
},
// 还车费用核算 能源部门获取客户能源余额
// getEnergyBalance(params) {
// return axios.get(`/truckRentReturnCost/getEnergyBalance`, params);
// },
};

67
api/standbyVehicle.js Normal file
View File

@@ -0,0 +1,67 @@
import axios from "@/utils/request";
export default {
queryPageList(params) {
return axios.post(`/standbyVehicleMain/queryPageList`, params);
},
getTodo(params) {
return axios.get(`/standbyVehicleMain/getTodo`, params)
},
getById(params) {
return axios.get(`/standbyVehicleMain/getById`, params)
},
saveStandbyVehicleDetail(params) {
return axios.post(`/standbyVehicleMain/saveStandbyVehicleDetail`, params)
},
getVehicleBrand() {
return axios.get(`/dic/queryByDicType`, { dicType: "dic_vehicle_brand" })
},
getBrandListByMode(params) {
return axios.get(`/truck/getBrandListByMode`, params)
},
getTruckType() {
return axios.get(`/dic/queryByDicType`, { dicType: "dic_truck_type" })
},
getYesNoDic() {
return axios.get(`/dic/queryByDicType`, { dicType: "dic_yes_no" })
},
getTypeName() {
return axios.get(`/dic/queryByDicType`, { dicType: "dic_failure_type" })// 故障类型
},
getFailureStatusName() {
return axios.get(`/dic/queryByDicType`, { dicType: "dic_is_settle_status" })// 故障状态
},
getFaultSourceName() {
return axios.get(`/dic/queryByDicType`, { dicType: "dic_fault_source" })// 故障来源
},
getCityName() {
return axios.get(`/dic/queryByDicType`, { dicType: "dic_unusual_action_apply_city_code" })// 城市
},
getCostTypeName() {
return axios.get(`/dic/queryByDicType`, { dicType: "dic_fault_cost_type" })// 费用类型
},
getPayerName() {
return axios.get(`/dic/queryByDicType`, { dicType: "dic_fault_payer" })// 付款方
},
getPaymentStatusDic() {
return axios.get(`/dic/queryByDicType`, { dicType: "dic_pub_payment_status" })// 付款状态
},
saveCache(params) {
return axios.post(`/standbyVehicleMain/saveCache`, params);
},
getCache(params) {
return axios.get(`/standbyVehicleMain/getCache`, params)
},
delCache(params) {
return axios.get(`/standbyVehicleMain/delCache`, params);
},
getOpManagerPhone(params) {
return axios.get(`/standbyVehicleMain/getOperationsManagerByRegion`, params)
},
edit(params) {
return axios.put(`/standbyVehicleMain/edit`, params)
},
getFormDataListByTruckId(params) {
return axios.get(`/standbyVehicleMain/getFormDataListByTruckId`, params)
}
}

33
api/truck.js Normal file
View File

@@ -0,0 +1,33 @@
import axios from "@/utils/request";
export default {
queryInStoreList(params) {
return axios.get(`/truck/queryInStoreList`, params);
},
queryAuthListByPlateNumber(params) {
return axios.get(`/truck/queryAuthListByPlateNumber`, params);
},
getTruckPageList(params) {
return axios.get(`/truck/queryList`, params);
},
// 用户权限范围的车辆
queryAuthList(params) {
return axios.get(`/truck/queryAuthList`, params);
},
//2025.4 hefei新增列表查询所有车辆接口 只返回ID NUMBER 后增加品牌,车型
getAllTruckList(params) {
return axios.get(`/truck/getAllTruckList`, params);
},
//2025.4 hefei新增列表查询实时数据接口
getActualDataByVin(params) {
return axios.get(`/truck/getActualDataByVin`, params);
},
//用来查询车辆状态的接口judgementTruckRentStatusSwagger为“根据车牌号判断该车状态”返回出具体车辆的状态例如在库自营或者租赁状态。
getTruckRentStatus(params) {
return axios.get(`/truck/judgementTruckRentStatus`, params);
},
queryInStoreListWithStatus(params) {
//queryInStoreList的全车辆版本备车那边有需求25.9.26 任政
return axios.get(`/truck/queryInStoreListWithStatus`, params);
},
};

20
api/truckPreparation.js Normal file
View File

@@ -0,0 +1,20 @@
import axios from "@/utils/request";
export default {
queryPageList(params) {
return axios.post(`/vehiclePreparation/queryPageList`, params); // 车辆整备列表
},
getById(params) {
return axios.get(`/vehiclePreparation/getInfoById`, params); // 车辆整备详情
},
editTruckPreparation(params) {
return axios.put(`/vehiclePreparation/edit`, params); // 添加车辆整备
},
getPreTypeList() {
return axios.get(`/dic/queryByDicType`, { dicType: "preparation_type" });
}, // 获取整备类型
getPreFormDataListByTruckId(params) {
//车辆整备新检查单
return axios.get(`/vehiclePreparation/getFormDataListByTruckId`, params);
},
};

44
api/truckRent.js Normal file
View File

@@ -0,0 +1,44 @@
import axios from "@/utils/request";
export default {
queryTakePageList(params) {
return axios.post(`/truckRentTask/queryTakePageList`, params);
},
getTakeId(params) {
return axios.get(`/truckRentTask/getTakeId`, params);
},
getSalesManagerDic() {
return axios.get(`/dic/queryByDicType`, { dicType: "sales_manager" });
},
getAddress(params) {
return axios.post(`/baidumap/getAddress`, params);
},
addTake(params) {
return axios.post(`/truckRentTask/addTake`, params);
},
generateWord(params) {
return axios.post(`/truckRentTask/generateWord`, params);
},
validateTruckByIds(params) {
return axios.get(`/contractRentTruck/validateTruckByIds`, params);
},
getFormDataTemplate(params) {
return axios.get(`/truckRentTask/getFormDataTemplate`, params);
},
initiateSignature(params) {
return axios.post(`/truckRentTask/initiateSignature`, params);
},
getSignatureUrl(params) {
return axios.post(`/truckRentTask/getSignatureUrl`, params);
},
generateWord(params) {
return axios.post(`/truckRentTask/generateWord`, params);
},
fileDownloadUrl(params) {
return axios.post(`/truckRentTask/fileDownloadUrl`, params);
},
// 交车单-安全审批
safeAudit(params) {
return axios.post(`/truckRentTask/safetyAuditing`, params);
},
};

54
api/unusualActionApply.js Normal file
View File

@@ -0,0 +1,54 @@
import axios from "@/utils/request";
export default {
queryPageList(params) {
return axios.post(`/unusualAction/queryPageList`, params); // 分页
},
getTakeId(params) {
return axios.get(`/unusualAction/getInfoById`, params); // 根据id查找详情
},
//审批
auditTransaction(params) {
return axios.post(`/unusualAction/approve`, params);
},
//撤销
revokeTransaction(params) {
return axios.post(`/unusualAction/revoke`, params);
},
getRoleList(params) {
return axios.get(`/unusualActionApply/queryApproveUserList`, params); // 查询可审批的用户列表
},
edit(params) {
return axios.post(`/unusualAction/edit`, params); // 修改
},
add(params) {
return axios.post(`/unusualAction/add`, params); // 添加
},
approveAfterEdit(params) {
return axios.put(`/unusualActionApply/approveAfterEdit`, params); // 审批后修改
},
//根据id查询车辆异动信息
getUnusualInfoById(params) {
return axios.get(`/truck/getUnusualInfoById`, params);
},
//根据车牌查询是否已经存在异动
getExistResult(params) {
return axios.get(`/unusualAction/checkTruckInUnusual`, params);
},
// 获取异动目的地类型
getTransactionAddressType() {
return axios.get(`/dic/queryByDicType`, {
dicType: "transaction_address_type",
});
},
// 获取异动类型
getTransactionType() {
return axios.get(`/dic/queryByDicType`, {
dicType: "transaction_type",
});
},
//在保养待办那边有一个按钮,根据车牌新增异动
addByTruckId(params) {
return axios.post(`/unusualAction/addByTruckId`, params);
},
};

View File

@@ -0,0 +1,124 @@
## 树形层级选择器
### 简介
为统一样式而生树形层级选择器picker弹窗形式的样式和比例参照uniapp的picker和uni-data-picker组件
* 支持单选、多选、父级选择,当然也支持单层选择
* 支持Object对象属性自定义映射
* 支持显示全部选中、部分选中、未选中三种状态
* 支持快速自定义简单样式分割线、按钮、标题、对齐等深入样式可复写css
### 使用方法
`script` 中引入组件
``` javascript
import baTreePicker from "@/components/ba-tree-picker/ba-tree-picker.vue"
export default {
components: {
baTreePicker
}
```
在 `template` 中使用组件
``` javascript
<ba-tree-picker ref="treePicker" :multiple='false' @select-change="selectChange" title="选择城市"
:localdata="listData" valueKey="value" textKey="label" childrenKey="children" />
```
在 `script` 中定义打开方法,和选择监听
``` javascript
methods: {
// 显示选择器
showPicker() {
this.$refs.treePicker._show();
},
//监听选择ids为数组
selectChange(ids, names) {
console.log(ids, names)
}
}
```
在 `template` 中调用打开
``` javascript
<view @click="showPicker">调用选择器</view>
```
### 属性
|属性名|类型|默认值|说明|
|:-|:-:|:--:|-:|
|localdata|Array|[]|源数据目前支持tree结构后续会考虑支持扁平化结构|
|valueKey|String|id|指定 Object 中 key 的值作为节点数据id|
|textKey|String|name|指定 Object 中 key 的值作为节点显示内容|
|childrenKey|String|children|指定 Object 中 key 的值作为节点子集|
|multiple|Boolean|false|是否多选,默认单选|
|selectParent|Boolean|true|是否可以选父级,默认可以|
|title|String| |标题|
|titleColor|String||标题颜色|
|confirmColor|String|#0055ff|确定按钮颜色|
|cancelColor|String|#757575|取消按钮颜色|
|switchColor|String|#666|节点切换图标颜色|
|border|Boolean|false|是否有分割线,默认无|
### 数据格式
注意必须有id、name(id可通过valueKey来配置为其它键值如value)字段,且唯一
``` json
[
{
id: 1,
name: '公司1',
children: [{
id: 11,
name: '研发部',
children: [{
id: 111,
name: '张三',
},{
id: 112,
name: '李四',
}]
},{
id: 12,
name: '综合部',
} ]
},
{
id: 2,
name: '公司2',
children: [{
id: 21,
name: '研发部',
},{
id: 22,
name: '综合部',
},{
id: 23,
name: '财务部',
}, ]
},
{
id: 3,
name: '公司3'
},
{
id: 4,
name: '公司4',
children: [{
id: 41,
name: '研发部',
}]
}
]
```
</details>
### 方法
|方法名|参数|默认值|说明|
|:-|:-:|:--:|-:|
|_show()| | |显示选择器|
|_hide()| | |隐藏选择器|

View File

@@ -0,0 +1,775 @@
<!-- 树形层级选择器-->
<!-- 1支持单选多选 -->
<template>
<view>
<view
class="tree-cover"
:class="{ show: showDialog }"
@tap="_cancel"
></view>
<view class="tree-dialog" :class="{ show: showDialog }">
<view class="tree-bar">
<view
class="tree-bar-cancel"
:style="{ color: cancelColor }"
hover-class="hover-c"
@tap="_cancel"
>取消
</view>
<view class="tree-bar-title" :style="{ color: titleColor }">{{
title
}}</view>
<view
class="tree-bar-confirm"
:style="{ color: confirmColor }"
hover-class="hover-c"
@tap="_confirm"
>
{{ multiple ? "确定" : "" }}
</view>
</view>
<view
class="item u-border"
style="margin: 0 16px; border-radius: 4px"
v-if="isShowOrgPicker"
>
<u-picker
:show="showOrgPicker"
:columns="[orgList]"
keyName="orgName"
@confirm="confirmOrg"
:immediateChange="true"
@cancel="showOrgPicker = false"
>
</u-picker>
<u-input
v-model="orgName"
border="surround"
:disabledColor="'#ffffff'"
disabled
placeholder="请选择车辆主体"
@tap="showOrgPicker = true"
>
<template slot="suffix">
<u-icon
v-if="orgName"
name="close"
color="#bfc7d6"
size="50"
@tap.stop="clearClick"
></u-icon>
</template>
</u-input>
</view>
<view class="tree-view">
<scroll-view class="tree-list" :scroll-y="true">
<block v-for="(item, index) in treeList" :key="index">
<view
class="tree-item"
:style="[
{
paddingLeft: item.level * 30 + 'rpx',
},
]"
:class="{
itemBorder: border === true,
show: item.isShow,
}"
>
<view class="item-label">
<view
class="item-icon uni-inline-item"
@tap.stop="_onItemSwitch(item, index)"
>
<view
v-if="!item.isLastLevel && item.isShowChild"
class="switch-on"
:style="{ 'border-left-color': switchColor }"
>
</view>
<view
v-else-if="!item.isLastLevel && !item.isShowChild"
class="switch-off"
:style="{ 'border-top-color': switchColor }"
>
</view>
<view
v-else
class="item-last-dot"
:style="{ 'border-top-color': switchColor }"
>
</view>
</view>
<view
class="uni-flex-item uni-inline-item"
style="display: flex; align-items: center; flex: 1"
@tap.stop="_onItemSelect(item, index)"
>
<view class="item-name">
{{ item.name + (item.num ? "(" + item.num + ")" : "") }}
</view>
<view
class="item-check"
v-if="selectParent ? true : item.isLastLevel"
>
<view
class="item-check-yes"
v-if="item.checkStatus == 1"
:class="{ radio: !multiple }"
:style="{ 'border-color': confirmColor }"
>
<view
class="item-check-yes-part"
:style="{ 'background-color': confirmColor }"
>
</view>
</view>
<view
class="item-check-yes"
v-else-if="item.checkStatus == 2"
:class="{ radio: !multiple }"
:style="{ 'border-color': confirmColor }"
>
<view
class="item-check-yes-all"
:style="{ 'background-color': confirmColor }"
>
</view>
</view>
<view
class="item-check-no"
v-else
:class="{ radio: !multiple }"
:style="{ 'border-color': confirmColor }"
></view>
</view>
</view>
</view>
</view>
</block>
</scroll-view>
</view>
</view>
</view>
</template>
<script>
export default {
emits: ["select-change"],
name: "ba-tree-picker",
props: {
valueKey: {
type: String,
default: "id",
},
textKey: {
type: String,
default: "name",
},
childrenKey: {
type: String,
default: "children",
},
localdata: {
type: Array,
default: function () {
return [];
},
},
localTreeList: {
//在已经格式化好的数据
type: Array,
default: function () {
return [];
},
},
selectedData: {
type: Array,
default: function () {
return [];
},
},
title: {
type: String,
default: "",
},
multiple: {
// 是否可以多选
type: Boolean,
default: true,
},
selectParent: {
//是否可以选父级
type: Boolean,
default: true,
},
confirmColor: {
// 确定按钮颜色
type: String,
default: "", // #0055ff
},
cancelColor: {
// 取消按钮颜色
type: String,
default: "", // #757575
},
titleColor: {
// 标题颜色
type: String,
default: "", //
},
switchColor: {
// 节点切换图标颜色
type: String,
default: "", // #666
},
border: {
// 是否有分割线
type: Boolean,
default: false,
},
isShowOrgPicker: {
type: Boolean,
default: false,
},
},
data() {
return {
showDialog: false,
treeList: [],
showOrgPicker: false,
orgList: [],
orgName: "",
orgId: "",
};
},
computed: {},
methods: {
clearClick() {
this.orgName = ""; // 重置组织名称
this.orgId = ""; // 重置组织id
this.$emit("emitOrgId"); //重新获取区域
},
getOrgList() {
this.orgName = ""; // 重置组织名称
this.orgId = ""; // 重置组织id
this.$api.map.getOrgsList().then((res) => {
console.log("res:\n", res);
const errList = ["羚牛总部", "嘉兴羚牛汽车服务有限公司"];
this.orgList =
res?.filter((item) => !errList.includes(item.orgName)) || [];
});
},
confirmOrg(e) {
console.log("confirmOrg:\n", e.value[0]);
this.orgName = e.value[0].orgName;
this.orgId = e.value[0].id;
this.$emit("emitOrgId", e.value[0].id);
this.showOrgPicker = false;
},
_show() {
this.showDialog = true;
},
_hide() {
this.showDialog = false;
},
_cancel() {
this._hide();
this.$emit("cancel", "");
},
_confirm() {
//多选
let selectedList = []; //如果子集全部选中,只返回父级 id
//let selectedNames;
let currentLevel = -1;
this.treeList.forEach((item, index) => {
if (currentLevel >= 0 && item.level > currentLevel) {
} else {
if (item.checkStatus === 2) {
currentLevel = item.level;
selectedList.push({ id: item.id, type: item.type });
// selectedNames = selectedNames
// ? selectedNames + " / " + item.name
// : item.name;
} else {
currentLevel = -1;
}
}
});
//console.log('_confirm', selectedList);
this._hide();
const obj = this.orgId
? { cityFilter: selectedList, orgId: this.orgId }
: { cityFilter: selectedList };
this.$emit("select-change", obj);
},
//格式化原数据原数据为tree结构
_formatTreeData(list = [], level = 0, parentItem, isShowChild = true) {
let nextIndex = 0;
let parentId = -1;
let initCheckStatus = 0;
if (parentItem) {
nextIndex =
this.treeList.findIndex((item) => item.id === parentItem.id) + 1;
parentId = parentItem.id;
if (!this.multiple) {
//单选
initCheckStatus = 0;
} else initCheckStatus = parentItem.checkStatus == 2 ? 2 : 0;
}
list.forEach((item) => {
let isLastLevel = true;
if (item && item[this.childrenKey]) {
let children = item[this.childrenKey];
if (Array.isArray(children) && children.length > 0) {
isLastLevel = false;
}
}
let itemT = {
id: item[this.valueKey],
name: item[this.textKey],
level,
isLastLevel,
isShow: isShowChild,
isShowChild: false,
checkStatus: initCheckStatus,
orCheckStatus: 0,
parentId,
children: item[this.childrenKey],
childCount: item[this.childrenKey]
? item[this.childrenKey].length
: 0,
childCheckCount: 0,
childCheckPCount: 0,
type: item.type, //新增type字段 后端接收数据需要这个type
num: item.num, //新增num字段 只显示车辆数量 不显示行政区数量 用后退返回数据
};
if (this.selectedData.indexOf(itemT.id) >= 0) {
itemT.checkStatus = 2;
itemT.orCheckStatus = 2;
itemT.childCheckCount = itemT.children ? itemT.children.length : 0;
this._onItemParentSelect(itemT, nextIndex);
}
this.treeList.splice(nextIndex, 0, itemT);
nextIndex++;
});
//console.log(this.treeList);
},
// 节点打开、关闭切换
_onItemSwitch(item, index) {
// console.log(item)
//console.log('_itemSwitch')
if (item.isLastLevel === true) {
return;
}
item.isShowChild = !item.isShowChild;
if (item.children) {
this._formatTreeData(item.children, item.level + 1, item);
item.children = undefined;
} else {
this._onItemChildSwitch(item, index);
}
},
_onItemChildSwitch(item, index) {
//console.log('_onItemChildSwitch')
const firstChildIndex = index + 1;
if (firstChildIndex > 0)
for (var i = firstChildIndex; i < this.treeList.length; i++) {
let itemChild = this.treeList[i];
if (itemChild.level > item.level) {
if (item.isShowChild) {
if (itemChild.parentId === item.id) {
itemChild.isShow = item.isShowChild;
if (!itemChild.isShow) {
itemChild.isShowChild = false;
}
}
} else {
itemChild.isShow = item.isShowChild;
itemChild.isShowChild = false;
}
} else {
return;
}
}
},
// 节点选中、取消选中
_onItemSelect(item, index) {
//console.log('_onItemSelect')
//console.log(item)
if (!this.multiple) {
//单选
item.checkStatus = item.checkStatus == 0 ? 2 : 0;
this.treeList.forEach((v, i) => {
if (i != index) {
this.treeList[i].checkStatus = 0;
} else {
this.treeList[i].checkStatus = 2;
}
});
let selectedList = [];
let selectedNames;
selectedList.push(item);
selectedNames = item.name;
this._hide();
this.$emit("select-change", selectedList, selectedNames);
return;
}
let oldCheckStatus = item.checkStatus;
switch (oldCheckStatus) {
case 0:
item.checkStatus = 2;
item.childCheckCount = item.childCount;
item.childCheckPCount = 0;
break;
case 1:
case 2:
item.checkStatus = 0;
item.childCheckCount = 0;
item.childCheckPCount = 0;
break;
default:
break;
}
//子节点 全部选中
this._onItemChildSelect(item, index);
//父节点 选中状态变化
this._onItemParentSelect(item, index, oldCheckStatus);
},
_onItemChildSelect(item, index) {
//console.log('_onItemChildSelect')
let allChildCount = 0;
if (item.childCount && item.childCount > 0) {
index++;
while (
index < this.treeList.length &&
this.treeList[index].level > item.level
) {
let itemChild = this.treeList[index];
itemChild.checkStatus = item.checkStatus;
if (itemChild.checkStatus == 2) {
itemChild.childCheckCount = itemChild.childCount;
itemChild.childCheckPCount = 0;
} else if (itemChild.checkStatus == 0) {
itemChild.childCheckCount = 0;
itemChild.childCheckPCount = 0;
}
// console.log('>>>>index', index, 'item', itemChild.name, ' status', itemChild
// .checkStatus)
index++;
}
}
},
_onItemParentSelect(item, index, oldCheckStatus) {
//console.log('_onItemParentSelect')
//console.log(item)
const parentIndex = this.treeList.findIndex(
(itemP) => itemP.id == item.parentId
);
//console.log('parentIndex' + parentIndex)
if (parentIndex >= 0) {
let itemParent = this.treeList[parentIndex];
let count = itemParent.childCheckCount;
let oldCheckStatusParent = itemParent.checkStatus;
if (oldCheckStatus == 1) {
itemParent.childCheckPCount -= 1;
} else if (oldCheckStatus == 2) {
itemParent.childCheckCount -= 1;
}
if (item.checkStatus == 1) {
itemParent.childCheckPCount += 1;
} else if (item.checkStatus == 2) {
itemParent.childCheckCount += 1;
}
if (
itemParent.childCheckCount <= 0 &&
itemParent.childCheckPCount <= 0
) {
itemParent.childCheckCount = 0;
itemParent.childCheckPCount = 0;
itemParent.checkStatus = 0;
} else if (itemParent.childCheckCount >= itemParent.childCount) {
itemParent.childCheckCount = itemParent.childCount;
itemParent.childCheckPCount = 0;
itemParent.checkStatus = 2;
} else {
itemParent.checkStatus = 1;
}
//console.log('itemParent', itemParent)
this._onItemParentSelect(itemParent, parentIndex, oldCheckStatusParent);
}
},
// 重置数据
_reTreeList() {
this.treeList.forEach((v, i) => {
this.treeList[i].checkStatus = v.orCheckStatus;
});
},
_initTree() {
this.treeList = [];
this._formatTreeData(this.localdata);
},
},
watch: {
localdata() {
this._initTree();
},
localTreeList() {
this.treeList = this.localTreeList;
},
},
mounted() {
this._initTree();
},
};
</script>
<style scoped lang="less">
/deep/ .u-border {
border-width: 1rpx !important;
border-color: #d4c7c7 !important;
border-style: solid !important;
}
.tree-cover {
position: fixed;
top: 0rpx;
right: 0rpx;
bottom: 0rpx;
left: 0rpx;
z-index: 100;
background-color: rgba(0, 0, 0, 0.4);
opacity: 0;
transition: all 0.3s ease;
visibility: hidden;
}
.tree-cover.show {
visibility: visible;
opacity: 1;
}
.tree-dialog {
position: fixed;
top: 0rpx;
right: 0rpx;
bottom: 0rpx;
left: 0rpx;
background-color: #fff;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
z-index: 102;
top: 20%;
transition: all 0.3s ease;
transform: translateY(100%);
}
.tree-dialog.show {
transform: translateY(0);
padding-bottom: 65px;
}
.tree-bar {
/* background-color: #fff; */
height: 90rpx;
padding-left: 25rpx;
padding-right: 25rpx;
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;
}
.tree-bar-confirm {
color: #0055ff;
padding: 15rpx;
}
.tree-bar-title {
}
.tree-bar-cancel {
color: #757575;
padding: 15rpx;
}
.tree-view {
flex: 1;
padding: 20rpx;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
overflow: hidden;
height: 100%;
}
.tree-list {
flex: 1;
height: 100%;
overflow: hidden;
}
.tree-item {
display: flex;
justify-content: space-between;
align-items: center;
line-height: 1;
height: 0;
opacity: 0;
transition: 0.2s;
overflow: hidden;
}
.tree-item.show {
height: 90rpx;
opacity: 1;
}
.tree-item.showchild:before {
transform: rotate(90deg);
}
.tree-item.last:before {
opacity: 0;
}
.switch-on {
width: 0;
height: 0;
border-left: 10rpx solid transparent;
border-right: 10rpx solid transparent;
border-top: 15rpx solid #666;
}
.switch-off {
width: 0;
height: 0;
border-bottom: 10rpx solid transparent;
border-top: 10rpx solid transparent;
border-left: 15rpx solid #666;
}
.item-last-dot {
position: absolute;
width: 10rpx;
height: 10rpx;
border-radius: 100%;
background: #666;
}
.item-icon {
width: 26rpx;
height: 26rpx;
margin-right: 8rpx;
padding-right: 20rpx;
padding-left: 20rpx;
}
.item-label {
flex: 1;
display: flex;
align-items: center;
height: 100%;
line-height: 1.2;
}
.item-name {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 450rpx;
}
.item-check {
width: 40px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
}
.item-check-yes,
.item-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: #0055ff;
display: flex;
justify-content: center;
align-items: center;
box-sizing: border-box;
}
.item-check-yes-part {
width: 12px;
height: 12px;
border-top-left-radius: 20%;
border-top-right-radius: 20%;
border-bottom-right-radius: 20%;
border-bottom-left-radius: 20%;
background-color: #0055ff;
}
.item-check-yes-all {
margin-bottom: 5px;
border: 2px solid #007aff;
border-left: 0;
border-top: 0;
height: 12px;
width: 6px;
transform-origin: center;
/* #ifndef APP-NVUE */
transition: all 0.3s;
/* #endif */
transform: rotate(45deg);
}
.item-check .radio {
border-top-left-radius: 50%;
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
border-bottom-left-radius: 50%;
}
.item-check .radio .item-check-yes-b {
border-top-left-radius: 50%;
border-top-right-radius: 50%;
border-bottom-right-radius: 50%;
border-bottom-left-radius: 50%;
}
.hover-c {
opacity: 0.6;
}
.itemBorder {
border-bottom: 1px solid #e5e5e5;
}
</style>

View File

@@ -0,0 +1,88 @@
<template>
<view>
<u--input :value="select" disabled disabledColor="#ffffff" :placeholder="placeholder" border="none"></u--input>
<u-picker :show="show" :loading="loading" ref="uPicker" :columns="columns" @confirm="confirm" keyName="dicName"
@cancel="show = false"></u-picker>
</view>
</template>
<script>
import axios from "@/utils/request";
export default {
name: "dic-select",
props: {
show: {
type: Boolean,
default: false
},
code: {
type: String,
require: true
},
placeholder: {
type: String,
default: "请选择"
}
},
computed: {
select() {
if (this.value == undefined || this.value == "") {
return '';
}
for (var i = 0; i < (this.columns[0] || []).length; i++) {
const item=this.columns[0][i]
if(item.dicCode==this.value){
return item.dicName;
}
}
}
},
mounted() {
this.getDic();
},
data() {
return {
columns: [
[
]
],
loading: false,
value:undefined,
};
},
methods: {
getDic() {
const that = this;
this.loading = true;
axios.get("/dic/queryByDicType", {
"dicType": this.code
}).then(res => {
that.columns[0]=res;
that.$refs.uPicker.setColumnValues(0, res);
that.loading = false;
}).catch(error => {
that.loading = false;
this.closeShow();
});
},
confirm(e) {
this.value = e.value[0].dicCode;
this.$emit("selectChangeValue",e.value[0].dicCode)
this.$emit("selectChange",e.value[0])
this.closeShow();
},
closeShow(){
this.$emit("closeShow",false);
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,70 @@
<template>
<view>
<u-picker :show="show" :loading="loading" ref="uPicker" :columns="columns" @confirm="confirm" keyName="dicName"
@cancel="show = false"></u-picker>
</view>
</template>
<script>
export default{
name:"select-show"
props: {
show: {
type: Boolean,
default: false
},
code: {
type: String,
require: true
},
placeholder: {
type: String,
default: "请选择"
}
},
mounted() {
this.getDic();
},
data() {
return {
columns: [
[
]
],
loading: false,
value:undefined,
};
},
methods: {
getDic() {
const that = this;
this.loading = true;
axios.get("/dic/queryByDicType", {
"dicType": this.code
}).then(res => {
that.columns[0]=res;
that.$refs.uPicker.setColumnValues(0, res);
that.loading = false;
}).catch(error => {
that.loading = false;
this.closeShow();
});
},
confirm(e) {
this.value = e.value[0].dicCode;
this.$emit("selectChangeValue",e.value[0].dicCode)
this.$emit("selectChange",e.value[0])
this.closeShow();
},
closeShow(){
this.$emit("closeShow",false);
}
}
}
</script>
<style>
</style>

View File

@@ -0,0 +1,262 @@
<template>
<view class="popup" v-show="show">
<view class="bg" @tap="cancelMultiple"></view>
<view class="selectMultiple" :animation="animationData">
<view class="multipleBody">
<view class="title">
<view class="close" @tap="cancelMultiple">
取消
</view>
<view class="name">
{{title}}
</view>
<view class="confirm" @tap="confirmMultiple">
确认
</view>
</view>
<view class="list">
<view class="mask mask-top"></view>
<view class="mask mask-bottom"></view>
<scroll-view class="diet-list" scroll-y="true">
<view v-for="(item, index) in list" :class="['item', item.selected ? 'checked' : '']" @tap="onChange(index, item)">
<span>{{item.label}}</span>
<view class="icon" v-show="item.selected">
<icon type="success_no_circle" size="16" color="#2D8DFF"/>
</view>
</view>
</scroll-view>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
name:"multiple-picker",
data() {
return {
// 选中值
value: [],
// 选中列表
selected: [],
// 列表数据
list: [],
// 出场动画
animationData: {},
};
},
props: {
// 是否显示
show: {
type: Boolean,
default: false
},
// 标题
title: {
type: String,
default: ''
},
//数据列表
columns: {
type: Array,
default: [
{
label: '测试1',
value: '1',
}
]
},
// 默认选中
defaultIndex: {
type: Array,
default: [],
}
},
watch: {
// 监听是否显示
show(val) {
if(val) {
this.openMultiple();
}
}
},
methods: {
// 列点击事件
onChange(index, item) {
// 是否已选中
if(this.value.indexOf(item.value.toString()) >= 0) {
this.list[index].selected = false;
}
else {
this.list[index].selected = true;
}
// 筛选已勾选数据
this.value = [];
this.selected = [];
this.list.forEach((col_item, col_index) => {
if(col_item.selected) {
this.value.push(col_item.value.toString());
this.selected.push({
label: col_item.label,
value: col_item.value,
});
}
});
this.$emit("change", {selected: this.selected, value: this.value});
},
// 弹出框开启触发事件
openMultiple() {
// 初始化列表数据,默认勾选数据
this.value = this.defaultIndex;
this.columns.forEach((item, index) => {
this.$set(item, "selected", false);
if(this.value.indexOf(item.value.toString()) >= 0) {
item.selected = true;
}
});
this.list = Object.assign([], this.columns);
// 弹出动画
this.openAnimation();
},
// 确认
confirmMultiple() {
this.$emit("confirm", {selected: this.selected, value: this.value});
},
// 关闭/取消
cancelMultiple() {
this.$emit("cancel");
},
// 展开动画
openAnimation() {
var animation = uni.createAnimation()
animation.translate(0, 300).step({ duration: 0 });
this.animationData = animation.export();
this.$nextTick(() => {
animation.translate(0, 0).step({ duration: 300, timingFunction: 'ease' });
this.animationData = animation.export()
})
},
}
}
</script>
<style scoped lang="scss">
.popup {
width: 100%;
height: 100vh;
position: fixed;
z-index: 99999;
left: 0;
bottom: 0;
.bg {
width: 100%;
height: 100%;
background-color: rgba(black, .5);
}
}
.selectMultiple {
width: 100%;
position: absolute;
left: 0;
bottom: 0;
background-color: white;
.multipleBody {
width: 100%;
padding: 30rpx;
box-sizing: border-box;
padding-bottom: 80rpx;
.title {
font-size: 28rpx;
display: flex;
flex-direction: row;
.close {
width: 80rpx;
opacity: .5;
}
.name {
width: 530rpx;
text-align: center;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:1;
}
.confirm {
width: 80rpx;
text-align: right;
color: #2D8DFF;
}
}
.list {
width: 100%;
padding-top: 30rpx;
position: relative;
.mask {
width: 100%;
height: 120rpx;
position: absolute;
left: 0;
z-index: 2;
pointer-events: none;
&.mask-top {
top: 30rpx;
background-image: linear-gradient(to bottom, #fff, rgba(#fff, 0));
}
&.mask-bottom {
bottom: 0;
background-image: linear-gradient(to bottom, rgba(#fff, 0), #fff);
}
}
.diet-list {
max-height: 400rpx;
}
.item {
position: relative;
width: 100%;
line-height: 40rpx;
border-bottom: 1px solid rgba($color: #000000, $alpha: .05);
padding: 20rpx 0;
font-size: 30rpx;
box-sizing: border-box;
text-align: center;
span {
overflow: hidden;
display: -webkit-box;
-webkit-box-orient:vertical;
-webkit-line-clamp:1;
padding: 0 40rpx;
}
.icon {
position: absolute;
right: 10rpx;
top: 50%;
transform: translateY(-50%);
height: 16px;
}
&.checked {
color: #2D8DFF;
}
&:last-child {
border-bottom: none;
margin-bottom: 60rpx;
}
&:first-child {
margin-top: 60rpx;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,73 @@
<template>
<view class="mask">
<view class="three-bounce">
<view class="bounce1"></view>
<view class="bounce2"></view>
<view class="bounce3"></view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
};
}
}
</script>
<style>
.mask{
position: absolute;
width: 100%;
height: 100%;
left:0;
top:0;
z-index:600;
background:rgba(0,0,0,.75);
}
.three-bounce {
min-width: 60px;
min-height: 30px;
position: absolute;
left:50%;
top:50%;
transform: translateX(-50%) translateY(-50%);
z-index:100;
}
.three-bounce view {
width: 12%;
height: 12%;
min-height: 10px;
min-width: 10px;
background-color: #ffffff;
border-radius: 100%;
display: inline-block;
animation: bouncedelay 1.4s infinite ease-in-out;
animation-fill-mode: both;
}
.three-bounce .bounce1 {
animation-delay: -0.32s;
}
.three-bounce .bounce2 {
animation-delay: -0.16s;
}
@keyframes bouncedelay {
0%,
80%,
100% {
transform: scale(0.0);
}
40% {
transform: scale(1.0);
}
}
</style>

View File

@@ -0,0 +1,293 @@
$div-table-border-color: #666;
$div-table-border-width: 1upx;
@mixin fixBorderWidth($dir:none) {
@if $dir==none{
@media screen and (-webkit-device-pixel-ratio: 1) {
border-width: 1px;
}
@media screen and (-webkit-device-pixel-ratio: 2) {
border-width: .5px;
}
@media screen and (-webkit-device-pixel-ratio: 3) {
border-width: .5px;
}
}
@else{
@media screen and (-webkit-device-pixel-ratio: 1) {
border-#{$dir}-width: 1px;
}
@media screen and (-webkit-device-pixel-ratio: 2) {
border-#{$dir}-width: .5px;
}
@media screen and (-webkit-device-pixel-ratio: 3) {
border-#{$dir}-width: .5px;
}
}
}
.no-bad-table-wrap {
position: relative;
overflow: hidden;
//外层容器
.table_box_big {
overflow: auto;
width: 100%;
position: relative;
// height: 350px;
}
//工具类
.verticalV{
position: absolute;
width: 100%;
text-align: center;
left:50%;
top:50%;
transform: translateY(-50%);
}
.table_box {
overflow: auto;
// position: absolute;
}
.table_tbody_box {
// height: 300px;
// overflow: scroll;
}
//没有任何数据
.empty-data-body-box {
min-height: 100px;
line-height: 100px;
text-align: center;
color: #666;
border: 1px solid $div-table-border-color;
@include fixBorderWidth;
border-top: 0;
}
&.fix-height {
.table_box_big {
overflow-x: scroll;
overflow-y: hidden;
position: relative;
// height: 350px;
}
.table_box {
overflow: hidden;
position: absolute;
}
.table_tbody_box {
// height: 300px;
overflow: scroll;
border-bottom: 1px solid $div-table-border-color;
@include fixBorderWidth(bottom);
}
//固定高低里面的内容表格底部不要边框
.div-table-body {
border-top: 0;
border-bottom:0;
//固定高度,数据为空
&.empty-data-body-box{
border-bottom: $div-table-border-width solid $div-table-border-color;
@include fixBorderWidth(bottom);
}
}
}
//头部表格
.th,
.thead .tr,
.fixed-thead-tr {
.td {
background-color: #e0e0ea;
.td_wrap {
background-color: #e0e0ea;
}
}
}
//固定右边一列
.fixed-right {
position: absolute;
top: 0upx;
right: 0px;
z-index: 100;
// border-right: $div-table-border-width solid $div-table-border-color;
// border-left: $div-table-border-width solid $div-table-border-color;
box-shadow: -2px 0 5px rgba(0, 0, 0, .5);
}
//固定左边一列
.fixed-left {
position: absolute;
top: 0upx;
left: -1px;
z-index: 100;
border-right: $div-table-border-width solid $div-table-border-color;
border-left: $div-table-border-width solid $div-table-border-color;
@include fixBorderWidth(right);
@include fixBorderWidth(left);
box-shadow: 2px 0 5px rgba(0, 0, 0, .5);
}
.tr,
.th {
display: table-row;
&+.tr,
&+.th {
.td,
.th {
border-top: $div-table-border-width solid $div-table-border-color;
@include fixBorderWidth(top);
word-break: break-word;
}
}
}
//外层容器控制td左右居中
&.td-center{
.td {
.td_wrap{
text-align: center;
}
}
}
.td {
display: table-cell;
vertical-align: middle;
text-align: center;
box-sizing: border-box;
z-index: 1;
position: relative;
overflow: hidden;
.td_wrap {
position: relative;
padding: 10upx;
box-sizing: border-box;
overflow: hidden;
line-height: 20px;
font-size: 12px;
background: #fff;
text-align: left;
}
&.colspan {
z-index: 10;
position: absolute;
.td_wrap {
width: 100%;
height: 100%;
left: 0;
top: 0;
position: absolute;
}
}
&.rowspan {
position: absolute;
z-index: 10;
}
&.empty-cells-for-celspan {
border-left: none !important;
.td_wrap {
opacity: 0;
}
}
&.empty-cells-for-rowspan {
border-top: none !important;
.td_wrap {
opacity: 0;
}
}
&.noPadding {
padding: 0;
}
&+.td {
border-left: $div-table-border-width solid $div-table-border-color;
@include fixBorderWidth(left);
}
}
.th .td {
font-weight: bold;
}
//单选样式========》选中
.selected {
.td {
background-color: #d3e3ef;
.td_wrap {
background-color: #d3e3ef;
}
}
}
//单选样式===》禁用
.disabled {
.td {
background-color: #f8f8f9;
opacity: .6;
}
}
.div-table {
display: table;
border: $div-table-border-width solid $div-table-border-color;
@include fixBorderWidth;
box-sizing: border-box;
table-layout: fixed;
position: relative;
&.div-table-body {
border-top: 0;
}
.tbody {
display: table-row-group;
}
.thead {
display: table-header-group;
// .tr,
// .th {
//
// .td,
// .th {
// width: 120upx;
// height: 75px;
// }
// }
}
.colgroup {
display: table-column-group;
}
.col {
display: table-column;
}
.caption {
display: table-caption;
}
}
}

View File

@@ -0,0 +1,841 @@
<template>
<view
class="no-bad-table-wrap"
:class="[
tableHeight != 'auto' ? 'fix-height' : '',
celCenter ? 'td-center' : '',
]"
>
<view class="table_box_big" :style="{ height: tableHeight }">
<view class="table_box">
<!-- 头部内容 -->
<view class="div-table div-table-head">
<view class="thead">
<view class="tr">
<view
class="td selection"
v-if="selection == 'mulit'"
:style="{ width: selectionTdWidth, height: thTdHeight + 'px' }"
>
<view
:class="['td_wrap']"
:style="{
width: selectionTdWidth,
height: thTdHeight + 'px',
}"
>
<checkbox-group @change="checkboxChangeAll">
<checkbox
value="all"
color="#999"
:checked="switchAllCheckBox"
style="transform: scale(0.7)"
/>
</checkbox-group>
</view>
</view>
<view
class="td"
:style="{
width: countHeadColspanWidth(item, index),
height: thTdHeight + 'px',
}"
v-for="(item, index) in columns"
:key="item.key"
>
<view
class="td_wrap"
:style="{
width: countHeadColspanWidth(item, index, true),
height: thTdHeight + 'px',
}"
>{{ item.title }}</view
>
</view>
</view>
</view>
</view>
<!-- 头部内容 -->
<!-- 有数据情况 -->
<template v-if="list.length">
<view class="table_tbody_box" :style="{ height: talbeBodyHeight }">
<view class="div-table div-table-body">
<checkbox-group @change="checkboxChange">
<template v-for="(item, index) in list">
<view
:class="[
'tr',
rowClassNamePlus(item, index),
selection == 'single' && checkBoxList[index].$checked
? 'selected'
: '',
selection == 'single' && checkBoxList[index].$disabled
? 'disabled'
: '',
]"
@click="selectRow(item, index)"
:key="item.id"
>
<!-- 多选操作 -->
<view
class="td selection"
v-if="selection == 'mulit'"
:style="{
width: selectionTdWidth,
height: tdHeight + 'px',
}"
>
<view
:class="['td_wrap']"
:style="{
width: selectionTdWidth,
height: tdHeight + 'px',
}"
>
<checkbox
:value="checkBoxList[index].id"
color="#999"
:disabled="checkBoxList[index].$disabled"
:checked="checkBoxList[index].$checked"
style="transform: scale(0.7)"
/>
</view>
</view>
<template v-for="(tdItem, tdItemIndex) in columns">
<view
class="td"
:class="[
item.cellClassName && item.cellClassName[tdItem.key]
? item.cellClassName[tdItem.key]
: '',
spanMethod(item, tdItem, index, tdItemIndex)[
'rowspan'
] == 0
? 'empty-cells-for-rowspan'
: '',
spanMethod(item, tdItem, index, tdItemIndex)[
'colspan'
] == 0
? 'empty-cells-for-celspan'
: '',
spanMethod(item, tdItem, index, tdItemIndex)[
'rowspan'
] > 1
? 'rowspan'
: '',
spanMethod(item, tdItem, index, tdItemIndex)[
'colspan'
] > 1
? 'colspan'
: '',
]"
:style="{
height: countRowspanHeight(
item,
tdItem,
index,
tdItemIndex
),
width: countColspanWidth(
item,
tdItem,
index,
tdItemIndex
),
}"
:key="tdItem.key"
>
<view
:class="['td_wrap']"
:style="{
height: countRowspanHeight(
item,
tdItem,
index,
tdItemIndex
),
width: countColspanWidth(
item,
tdItem,
index,
tdItemIndex,
true
),
}"
>
<slot
:row="item"
:index="index"
:col="tdItem"
:isRead="isRead"
v-if="slotCols.indexOf(tdItem.key) > -1"
></slot>
<template v-else-if="tdItem.$operateList">
<template v-for="btn in tdItem.$operateList">
<button
:class="[btn.styles ? btn.styles : '']"
v-bind:style="{
padding: '2px 5px',
fontSize: '12px',
lineHeight: '1.2',
display: 'inline-block',
}"
@click="
pullEvent(btn.event, {
row: item,
index: index,
})
"
type="primary"
size="min"
:key="btn.id"
>
{{ btn.label }}
</button>
</template>
</template>
<template v-else>{{ item[tdItem.key] }} </template>
</view>
</view>
</template>
</view>
</template>
</checkbox-group>
</view>
</view>
</template>
<template v-else>
<view
class="table_tbody_box empty-data-body-box div-table-body"
:style="{ height: emptyColHeight, width: emptyColWidth }"
>
<view
class="tr"
:style="{ height: emptyColHeight, width: emptyColWidth }"
>
<view
class="td"
:style="{ height: emptyColHeight, width: emptyColWidth }"
>
<view
:class="['td_wrap']"
:style="{
height: parseInt(emptyColHeight - 2) + 'px',
width: emptyColWidth,
lineHeight: parseInt(emptyColHeight - 2) + 'px',
}"
>
<text @click="emptyClickCallBack">{{ emptyText }}</text>
</view>
</view>
</view>
</view>
</template>
<template v-if="list.length">
<!-- 固定左边一列 -->
<view
class="fixed-left"
v-if="
columnsFixedLeft[0] || (selection == 'mulit' && fixedCheckbox)
"
>
<view class="tr fixed-thead-tr">
<!-- 多选且固定左边 【-->
<view
class="td selection"
v-if="selection == 'mulit' && fixedCheckbox"
:style="{ width: selectionTdWidth, height: thTdHeight + 'px' }"
>
<view
:class="['td_wrap']"
:style="{
width: selectionTdWidth,
height: thTdHeight + 'px',
}"
>
<checkbox-group @change="checkboxChangeAll">
<checkbox
value="all"
color="#999"
:checked="switchAllCheckBox"
style="transform: scale(0.7)"
/>
</checkbox-group>
</view>
</view>
<!-- 多选且固定左边 】-->
<!-- 普通固定左边 【-->
<view
class="td"
v-if="columnsFixedLeft[0]"
:style="{
height: fixedHeight(columnsFixedLeft[0]),
width: fixedWidth(columnsFixedLeft),
}"
>
<view
class="td_wrap"
:style="{
height: fixedHeight(columnsFixedLeft[0]),
width: fixedWidth(columnsFixedLeft),
}"
>
{{ columnsFixedLeft[0].title }}
</view>
</view>
<!-- 普通固定左边 】-->
</view>
<view
v-for="(item, index) in list"
:key="item.id"
:class="[
'tr',
selection == 'single' && checkBoxList[index].$checked
? 'selected'
: '',
selection == 'single' && checkBoxList[index].$disabled
? 'disabled'
: '',
]"
@click="selectRow(item, index)"
>
<!-- 多选且固定左边 】-->
<view
class="td selection fixed-td"
v-if="selection == 'mulit' && fixedCheckbox"
:style="{ width: selectionTdWidth, height: tdHeight + 'px' }"
>
<view
:class="['td_wrap']"
:style="{ width: selectionTdWidth, height: tdHeight + 'px' }"
>
<checkbox
:value="checkBoxList[index].id"
color="#999"
:disabled="checkBoxList[index].$disabled"
:checked="checkBoxList[index].$checked"
style="transform: scale(0.7)"
/>
</view>
</view>
<!-- 普通固定左边 【-->
<view
class="td fixed-td"
v-if="columnsFixedLeft[0]"
:style="{
height: fixedHeight(columnsFixedLeft[0]),
width: fixedWidth(columnsFixedLeft),
}"
>
<view
class="td_wrap fixed-wrap"
:style="{
height: fixedHeight(columnsFixedLeft[0]),
width: fixedWidth(columnsFixedLeft[0]),
}"
>
<!-- td内容 【-->
<slot
:row="item"
v-if="
slotCols.indexOf(
columnsFixedLeft[0] && columnsFixedLeft[0].key
) > -1
"
></slot>
<template v-if="columnsFixedLeft[0].$operateList">
<template v-for="btn in columnsFixedLeft[0].$operateList">
<button
:class="[btn.styles ? btn.styles : '']"
v-bind:style="{
padding: '2px 5px',
fontSize: '12px',
lineHeight: '1.2',
display: 'inline-block',
}"
@click="
pullEvent(btn.event, { row: item, index: index })
"
type="primary"
size="min"
:key="btn.id"
>
{{ btn.label }}
</button>
</template>
</template>
<template v-else
>{{ item[columnsFixedLeft[0].key] }}
</template>
<!-- td内容 】-->
</view>
</view>
<!-- 普通固定左边 】-->
</view>
</view>
<!-- 固定左边一列 】-->
<!-- 固定右边一列 【-->
<view class="fixed-right" v-if="columnsFixedRight[0]">
<view class="tr fixed-thead-tr">
<view
class="td"
:style="{
height: fixedHeight(columnsFixedLeft[0]),
width: fixedWidth(columnsFixedLeft),
}"
>
<view
class="td_wrap"
:style="{
height: fixedHeight(columnsFixedLeft[0]),
width: fixedWidth(columnsFixedLeft),
}"
>
{{ columnsFixedRight[0].title }}
</view>
</view>
</view>
<view
v-for="(item, index) in list"
:key="item.id"
:class="[
'tr',
selection == 'single' && checkBoxList[index].$checked
? 'selected'
: '',
selection == 'single' && checkBoxList[index].$disabled
? 'disabled'
: '',
]"
@click="selectRow(item, index)"
>
<view
class="td fixed-td"
:style="{
height: fixedHeight(columnsFixedRight[0]),
width: fixedWidth(columnsFixedRight[0]),
}"
>
<view
class="td_wrap fixed-wrap"
:style="{
height: fixedHeight(columnsFixedRight[0]),
width: fixedWidth(columnsFixedRight[0]),
}"
>
<!-- td内容 【-->
<slot
:row="item"
v-if="
slotCols.indexOf(
columnsFixedRight[0] && columnsFixedRight[0].key
) > -1
"
></slot>
<template
v-if="
columnsFixedRight[0] && columnsFixedRight[0].$operateList
"
>
<template v-for="btn in columnsFixedRight[0].$operateList">
<button
:class="[btn.styles ? btn.styles : '']"
v-bind:style="{
padding: '2px 5px',
fontSize: '12px',
lineHeight: '1.2',
display: 'inline-block',
}"
@click="
pullEvent(btn.event, { row: item, index: index })
"
type="primary"
size="min"
:key="btn.id"
>
{{ btn.label }}
</button>
</template>
</template>
<template v-else
>{{ item[columnsFixedRight[0].key] }}
</template>
<!-- td内容 】-->
</view>
</view>
</view>
</view>
<!-- 固定右边一列 】-->
</template>
</view>
</view>
<loading-component v-if="loading" />
</view>
</template>
<script>
import loadingComponent from "./loading.vue";
export default {
components: { loadingComponent },
props: {
//显示列
columns: {
type: Array,
required: true,
},
//数据
list: {
type: Array,
required: true,
},
//单元格样式居中
"cel-center": {
type: Boolean,
default: true,
},
//自定义行和列样式
rowClassName: {
type: [String, Function],
default: "",
},
//自定义列元素
"slot-cols": {
type: Array,
default: () => {
return [];
},
},
//行列合并函数
"span-method": {
type: Function,
default: () => {
return () => {
return {
rowspan: 1,
colspan: 1,
};
};
},
},
spanArr: {
type: Array,
default: [],
},
isRead: {
type: Number,
default: 0,
},
//是否可选 mulit=>多选 single=》单选
selection: {
type: String,
default: "none",
},
"fixed-checkbox": {
type: Boolean,
default: false,
},
loading: {
type: Boolean,
default: false,
},
height: {
type: Number,
default: undefined,
},
"td-width": {
type: Number,
default: 110,
},
"td-height": {
type: Number,
default: 50,
},
"th-td-height": {
type: Number,
default: 50,
},
"td-padding": {
type: Number,
default: 10,
},
"border-color": {
type: String,
default: "#666",
},
emptyText: {
type: String,
default: "数据为空",
},
//空提示点击事件
emptyClickFn: {
type: Function,
default() {
return () => {};
},
},
},
computed: {
columnsFixedRight() {
let t = this.columns.filter((item) => item.$fixed == "right");
return t.length ? [t[0]] : [];
},
columnsFixedLeft() {
let t = this.columns.filter((item) => item.$fixed == "left");
return t.length ? [t[0]] : [];
},
//表格高度
tableHeight() {
return Number(this.height) && Number(this.height) > this.tdHeight * 3
? this.height + "px"
: "auto";
},
//表格主体高度
talbeBodyHeight() {
let t =
this.tableHeight !== "auto"
? parseInt(this.tableHeight) - this.tdHeight - 3 + "px"
: "auto";
return t;
},
//可选的列表长度
allCheckBoxAbledLen() {
return this.checkBoxList.filter((item) => !item.$disabled).length;
},
//没数据时候主体高度
emptyColHeight() {
let t = this.height ? this.height - this.thTdHeight - 30 + "px" : "100px";
// console.log("emptyColHeight",this.height, this.thTdHeight,t)
return t;
},
//没数据时候,主体的宽度
emptyColWidth() {
let t = this.tdWidth * this.columns.length;
if (this.selection == "mulit") {
t = parseInt(this.selectionTdWidth) + t;
}
return t + "px";
},
},
data() {
return {
checkBoxList: [], //多选=》选中列表
switchAllCheckBox: false, //多选=》全选
selectionTdWidth: "750rpx", //多选列宽
singleSelect: {}, //单选,选中行
};
},
watch: {
list() {
this.asyncCheckBoxList();
},
},
created() {
this.asyncCheckBoxList();
},
methods: {
//获取数据副本,轻拷贝
asyncCheckBoxList() {
this.checkBoxList = this.list.map((item) => {
return { ...item };
});
},
//自定义行样式
rowClassNamePlus(row, index) {
if (typeof this.rowClassName === "string") {
return this.rowClassName;
} else if (typeof this.rowClassName === "function") {
return this.rowClassName(row, index);
}
},
//事件触发
pullEvent(event, data) {
this.$emit(event, data);
},
/**
* 计算单列宽
* iswrap 是否是内容容器
*/
countColspanWidth(item, tdItem, index, tdItemIndex, iswrap = false) {
let borderLeft = iswrap && tdItemIndex > 0 ? 1 : 0;
//是否跨列,返回跨列个数1为不跨列
let moreThanOne =
this.spanMethod(item, tdItem, index, tdItemIndex) &&
this.spanMethod(item, tdItem, index, tdItemIndex)["colspan"];
//console.log(`第${index}行,第${tdItemIndex}列 是跨列么?${moreThanOne}`);
let t =
moreThanOne > 1
? moreThanOne * this.tdWidth - borderLeft + "px"
: this.tdWidth - borderLeft + "px";
//跨列
if (moreThanOne > 1) {
let countWidth = 0;
for (let i = tdItemIndex; i < tdItemIndex + (moreThanOne - 1); i++) {
countWidth +=
this.columns[i].$width && parseInt(this.columns[i].$width)
? parseInt(moreThanOne * this.columns[i].$width) - borderLeft
: this.tdWidth * moreThanOne;
}
return countWidth + "px";
} else {
//不跨列
let tmp =
this.columns[tdItemIndex].width &&
parseInt(this.columns[tdItemIndex].width)
? parseInt(this.columns[tdItemIndex].width)
: this.tdWidth;
return tmp + "rpx";
}
return t;
},
/**
* 固定列宽
*/
fixedWidth(fixedWidth) {
return fixedWidth && fixedWidth.$width
? fixedWidth + "px"
: this.tdWidth + "px";
},
/*
* 固定列-》列高
*/
fixedHeight(fixedHeight) {
return fixedHeight && fixedHeight.$height
? fixedHeight + "px"
: this.tdHeight + "px";
},
/**
* 计算头部td的宽度
* */
countHeadColspanWidth(item, index, iswrap = false) {
let borderLeft = iswrap && index > 0 ? 1 : 0;
let tmp = item.width ? parseInt(item.width) : this.tdWidth;
return tmp + "rpx";
},
/**
* 计算单列高
* */
countRowspanHeight(item, tdItem, index, tdItemIndex) {
//是否跨行
let moreThanOne =
this.spanMethod(item, tdItem, index, tdItemIndex) &&
this.spanMethod(item, tdItem, index, tdItemIndex)["rowspan"] > 1;
let t = moreThanOne
? this.spanMethod(item, tdItem, index, tdItemIndex)["rowspan"] *
this.tdHeight +
"px"
: this.tdHeight + "px";
return t;
},
/*
* 单选行
* */
selectRow(item, index) {
if (item.$disabled) {
return;
}
//非单选方式
if (this.selection != "single") {
return;
}
this.checkBoxList = this.checkBoxList.map((sitem, sindex) => {
if (index === sindex) {
sitem.$checked = true;
} else {
sitem.$checked = false;
}
return sitem;
});
if (this.selection) {
this.$emit("on-selection-change", {
old: this.singleSelect,
new: {
index,
item,
},
});
}
this.singleSelect = {
index,
item,
};
},
/*
* 多选
* */
checkboxChange(e) {
let val = e.detail.value;
let before = [];
for (let v = 0; v < this.allCheckBoxAbledLen; v++) {
if (this.checkBoxList[v].$checked === true) {
before.push({ ...this.checkBoxList[v] });
}
}
if (val.length == this.allCheckBoxAbledLen) {
this.switchAllCheckBox = true;
this.checkBoxList = this.checkBoxList.map((item) => {
if (!item.$disabled) {
item.$checked = true;
}
return item;
});
} else {
this.switchAllCheckBox = false;
this.checkBoxList = this.checkBoxList.map((item) => {
if (val.indexOf(item.id) > -1) {
item.$checked = true;
} else {
item.$checked = false;
}
return item;
});
}
this.$emit("on-selection-change", {
old: before,
new: this.checkBoxList.filter((item) => item.$checked === true),
});
},
/*
* 全选
* */
checkboxChangeAll(e) {
let val = e.detail.value;
let before = [];
for (let v = 0; v < this.allCheckBoxAbledLen; v++) {
if (this.checkBoxList[v].$checked === true) {
before.push({ ...this.checkBoxList[v] });
}
}
if (val && val[0] == "all") {
this.switchAllCheckBox = true;
this.checkBoxList = this.checkBoxList.map((item) => {
if (!item.$disabled) {
item.$checked = true;
}
return item;
});
} else {
this.switchAllCheckBox = false;
this.checkBoxList = this.checkBoxList.map((item) => {
item.$checked = false;
return item;
});
}
this.$emit("on-selection-change", {
old: before,
new: this.checkBoxList.filter((item) => item.$checked === true),
});
},
/*
* 空提示点击事件
* */
emptyClickCallBack() {
typeof this.emptyClickFn == "function" ? this.emptyClickFn() : "";
},
},
};
</script>
<style lang="scss">
@import "components/no-bad-table/table.scss";
</style>

View File

@@ -0,0 +1,163 @@
<template>
<view>
<u-tabbar
:value="current"
@change="tabbarChange"
z-index="999"
activeColor="#2F6D47"
inactiveColor="#687379"
:fixed="true"
:placeholder="true"
:safeAreaInsetBottom="true"
>
<u-tabbar-item name="index" text="首页" v-if="!_isGjt">
<u-icon
name="home-fill"
size="45"
slot="active-icon"
color="#2F6D47"
></u-icon>
<u-icon
name="home-fill"
size="45"
slot="inactive-icon"
color="#687379"
></u-icon>
</u-tabbar-item>
<u-tabbar-item name="map" text="地图" v-if="_isShowMap">
<u-icon
name="map-fill"
size="45"
slot="active-icon"
color="#2F6D47"
></u-icon>
<u-icon
name="map-fill"
size="45"
slot="inactive-icon"
color="#687379"
></u-icon>
</u-tabbar-item>
<u-tabbar-item name="my" text="我的">
<u-icon
name="account-fill"
size="45"
slot="active-icon"
color="#2F6D47"
></u-icon>
<u-icon
name="account-fill"
size="45"
slot="inactive-icon"
color="#687379"
></u-icon>
</u-tabbar-item>
</u-tabbar>
</view>
</template>
<script>
import { getUser } from "@/utils/auth.js";
import { checkButtonPermission } from "@/utils/permission.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
// userInfo: {}, // 用户信息
// list: [],
};
},
computed: {
current() {
return this.$store.state.current || "index";
},
_userInfo() {
console.log("---------------------");
console.log(getUser());
return getUser() || {};
},
_isGjt() {
console.log(123123123);
console.log(this._userInfo.id);
return this._userInfo.id == "1131365259079106560";
},
_isShowMap() {
return checkButtonPermission(
"weappMap",
"vehicle" //按钮在基础信息菜单的车辆信息下面
);
// const ids = this._userInfo?.roles?.map((item) => item.roleName) || [];
// if (ids.includes("地图查看")) {
// // if (ids.includes("1120244873740435456")) ID切库会变 改成中文吧
// return true; //统一改成地图查看权限配置
// } else {
// return false; //其他
// }
},
// _list() {
// return this._isShowMap
// ? [
// {
// path: "pages/index/index",
// },
// {
// path: "pages/map/index",
// },
// {
// path: "pages/my/my",
// },
// ]
// : [
// {
// path: "pages/index/index",
// },
// {
// path: "pages/my/my",
// },
// ];
// },
},
// watch: {
// _userInfo: {
// handler(newVal) {
// this.userInfo = newVal;
// },
// immediate: true,
// deep: true,
// },
// },
mounted() {
console.log("tabBar mounted");
console.log(this._userInfo);
},
methods: {
tabbarChange(e) {
console.log(e);
this.$store.state.current = e;
let arr = [
{
name: "index",
path: "pages/index/index",
},
{
name: "map",
path: "pages/map/index",
},
{
name: "my",
path: "pages/my/my",
},
];
let path =
arr.find((item) => item.name == e)?.path || "pages/index/index";
uni.switchTab({
url: "/" + path,
});
},
},
};
</script>
<style scoped></style>

View File

@@ -0,0 +1,153 @@
<template>
<view>
<u-upload :accept="accept" :fileList="imgList" @afterRead="afterRead" @delete="deletePic" :name="paramsName"
:multiple="isMultiple" :maxCount="limit" ref="upload">
<u-button v-if="isBtn" plain type="primary" text="上传" size="mini" icon="arrow-upward" class="btn-icon"
style="border: 1px solid #c2d10a;" iconColor="#c2d10a" color="#c2d10a"></u-button>
<view v-else class="u-upload__button" :hover-class="!disabled ? 'u-upload__button--hover' : ''"
hover-stay-time="150" :class="[disabled && 'u-upload__button--disabled']" :style="[{
width: $u.addUnit(80),
height: $u.addUnit(80)
}]" style="background-color: aliceblue;display: flex;align-items: center;justify-content: center;">
<u-icon name="camera-fill" size="26" color="#D3D4D6"></u-icon>
</view>
</u-upload>
</view>
</template>
<script>
export default {
options: {
styleIsolation: 'shared', // 解除样式隔离
},
name: "upload_img_video",
props: {
limit: {
type: Number,
default: 10
},
isMultiple: {
type: Boolean,
default: true
},
isBtn: {
type: Boolean,
default: false
},
accept: {
type: String,
default: "image"
},
disabled: {
type: Boolean,
default: false
},
paramsName: {
type: String,
default: "file"
}
},
data() {
return {
imgList: [],
};
},
methods: {
// 删除图片
deletePic(event) {
this.imgList.splice(event.index, 1)
this.$emit('successFile', this.imgList);
},
// 新增图片
async afterRead(event) {
const that = this;
// 当设置 multiple 为 true 时, file 为数组格式,否则为对象格式
let lists = [].concat(event.file)
let fileListLen = this.imgList.length
lists.map((item) => {
that.imgList.push({
...item,
status: 'uploading',
message: '上传中'
})
})
for (let i = 0; i < lists.length; i++) {
const result = await this.uploadFilePromise(lists[i].url)
let item = this.imgList[fileListLen]
that.imgList.splice(fileListLen, 1, Object.assign(item, {
status: 'success',
message: '',
url: result.data.url,
name: result.data.fileName
}))
fileListLen++
}
this.$emit('successFile', this.imgList);
},
uploadFilePromise(url) {
return new Promise((resolve, reject) => {
let a = uni.uploadFile({
url: '/attachment/upload', // 仅为示例,非真实的接口地址
filePath: url,
name: this.paramsName,
success: (res) => {
resolve(JSON.parse(res.data || {}))
},
fail: (e) => {
reject(e);
}
});
})
},
}
}
</script>
<style lang="less" scoped>
/deep/.btn-icon {
font-size: 10rpx !important;
height: 58rpx !important;
/deep/.u-icon {
/deep/.u-icon__icon--primary {
font-size: 20rpx !important;
}
}
}
/deep/.u-button--mini {
width: 120rpx !important;
.u-icon {
font-size: 20rpx !important;
.u-icon__icon {
font-size: 20rpx !important;
}
}
height: 58rpx !important;
}
/deep/.u-upload__deletable {
width: 20px !important;
height: 20px !important;
.uicon-close {
font-size: 14px !important;
line-height: 14px !important;
}
}
/deep/.u-upload__success {
border-bottom-color: #c2d10a !important;
border-right-color: #c2d10a !important;
.uicon-checkmark {
font-size: 14px !important;
line-height: 14px !important;
}
}
</style>

20
index.html Normal file
View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

90
main.js Normal file
View File

@@ -0,0 +1,90 @@
import App from "./App";
// #ifndef VUE3
import Vue from "vue";
import "./uni.promisify.adaptor";
import store from "./store";
import { v1 as uuidv1 } from "uuid";
// main.js注意要在use方法之后执行
import uView from "uview-ui";
import tabBar from "components/tabBar/tabBar.vue"; //引入我们自己定义的tabBar组件
import noBadTable from "components/no-bad-table/table.vue";
Vue.use(uView);
// 调用setConfig方法方法内部会进行对象属性深度合并可以放心嵌套配置
// 需要在Vue.use(uView)之后执行
uni.$u.setConfig({
// 修改$u.config对象的属性
config: {
// 修改默认单位为rpx相当于执行 uni.$u.config.unit = 'rpx'
unit: "rpx",
},
// 修改$u.props对象的属性
props: {
// 修改radio组件的size参数的默认值相当于执行 uni.$u.props.radio.size = 30
radio: {
size: 30,
},
text: {
size: 30,
},
search: {
height: 60,
},
form: {
labelWidth: 160,
},
actionSheet: {
round: 40,
},
datetimePicker: {
value: Number(new Date()),
},
checkbox: {
labelSize: 24,
},
// badge: {
// bgColor: "#c2d10a",
// },
subsection: {
activeColor: "#687379",
},
loadingPage: {
loadingColor: "#c2d10a",
color: "#c2d10a",
iconSize: 112,
fontSize: 38,
},
// 其他组件属性配置
// ......
},
});
// 全局方法挂载
Vue.prototype.uuidv1 = uuidv1;
Vue.prototype.$store = store;
Vue.component("tab-bar", tabBar); //使用tabBar组件
Vue.component("no-bad-table", noBadTable); //使用tabBar组件
import Api from "./api";
Vue.prototype.$api = Api;
Vue.config.productionTip = false;
App.mpType = "app";
const app = new Vue({
store,
...App,
});
app.$mount();
// #endif
// #ifdef VUE3
import { createSSRApp } from "vue";
export function createApp() {
const app = createSSRApp(App);
return {
app,
};
}
// #endif

98
manifest.json Normal file
View File

@@ -0,0 +1,98 @@
{
"name" : "gjt_mini",
"appid" : "__UNI__CAF3DD8",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/*ios*/
"safearea" : {
"background" : "#FFFFFF",
"bottom" : {
"offset" : "auto"
}
},
/* */
"modules" : {},
/* */
"distribute" : {
/* android */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios" : {},
/* SDK */
"sdkConfigs" : {
"oauth" : {}
}
}
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "wx4438f1a71e030de0",
"setting" : {
"urlCheck" : false,
"postcss" : true,
"minified" : true
},
"usingComponents" : true,
"lazyCodeLoading" : "requiredComponents",
"permission" : {
"scope.userLocation" : {
"desc" : "初始化时获取用户的位置信息用于交车定位确认"
},
"scope.camera" : {
"desc" : "获取用户的拍照和相册权限用于拍摄交车、还车照片"
}
},
"requiredPrivateInfos" : [ "getLocation", "chooseLocation" ]
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "2",
"fallbackLocale" : "zh-Hans",
"locale" : "zh-Hans",
"h5" : {
"template" : "template.html"
}
}

954
package-lock.json generated Normal file
View File

@@ -0,0 +1,954 @@
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"@parcel/watcher": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/@parcel/watcher/-/watcher-2.5.0.tgz",
"integrity": "sha512-i0GV1yJnm2n3Yq1qw6QrUrd/LI9bE8WEBOTtOkpCXHHdyN3TAGgqAK/DAT05z4fq2x04cARXt2pDmjWjL92iTQ==",
"dev": true,
"optional": true,
"requires": {
"@parcel/watcher-android-arm64": "2.5.0",
"@parcel/watcher-darwin-arm64": "2.5.0",
"@parcel/watcher-darwin-x64": "2.5.0",
"@parcel/watcher-freebsd-x64": "2.5.0",
"@parcel/watcher-linux-arm-glibc": "2.5.0",
"@parcel/watcher-linux-arm-musl": "2.5.0",
"@parcel/watcher-linux-arm64-glibc": "2.5.0",
"@parcel/watcher-linux-arm64-musl": "2.5.0",
"@parcel/watcher-linux-x64-glibc": "2.5.0",
"@parcel/watcher-linux-x64-musl": "2.5.0",
"@parcel/watcher-win32-arm64": "2.5.0",
"@parcel/watcher-win32-ia32": "2.5.0",
"@parcel/watcher-win32-x64": "2.5.0",
"detect-libc": "^1.0.3",
"is-glob": "^4.0.3",
"micromatch": "^4.0.5",
"node-addon-api": "^7.0.0"
}
},
"@parcel/watcher-android-arm64": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.0.tgz",
"integrity": "sha512-qlX4eS28bUcQCdribHkg/herLe+0A9RyYC+mm2PXpncit8z5b3nSqGVzMNR3CmtAOgRutiZ02eIJJgP/b1iEFQ==",
"dev": true,
"optional": true
},
"@parcel/watcher-darwin-arm64": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.0.tgz",
"integrity": "sha512-hyZ3TANnzGfLpRA2s/4U1kbw2ZI4qGxaRJbBH2DCSREFfubMswheh8TeiC1sGZ3z2jUf3s37P0BBlrD3sjVTUw==",
"dev": true,
"optional": true
},
"@parcel/watcher-darwin-x64": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.0.tgz",
"integrity": "sha512-9rhlwd78saKf18fT869/poydQK8YqlU26TMiNg7AIu7eBp9adqbJZqmdFOsbZ5cnLp5XvRo9wcFmNHgHdWaGYA==",
"dev": true,
"optional": true
},
"@parcel/watcher-freebsd-x64": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.0.tgz",
"integrity": "sha512-syvfhZzyM8kErg3VF0xpV8dixJ+RzbUaaGaeb7uDuz0D3FK97/mZ5AJQ3XNnDsXX7KkFNtyQyFrXZzQIcN49Tw==",
"dev": true,
"optional": true
},
"@parcel/watcher-linux-arm-glibc": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.0.tgz",
"integrity": "sha512-0VQY1K35DQET3dVYWpOaPFecqOT9dbuCfzjxoQyif1Wc574t3kOSkKevULddcR9znz1TcklCE7Ht6NIxjvTqLA==",
"dev": true,
"optional": true
},
"@parcel/watcher-linux-arm-musl": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.0.tgz",
"integrity": "sha512-6uHywSIzz8+vi2lAzFeltnYbdHsDm3iIB57d4g5oaB9vKwjb6N6dRIgZMujw4nm5r6v9/BQH0noq6DzHrqr2pA==",
"dev": true,
"optional": true
},
"@parcel/watcher-linux-arm64-glibc": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.0.tgz",
"integrity": "sha512-BfNjXwZKxBy4WibDb/LDCriWSKLz+jJRL3cM/DllnHH5QUyoiUNEp3GmL80ZqxeumoADfCCP19+qiYiC8gUBjA==",
"dev": true,
"optional": true
},
"@parcel/watcher-linux-arm64-musl": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.0.tgz",
"integrity": "sha512-S1qARKOphxfiBEkwLUbHjCY9BWPdWnW9j7f7Hb2jPplu8UZ3nes7zpPOW9bkLbHRvWM0WDTsjdOTUgW0xLBN1Q==",
"dev": true,
"optional": true
},
"@parcel/watcher-linux-x64-glibc": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.0.tgz",
"integrity": "sha512-d9AOkusyXARkFD66S6zlGXyzx5RvY+chTP9Jp0ypSTC9d4lzyRs9ovGf/80VCxjKddcUvnsGwCHWuF2EoPgWjw==",
"dev": true,
"optional": true
},
"@parcel/watcher-linux-x64-musl": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.0.tgz",
"integrity": "sha512-iqOC+GoTDoFyk/VYSFHwjHhYrk8bljW6zOhPuhi5t9ulqiYq1togGJB5e3PwYVFFfeVgc6pbz3JdQyDoBszVaA==",
"dev": true,
"optional": true
},
"@parcel/watcher-win32-arm64": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.0.tgz",
"integrity": "sha512-twtft1d+JRNkM5YbmexfcH/N4znDtjgysFaV9zvZmmJezQsKpkfLYJ+JFV3uygugK6AtIM2oADPkB2AdhBrNig==",
"dev": true,
"optional": true
},
"@parcel/watcher-win32-ia32": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.0.tgz",
"integrity": "sha512-+rgpsNRKwo8A53elqbbHXdOMtY/tAtTzManTWShB5Kk54N8Q9mzNWV7tV+IbGueCbcj826MfWGU3mprWtuf1TA==",
"dev": true,
"optional": true
},
"@parcel/watcher-win32-x64": {
"version": "2.5.0",
"resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.0.tgz",
"integrity": "sha512-lPrxve92zEHdgeff3aiu4gDOIt4u7sJYha6wbdEZDCDUhtjTsOMiaJzG5lMY4GkWH8p0fMmO2Ppq5G5XXG+DQw==",
"dev": true,
"optional": true
},
"@types/json-schema": {
"version": "7.0.15",
"resolved": "https://registry.npmmirror.com/@types/json-schema/-/json-schema-7.0.15.tgz",
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
"dev": true
},
"@yarnpkg/lockfile": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz",
"integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==",
"dev": true
},
"ajv": {
"version": "6.12.6",
"resolved": "https://registry.npmmirror.com/ajv/-/ajv-6.12.6.tgz",
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
"dev": true,
"requires": {
"fast-deep-equal": "^3.1.1",
"fast-json-stable-stringify": "^2.0.0",
"json-schema-traverse": "^0.4.1",
"uri-js": "^4.2.2"
}
},
"ajv-keywords": {
"version": "3.5.2",
"resolved": "https://registry.npmmirror.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
"dev": true
},
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"at-least-node": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/at-least-node/-/at-least-node-1.0.0.tgz",
"integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==",
"dev": true
},
"axios": {
"version": "1.7.7",
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.7.tgz",
"integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
"requires": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.0",
"proxy-from-env": "^1.1.0"
}
},
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"big.js": {
"version": "5.2.2",
"resolved": "https://registry.npmmirror.com/big.js/-/big.js-5.2.2.tgz",
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
"dev": true
},
"bignumber.js": {
"version": "9.1.2",
"resolved": "https://registry.npmmirror.com/bignumber.js/-/bignumber.js-9.1.2.tgz",
"integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug=="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"braces": {
"version": "3.0.3",
"resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"requires": {
"fill-range": "^7.1.1"
}
},
"call-bind": {
"version": "1.0.7",
"resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.7.tgz",
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
"dev": true,
"requires": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"set-function-length": "^1.2.1"
}
},
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"chokidar": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/chokidar/-/chokidar-4.0.1.tgz",
"integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==",
"dev": true,
"requires": {
"readdirp": "^4.0.1"
}
},
"ci-info": {
"version": "3.9.0",
"resolved": "https://registry.npmmirror.com/ci-info/-/ci-info-3.9.0.tgz",
"integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==",
"dev": true
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"requires": {
"delayed-stream": "~1.0.0"
}
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true
},
"cross-spawn": {
"version": "7.0.5",
"resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.5.tgz",
"integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==",
"dev": true,
"requires": {
"path-key": "^3.1.0",
"shebang-command": "^2.0.0",
"which": "^2.0.1"
}
},
"crypto-js": {
"version": "4.2.0",
"resolved": "https://registry.npmmirror.com/crypto-js/-/crypto-js-4.2.0.tgz",
"integrity": "sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q=="
},
"define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmmirror.com/define-data-property/-/define-data-property-1.1.4.tgz",
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
"dev": true,
"requires": {
"es-define-property": "^1.0.0",
"es-errors": "^1.3.0",
"gopd": "^1.0.1"
}
},
"delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
},
"detect-libc": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/detect-libc/-/detect-libc-1.0.3.tgz",
"integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==",
"dev": true,
"optional": true
},
"emojis-list": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true
},
"es-define-property": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.0.tgz",
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
"dev": true,
"requires": {
"get-intrinsic": "^1.2.4"
}
},
"es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"dev": true
},
"fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
"fast-json-stable-stringify": {
"version": "2.1.0",
"resolved": "https://registry.npmmirror.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true
},
"fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"requires": {
"to-regex-range": "^5.0.1"
}
},
"find-yarn-workspace-root": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz",
"integrity": "sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==",
"dev": true,
"requires": {
"micromatch": "^4.0.2"
}
},
"follow-redirects": {
"version": "1.15.9",
"resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz",
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="
},
"form-data": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.1.tgz",
"integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==",
"requires": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"mime-types": "^2.1.12"
}
},
"fs-extra": {
"version": "9.1.0",
"resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-9.1.0.tgz",
"integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==",
"dev": true,
"requires": {
"at-least-node": "^1.0.0",
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
"universalify": "^2.0.0"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
"dev": true
},
"function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"dev": true
},
"get-intrinsic": {
"version": "1.2.4",
"resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
"dev": true,
"requires": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
"hasown": "^2.0.0"
}
},
"glob": {
"version": "7.2.3",
"resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.3.tgz",
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
"dev": true,
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.1.1",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/gopd/-/gopd-1.0.1.tgz",
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
"dev": true,
"requires": {
"get-intrinsic": "^1.1.3"
}
},
"graceful-fs": {
"version": "4.2.11",
"resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.11.tgz",
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
"dev": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"has-property-descriptors": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
"dev": true,
"requires": {
"es-define-property": "^1.0.0"
}
},
"has-proto": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/has-proto/-/has-proto-1.0.3.tgz",
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
"dev": true
},
"has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz",
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
"dev": true
},
"hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dev": true,
"requires": {
"function-bind": "^1.1.2"
}
},
"immutable": {
"version": "4.3.7",
"resolved": "https://registry.npmmirror.com/immutable/-/immutable-4.3.7.tgz",
"integrity": "sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==",
"dev": true
},
"inflight": {
"version": "1.0.6",
"resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
"dev": true,
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"is-docker": {
"version": "2.2.1",
"resolved": "https://registry.npmmirror.com/is-docker/-/is-docker-2.2.1.tgz",
"integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
"dev": true
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"optional": true
},
"is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"optional": true,
"requires": {
"is-extglob": "^2.1.1"
}
},
"is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true
},
"is-wsl": {
"version": "2.2.0",
"resolved": "https://registry.npmmirror.com/is-wsl/-/is-wsl-2.2.0.tgz",
"integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",
"dev": true,
"requires": {
"is-docker": "^2.0.0"
}
},
"isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmmirror.com/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
"dev": true
},
"isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
"dev": true
},
"js-base64": {
"version": "3.7.7",
"resolved": "https://registry.npmmirror.com/js-base64/-/js-base64-3.7.7.tgz",
"integrity": "sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw=="
},
"json-bigint": {
"version": "1.0.0",
"resolved": "https://registry.npmmirror.com/json-bigint/-/json-bigint-1.0.0.tgz",
"integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
"requires": {
"bignumber.js": "^9.0.0"
}
},
"json-schema-traverse": {
"version": "0.4.1",
"resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
"dev": true
},
"json-stable-stringify": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz",
"integrity": "sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg==",
"dev": true,
"requires": {
"call-bind": "^1.0.5",
"isarray": "^2.0.5",
"jsonify": "^0.0.1",
"object-keys": "^1.1.1"
}
},
"json5": {
"version": "2.2.3",
"resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true
},
"jsonfile": {
"version": "6.1.0",
"resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz",
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.6",
"universalify": "^2.0.0"
}
},
"jsonify": {
"version": "0.0.1",
"resolved": "https://registry.npmmirror.com/jsonify/-/jsonify-0.0.1.tgz",
"integrity": "sha512-2/Ki0GcmuqSrgFyelQq9M05y7PS0mEwuIzrf3f1fPqkVDVRvZrPZtVSMHxdgo8Aq0sxAOb/cr2aqqA3LeWHVPg==",
"dev": true
},
"klaw-sync": {
"version": "6.0.0",
"resolved": "https://registry.npmmirror.com/klaw-sync/-/klaw-sync-6.0.0.tgz",
"integrity": "sha512-nIeuVSzdCCs6TDPTqI8w1Yre34sSq7AkZ4B3sfOBbI2CgVSB4Du4aLQijFU2+lhAFCwt9+42Hel6lQNIv6AntQ==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.11"
}
},
"klona": {
"version": "2.0.6",
"resolved": "https://registry.npmmirror.com/klona/-/klona-2.0.6.tgz",
"integrity": "sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==",
"dev": true
},
"loader-utils": {
"version": "2.0.4",
"resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
"integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
},
"micromatch": {
"version": "4.0.8",
"resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"requires": {
"braces": "^3.0.3",
"picomatch": "^2.3.1"
}
},
"mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
},
"mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"requires": {
"mime-db": "1.52.0"
}
},
"minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"dev": true,
"requires": {
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.8",
"resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.8.tgz",
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"dev": true
},
"neo-async": {
"version": "2.6.2",
"resolved": "https://registry.npmmirror.com/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"dev": true
},
"node-addon-api": {
"version": "7.1.1",
"resolved": "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-7.1.1.tgz",
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
"dev": true,
"optional": true
},
"object-keys": {
"version": "1.1.1",
"resolved": "https://registry.npmmirror.com/object-keys/-/object-keys-1.1.1.tgz",
"integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
"dev": true
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"requires": {
"wrappy": "1"
}
},
"open": {
"version": "7.4.2",
"resolved": "https://registry.npmmirror.com/open/-/open-7.4.2.tgz",
"integrity": "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==",
"dev": true,
"requires": {
"is-docker": "^2.0.0",
"is-wsl": "^2.1.1"
}
},
"os-tmpdir": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
"integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
"dev": true
},
"patch-package": {
"version": "8.0.0",
"resolved": "https://registry.npmmirror.com/patch-package/-/patch-package-8.0.0.tgz",
"integrity": "sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA==",
"dev": true,
"requires": {
"@yarnpkg/lockfile": "^1.1.0",
"chalk": "^4.1.2",
"ci-info": "^3.7.0",
"cross-spawn": "^7.0.3",
"find-yarn-workspace-root": "^2.0.0",
"fs-extra": "^9.0.0",
"json-stable-stringify": "^1.0.2",
"klaw-sync": "^6.0.0",
"minimist": "^1.2.6",
"open": "^7.4.2",
"rimraf": "^2.6.3",
"semver": "^7.5.3",
"slash": "^2.0.0",
"tmp": "^0.0.33",
"yaml": "^2.2.2"
}
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
"dev": true
},
"path-key": {
"version": "3.1.1",
"resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz",
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true
},
"picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true
},
"proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
},
"punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.3.1.tgz",
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
"dev": true
},
"readdirp": {
"version": "4.0.2",
"resolved": "https://registry.npmmirror.com/readdirp/-/readdirp-4.0.2.tgz",
"integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==",
"dev": true
},
"rimraf": {
"version": "2.7.1",
"resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"dev": true,
"requires": {
"glob": "^7.1.3"
}
},
"sass": {
"version": "1.80.6",
"resolved": "https://registry.npmmirror.com/sass/-/sass-1.80.6.tgz",
"integrity": "sha512-ccZgdHNiBF1NHBsWvacvT5rju3y1d/Eu+8Ex6c21nHp2lZGLBEtuwc415QfiI1PJa1TpCo3iXwwSRjRpn2Ckjg==",
"dev": true,
"requires": {
"@parcel/watcher": "^2.4.1",
"chokidar": "^4.0.0",
"immutable": "^4.0.0",
"source-map-js": ">=0.6.2 <2.0.0"
}
},
"sass-loader": {
"version": "10.5.2",
"resolved": "https://registry.npmmirror.com/sass-loader/-/sass-loader-10.5.2.tgz",
"integrity": "sha512-vMUoSNOUKJILHpcNCCyD23X34gve1TS7Rjd9uXHeKqhvBG39x6XbswFDtpbTElj6XdMFezoWhkh5vtKudf2cgQ==",
"dev": true,
"requires": {
"klona": "^2.0.4",
"loader-utils": "^2.0.0",
"neo-async": "^2.6.2",
"schema-utils": "^3.0.0",
"semver": "^7.3.2"
}
},
"schema-utils": {
"version": "3.3.0",
"resolved": "https://registry.npmmirror.com/schema-utils/-/schema-utils-3.3.0.tgz",
"integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.8",
"ajv": "^6.12.5",
"ajv-keywords": "^3.5.2"
}
},
"semver": {
"version": "7.6.3",
"resolved": "https://registry.npmmirror.com/semver/-/semver-7.6.3.tgz",
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
"dev": true
},
"set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmmirror.com/set-function-length/-/set-function-length-1.2.2.tgz",
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
"dev": true,
"requires": {
"define-data-property": "^1.1.4",
"es-errors": "^1.3.0",
"function-bind": "^1.1.2",
"get-intrinsic": "^1.2.4",
"gopd": "^1.0.1",
"has-property-descriptors": "^1.0.2"
}
},
"shebang-command": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
"dev": true,
"requires": {
"shebang-regex": "^3.0.0"
}
},
"shebang-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz",
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
"dev": true
},
"slash": {
"version": "2.0.0",
"resolved": "https://registry.npmmirror.com/slash/-/slash-2.0.0.tgz",
"integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
"dev": true
},
"source-map-js": {
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.2.1.tgz",
"integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
"dev": true
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
},
"tmp": {
"version": "0.0.33",
"resolved": "https://registry.npmmirror.com/tmp/-/tmp-0.0.33.tgz",
"integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
"dev": true,
"requires": {
"os-tmpdir": "~1.0.2"
}
},
"to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"requires": {
"is-number": "^7.0.0"
}
},
"uni-uploadfile": {
"version": "1.1.4",
"resolved": "https://registry.npmmirror.com/uni-uploadfile/-/uni-uploadfile-1.1.4.tgz",
"integrity": "sha512-2WO01OVT8hqXoBO8M6cyE2bOFC6cW+RXrbRvDR+tUXqUR/aDbYeJ31lE1/5xeMlm3TNJpfTZWvTUyiIzhGmd7g=="
},
"universalify": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.1.tgz",
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
"dev": true
},
"uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz",
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
"dev": true,
"requires": {
"punycode": "^2.1.0"
}
},
"uuid": {
"version": "9.0.1",
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz",
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="
},
"uview-ui": {
"version": "2.0.38",
"resolved": "https://registry.npmmirror.com/uview-ui/-/uview-ui-2.0.38.tgz",
"integrity": "sha512-6egHDf9lXHKpG3hEjRE0vMx4+VWwKk/ReTf5x18KrIKqdvdPRqO3+B8Unh7vYYwrIxzAWIlmhZ9RJpKI/4UqPQ=="
},
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"dev": true,
"requires": {
"isexe": "^2.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
},
"yaml": {
"version": "2.6.0",
"resolved": "https://registry.npmmirror.com/yaml/-/yaml-2.6.0.tgz",
"integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==",
"dev": true
}
}
}

19
package.json Normal file
View File

@@ -0,0 +1,19 @@
{
"dependencies": {
"axios": "^1.5.0",
"crypto-js": "^4.1.1",
"js-base64": "^3.7.5",
"json-bigint": "^1.0.0",
"uni-uploadfile": "^1.1.4",
"uuid": "^9.0.1",
"uview-ui": "^2.0.38"
},
"devDependencies": {
"patch-package": "^8.0.0",
"sass": "^1.66.1",
"sass-loader": "^10.4.1"
},
"scripts": {
"postinstall": "patch-package"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,294 @@
<template>
<view>
<u-sticky>
<view style="background-color: #fff">
<u-subsection
mode="subsection"
:list="list"
:current="current"
@change="sectionChange"
activeColor="#7ba746"
:fontSize="30"
>
</u-subsection>
</view>
<u-search
placeholder="请输入"
v-model="keyword"
:showAction="false"
@search="searchList()"
></u-search>
</u-sticky>
<view class="list">
<view class="item" v-for="item in dataList" :key="item.id">
<view class="line" v-if="item.annualInspectionStatus == 1">
<u-badge :isDot="true" type="error"></u-badge>
<view class="text-normal" style="margin-left: 20rpx">年审中</view>
</view>
<view class="line" v-else-if="item.annualInspectionStatus == 2">
<u-badge :isDot="true" type="error"></u-badge>
<view class="text-normal" style="margin-left: 20rpx">未通过</view>
</view>
<view class="line" v-else-if="item.annualInspectionStatus == 0">
<u-badge :isDot="true" type="error"></u-badge>
<view class="text-normal" style="margin-left: 20rpx">待年审</view>
</view>
<view class="line" v-else-if="item.annualInspectionStatus == 3">
<u-badge :isDot="true" type="success"></u-badge>
<view class="text-normal" style="margin-left: 20rpx">已通过</view>
</view>
<view class="line" style="justify-content: space-between">
<view class="text-small">车牌号: {{ item.plateNumber }}</view>
</view>
<view class="line">
<view class="text-small"
>资产状态: {{ item.truckRentStatusName }}</view
>
</view>
<view class="line" style="justify-content: space-between">
<view class="text-small left"
>年审到期时间:
{{
formatDateTime(item.annualInspectionExpireDate, "minute")
}}</view
>
<view class="text-small"
>负责人: {{ item.submitterName || "--" }}</view
>
</view>
<view class="buttons">
<!--deliveryPermit为1的时候准许交车 -->
<button
@tap="goto"
:data-url="`/pageSub/annualReview/detail?id=${item.id}`"
>
编辑
</button>
<button
@tap="goto"
:data-url="`/pageSub/annualReview/detail?id=${item.id}&isRead=1`"
>
查看
</button>
</view>
</view>
<view class="no-more" v-if="noMoreData">没有更多数据了</view>
</view>
<view
clas="line"
style="margin-top: 150rpx"
v-if="!dataList || dataList.length === 0"
>
<u-empty mode="search" text="暂无数据" width="400" textSize="16">
</u-empty
></view>
<u-loading-page
bg-color="#ffffff"
:loading="loading"
color="#7ba746"
font-size="24"
></u-loading-page>
</view>
</template>
<script>
import stora from "@/utils/storage";
import { getUser } from "@/utils/auth.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
current: 0,
list: ["待办", "已年审"],
queryPage: {
pageNo: 1, // 页码
pageSize: 10, //每页查询条数
total: 0, //总页数
pages: 1, //总页数
accessType: 1, // 访问类型 小程序传一
// userid: 0, //当前账号id
annualInspectionStatus: 0, // 表示待办
},
dataList: [],
pageNo: 1,
noMoreData: false,
loading: false,
keyword: "",
};
},
methods: {
// 新增的搜索方法
searchList() {
this.queryPage.plateNumber = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
this.current = index;
this.keyword = "";
this.queryPage.plateNumber = undefined; // 清空搜索关键字
if (index == 1) {
this.queryPage.annualInspectionStatus = 3;
} else {
this.queryPage.annualInspectionStatus = 0;
}
this.loadmore();
this.getToDo();
this.queryPage.pageNo = 1;
this.dataList = [];
},
// submitEvent() {
// getToDo();
// this.current = 1;
// //提交后删除缓存
// stora.remove("fault_fromData");
// },
formatDateTime(obj) {
if (obj == null) {
return "";
}
let date = new Date(obj);
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return (
y +
"-" +
m.substring(m.length - 2, m.length) +
"-" +
d.substring(d.length - 2, d.length)
);
},
loadmore() {
this.loading = true;
this.$api.annualReview
.queryTakePageList(this.queryPage)
.then((res) => {
console.log(res);
this.queryPage.pageNo = res.current;
this.queryPage.pages = res.pages;
this.queryPage.total = res.total;
this.dataList.push(...(res.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
// 获取待办数量
getToDo() {
this.$api.annualReview.getToDo().then((res) => {
console.log("数量");
console.log(res);
this.list[0] = `待办 + ${res}`; // 动态设置
});
},
},
onLoad() {
// this.getToDo();
this.userInfo = getUser() || {};
console.log(this.userInfo);
// this.queryPage.userid = this.userInfo.id;
console.log(this.queryPage.userid);
},
onPullDownRefresh() {
this.sectionChange(this.current);
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
destroyed() {
//页面销毁删除掉数据缓存
stora.remove("fault_fromData");
},
onReachBottom() {
console.log("触底了");
//当前页数小于总页数
if (this.queryPage.pageNo < this.queryPage.pages) {
this.queryPage.pageNo++;
this.loadmore();
this.getToDo();
} else {
this.noMoreData = true;
console.log("没有更多数据了");
}
},
onShow() {
this.sectionChange(this.current);
},
};
</script>
<style lang="less" scoped>
/deep/ .u-badge--error {
background-color: red !important;
}
/deep/ .u-badge--success {
background-color: #4cd964 !important;
}
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
.list {
background: #d7d7d7;
padding: 20rpx;
.item {
background: white;
width: calc(100% - 40rpx);
padding: 20rpx;
margin-bottom: 20rpx;
position: relative;
border-radius: 15rpx;
.line {
display: flex;
align-items: center;
margin-bottom: 15rpx;
.left {
margin-right: 50rpx;
width: 300rpx;
}
.text-small {
font-size: x-small;
}
.text-normal {
font-size: small;
}
}
.buttons {
position: absolute;
top: 20rpx;
right: 20rpx;
button {
width: 130rpx;
height: 50rpx;
padding: 12rpx 0;
font-size: 26rpx;
line-height: 26rpx;
margin-bottom: 10rpx;
}
}
}
.no-more {
width: 100%;
text-align: center;
font-size: xx-small;
color: white;
}
}
</style>

1832
pageSub/failure/detail.vue Normal file

File diff suppressed because it is too large Load Diff

272
pageSub/failure/index.vue Normal file
View File

@@ -0,0 +1,272 @@
<template>
<view>
<u-sticky>
<u-button text="去上报" color="#7ba746" @click="addFailuer"></u-button>
<u-search
placeholder="请输入车牌号/上报人"
v-model="keyword"
:showAction="false"
@search="searchList()"
></u-search>
</u-sticky>
<view class="list">
<view class="item" v-for="item in dataList" :key="item.id">
<view
class="line"
v-if="item.failureStatusName == '已解决' && item.isSubmit != 0"
>
<u-badge :isDot="true" type="success"></u-badge>
<view class="text-normal" style="margin-left: 20rpx">已解决</view>
</view>
<view class="line" v-else>
<u-badge :isDot="true" type="error"></u-badge>
<view class="text-normal" style="margin-left: 20rpx">未解决</view>
</view>
<view class="line">
<view class="text-normal"
>上报人: {{ item.implementerName || "" }}</view
>
</view>
<view class="line" style="justify-content: space-between">
<view class="text-small left"
>上报时间: {{ formatDateTime(item.failureTime, "minute") }}</view
>
</view>
<view class="line" style="justify-content: space-between">
<view class="text-small left"
>解决时间: {{ formatDateTime(item.solutionTime, "minute") }}</view
>
</view>
<view class="line">
<view class="text-small"
>维修效率时长: {{ item.timeConsuming || "" }}</view
>
</view>
<view class="line">
<view class="text-small">故障来源: {{ item.faultSourceName }}</view>
</view>
<view class="line">
<view class="text-small">故障状态: {{ item.failureStatusName }}</view>
</view>
<view class="line" style="justify-content: space-between">
<view class="text-small left"
>故障类型: {{ item.typeName || item.type }}</view
>
<view class="text-small">车牌号: {{ item.plateNumber }}</view>
</view>
<view class="buttons">
<button
@tap="goto"
:data-url="`/pageSub/failure/detail?id=${item.id}`"
v-if="item.failureStatusName != '已解决' || item.isSubmit == 0"
>
编辑
</button>
<button
@tap="goto"
:data-url="`/pageSub/failure/detail?id=${item.id}&isRead=1`"
>
查看
</button>
</view>
</view>
<view class="no-more" v-if="noMoreData">没有更多数据了</view>
</view>
<u-loading-page
bg-color="#ffffff"
:loading="loading"
color="#7ba746"
font-size="24"
></u-loading-page>
</view>
</template>
<script>
import stora from "@/utils/storage";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
keyword: "",
current: 0,
list: ["待交车", "全部"],
queryPage: {
pageNo: 1, // 页码
pageSize: 10, //每页查询条数
total: 0, //总页数
pages: -1, //总页数
keyword: "", // 新增车牌号查询条件
},
dataList: [],
pageNo: 1,
noMoreData: false,
loading: false,
};
},
methods: {
formatDateTime(obj, type = "data") {
if (obj == null) {
return "";
}
const date = new Date(obj);
if (type === "date") {
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return (
y +
"-" +
m.substring(m.length - 2, m.length) +
"-" +
d.substring(d.length - 2, d.length)
);
} else if (type === "minute") {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从0开始
const day = String(date.getDate()).padStart(2, "0");
const hour = String(date.getHours()).padStart(2, "0");
const minute = String(date.getMinutes()).padStart(2, "0");
return `${year}-${month}-${day} ${hour}:${minute}`;
}
},
loadmore() {
this.loading = true;
this.$api.failure
.queryPageList(this.queryPage)
.then((res) => {
console.log(res);
this.queryPage.pageNo = res.current;
this.queryPage.pages = res.pages;
this.queryPage.total = res.total;
this.dataList.push(...(res.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
},
// 新增的搜索方法
searchList() {
this.queryPage.keyword = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
addFailuer() {
uni.navigateTo({ url: `/pageSub/failure/detail` });
},
},
onLoad() {},
onPullDownRefresh() {
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
onReachBottom() {
console.log("触底了");
//当前页数小于总页数
if (this.queryPage.pageNo < this.queryPage.pages) {
this.queryPage.pageNo++;
this.loadmore();
} else {
this.noMoreData = true;
console.log("没有更多数据了");
}
},
onShow() {
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
};
</script>
<style lang="less" scoped>
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
// /deep/ .u-search__content__input {
// height: 50rpx !important;
// padding-top: 20rpx !important; /* 上边距 */
// padding-bottom: 20rpx !important; /* 下边距 */
// }
/deep/ .u-icon__icon {
font-size: 26rpx !important;
}
/deep/ .u-badge--error {
background-color: red !important;
}
/deep/ .u-badge--dot {
height: 20rpx !important;
width: 20rpx !important;
}
.list {
background: #d7d7d7;
padding: 0 20px 20rpx;
.item {
background: white;
width: calc(100% - 40rpx);
padding: 20rpx;
margin-bottom: 20rpx;
position: relative;
border-radius: 15rpx;
.line {
display: flex;
align-items: center;
margin-bottom: 15rpx;
.left {
margin-right: 50rpx;
width: 300rpx;
}
.text-small {
font-size: x-small;
}
.text-normal {
font-size: small;
}
}
.buttons {
position: absolute;
top: 20rpx;
right: 20rpx;
button {
width: 130rpx;
height: 50rpx;
padding: 12rpx 0;
font-size: 26rpx;
line-height: 26rpx;
margin-bottom: 10rpx;
}
}
}
.no-more {
width: 100%;
text-align: center;
font-size: xx-small;
color: white;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,348 @@
<template>
<view>
<u-sticky>
<view style="background-color: #fff">
<u-subsection
mode="subsection"
:list="list"
:current="current"
@change="sectionChange"
activeColor="#7ba746"
:fontSize="30"
>
</u-subsection>
</view>
<u-search
placeholder="请输入"
v-model="keyword"
:showAction="false"
@search="searchList()"
></u-search>
</u-sticky>
<!-- // 还车根据id获取详情
// 待费用核篡(code: 0
// 撤回(code:1
// 待提交审批(code:9
// 待审批(code:10,
// 审批史(code:20
// 待付款确认(code:30
// 审批通过(code:30,
// 审批驳回(code:40
// 待费用结算(code:60
// 已付款(code:70 -->
<view class="list">
<view class="item" v-for="item in dataList" :key="item.id">
<view class="line" v-if="item.costApprovalStatus === 20">
<u-badge :isDot="true" type="warning"></u-badge>
<view class="text-normal" style="margin-left: 10rpx">待审批</view>
</view>
<view
class="line"
v-else-if="[30, 60].includes(item.costApprovalStatus)"
>
<u-badge :isDot="true" type="success"></u-badge>
<view class="text-normal" style="margin-left: 10rpx">已通过</view>
</view>
<view class="line" v-else-if="item.costApprovalStatus == 40">
<u-badge :isDot="true" type="error"></u-badge>
<view class="text-normal" style="margin-left: 10rpx">驳回</view>
</view>
<view class="line">
<view class="text-small">车牌号: {{ item.plateNumber || "--" }}</view>
</view>
<view class="line">
<view class="text-small"
>项目名称: {{ item.projectName || "--" }}</view
>
</view>
<view class="line">
<view class="text-small"
>还车时间: {{ formatDateTime(item.returnDate) }}</view
>
</view>
<view
class="line"
v-if="item.approvalName"
style="justify-content: flex-end"
>
<view class="text-small right"
>当前审批人: {{ item.approvalName }}</view
>
</view>
<view class="buttons">
<!-- 仅待运维备车的数据才显示编辑按钮 v-if="[0, 2].includes(item.preparationStatus)" -->
<button
@tap="goto"
v-if="item.canApprove"
:data-url="`/pageSub/returnCarCost/detail?id=${item.id}&returnId=${item.returnId}`"
>
审批
</button>
<button
@tap="goto"
v-if="disbursement && item.costApprovalStatus === 60"
:data-url="`/pageSub/returnCarCost/detail?id=${item.id}&returnId=${item.returnId}&isCoster=1`"
>
费用结算
</button>
<button
@tap="showModal(item.returnId)"
v-if="paymentConfirmBtn && item.costApprovalStatus === 30"
>
付款确认
</button>
<button
v-if="costView"
@tap="goto"
:data-url="`/pageSub/returnCarCost/detail?id=${
item.id
}&isRead=1&returnId=${item.returnId}&isCoster=${
disbursement ? 1 : 0
}`"
>
查看
</button>
</view>
</view>
<view class="no-more" v-if="noMoreData">没有更多数据了</view>
</view>
<view
clas="line"
style="margin-top: 150rpx"
v-if="!dataList || dataList.length === 0"
>
<u-empty mode="search" text="暂无数据" width="400" textSize="16">
</u-empty
></view>
<u-loading-page
bg-color="#ffffff"
:loading="loading"
color="#7ba746"
font-size="24"
></u-loading-page>
</view>
</template>
<script>
import { checkButtonPermission } from "@/utils/permission.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
current: 0,
list: ["待审批", "审批通过"],
queryPage: {
pageNo: 1, // 页码
pageSize: 10, //每页查询条数
total: 0, //总页数
pages: -1, //总页数
},
dataList: [],
pageNo: 1,
noMoreData: false,
loading: false,
keyword: "",
pageCode: "returnCarCost",
};
},
computed: {
//业务审批
flowAudit: function () {
return checkButtonPermission("flowAudit", this.pageCode);
},
//查看
costView: function () {
return checkButtonPermission("costView", this.pageCode);
},
disbursement: function () {
return checkButtonPermission("disbursementSettlement", this.pageCode);
},
paymentConfirmBtn: function () {
return checkButtonPermission("paymentConfirm", this.pageCode);
},
},
methods: {
// 新增的搜索方法
searchList() {
this.queryPage.plateNumber = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
this.current = index;
this.queryPage.plateNumber = ""; // 清空搜索关键字
this.keyword = ""; // 清空搜索关键字
if (index == 1) {
// 通过
this.queryPage.costApprovalStatus = [30, 60, 70];
} else {
// 审批中
this.queryPage.costApprovalStatus = [20];
}
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
formatDateTime(obj) {
if (obj == null) {
return "";
}
let date = new Date(obj);
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return (
y +
"-" +
m.substring(m.length - 2, m.length) +
"-" +
d.substring(d.length - 2, d.length)
);
},
loadmore() {
this.loading = true;
this.$api.returnCost
.queryPageList(this.queryPage)
.then((res) => {
this.queryPage.pageNo = res.data.current;
this.queryPage.pages = res.data.pages;
this.queryPage.total = res.data.total;
this.dataList.push(...(res.data.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
},
showModal(id) {
uni.showModal({
title: "确认提示",
content: "确认已于钉钉提交付款申请?",
success: (res) => {
if (res.confirm) {
this.$api.returnCost
.paymentConfirm({
id: id,
status: 1,
})
.then((res) => {
console.log(res);
this.sectionChange(this.current);
});
} else {
console.log("用户点击取消");
}
},
});
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
},
onLoad() {},
onPullDownRefresh() {
this.sectionChange(this.current);
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
onReachBottom() {
console.log("触底了");
//当前页数小于总页数
if (this.queryPage.pageNo < this.queryPage.pages) {
this.queryPage.pageNo++;
this.loadmore();
} else {
this.noMoreData = true;
console.log("没有更多数据了");
}
},
onShow() {
this.sectionChange(this.current);
},
};
</script>
<style lang="less" scoped>
/deep/ .u-badge--error {
background-color: red !important;
}
/deep/ .u-badge--success {
background-color: #4cd964 !important;
}
/deep/ .u-badge--dot {
height: 20rpx !important;
width: 20rpx !important;
}
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
// /deep/ .u-search__content__input {
// height: 50rpx !important;
// padding-top: 20rpx !important; /* 上边距 */
// padding-bottom: 20rpx !important; /* 下边距 */
// }
.list {
background: #d7d7d7;
padding: 0 20px 20rpx;
.item {
background: white;
width: calc(100% - 40rpx);
padding: 20rpx;
margin-bottom: 20rpx;
position: relative;
border-radius: 15rpx;
.line {
display: flex;
align-items: center;
margin-bottom: 15rpx;
.left {
margin-right: 50rpx;
width: 300rpx;
}
.text-small {
font-size: x-small;
}
.text-normal {
font-size: small;
}
}
.buttons {
position: absolute;
top: 20rpx;
right: 20rpx;
button {
width: 130rpx;
height: 50rpx;
padding: 12rpx 0;
font-size: 26rpx;
line-height: 26rpx;
margin-bottom: 10rpx;
}
}
}
.no-more {
width: 100%;
text-align: center;
font-size: xx-small;
color: white;
}
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,287 @@
<template>
<view>
<u-sticky>
<view style="background-color: #fff">
<u-subsection
mode="subsection"
:list="list"
:current="current"
@change="sectionChange"
activeColor="#7ba746"
:fontSize="30"
>
</u-subsection>
</view>
<u-search
placeholder="请输入"
v-model="keyword"
:showAction="false"
@search="searchList()"
></u-search>
</u-sticky>
<view class="list">
<view class="item" v-for="item in dataList" :key="item.id">
<view class="line" v-if="item.preparationStatus === 0">
<u-badge :isDot="true" type="warning"></u-badge>
<view class="text-normal" style="margin-left: 10rpx">未整备</view>
</view>
<view class="line" v-else-if="item.preparationStatus == 2">
<u-badge :isDot="true" type="error"></u-badge>
<view class="text-normal" style="margin-left: 10rpx">整备过期</view>
</view>
<view class="line" v-else-if="item.preparationStatus == 1">
<u-badge :isDot="true" type="success"></u-badge>
<view class="text-normal" style="margin-left: 10rpx">已整备</view>
</view>
<view class="line">
<!-- <u-badge
:isDot="true"
type="warning"
v-if="item.preparationStatus === 0"
></u-badge>
<u-badge
:isDot="true"
type="error"
v-if="item.preparationStatus === 2"
></u-badge>
<u-badge
:isDot="true"
type="success"
v-if="item.preparationStatus === 1"
></u-badge> -->
<view class="text-small">品牌: {{ item.brandName }}</view>
</view>
<view class="line">
<view class="text-small">车型: {{ item.modelName }}</view>
</view>
<view class="line">
<view class="text-small">停车场: {{ item.parkingName }}</view>
</view>
<view class="line">
<view class="text-small"
>整备类型: {{ item.preparationTypeName }}</view
>
</view>
<view class="line">
<view class="text-small"
>备车完成时间:
{{ formatDateTime(item.preparationCompletionTime) }}</view
>
</view>
<view class="line" style="justify-content: space-between">
<view class="text-small left"
>下次整备时间: {{ formatDateTime(item.nextPreparationDate) }}</view
>
<view class="text-small">车牌号: {{ item.plateNumber }}</view>
</view>
<view class="buttons">
<!-- 仅待运维备车的数据才显示编辑按钮 v-if="[0, 2].includes(item.preparationStatus)" -->
<button
@tap="goto"
:data-url="`/pageSub/truckPreparation/detail?id=${item.id}`"
>
备车
</button>
<button
@tap="goto"
:data-url="`/pageSub/truckPreparation/detail?id=${item.id}&isRead=1`"
>
查看
</button>
</view>
</view>
<view class="no-more" v-if="noMoreData">没有更多数据了</view>
</view>
<u-loading-page
bg-color="#ffffff"
:loading="loading"
color="#7ba746"
font-size="24"
></u-loading-page>
</view>
</template>
<script>
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
current: 0,
list: ["未整备", "已整备"],
queryPage: {
pageNo: 1, // 页码
pageSize: 10, //每页查询条数
total: 0, //总页数
pages: -1, //总页数
preparationStatus: [0, 2], // 整备状态, 0表示未整备, 1整备完成2表示整备过期
},
dataList: [],
pageNo: 1,
noMoreData: false,
loading: false,
keyword: "",
};
},
methods: {
// 新增的搜索方法
searchList() {
this.queryPage.plateNumber = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
this.current = index;
this.queryPage.plateNumber = undefined; // 清空搜索关键字
if (index == 1) {
// 显示已整备
this.queryPage.preparationStatus = [1];
} else {
// 显示未整备
this.queryPage.preparationStatus = [0, 2];
}
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
formatDateTime(obj) {
if (obj == null) {
return "";
}
let date = new Date(obj);
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return (
y +
"-" +
m.substring(m.length - 2, m.length) +
"-" +
d.substring(d.length - 2, d.length)
);
},
loadmore() {
this.loading = true;
this.$api.truckPreparation
.queryPageList(this.queryPage)
.then((res) => {
this.queryPage.pageNo = res.data.current;
this.queryPage.pages = res.data.pages;
this.queryPage.total = res.data.total;
this.dataList.push(...(res.data.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
},
onLoad() {},
onPullDownRefresh() {
this.sectionChange(this.current);
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
onReachBottom() {
console.log("触底了");
//当前页数小于总页数
if (this.queryPage.pageNo < this.queryPage.pages) {
this.queryPage.pageNo++;
this.loadmore();
} else {
this.noMoreData = true;
console.log("没有更多数据了");
}
},
onShow() {
this.sectionChange(this.current);
},
};
</script>
<style lang="less" scoped>
/deep/ .u-badge--error {
background-color: red !important;
}
/deep/ .u-badge--success {
background-color: #4cd964 !important;
}
/deep/ .u-badge--dot {
height: 20rpx !important;
width: 20rpx !important;
}
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
// /deep/ .u-search__content__input {
// height: 50rpx !important;
// padding-top: 20rpx !important; /* 上边距 */
// padding-bottom: 20rpx !important; /* 下边距 */
// }
.list {
background: #d7d7d7;
padding: 0 20px 20rpx;
.item {
background: white;
width: calc(100% - 40rpx);
padding: 20rpx;
margin-bottom: 20rpx;
position: relative;
border-radius: 15rpx;
.line {
display: flex;
align-items: center;
margin-bottom: 15rpx;
.left {
margin-right: 50rpx;
width: 300rpx;
}
.text-small {
font-size: x-small;
}
.text-normal {
font-size: small;
}
}
.buttons {
position: absolute;
top: 20rpx;
right: 20rpx;
button {
width: 130rpx;
height: 50rpx;
padding: 12rpx 0;
font-size: 26rpx;
line-height: 26rpx;
margin-bottom: 10rpx;
}
}
}
.no-more {
width: 100%;
text-align: center;
font-size: xx-small;
color: white;
}
}
</style>

277
pages.json Normal file
View File

@@ -0,0 +1,277 @@
{
"easycom": {
"^u-(.*)": "uview-ui/components/u-$1/u-$1.vue"
},
"pages": [
//pages数组中第一项表示应用启动页参考https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"enablePullDownRefresh": true
}
},
{
"path": "pages/login/login",
"style": {
"navigationBarTitleText": "广交投氢能",
"enablePullDownRefresh": false
}
},
{
"path": "pages/map/index",
"style": {
"navigationBarTitleText": "地图",
"enablePullDownRefresh": false
}
},
{
"path": "pages/my/my",
"style": {
"navigationBarTitleText": "我的",
"enablePullDownRefresh": false
}
},
{
"path": "components/tabBar/tabBar",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path": "pages/standbyVehicle/index",
"style": {
"navigationBarTitleText": "备车管理",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/standbyVehicle/detail",
"style": {
"navigationBarTitleText": "备车单",
"enablePullDownRefresh": true
}
},
{
"path": "pages/standbyVehicle/detailInfo",
"style": {
"navigationBarTitleText": "备车信息",
"enablePullDownRefresh": true
}
},
{
"path": "pages/truckRent/index",
"style": {
"navigationBarTitleText": "交车管理",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/truckRent/detail",
"style": {
"navigationBarTitleText": "交车单",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/webview/index",
"style": {
"navigationBarTitleText": "webview",
"enablePullDownRefresh": true
}
},
{
"path": "pages/face/index",
"style": {
"navigationBarTitleText": "e签宝人脸验证",
"enablePullDownRefresh": true
}
},
{
"path": "pages/returnCar/index",
"style": {
"navigationBarTitleText": "还车管理",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/returnCar/detail",
"style": {
"navigationBarTitleText": "还车单",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/returnCar/cost",
"style": {
"navigationBarTitleText": "费用核算",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/audit/index",
"style": {
"navigationBarTitleText": "在线审批",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/audit/detail",
"style": {
"navigationBarTitleText": "合同审批详情",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/unusualActionApply/index",
"style": {
"navigationBarTitleText": "异动管理",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/unusualActionApply/detail",
"style": {
"navigationBarTitleText": "异动申请",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/maintain/index",
"style": {
"navigationBarTitleText": "保养待办",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "pages/maintain/detail",
"style": {
"navigationBarTitleText": "保养信息",
"enablePullDownRefresh": true
}
}
],
"subPackages": [
{
"root": "pageSub",
"pages": [
{
"path": "failure/index",
"style": {
"navigationBarTitleText": "故障台账",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "failure/detail",
"style": {
"navigationBarTitleText": "故障上报",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "returnCarCost/index",
"style": {
"navigationBarTitleText": "还车费用核算",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "returnCarCost/detail",
"style": {
"navigationBarTitleText": "还车费用核算",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "truckPreparation/index",
"style": {
"navigationBarTitleText": "车辆整备",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "truckPreparation/detail",
"style": {
"navigationBarTitleText": "备车信息",
"enablePullDownRefresh": true
}
},
{
"path": "annualReview/index",
"style": {
"navigationBarTitleText": "年审待办",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
},
{
"path": "annualReview/detail",
"style": {
"navigationBarTitleText": "年审",
"enablePullDownRefresh": true,
"onReachBottomDistance": 50
}
}
]
}
],
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#3cc51f",
"borderStyle": "white",
"backgroundColor": "#f4f5f7",
"custom": true,
"list": [
{
"pagePath": "pages/index/index",
// "iconPath": "home",
// "selectedIconPath": "home-fill",
"text": "首页"
// "customIcon": false
},
{
"pagePath": "pages/map/index",
// "iconPath": "home",
// "selectedIconPath": "home-fill",
"text": "地图"
// "customIcon": false
},
{
"pagePath": "pages/my/my",
// "iconPath": "account",
// "selectedIconPath": "account-fill",
"text": "我的"
// "customIcon": false
}
],
"current": 0
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "广交投",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"uniIdRouter": {}
}

1052
pages/audit/detail.vue Normal file

File diff suppressed because it is too large Load Diff

290
pages/audit/index.vue Normal file
View File

@@ -0,0 +1,290 @@
<template>
<view>
<u-sticky>
<view style="background-color: #fff">
<u-subsection
mode="subsection"
:list="list"
:current="current"
@change="sectionChange"
activeColor="#7ba746"
:fontSize="30"
>
</u-subsection>
</view>
<u-search
placeholder="请输入"
v-model="keyword"
:showAction="false"
@search="searchList()"
></u-search>
</u-sticky>
<view class="list">
<view class="item" v-for="item in dataList" :key="item.id">
<view class="line">
<view class="text-normal" v-if="current == 0 || item.approvalName"
>@{{ item.approvalName }}请处理待处理审批单:
</view>
</view>
<view class="block">
<view class="line">
<view class="text-small">
{{ item.createName }}提交的{{ item.contractTypeName }}申请</view
>
</view>
<view class="line">
<view class="text-small"> {{ item.customerName }}</view>
</view>
<view class="line">
<view class="text-small">等待</view>
<view class="text-small hot">{{ item.waitTime || "--" }}</view>
<view class="text-small">小时</view>
</view>
</view>
<view class="line" style="justify-content: flex-end">
<view class="buttons">
<!--deliveryPermit为1的时候准许交车 -->
<button
@tap="goto"
v-if="current == 0"
:data-url="`/pages/audit/detail?id=${item.id}`"
>
处理
</button>
<button
v-else
@tap="goto"
:data-url="`/pages/audit/detail?id=${item.id}&isRead=1`"
>
查看
</button>
</view>
</view>
<view class="line">
<view class="line" style="justify-content: space-between">
<view class="text-small left"
>合同提交时间: {{ formatDateTime(item.createTime) }}</view
>
</view>
</view>
</view>
<view class="no-more" v-if="noMoreData">没有更多数据了</view>
</view>
<view
clas="line"
style="margin-top: 150rpx"
v-if="!dataList || dataList.length === 0"
>
<u-empty mode="search" text="暂无数据" width="400" textSize="16">
</u-empty
></view>
<u-loading-page
bg-color="#ffffff"
:loading="loading"
color="#7ba746"
font-size="24"
></u-loading-page>
</view>
</template>
<script>
import stora from "@/utils/storage";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
keyword: "",
current: 0,
list: ["待审批", "审批通过"],
queryPage: {
pageNo: 1, // 页码
pageSize: 10, //每页查询条数
total: 0, //总页数
pages: -1, //总页数
// contractStatus: "2", // 交车许可 1表示 准许交车
},
dataList: [],
pageNo: 1,
noMoreData: false,
loading: false,
};
},
methods: {
// 新增的搜索方法
searchList() {
this.queryPage.customerName = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
this.queryPage.customerName = "";
this.keyword = "";
this.current = index;
// if (index == 1) {
// // 全部 (准许交车 + 已交车)
// this.queryPage.contractStatus = "3";
// } else {
// // 仅显示准许交车
// this.queryPage.contractStatus = "2";
// }
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
formatDateTime(obj) {
if (obj == null) {
return "";
}
let date = new Date(obj);
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return (
y +
"-" +
m.substring(m.length - 2, m.length) +
"-" +
d.substring(d.length - 2, d.length)
);
},
loadmore() {
this.loading = true;
if (this.current == 0) {
this.$api.audit
.queryAuditList(this.queryPage)
.then((res) => {
console.log(res);
this.queryPage.pageNo = res.data.current;
this.queryPage.pages = res.data.pages;
this.queryPage.total = res.data.total;
this.dataList.push(...(res.data.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
} else {
this.$api.audit
.queryAuditedList(this.queryPage)
.then((res) => {
console.log(res);
this.queryPage.pageNo = res.data.current;
this.queryPage.pages = res.data.pages;
this.queryPage.total = res.data.total;
this.dataList.push(...(res.data.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
}
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
},
onLoad() {},
onPullDownRefresh() {
this.sectionChange(this.current);
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
destroyed() {
//页面销毁删除掉数据缓存
stora.remove("fault_fromData");
},
onReachBottom() {
console.log("触底了");
//当前页数小于总页数
if (this.queryPage.pageNo < this.queryPage.pages) {
this.queryPage.pageNo++;
this.loadmore();
} else {
this.noMoreData = true;
console.log("没有更多数据了");
}
},
onShow() {
this.sectionChange(this.current);
},
};
</script>
<style lang="less" scoped>
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
// /deep/ .u-search__content__input {
// height: 50rpx !important;
// padding-top: 20rpx !important; /* 上边距 */
// padding-bottom: 20rpx !important; /* 下边距 */
// }
.list {
background: #d7d7d7;
padding: 0 20px 20rpx;
.item {
background: white;
padding: 20rpx;
margin-bottom: 20rpx;
position: relative;
border-radius: 15rpx;
.block {
display: flex;
line-height: 1.5;
padding: 10px;
flex-direction: column;
align-items: left;
margin-bottom: 15rpx;
border: 1px solid #ccc;
}
.hot {
color: red;
}
.line {
display: flex;
align-items: center;
margin-bottom: 15rpx;
.left {
margin-right: 50rpx;
width: 300rpx;
}
.text-small {
font-size: x-small;
}
.text-normal {
font-size: small;
}
}
.buttons {
button {
width: 130rpx;
display: inline-block;
height: 50rpx;
padding: 12rpx 0;
font-size: 26rpx;
line-height: 26rpx;
margin-bottom: 10rpx;
}
}
}
.no-more {
width: 100%;
text-align: center;
font-size: xx-small;
color: white;
}
}
</style>

87
pages/face/index.vue Normal file
View File

@@ -0,0 +1,87 @@
<template>
<view class="container">
<!-- 唤起上链公证签刷脸小程序提示文本 -->
<view class="btn-content">
<text>中间页唤起上链公证签刷脸小程序</text>
<!-- 点击按钮跳转刷脸小程序 -->
<button type="default" @click="goFaceAuth()">若未自动唤起手动点击跳转刷脸小程序</button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
bizToken: "", // 公证签业务 token
redirectUrl: "", // 重定向地址
goFaceDone: "" // 是否已自动跳转至公证签做人脸
};
},
onLoad: function(option) {
// 设置 bizToken 和 redirectUrl
this.bizToken = option.bizToken;
this.redirectUrl = option.redirectUrl;
this.goFaceDone=false
console.log('onLoad----this.goFaceDone',this.goFaceDone)
},
onShow: function(option) {
console.log('this.goFaceDone',this.goFaceDone)
// 自动请求跳转刷脸小程序
if (!this.goFaceDone) {
this.goFaceAuth()
return
}
// 从公证签小程序返回判断刷脸结果
const options = uni.getEnterOptionsSync();
console.log('---options', options);
if (
options.scene === 1038 &&
options.referrerInfo.extraData &&
options.referrerInfo.extraData.faceResult
) {
// 刷脸成功跳转签署页面,并携带重定向地址
uni.redirectTo({
url: `/pages/webview/index?url=${this.redirectUrl}&type=face`,
success: () => {},
fail: (err) => {
console.log('Failed to navigate back:', err);
},
});
}
},
methods: {
// 跳转刷脸小程序方法
goFaceAuth() {
this.goFaceDone = true;
uni.navigateToMiniProgram({
appId: 'wx1cf2708c2de46337',
path: 'pages/face/index?bizToken=' + this.bizToken,
success: (res) => {
// 打开成功
console.log('跳转成功,this.goFaceDone', this.goFaceDone);
},
fail(res) {
// 打开失败
console.log(res);
},
});
},
}
};
</script>
<style>
.container {
display: flex;
justify-content: center;
align-items: center;
height: 100vh; /* 可以根据实际需求设置容器高度 */
}
.btn-content {
text-align: center;
}
</style>

673
pages/index/index.vue Normal file
View File

@@ -0,0 +1,673 @@
<template>
<view class="content showMap">
<u-toast ref="uToast"></u-toast>
<h5>业务菜单{{ _isOnline ? "" : "(当前接口为测试环境)" }}</h5>
<view class="menuList">
<view
class="menuItem"
@tap="goto('/pages/standbyVehicle/index')"
v-if="!isSafe && !isEnergyRole && beicheBtn"
>
<view class="menuContent"
><view class="text">备车</view>
<image
src="/static/beiche.png"
style="width: 95rpx; height: 56rpx"
></image>
<u-badge
v-if="todo.standByCar != 0"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.standByCar"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge
></view>
</view>
<view
class="menuItem"
v-if="!isEnergyRole && jiaocheBtn"
@tap="goto('/pages/truckRent/index')"
>
<view class="menuContent">
<view class="text">交车</view>
<image
src="/static/jiaoche.png"
style="width: 89rpx; height: 57rpx"
></image>
<u-badge
v-if="todo.handoverCar != 0"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.handoverCar"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge>
</view>
</view>
<view
class="menuItem"
@tap="goto('/pages/returnCar/index')"
v-if="!isSafe && returnCarBtn"
>
<view class="menuContent">
<view class="text">还车</view>
<image
src="/static/huanche.png"
style="width: 89rpx; height: 57rpx"
></image>
<u-badge
v-if="todo.returnCar != 0"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.returnCar"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge>
</view>
</view>
<view
class="menuItem"
@tap="goto('/pageSub/failure/index')"
v-if="
!isSafe &&
!isBussinessRole &&
!isFinanceRole &&
!isEnergyRole &&
guzhangBtn
"
>
<view class="menuContent">
<view class="text">故障台账</view>
<image
style="width: 80rpx; height: 50rpx"
src="/static/fault.png"
></image>
<u-badge
v-if="todo.failureNumber != 0"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.failureNumber"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge>
</view>
</view>
<view
class="menuItem"
v-if="!isSafe && !isEnergyRole && auditBtn"
@tap="goto('/pages/audit/index')"
>
<view class="menuContent">
<view class="text">审批</view>
<image
style="width: 57rpx; height: 55rpx"
src="/static/audit.png"
></image>
<u-badge
v-if="todo.contractWaitApproval != 0"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.contractWaitApproval"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge>
</view>
</view>
<!-- v-if="!isSafe && !isBussinessRole && !isFinanceRole && !isEnergyRole" v-if="transactionManagement"-->
<view
class="menuItem"
v-if="transactionManagement"
@tap="goto('/pages/unusualActionApply/index')"
>
<view class="menuContent">
<view class="text">异动管理</view>
<image
style="width: 48rpx; height: 55rpx"
src="/static/yidong.png"
></image>
<u-badge
v-if="todo.transaction"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.transaction"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge>
</view>
</view>
<!-- v-if="!isSafe && !isBussinessRole && !isFinanceRole && !isEnergyRole" -->
<view
class="menuItem"
v-if="annualVerificationNew"
@tap="goto('/pageSub/annualReview/index')"
>
<view class="menuContent">
<view class="text">年审待办</view>
<image
style="width: 54rpx; height: 54rpx"
src="/static/nianshen.png"
></image>
<!-- <u-badge
v-if="todo.vehicleAnnualInspection != 0"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.vehicleAnnualInspection"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge> -->
</view>
</view>
<!-- v-if="truckPreparation" -->
<view
v-if="truckPreparation"
class="menuItem"
@tap="goto('/pageSub/truckPreparation/index')"
>
<view class="menuContent">
<view class="text">车辆整备</view>
<image
src="/static/zhengbei.png"
style="width: 95rpx; height: 56rpx"
></image>
</view>
</view>
<view
v-if="maintainTodo"
class="menuItem"
@tap="goto('/pages/maintain/index')"
>
<view class="menuContent">
<view class="text">保养待办</view>
<image
src="/static/baoyang.png"
style="width: 60rpx; height: 56rpx"
></image>
</view>
</view>
<view
v-if="returnCarCost"
class="menuItem"
@tap="goto('/pageSub/returnCarCost/index')"
>
<view class="menuContent">
<view class="text">费用核算</view>
<image
src="/static/cost.png"
style="width: 95rpx; height: 56rpx"
></image>
<u-badge
v-if="todo.returnCost != 0"
slot="value"
numberType="limit"
type="warning"
max="99"
:value="todo.returnCost"
:absolute="true"
:offset="[-10, -10]"
bgColor="#c2d10a"
>
</u-badge>
</view>
</view>
</view>
<h5>BI报表</h5>
<view class="menuList">
<view class="menuItem" @tap="gotoBi('car')" v-if="carBiPage">
<view class="menuContent"
><view class="text">车辆统计</view>
<image
src="/static/bi.png"
style="width: 60rpx; height: 56rpx"
></image>
</view>
</view>
<view class="menuItem" @tap="gotoBi('h2')" v-if="h2BiPage">
<view class="menuContent"
><view class="text">氢费统计</view>
<image
src="/static/hydrogen.png"
style="width: 56rpx; height: 56rpx"
></image>
</view>
</view>
<view class="menuItem" @tap="gotoBi('daily')" v-if="dailyBiPage">
<view class="menuContent"
><view class="text">每日氢量表</view>
<image
src="/static/jiaqingzhan.png"
style="width: 56rpx; height: 56rpx"
></image>
</view>
</view>
<view class="menuItem" @tap="gotoBi('electric')" v-if="electricBiPage">
<view class="menuContent"
><view class="text">每日电费表</view>
<image
src="/static/chongdianzhan_white.png"
style="width: 48rpx; height: 48rpx"
></image>
</view>
</view>
<view class="menuItem" @tap="gotoBi('mileage')" v-if="weappMileageBi">
<view class="menuContent"
><view class="text">里程查询</view>
<image
src="/static/kachetou.png"
style="width: 56rpx; height: 56rpx"
></image>
</view>
</view>
</view>
<!-- <u-collapse :value="['basic', 'bi']" :border="false">
<u-collapse-item
title="业务菜单"
ref="basicCollapse"
name="basic"
v-if="isShowCollapse"
>
</u-collapse-item>
<u-collapse-item title="BI报表" name="bi" v-if="biPage">
</u-collapse-item>
</u-collapse> -->
<tab-bar></tab-bar>
</view>
</template>
<script>
import { getUser } from "@/utils/auth.js";
import { checkPagePermission } from "@/utils/permission.js";
import { baseUrl } from "@/utils/request.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
userInfo: {}, // 用户信息
loading: false,
home: {
training: 0,
examination: 0,
},
todo: {
standByCar: 0,
},
isShowCollapse: false,
};
},
computed: {
_isOnline() {
return baseUrl === "https://lnh2e.com/api/";
},
_userInfo() {
console.log("---------------------");
console.log(getUser());
return getUser() || {};
},
beicheBtn() {
return checkPagePermission("standbyVehicle");
},
biPage() {
return checkPagePermission("FineBI");
},
carBiPage() {
return checkPagePermission("truckOptBI");
},
h2BiPage() {
return checkPagePermission("hydrogenBill");
},
dailyBiPage() {
return checkPagePermission("dailyHydrogenOrderBI");
},
electricBiPage() {
return checkPagePermission("bi_ele_daily_summary");
},
weappMileageBi() {
return checkPagePermission("weappMileageBi");
},
//utils\permission.js记得改 不然没有外链接
jiaocheBtn() {
return checkPagePermission("applicationForDelivery");
},
returnCarBtn() {
return checkPagePermission("carapplicationForDelivery");
},
auditBtn() {
return checkPagePermission("contract");
},
guzhangBtn() {
return checkPagePermission("faultManagement");
},
returnCarCost() {
return checkPagePermission("returnCarCost");
},
maintainTodo() {
return checkPagePermission("maintain");
},
truckPreparation() {
return checkPagePermission("truckPreparation");
},
//年审待办
annualVerificationNew() {
return checkPagePermission("annualVerificationNew");
},
transactionManagement() {
return checkPagePermission("transactionManagement");
},
// isOutServiceRole() {
// const ids = this.userInfo?.roles?.map((item) => item.id) || [];
// if (ids.includes("202306091251370002")) {
// console.log("运维外勤");
// return true; //运维外勤
// } else {
// return false; //其他
// }
// },
currRole() {
const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (ids.includes("1076403008717209600")) {
return 2; //安全经理
} else if (ids.includes("1012435145369616384")) {
return 1; //安全员
} else {
return 0; //其他
}
},
isSafe() {
return [1, 2].includes(this.currRole);
},
isEnergyRole() {
//const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (this.userInfo.depCode === "0502") {
console.log("能源部");
return true; //
} else {
return false; //其他
}
},
isFinanceRole() {
//const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (this.userInfo.depCode === "02") {
console.log("财务部");
return true; //财务部
} else {
return false; //其他
}
},
isBussinessRole() {
console.log(this.userInfo);
if (this.userInfo.depCode === "0501") {
console.log("业务服务组-业务助理");
return true; //业务服务组-业务助理
} else {
return false; //其他
}
},
},
onShow() {
// 这样数据是不会刷新的
this.userInfo = getUser() || {};
console.log(this.$store.state.resources);
this.getTodo();
if (this.$store.state?.resources?.length === 0) this.getUserMenu();
console.log(this.userInfo);
},
onPullDownRefresh(event) {
if (this.$store.state?.resources?.length === 0) this.getUserMenu();
this.getTodo()
.then((res) => {
uni.stopPullDownRefresh();
})
.catch((err) => {
uni.stopPullDownRefresh();
});
},
mounted() {
// this.$api.login
// .getUrl()
// .then((res) => {
// console.log("12312312312333#########################");
// console.log(res);
// })
// .catch((err) => {
// console.log("12312312312333#########################");
// console.log(err);
// });
this.$store.state.current = "index";
if (this._userInfo.id == "1131365259079106560") {
setTimeout(() => {
this.$store.state.current = "map";
uni.switchTab({
url: "/pages/map/index",
});
}, 500);
} else {
this.isShowCollapse = false;
setTimeout(() => {
this.isShowCollapse = true;
}, 100);
}
},
methods: {
async getUserMenu() {
await this.$api.login
.getUserMenu()
.then((res) => {
console.log(res);
this.$store.dispatch("setResources", res);
})
.catch((err) => {
console.log("error");
});
},
async getTodo() {
this.$api.standbyVehicle.getTodo().then((res) => {
this.todo.standByCar = res.standByCar;
this.todo.handoverCar = res.handoverCar;
this.todo.returnCar = res.returnCar;
this.todo.failureNumber = res.failureNumber;
this.todo.contractWaitApproval = res.contractWaitApproval;
this.todo.transaction = res.transaction || 0;
//this.todo.vehicleAnnualInspection = res.vehicleAnnualInspection || 0;
console.log(`this.home.standByCar:\n`, this.home.standByCar);
});
this.$api.returnCost.getCostToDo().then((res) => {
console.log(res.data);
this.todo.returnCost = res.data;
});
},
showToast(type, message) {
this.$refs.uToast.show({
type,
icon: false,
message,
});
},
goto(url) {
// uni.navigateTo({ url: e.target.dataset.url });可以用dataset取data-url <!-- data-url="/pages/annualReview/index"
uni.navigateTo({ url: url });
},
gotoBi(type) {
//carBiPage, h2BiPage,dailyBiPage 都是用的系统菜单配置的外链接
switch (type) {
case "car":
uni.navigateTo({
//https://wxaurl.cn/YIKi8duNbCh 根据地图路劲生成的url link
url: `/pages/webview/index?url=` + this.carBiPage,
});
break;
case "h2":
uni.navigateTo({
url: `/pages/webview/index?url=` + this.h2BiPage,
});
break;
case "mileage":
uni.navigateTo({
url: `/pages/webview/index?url=` + this.weappMileageBi,
});
break;
case "electric":
uni.navigateTo({
url: `/pages/webview/index?url=` + this.electricBiPage,
});
break;
default:
uni.navigateTo({
url: `/pages/webview/index?url=` + this.dailyBiPage,
});
break;
}
},
},
};
</script>
<style lang="less" scoped>
.banner {
height: 30vh;
width: 100%;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
.login-btn {
margin: 30rpx 0rpx;
}
.wexin-but::after {
border: unset !important;
}
.wexin-but {
border: unset !important;
border-radius: unset;
box-sizing: unset;
background-color: transparent;
padding-left: 0px;
padding-right: 0px;
}
/deep/.u-cell__body {
padding: 10px 15px !important;
}
// 或者直接覆盖 u-collapse-item 的样式
/deep/ .u-cell--clickable {
background-color: #e1eae5 !important;
}
/deep/ .u-cell__title-text {
font-size: unset !important;
line-height: unset !important;
color: unset !important;
}
/deep/ .u-cell__body {
font-size: unset !important;
color: unset !important;
}
/deep/ .u-cell__right-icon-wrap text {
font-size: 32rpx !important;
}
.content {
background: #e1eae5;
height: calc(100vh - 50px);
// h3 {
// font-weight: normal;
// text-align: center;
// border-bottom: 1rpx solid silver;
// padding: 20rpx 0;
// }
h5 {
padding: 10px;
}
.menuList {
display: flex;
flex-wrap: wrap;
// .menuItem:last-child {
// margin-right: auto;
// }
.menuItem {
padding: 18rpx;
flex: 0 0 33.3%;
box-sizing: border-box;
// margin-right: 56.6rpx;
// &:nth-of-type(4) {
// margin-right: 0;
// }
.menuContent {
position: relative;
text-align: right;
padding: 18rpx;
background-image: url(../../static/g_bg.png);
background-size: 100% 100%;
image {
width: 75rpx;
height: 75rpx;
margin-top: 10rpx;
}
.text {
// width: 125rpx;
text-align: left;
font-size: 32rpx;
color: #fff;
font-weight: bold;
}
/deep/.u-badge {
font-size: 30rpx;
}
/deep/.u-badge--not-dot {
padding: 15rpx 18rpx;
}
}
}
}
}
.showMap.content {
height: calc(100vh - 65px);
/deep/ .u-tabbar-item {
padding-bottom: 19px;
}
}
</style>

187
pages/login/login.vue Normal file
View File

@@ -0,0 +1,187 @@
<template>
<view class="content">
<u-loading-page bg-color="#a7a7a7" :loading="loading"></u-loading-page>
<!-- <view class="bt1 door" @tap="showBtn = true"></view>
<view class="bt2 door" v-if="showBtn" @tap="showUser = true"></view> -->
<image class="logo" src="/static/logo.png"></image>
<view class="helloTip"> Hello! </view>
<view class="helloText"> 欢迎使用广交投氢能车辆运营监控 </view>
<view class="remarkText"> 此小程序仅限氢能车辆运营方内部人员使用 </view>
<view style="width: 80%; margin-top: 80rpx">
<!-- <u-subsection
mode="subsection"
:list="list"
:current="current"
@change="sectionChange"
:fontSize="30"
style="margin-bottom: 20rpx"
></u-subsection> -->
<!-- <view v-if="current == 0">
<login-user></login-user>
</view>
-->
</view>
<view class="loginBlock">
<view class="helloText"> </view>
<view>
<login-user></login-user>
</view>
</view>
</view>
</template>
<script>
import loginUser from "./user-login/index.vue";
// import loginDriver from "./driver-login/index.vue";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
components: {
loginUser,
// loginDriver,
},
data() {
return {
loading: false,
current: 0,
list: ["广交投员工", "司机"],
showUser: false,
showBtn: false,
};
},
onReady() {
// this.getToDo();
const tempIds = ["7NTdeu2Sft31k4wtCGVEjvfvvG3MDxAtUW3g17vv48E"];
wx.getSetting({
withSubscriptions: true,
success(res) {
// console.log(res.authSetting);
// console.log(res.subscriptionsSetting);
if (res.subscriptionsSetting[tempIds[0]] !== "accept") {
uni.showModal({
title: "授权提示",
content: "同意订阅通知消息吗?",
success: (res) => {
console.log(res);
if (res.confirm) {
uni.requestSubscribeMessage({
tmplIds: tempIds, // 需要下发的订阅消息模板id数组
success(res) {
console.log(res);
if (res[tempIds[0]] === "accept") {
console.log("用户同意订阅");
}
},
});
}
},
});
}
// res.subscriptionsSetting = {
// mainSwitch: true, // 订阅消息总开关
// itemSettings: { // 每一项开关
// SYS_MSG_TYPE_INTERACTIVE: 'accept', // 小游戏系统订阅消息
// SYS_MSG_TYPE_RANK: 'accept'
// zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: 'reject', // 普通一次性订阅消息
// ke_OZC_66gZxALLcsuI7ilCJSP2OJ2vWo2ooUPpkWrw: 'ban',
// }
// }
},
});
},
methods: {
sectionChange(index) {
this.current = index;
},
},
};
</script>
<style lang="less" scoped>
.content {
display: flex;
flex-direction: column;
height: 100vh;
padding: 40rpx;
background: linear-gradient(0deg, #b6e2fb, #2890e5);
justify-content: center;
position: relative;
font-family: MiSans-Semibold, MiSans-Demibold, "Segoe UI", Tahoma, Geneva,
Verdana, sans-serif;
}
.helloTip {
font-size: 100rpx;
color: #fff;
font-weight: bold;
margin-top: -200rpx;
}
.helloText {
margin-top: 20rpx;
margin-bottom: 20rpx;
font-size: 46rpx;
color: #fff;
font-weight: 400;
}
.remarkText {
margin-top: 10rpx;
margin-bottom: 20rpx;
font-size: 36rpx;
color: #b54b45;
font-weight: 400;
}
.loginBlock {
display: flex;
flex-direction: column;
justify-content: center;
width: 685rpx;
height: 664rpx;
padding: 0 30rpx;
box-sizing: border-box;
// background-image: url("../../static/login_bg.png");
background-size: cover;
background-color: #fff;
// background: #ffffff;
border-radius: 20rpx;
.helloText {
color: #017043;
text-align: center;
font-weight: bold;
}
}
.logo {
position: absolute;
height: 76rpx;
/* width: 568rpx ; */
top: 40rpx;
right: 40rpx;
// margin-left: auto;
// margin-right: auto;
// margin-bottom: 50rpx;
}
// .door {
// width: 20px;
// height: 20px;
// background: green;
// }
// .bt1 {
// position: absolute;
// top: 10px;
// left: 10px;
// opacity: 0;
// }
// .bt2 {
// position: absolute;
// bottom: 10px;
// left: 10px;
// opacity: 0;
// }
.title {
font-size: 36rpx;
color: #8f8f94;
}
.login-btn {
margin: 30rpx 0rpx;
}
</style>

View File

@@ -0,0 +1,372 @@
<template>
<view>
<u--form
labelPosition="left"
:model="formData"
ref="uForm"
labelWidth="100"
:rules="rules"
class="loginForm"
>
<u-form-item prop="loginName">
<u--input
border="surround"
placeholder="账号"
shape="circle"
v-model="formData.loginName"
fontSize="30"
></u--input>
</u-form-item>
<u-form-item prop="pwd">
<u--input
border="surround"
placeholder="密码"
type="password"
shape="circle"
v-model="formData.pwd"
fontSize="30"
></u--input>
</u-form-item>
<view>
<checkbox-group @change="changeCheck">
<checkbox class="checkbox">
<view slot="label">
<view class="label">
阅读并同意
<view class="text_link" @tap="privatyShow = true"
>用户服务协议隐私政策</view
>
</view>
</view>
</checkbox>
</checkbox-group>
</view>
<!-- <view v-if="showAgreement" class="index-privaty">
<van-checkbox checked-color="#4A47E0" value="{{ hasAgreement }}" bind:change="onCheckboxChanged"/>
</view> -->
<view class="login-btn">
<button
open-type="getPhoneNumber"
@getphonenumber="getPhoneNumber"
class="u-button u-reset-button u-button--success u-button--square u-button--normal wexin-but"
>
授权登录
</button>
<u-button
@click="submit"
plain
color="#017043"
:hairline="false"
:loading="loading"
:disabled="loading"
>{{ `登 录` }}</u-button
>
</view>
</u--form>
<u-popup :show="privatyShow" mode="bottom" @close="privatyShow = false">
<scroll-view scroll-y="true" style="height: 95vh">
<view class="content">
<text style="text-align: center">隐私协议</text>
<view>
<text>概述</text>
<text
>本小程序是由羚牛氢能科技上海有限公司开发运营的一款产品以下简称我们帮助解决用户开通搭建小程序公众号网站方面遇到的问题可以达到快速上线的目的我们深知个人信息对您而言的重要性也感谢您对我们的信任我们将通过本政策向您说明互助文档会如何收集存储保护使用及对外提供您的信息并说明您享有的权利其中要点如下</text
>
<view>
<text
>1.
为了便于您了解您在使用我们的服务时我们需要收集的信息类型与用途我们将结合具体服务向您逐一说明</text
>
</view>
<view>
<text
>2.
为了向您提供服务所需我们会按照合法正当必要的原则收集您的信息</text
>
</view>
<view>
<text
>3.
如果为了向您提供服务而需要将您的信息共享至第三方我们将评估该第三方收集信息的合法性正当性必要性我们将要求第三方对您的信息采取保护措施并严格遵守相关法律法规与监管要求另外我们会按照法律法规及国家标准的要求以确认协议具体场景下的文案确认弹窗提示等形式征得您的同意或确认第三方已经征得您的同意</text
>
</view>
<!-- 省略其他条款内容以类似方式嵌入 -->
<view>
<text>我们如何收集信息</text>
<text
>在您使用互助文档以下各项业务功能以下简称服务的过程中我们需要收集您的一些信息用以向您提供服务提升我们的服务质量保障您的账户和资金安全以及符合国家法律法规及监管规定</text
>
<view>
<text
>1.
依据法律法规及监管规定进行实名制管理在您注册互助文档账户或使用互助文档服务时您需提供手机号码或者第三方账号登陆信息作为账户登录名</text
>
</view>
<view>
<text>2. 身份验证</text>
<view>
<text>1登录验证</text>
<text
>为了让您更安全便捷地登录互助文档我们提供自动登陆服务您也可以选择密码登录短信验证码登录等其他方式</text
>
</view>
<view>
<text>2重要操作行为验证</text>
<text
>为了保障您的账户安全在您进行一些重要的账户操作时例如查看收藏下载应用内资料内容时我们需要验证您的身份为此您可能需向第三方安全服务提供商提交身份验证信息如您不同意提供前述信息您将无法完成特定操作但不影响您使用我们提供的其他服务</text
>
</view>
<!-- 省略其他子条款内容以类似方式嵌入 -->
</view>
<!-- 省略其他条款内容以类似方式嵌入 -->
<view>
<text>3. 获取外部存储权限获取设备ID, MAC地址</text>
<text
>获取外部存储权限用于记录登录同意的信息下次登录不用重新选择获取设备IDMAC地址设备ID用于记录用户的唯一性MAC地址获取是用于确定用户是属于真实用户</text
>
<text
>本程序嵌入了百度插移动统计分析sdk百度移动SDK隐私政策说明具体隐私政策准则按百度移动SDK隐私为准</text
>
</view>
<view>
<text>4. 其他</text>
<text
>请您理解我们向您提供的服务是不断更新和发展的如您选择使用了前述说明当中尚未涵盖的其他服务基于该服务我们需要收集您的信息的我们会通过页面提示交互流程协议约定的方式另行向您说明信息收集的范围与目的并征得您的同意我们会按照本政策以及相应的用户协议约定使用存储对外提供及保护您的信息如您选择不提供前述信息您可能无法使用某项或某部分服务但不影响您使用我们提供的其他服务此外第三方主体可能会通过互助文档APP向您提供服务当您进入第三方主体运营的服务页面时请注意相关服务由第三方主体向您提供涉及到第三方主体向您收集个人信息的建议您仔细查看第三方主体的隐私政策或协议约定</text
>
</view>
</view>
<view>
<text>我们如何存储和保护信息</text>
<view>
<text
>1.
我们在中华人民共和国境内收集和产生的个人信息将存储在中华人民共和国境内如部分服务涉及跨境业务我们需要向境外机构传输境内收集的相关个人信息的我们会按照法律法规和相关监管部门的规定执行向您说明个人信息出境的目的以及涉及的个人信息类型征得您的同意并通过签订协议现场核查等有效措施要求境外机构为所获得的您的个人信息保密我们仅在本政策所述目的所必需期间和法律法规及监管规定的时限内保存您的个人信息</text
>
</view>
<view>
<text
>2.
为了保障您的信息安全我们在收集您的信息后将采取各种合理必要的措施保护您的信息例如在技术开发环境当中我们仅使用经过去标识化处理的信息进行统计分析对外提供研究报告时我们将对报告中所包含的信息进行去标识化处理我们会将去标识化后的信息与可用于恢复识别个人的信息分开存储确保在针对去标识化信息的后续处理中不重新识别个人</text
>
</view>
<view>
<text
>3.
我们承诺我们将使信息安全保护达到业界领先的安全水平为保障您的信息安全我们致力于使用各种安全技术及配套的管理体系来尽量降低您的信息被泄露毁损误用非授权访问非授权披露和更改的风险例如通过网络安全层软件SSL进行加密传输信息加密存储严格限制数据中心的访问传输和存储个人敏感信息时我们将采用加密权限控制去标识化等安全措施</text
>
</view>
<view>
<text
>4.
请您务必妥善保管好您的互助文档登录名及其他身份要素您在使用互助文档服务时我们会通过您的登录名及其他身份要素来识别您的身份一旦您泄漏了前述信息您可能会蒙受损失并可能对您产生不利如您发现互助文档登录名及/或其他身份要素可能或已经泄露时请您立即和我们取得联系以便我们及时采取相应措施以避免或降低相关损失</text
>
</view>
<view>
<text
>5.
在您终止使用互助文档服务后我们会停止对您的信息的收集和使用法律法规或监管部门另有规定的除外如我们停止运营我们将及时停止收集您个人信息的活动将停止运营的通知以逐一送达或公告的形式通知您并对所持有的您的个人信息进行删除或匿名化处理</text
>
</view>
</view>
</view>
</view>
</scroll-view>
</u-popup>
</view>
</template>
<script>
import { setToken, setUser } from "@/utils/auth.js";
import en from "@/utils/key.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
loading: false,
privatyShow: false,
showAgreement: false,
formData: {
loginName: "",
pwd: "",
},
rules: {
loginName: [
{
required: true,
message: "请输入账号",
trigger: ["blur", "change"],
},
],
pwd: [
{
required: true,
message: "请输入密码",
trigger: ["blur", "change"],
},
],
},
};
},
methods: {
changeCheck(e) {
if (e.detail.value.length > 0) {
this.showAgreement = true;
} else {
this.showAgreement = false;
}
},
getPhoneNumber(data) {
// 获取手机号
//debugger;
if (!this.showAgreement) {
uni.showToast({
title: "请先勾选用户协议",
icon: "none",
duration: 1500,
});
return;
}
const _this = this;
if (!data.detail.errno) {
this.loading = true;
wx.login({
success: function (resp) {
console.log(resp);
//var userInfo = res.userInfo;
_this.$api.login
.loginByPhoneForDriver({
phoneCode: data.detail.code,
sessionCode: resp.code,
})
.then((res) => {
const result = res;
_this.loading = false;
setToken(result.token);
_this.getUserMenu();
setUser(result.userInfo);
uni.switchTab({
url: "/pages/index/index",
});
})
.catch((errors) => {
_this.loading = false;
});
},
});
}
},
async getUserMenu() {
await this.$api.login
.getUserMenu()
.then((res) => {
console.log(res);
this.$store.dispatch("setResources", res);
})
.catch((err) => {
console.log("error");
});
},
submit() {
if (!this.showAgreement) {
uni.showToast({
title: "请先勾选用户协议",
icon: "none",
duration: 1500,
});
return;
}
this.$refs.uForm.validate().then(() => {
const nPwd = en.encrypt(this.formData.pwd);
this.loading = true;
const _this = this;
wx.login({
success: function (resp) {
console.log(resp);
//var userInfo = res.userInfo;
_this.$api.login
.loginUser({
loginName: _this.formData.loginName,
pwd: nPwd,
})
.then((res) => {
const result = res;
_this.loading = false;
setToken(result.token);
setUser(result.userInfo);
_this.getUserMenu();
setTimeout(() => {
uni.switchTab({
url: "/pages/index/index",
});
}, 500);
})
.catch((errors) => {
_this.loading = false;
});
},
});
});
},
},
onReady() {
try {
//如果需要兼容微信小程序并且校验规则中含有方法等只能通过setRules方法设置规则。
this.$refs.uForm.setRules(this.rules);
} catch (e) {}
},
};
</script>
<style lang="less" scoped>
/deep/ .u-input--circle {
background-color: #f5f6fa !important;
padding-left: 20px !important;
}
/deep/ .u-button {
border: none !important;
color: #017043;
margin-top: 10rpx;
width: auto;
}
.content {
padding: 10px;
}
.checkbox {
display: flex;
font-size: 28rpx;
.label {
display: flex;
padding-top: 5rpx;
flex-wrap: wrap;
}
.text_link {
color: #4a47e0;
}
}
/deep/ .wx-checkbox-input {
width: 36rpx !important;
height: 36rpx !important;
}
.login-btn {
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
padding: 0 80rpx;
.wexin-but {
// width: 80%;
margin-top: 40rpx;
padding: 0rpx 122rpx;
border-radius: 50rpx;
box-sizing: border-box;
background-color: #017043;
color: white;
font-size: 38rpx;
}
}
</style>

2060
pages/maintain/detail.vue Normal file

File diff suppressed because it is too large Load Diff

309
pages/maintain/index.vue Normal file
View File

@@ -0,0 +1,309 @@
<template>
<view>
<u-sticky>
<view style="background-color: #fff">
<u-subsection
mode="subsection"
:list="list"
:current="current"
@change="sectionChange"
activeColor="#7ba746"
:fontSize="30"
>
</u-subsection>
</view>
<u-search
placeholder="请输入"
v-model="keyword"
:showAction="false"
@search="searchList()"
></u-search>
</u-sticky>
<view class="list">
<view class="item" v-for="item in dataList" :key="item.id">
<view class="line" v-if="item.maintenanceStatus === 0">
<u-badge :isDot="true" type="error"></u-badge>
<view class="text-normal" style="margin-left: 10rpx">未保养</view>
</view>
<view class="line" v-else-if="item.maintenanceStatus == 1">
<u-badge :isDot="true" type="success"></u-badge>
<view class="text-normal" style="margin-left: 10rpx">已保养</view>
</view>
<!-- <u-badge
:isDot="true"
type="warning"
v-if="item.preparationStatus === 0"
></u-badge>
<u-badge
:isDot="true"
type="error"
v-if="item.preparationStatus === 2"
></u-badge>
<u-badge
:isDot="true"
type="success"
v-if="item.preparationStatus === 1"
></u-badge> -->
<view class="line">
<view class="text-small"
>项目名称: {{ item.projectName || "--" }}</view
>
</view>
<view class="line">
<view class="text-small"
>资产状态: {{ item.truckRentStatusName }}</view
>
</view>
<view class="line" v-if="current === 1">
<view class="text-small"
>维修站: {{ item.maintainSiteName || "--" }}</view
>
</view>
<view class="line">
<view class="text-small">负责人: {{ item.handlerName || "--" }}</view>
</view>
<view
class="line"
v-if="current === 1"
style="justify-content: space-between"
>
<view class="text-small left"
>公司应支付: {{ item.companyPayable || 0 }}</view
>
<view class="text-small"
>公司已支付: {{ item.companyPayed || 0 }}</view
>
</view>
<view
class="line"
v-if="current === 1"
style="justify-content: space-between"
>
<view class="text-small left"
>客户应支付: {{ item.customerPayable || 0 }}</view
>
<view class="text-small"
>客户已支付: {{ item.customerPayed || 0 }}</view
>
</view>
<view class="line" style="justify-content: flex-end">
<view class="text-small right">车牌号: {{ item.plateNumber }}</view>
</view>
<view class="buttons">
<!-- 仅待运维备车的数据才显示编辑按钮 v-if="[0, 2].includes(item.preparationStatus)" -->
<button
@tap="goto"
:data-url="`/pages/maintain/detail?id=${item.id}`"
>
编辑
</button>
<button
@tap="goto"
:data-url="`/pages/maintain/detail?id=${item.id}&isRead=1`"
>
查看
</button>
</view>
</view>
<view class="no-more" v-if="noMoreData">没有更多数据了</view>
</view>
<view
clas="line"
style="margin-top: 150rpx"
v-if="!dataList || dataList.length === 0"
>
<u-empty mode="search" text="暂无数据" width="400" textSize="16">
</u-empty
></view>
<u-loading-page
bg-color="#ffffff"
:loading="loading"
color="#7ba746"
font-size="24"
></u-loading-page>
</view>
</template>
<script>
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
current: 0,
list: ["未保养", "已保养"],
queryPage: {
pageNo: 1, // 页码
pageSize: 10, //每页查询条数
total: 0, //总页数
pages: -1, //总页数
},
dataList: [],
pageNo: 1,
noMoreData: false,
loading: false,
keyword: "",
};
},
methods: {
// 新增的搜索方法
searchList() {
this.queryPage.plateNumber = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
this.current = index;
this.queryPage.plateNumber = ""; // 清空搜索关键字
this.keyword = ""; // 清空搜索关键字
if (index == 1) {
// 显示已整备
this.queryPage.maintenanceStatus = 1;
} else {
// 显示未整备
this.queryPage.maintenanceStatus = 0;
}
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
formatDateTime(obj) {
if (obj == null) {
return "";
}
let date = new Date(obj);
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return (
y +
"-" +
m.substring(m.length - 2, m.length) +
"-" +
d.substring(d.length - 2, d.length)
);
},
loadmore() {
this.loading = true;
this.$api.maintainTodo
.queryPageList(this.queryPage)
.then((res) => {
this.queryPage.pageNo = res.data.current;
this.queryPage.pages = res.data.pages;
this.queryPage.total = res.data.total;
this.dataList.push(...(res.data.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
},
onLoad() {},
onPullDownRefresh() {
this.sectionChange(this.current);
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
onReachBottom() {
console.log("触底了");
//当前页数小于总页数
if (this.queryPage.pageNo < this.queryPage.pages) {
this.queryPage.pageNo++;
this.loadmore();
} else {
this.noMoreData = true;
console.log("没有更多数据了");
}
},
onShow() {
this.sectionChange(this.current);
},
};
</script>
<style lang="less" scoped>
/deep/ .u-badge--error {
background-color: red !important;
}
/deep/ .u-badge--success {
background-color: #4cd964 !important;
}
/deep/ .u-badge--dot {
height: 20rpx !important;
width: 20rpx !important;
}
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
// /deep/ .u-search__content__input {
// height: 50rpx !important;
// padding-top: 20rpx !important; /* 上边距 */
// padding-bottom: 20rpx !important; /* 下边距 */
// }
.list {
background: #d7d7d7;
padding: 0 20px 20rpx;
.item {
background: white;
width: calc(100% - 40rpx);
padding: 20rpx;
margin-bottom: 20rpx;
position: relative;
border-radius: 15rpx;
.line {
display: flex;
align-items: center;
margin-bottom: 15rpx;
.left {
margin-right: 50rpx;
width: 300rpx;
}
.text-small {
font-size: x-small;
}
.text-normal {
font-size: small;
}
}
.buttons {
position: absolute;
top: 20rpx;
right: 20rpx;
button {
width: 130rpx;
height: 50rpx;
padding: 12rpx 0;
font-size: 26rpx;
line-height: 26rpx;
margin-bottom: 10rpx;
}
}
}
.no-more {
width: 100%;
text-align: center;
font-size: xx-small;
color: white;
}
}
</style>

1639
pages/map/index.vue Normal file

File diff suppressed because it is too large Load Diff

84
pages/my/my.vue Normal file
View File

@@ -0,0 +1,84 @@
<template>
<view class="content">
<view>
<u-cell-group>
<u-cell title="姓名/账号" :value="userInfo.userName"></u-cell>
<u-cell title="手机号" :value="userInfo.phone"></u-cell>
<u-cell title="身份证" :value="userInfo.idNo"></u-cell>
</u-cell-group>
<u-button
@click="logout"
type="primary"
:hairline="false"
:loading="loading"
:disabled="loading"
style="margin-top: 50rpx"
>退出登录</u-button
>
<u-modal
:show="loading"
@cancel="cancel"
:showCancelButton="true"
:asyncClose="true"
@confirm="confirm"
>
<view class="slot-content">
<text>退出账号</text>
</view>
</u-modal>
</view>
<tab-bar></tab-bar>
</view>
</template>
<script>
import { getUser, removeToken, removeUser } from "@/utils/auth.js";
export default {
data() {
return {
loading: false,
userInfo: {},
};
},
mounted() {
this.userInfo = getUser() || {};
},
methods: {
logout() {
this.loading = true;
},
cancel() {
this.loading = false;
},
confirm() {
this.$api.login
.logout()
.then((res) => {
removeToken();
removeUser();
uni.reLaunch({
url: "/pages/login/login",
});
this.$store.state.current = "index";
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
},
},
};
</script>
<style lang="less" scoped>
/deep/.u-cell__body {
padding: 10px 15px !important;
}
.content {
height: calc(100vh - 65px);
/deep/ .u-tabbar-item {
padding-bottom: 19px;
}
}
</style>

1917
pages/returnCar/cost.vue Normal file

File diff suppressed because it is too large Load Diff

3869
pages/returnCar/detail.vue Normal file

File diff suppressed because it is too large Load Diff

582
pages/returnCar/index.vue Normal file
View File

@@ -0,0 +1,582 @@
<template>
<view>
<u-sticky>
<view style="background-color: #fff">
<u-subsection
v-if="!isEnergyRole"
mode="subsection"
:list="list"
:current="current"
@change="sectionChange"
activeColor="#7ba746"
:fontSize="30"
>
</u-subsection>
</view>
<u-search
placeholder="请输入"
v-model="keyword"
:showAction="false"
@search="searchList()"
></u-search>
</u-sticky>
<view class="list">
<view class="item" v-for="item in dataList" :key="item.id">
<view class="line">
<view class="text-normal">合同编号: {{ item.contractNo }}</view>
</view>
<view class="line">
<view class="text-normal">项目名称: {{ item.projectName }}</view>
</view>
<view class="line">
<view class="text-small">客户名称: {{ item.customerName }}</view>
</view>
<!-- <view class="line">
<view class="text-small">交车区域: {{ item.deliveryAreaName }}</view>
</view> -->
<view class="line">
<view class="text-small"
>交车地点: {{ item.handoverAddressName }}</view
>
</view>
<view class="line">
<view class="text-small"
>还车地点: {{ item.returnLocationName }}</view
>
</view>
<view class="line" style="justify-content: space-between">
<view class="text-small left"
>还车时间: {{ formatDateTime(item.returnDate) }}</view
>
<view class="text-small">车牌号: {{ item.plateNumber }}</view>
</view>
<view class="buttons">
<!--deliveryPermit为1的时候准许交车 -->
<button
@tap="goto"
v-if="
item.taskStatus == 0 &&
editButton &&
current == 0 &&
[null, 1].includes(item.vehicleArrival)
"
:data-url="`/pages/returnCar/detail?id=${item.id}`"
>
编辑
<!-- item.taskStatus == 0 && //未提交编辑
isServiceDep && //是运维
current === 0 && //菜单是待还车
item.vehicleArrival === 1 //已到达 -->
</button>
<button
v-if="
current === 0 && isOutServiceRole && item.vehicleArrival === 0
"
@tap="reachCar(item.id)"
>
<!-- :disabled="![1, 2].includes(item.safetyAuditStatus)" -->
车辆到达
</button>
<button
v-if="
isOutServiceRole &&
item.returnLocationType === 2 &&
item.taskStatus === 1
"
@tap="parkingFunc(item.id)"
>
<!-- :disabled="![1, 2].includes(item.safetyAuditStatus)" -->
停车场
</button>
<!-- <button
@tap="goto"
v-if="
!(
(isBussinessDep && current === 1) ||
(isServiceDep && current === 0) ||
(isFinanceDep && current === 1)
)
"
:data-url="`/pages/returnCar/cost?id=${item.id}`"
>
费用核算
</button>
<button
v-if="
current === 1 &&
isFinanceDep &&
item.returnCostApprovalStatus != 30
"
@tap="goto"
:data-url="`/pages/returnCar/cost?id=${item.id}`"
>
费用结算
</button> -->
<!-- :data-url="
isCostUser || (isServiceDep && current == 1)
? `/pages/returnCar/cost?id=${item.id}&isRead=1`
: `/pages/returnCar/detail?id=${item.id}&isRead=1`
" -->
<button
@tap="goto"
:data-url="`/pages/returnCar/detail?id=${item.id}&isRead=1`"
>
查看
</button>
</view>
</view>
<view class="no-more" v-if="noMoreData">没有更多数据了</view>
</view>
<u-loading-page
bg-color="#ffffff"
:loading="loading"
color="#7ba746"
font-size="24"
></u-loading-page>
<u-modal
:show="showParkingModal"
@confirm="confirmModal"
@cancel="cancelModal"
:showCancelButton="true"
buttonReverse
:asyncClose="true"
>
<view class="slot-content testClass">
<view class="item">
<view class="title">停车场确认</view>
<u-picker
:show="showParkingPicker"
:columns="[parkingList]"
keyName="dicName"
:immediateChange="true"
@confirm="confirmPark"
@cancel="showParkingPicker = false"
>
</u-picker>
<u--input
border="surround"
disabled
fontSize="26"
placeholder="请选择停车场"
:value="getParkingName(parking)"
@tap="showParkingPicker = true"
>
</u--input>
</view>
</view>
</u-modal>
</view>
</template>
<script>
import { getUser } from "@/utils/auth.js";
import stora from "@/utils/storage";
import { checkButtonPermission } from "@/utils/permission.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
current: 0,
list: ["待还车", "全部"],
currRowId: "",
queryPage: {
pageNo: 1, // 页码
pageSize: 10, //每页查询条数
total: 0, //总页数
pages: -1, //总页数
taskStatus: "0", // 编辑完成 0 表示待编辑 1 表示编辑完成
// deliveryPermits: ['1'] // 交车许可 1表示 准许交车
},
dataList: [],
pageNo: 1,
userInfo: {},
noMoreData: false,
loading: false,
showParkingPicker: false,
showParkingModal: false,
parking: "",
parkingList: [],
keyword: "", //搜索关键字
pageCode: "carapplicationForDelivery", //页面编码
// banPlateNumber: [工单#7045017 工单 1023 标红车辆车辆车牌号恢复为黑色
// "粤AGP7018",
// "粤AGR6879",
// "粤AGR9815",
// "粤AGP9825",
// "粤AGP6639",
// "粤AGP5158",
// "粤AGP6651",
// "粤AGP9331",
// "粤AGP9786",
// "粤AGR9866",
// "粤AGR8500",
// "粤AGR9877",
// "粤AGR5547",
// "粤AGR8531",
// "粤AGQ0119",
// ],
};
},
computed: {
editButton: function () {
return checkButtonPermission(
"carapplicationForDeliveryEdit",
this.pageCode
);
},
isCostUser() {
return this.isEnergyRole || this.isBussinessDep || this.isFinanceDep;
},
isOutServiceRole() {
const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (ids.includes("202306091251370002")) {
console.log("运维外勤");
return true; //运维外勤
} else {
return false; //其他
}
},
isServiceDep() {
//const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (this.userInfo.depCode === "0601") {
console.log("运维部");
return true; //运维部
} else {
return false; //其他
}
},
isEnergyRole() {
//const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (this.userInfo.depCode === "0502") {
console.log("能源部");
return true; //
} else {
return false; //其他
}
},
isFinanceDep() {
//const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (this.userInfo.depCode === "02") {
console.log("财务部");
return true; //财务部
} else {
return false; //其他
}
},
isBussinessDep() {
console.log(this.userInfo);
if (this.userInfo.depCode === "0501") {
console.log("业务服务组-业务助理");
return true; //业务服务组-业务助理
} else {
return false; //其他
}
// const ids = this.userInfo?.roles?.map((item) => item.id) || [];
// if (ids.includes("1066262176854999040")) {
},
},
onLoad() {
this.userInfo = getUser() || {};
// this.$nextTick(() => {
// if (this.isBussinessDep) {
// this.list = ["费用核算", "已提交"];
// } else if (this.isFinanceDep) {
// this.list = ["费用核算", "费用结算"];
// }
// });
},
methods: {
async getParkList() {
await this.$api.returnCar
.getParkingPageList({
pageNo: 1,
pageSize: 999,
})
.then((res) => {
if (res) {
let datas = res?.data;
this.parkingList = datas.records.map((item) => {
return {
dicCode: item.id,
dicName: item.parkingName,
};
});
}
});
},
cancelModal() {
this.parking = "";
this.currRowId = "";
this.showParkingModal = false;
},
getDicValue(dic, dicCode) {
if (dic.length == 0) {
return "";
}
return dic.find((x) => x.dicCode == dicCode)?.dicName ?? "";
},
async parkingFunc(val) {
this.currRowId = val;
this.parking = "";
await this.getParkList();
this.showParkingModal = true;
},
confirmModal() {
if (!this.parking) {
uni.showToast({
title: "停车场不能为空",
icon: "none",
duration: 1500,
});
this.showParkingModal = false;
return;
}
const _this = this;
this.$api.returnCar
.updateParking({
id: this.currRowId,
returnLocation: this.parking,
returnLocationType: 1,
})
.then((res) => {
if (res) {
uni.showToast({
title: "操作成功",
icon: "success",
duration: 1500,
success() {
_this.sectionChange(_this.current);
},
});
}
});
this.showParkingModal = false;
},
confirmPark(e) {
console.log(e);
this.parking = e.value[0].dicCode;
this.showParkingPicker = false;
},
getParkingName(dicCode) {
console.log(dicCode);
return this.getDicValue(this.parkingList, dicCode);
},
// 新增的搜索方法
searchList() {
this.queryPage.plateNumber = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
this.current = index;
this.queryPage.plateNumber = undefined; // 清空搜索关键字
this.keyword = ""; // 清空搜索关键字
if (index == 1) {
this.queryPage.vehicleArrival = "";
this.queryPage.taskStatus = "1";
if (this.isServiceDep) {
this.queryPage.vehicleArrival = "1"; // 已到车
}
// if (this.isBussinessDep || this.isFinanceDep) {
// this.queryPage.vehicleArrival = "1";
// this.queryPage.returnCostApprovalStatus = [10, 30]; // 已大提交
// }
} else {
// 仅显示待还车
this.queryPage.vehicleArrival = "";
this.queryPage.taskStatus = "0";
// if (this.isBussinessDep || this.isEnergyRole || this.isFinanceDep) {
// this.queryPage.vehicleArrival = "1"; // 已到车
// this.queryPage.taskStatus = "1";
// this.queryPage.returnCostApprovalStatus = [0, 40]; //未大提交
// }
//偷懒写法
// if (this.isBussinessDep) {
// this.queryPage.vehicleArrival = "0";
// }
}
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
submitEvent() {
this.current = 1;
//提交后删除缓存
stora.remove("fault_fromData");
},
formatDateTime(obj) {
if (obj == null) {
return "";
}
let date = new Date(obj);
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return (
y +
"-" +
m.substring(m.length - 2, m.length) +
"-" +
d.substring(d.length - 2, d.length)
);
},
loadmore() {
this.loading = true;
this.$api.returnCar
.queryTakePageList(this.queryPage)
.then((res) => {
console.log(res);
this.queryPage.pageNo = res.current;
this.queryPage.pages = res.pages;
this.queryPage.total = res.total;
this.dataList.push(...(res.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
reachCar(id) {
const _this = this;
uni.showModal({
title: "提示",
content: "确认到达?",
success: (res) => {
if (res.confirm) {
this.$api.returnCar.sureReturn({ id }).then((res) => {
if (res) {
uni.showToast({
title: "操作成功",
icon: "success",
duration: 1500,
success() {
_this.sectionChange(_this.current);
},
});
}
});
}
},
});
},
},
onPullDownRefresh() {
this.sectionChange(this.current);
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
destroyed() {
//页面销毁删除掉数据缓存
stora.remove("fault_fromData");
},
onReachBottom() {
console.log("触底了");
//当前页数小于总页数
if (this.queryPage.pageNo < this.queryPage.pages) {
this.queryPage.pageNo++;
this.loadmore();
} else {
this.noMoreData = true;
console.log("没有更多数据了");
}
},
onShow() {
this.sectionChange(this.current);
},
};
</script>
<style lang="less" scoped>
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
// /deep/ .u-search__content__input {
// height: 50rpx !important;
// padding-top: 20rpx !important; /* 上边距 */
// padding-bottom: 20rpx !important; /* 下边距 */
// }
/deep/ .testClass {
width: 80%;
}
.item {
.title {
font-size: 26rpx;
margin-bottom: 15rpx;
&.required::before {
content: "*";
color: red;
margin-right: 3rpx;
}
}
}
.list {
background: #d7d7d7;
padding: 0 20px 20rpx;
.item {
background: white;
width: calc(100% - 40rpx);
padding: 20rpx;
margin-bottom: 20rpx;
position: relative;
border-radius: 15rpx;
.line {
display: flex;
align-items: center;
margin-bottom: 15rpx;
.left {
margin-right: 50rpx;
width: 300rpx;
}
.text-small {
font-size: x-small;
}
.text-normal {
font-size: small;
}
}
.buttons {
position: absolute;
top: 20rpx;
right: 20rpx;
button {
width: 130rpx;
height: 50rpx;
padding: 12rpx 0;
font-size: 26rpx;
line-height: 26rpx;
margin-bottom: 10rpx;
}
}
}
.no-more {
width: 100%;
text-align: center;
font-size: xx-small;
color: white;
}
}
</style>

View File

@@ -0,0 +1,591 @@
<template>
<view class="container">
<view class="header">基本信息</view>
<view class="item">
<view class="title">合同编号</view>
<u--input
border="surround"
v-model="datas.contract.contractNo"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">项目名称</view>
<u--input
border="surround"
v-model="datas.contract.projectName"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">客户名称</view>
<u--input
border="surround"
v-model="datas.contract.customerName"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">备车数量</view>
<u--input
border="surround"
v-model="datas.standbyVehicleQuantity"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">交车区域</view>
<u--input
border="surround"
v-model="datas.contract.deliveryAreaName"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">交车地点</view>
<u--input
border="surround"
v-model="datas.contract.handoverAddress"
disabled
fontSize="26"
></u--input>
</view>
<view class="item">
<view class="title">备注</view>
<u--textarea
border="surround"
v-model="datas.remark"
disabled
fontSize="26"
autoHeight
></u--textarea>
</view>
<view class="header" style="margin-top: 30rpx">车辆信息</view>
<view class="carList">
<u-checkbox-group v-model="checkoutIds" size="36" placement="column">
<view v-for="item in detailList" :key="item.id">
<view class="carItem" v-if="!item.isHidden">
<u-checkbox
:customStyle="{
marginBottom: '8px',
position: 'absolute',
top: '6px',
left: '10px',
}"
:disabled="item.standbyStatus !== 4"
:key="index"
:label="` `"
:name="item.id"
>
</u-checkbox>
<view class="innerItem">
<view class="title">品牌</view>
<u--input
border="surround"
:value="brands[item.brand - 1].dicName"
disabled
fontSize="26"
></u--input>
</view>
<view class="innerItem">
<view class="title">车型</view>
<u--input
border="surround"
:value="getModelName(item.model)"
disabled
fontSize="26"
></u--input>
</view>
<view class="innerItem">
<view class="title">车牌</view>
<u--input
border="surround"
:value="item.plateNumber"
disabled
fontSize="26"
></u--input>
</view>
<view class="innerItem">
<view class="title">约定交车日期</view>
<u--input
border="surround"
:value="formatDateTime(item.appointedDate)"
disabled
fontSize="26"
></u--input>
</view>
<!-- <view class="innerItem">
<view class="title">备车完成时间</view>
<u--input
border="surround"
:value="formatDateTime(item.standbyDate)"
disabled
fontSize="26"
></u--input>
</view> -->
<view class="innerItem">
<view class="title">状态</view>
<u--input
border="surround"
:value="item.standbyStatusName || ''"
disabled
fontSize="26"
></u--input>
</view>
<button
class="detailBtn"
:class="{ disabled: item.disabled }"
@tap="saveCache"
:data-id="item.id"
:data-status="item.standbyStatus"
:disabled="item.disabled"
>
备车信息
</button>
</view>
</view>
</u-checkbox-group>
</view>
<view class="btns">
<button class="cancel" @tap="navigateBack">取消</button>
<button
class="done"
:class="{ disabled: _disabled }"
:disabled="_disabled"
@tap="submitApprovalConfirm"
>
备车完成
</button>
</view>
</view>
</template>
<script>
import { getUser } from "@/utils/auth.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
datas: {
contractNo: "合同编号",
projectName: "项目名称",
},
tempDetailList: [], // 临时车辆信息列表 (不包含是否禁用备车信息按钮 信息)
detailList: [], // 车辆信息列表
checkoutIds: [], // 检查单选中项
id: "1058472991198855168",
brands: [], // 车辆品牌字典列表
truckType: [], // 车辆型号字典列表
userInfo: {}, // 用户信息
cacheList: [], // 操作标识缓存信息
cacheKeys: [], // 所有车辆的id联结用于获取操作标识缓存
cacheRequestTimer: 0, // 定时请求定时器
doneBtnDisabled: false, // 备车完成按钮是否禁用
isRead: false, // 页面是否处于阅读模式
};
},
computed: {
// 大部分组件的禁用直接用 disabled查看模式或者已完成签署
_disabled() {
return this.isRead;
},
},
methods: {
getData() {
this.$api.standbyVehicle.getById({ id: this.id }).then((res) => {
if (res.code == 200) {
this.datas = res.data;
// let detailList = res.data.detailList.map((item) => {
// return item;
// });
// res.data.detailList.filter(
// (item) => ![0, 6].includes(item.standbyStatus)
// ) || [];
this.tempDetailList =
res.data.detailList.map((item) => {
item.isStandby = false;
if ([0, 6].includes(item.standbyStatus)) {
item.isHidden = true; //过滤0未备车6已撤销 不能用filter提交的时候要带上这些数据
} else {
item.isHidden = false;
}
return item;
}) || [];
const keys = this.tempDetailList.map((x) => x.id).join(",");
this.cacheKeys = keys;
this.getCache({ keys });
this.getOpManagerPhone();
}
});
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
getCache(params) {
this.$api.standbyVehicle.getCache(params).then((res) => {
if (res.code != 200) {
this.detailList = this.tempDetailList;
return;
}
for (let item of this.tempDetailList) {
item.disabled = false;
}
const cacheList = res.data;
for (let [key, value] of Object.entries(cacheList)) {
const targetIndex = this.tempDetailList.findIndex((x) => x.id == key);
// 备车车辆某记录正在被编辑,且被编辑的人员和当前用户手机号不同
// 则禁用备车信息按钮
if (targetIndex != -1 && value != this.userInfo.phone) {
this.tempDetailList[targetIndex].disabled = true;
}
}
this.detailList = [...this.tempDetailList];
});
},
saveCache(e) {
// 保存前重新获取该id最新的操作标识缓存查看是否已被别人占用
this.$api.standbyVehicle
.getCache({ keys: e.target.dataset.id })
.then((res) => {
console.log(`该id的缓存表示:\n`, res);
const _phone = res.data[e.target.dataset.id];
if (_phone && _phone != this.userInfo.phone) {
uni.showToast({
icon: "none",
title: "已有其他运维人员在编辑此车辆",
duration: 2000,
});
this.getData();
return;
}
// 如果没有其他人正在编辑则标识当前用户正在编辑此id
const id = e.target.dataset.id;
const phone = this.userInfo.phone;
console.log(this.isRead);
const isRead = this.isRead || e.target.dataset.status != 4;
console.log(`isRead:\n`, isRead);
this.$api.standbyVehicle
.saveCache({ key: id, value: phone })
.then((res) => {
console.log(res);
uni.navigateTo({
url: `/pages/standbyVehicle/detailInfo?id=${id}&mainId=${this.id}&isRead=${isRead}`,
});
});
});
},
navigateBack() {
uni.navigateBack();
},
formatDateTime(obj) {
if (obj == null) {
return "";
}
let date = new Date(obj);
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return (
y +
"-" +
m.substring(m.length - 2, m.length) +
"-" +
d.substring(d.length - 2, d.length)
);
},
getVehicleBrand() {
this.$api.standbyVehicle.getVehicleBrand().then((res) => {
this.brands = res;
});
},
getTruckType() {
this.$api.standbyVehicle.getTruckType().then((res) => {
this.truckType = res;
});
},
getOpManagerPhone() {
const regionCode = this.datas.contract.deliveryArea;
// 有些合同可能没有设置交车区域,因此无需做按钮权限校验
if (!regionCode) {
console.log(`该合同未设置交车区域,无法获取区域运维负责人`);
return;
}
// this.$api.standbyVehicle.getOpManagerPhone({ regionCode }).then((res) => {
// //2025.3.18修改,去掉控制
// // 如果当前区域运维负责人不是当前小程序用户 则禁用备车完成按钮
// // if (res != this.userInfo.phone) {
// // this.doneBtnDisabled = true;
// // } else {
// // this.doneBtnDisabled = false;
// // }
// console.log(res);
// });
},
submitApprovalConfirm() {
uni.showModal({
title: "提示",
content: "确认备车完成?",
success: (res) => {
if (res.confirm) {
this.submitApproval();
}
},
});
},
alert(msg) {
uni.showToast({
title: msg,
icon: "none",
duration: 1500,
});
},
// 备车完成
submitApproval() {
// 点击备车收再获取一下数据,确保页面即将要提交的的数据是最新的
if (this.checkoutIds.length === 0) {
uni.showToast({
title: "请先勾选车辆",
icon: "none",
});
return;
}
console.log(this.checkoutIds);
let flag = false;
for (let item of this.datas.detailList.filter((item) =>
this.checkoutIds.includes(item.id)
)) {
if (item.plateNumber && this.datas.approvalStatus === 4) {
if (
item.hasAdvertisement == null ||
item.hasTailboard == null ||
item.isHang == null ||
item.operationExpectedDeliveryDate == null ||
item.standbyDate == null
) {
console.log(item);
this.alert("请完整填写车牌为:" + item.plateNumber + "的车辆信息");
flag = true;
return false;
}
}
if (item.isHang == 1 && !item.hangPlateNumber) {
this.alert("请输入车牌为:" + item.plateNumber + "的挂车车牌号");
flag = true;
return false;
}
if (
item.operationExpectedDeliveryDate > item.appointedDate &&
!item.remark &&
this.datas.approvalStatus === 4
) {
this.alert(
"请输入车牌为:" +
item.plateNumber +
"的约定交车日期和运维预计交车日期不一致的备注"
);
flag = true;
return false;
}
}
if (flag) {
return;
}
this.datas.detailList
.filter((item) => this.checkoutIds.includes(item.id))
.map((item) => {
item.submitStatus = 1;
return item;
});
this.datas.submitApproval = true; // 标识让流程继续往下走
this.$api.standbyVehicle.edit(this.datas).then((res) => {
console.log(`编辑接口返回:\n`, res);
if (res == this.datas.id) {
uni.showToast({
title: "备车成功",
icon: "success",
duration: 1500,
success() {
setTimeout(() => {
uni.navigateBack();
}, 1500);
},
});
}
});
// this.$api.standbyVehicle.getById({ id: this.id }).then((res) => {
// if (res.code == 200) {
// this.datas = res.data;
// }
// });
},
getModelName(model) {
if (this.truckType.length == 0) {
return "";
}
return this.truckType.find((x) => x.dicCode == model)?.dicName ?? "";
},
},
onLoad(options) {
if (options.id) {
this.id = options.id;
}
if (options.isRead) {
this.isRead = Number(options.isRead);
}
this.userInfo = getUser() || {};
console.log(`userInfo:\n`, this.userInfo);
this.getVehicleBrand();
this.getTruckType();
// this.getData();
this.cacheRequestTimer = setInterval(() => {
this.getCache({ keys: this.cacheKeys });
}, 5000);
},
onPullDownRefresh() {
this.getData();
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
onShow() {
this.getData();
if (this.cacheRequestTimer) {
clearInterval(this.cacheRequestTimer);
this.cacheRequestTimer = setInterval(() => {
this.getCache({ keys: this.cacheKeys });
}, 5000);
}
},
onHide() {
if (this.cacheRequestTimer) {
clearInterval(this.cacheRequestTimer);
}
},
destroyed() {
if (this.cacheRequestTimer) {
clearInterval(this.cacheRequestTimer);
}
},
};
</script>
<style lang="less" scoped>
.container {
background-color: #d7d7d7;
padding: 30rpx;
.item {
margin-top: 30rpx;
.title {
font-size: 26rpx;
margin-bottom: 15rpx;
}
}
.carList {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.carItem {
width: calc(100%);
background-color: white;
// height: 200rpx;
margin: 25rpx 0;
border-radius: 10rpx;
padding: 10rpx;
display: flex;
flex-wrap: wrap;
position: relative;
justify-content: space-between;
.innerItem {
width: 220rpx;
margin-bottom: 10rpx;
.title {
text-align: center;
margin-bottom: 10rpx;
font-size: 26rpx;
}
}
.detailBtn {
height: 60rpx;
width: 200rpx;
background-color: #1e98d7;
color: white;
border-radius: 10rpx;
text-align: center;
font-size: 26rpx;
line-height: 26rpx;
padding: 17rpx 0;
margin: 0;
margin-top: 50rpx;
&.disabled {
background-color: #eee;
color: #ccc;
}
}
}
}
.btns {
display: flex;
align-items: center;
justify-content: space-around;
margin-top: 20rpx;
button {
width: 200rpx;
height: 60rpx;
font-size: 26rpx;
line-height: 26rpx;
padding: 17rpx 0;
text-align: center;
}
.cancel {
background-color: white;
color: #7ba746;
border: 1rpx #7ba746 solid;
}
.done {
background-color: #7ba746;
color: white;
}
.disabled {
opacity: 0.6;
}
}
}
/deep/ .u-textarea textarea {
font-size: 26rpx !important;
}
/deep/ .u-border {
border-width: 1rpx !important;
border-color: gray !important;
border-style: solid;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,288 @@
<template>
<view>
<u-sticky>
<view style="background-color: #fff">
<u-subsection
mode="subsection"
:list="list"
:current="current"
@change="sectionChange"
activeColor="#7ba746"
:fontSize="30"
>
</u-subsection>
</view>
<u-search
placeholder="请输入客户名称"
v-model="keyword"
:showAction="false"
@search="searchList()"
></u-search>
</u-sticky>
<view class="list">
<view class="item" v-for="item in dataList" :key="item.id">
<view class="line">
<view class="text-normal">合同编号: {{ item.contractNo }}</view>
</view>
<view class="line">
<view class="text-normal">客户名称: {{ item.customerName }}</view>
</view>
<view class="line">
<view class="text-small"
>合同约定数量: {{ item.contractVehicleQuantity }}</view
>
</view>
<view class="line">
<view class="text-small"
>待备车数量: {{ item.standbyVehicleQuantity }}</view
>
</view>
<view class="line">
<view class="text-small left"
>合同签订时间: {{ formatDateTime(item.signingDate) }}</view
>
<view class="text-small"
>约定交车时间: {{ formatDateTime(item.appointedDate) }}</view
>
</view>
<view class="buttons">
<!-- 仅待运维备车的数据才显示编辑按钮 -->
<button
v-if="
submitButton &&
item.approvalStatus != 6 &&
item.standbyVehicleQuantity &&
item.standbyVehicleQuantity > 0
"
@tap="goto"
:data-url="`/pages/standbyVehicle/detail?id=${item.id}`"
>
备车办理
</button>
<button
@tap="goto"
:data-url="`/pages/standbyVehicle/detail?isRead=1&id=${item.id}`"
>
查看
</button>
</view>
</view>
<view class="no-more" v-if="noMoreData">没有更多数据了</view>
</view>
<u-loading-page
bg-color="#ffffff"
:loading="loading"
color="#7ba746"
font-size="24"
></u-loading-page>
</view>
</template>
<script>
import stora from "@/utils/storage";
import { checkButtonPermission } from "@/utils/permission.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
current: 0,
list: ["待处理", "全部"],
queryPage: {
pageNo: 1, // 页码
pageSize: 10, //每页查询条数
total: 0, //总页数
pages: -1, //总页数
approvalStatuss: [4], // 审批状态, 4表示待运维备车
filterCompleted: true, //增加参数 filterCompleted=true 过滤备车完成的记录
customerName: "", //客户名称
},
dataList: [],
// testRecord: {
// contractNo: "LNZLHTJX2023051201",
// customerName: "中外运物流华东有限公司",
// contractVehicleQuantity: 10,
// standbyVehicleQuantity: 10,
// signingDate: 1728489600000,
// appointedDate: 1728489600000,
// },
pageNo: 1,
noMoreData: false,
loading: false,
pageCode: "standbyVehicle",
keyword: "",
};
},
computed: {
submitButton: function () {
return checkButtonPermission("standbyVehicleSubmit", this.pageCode);
},
},
methods: {
// 新增的搜索方法
searchList() {
this.queryPage.customerName = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
this.keyword = ""; // 清空搜索关键字
this.queryPage.customerName = undefined; // 清空搜索关键字
this.current = index;
if (index == 1) {
// 待业务编辑 1
// 待审批 2
// 审批中 3
// 待运维备车 4
// 备车完成 5
// 已撤销 6
// 部分待业务编辑 7
// 终止 8
// 已全部交车 9
// 全部 (待运维备车 + 备车已完成)
this.queryPage.approvalStatuss = [4, 5, 1];
this.queryPage.filterCompleted = false; //增加参数 filterCompleted=true 过滤备车完成的记录
} else {
// 仅显示待运维备车
this.queryPage.approvalStatuss = [4, 1];
this.queryPage.filterCompleted = true; //增加参数 filterCompleted=true 过滤备车完成的记录
}
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
submitEvent() {
this.current = 1;
//提交后删除缓存
stora.remove("fault_fromData");
},
formatDateTime(obj) {
if (obj == null) {
return "";
}
let date = new Date(obj);
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return (
y +
"-" +
m.substring(m.length - 2, m.length) +
"-" +
d.substring(d.length - 2, d.length)
);
},
loadmore() {
this.loading = true;
this.$api.standbyVehicle
.queryPageList(this.queryPage)
.then((res) => {
this.queryPage.pageNo = res.data.current;
this.queryPage.pages = res.data.pages;
this.queryPage.total = res.data.total;
this.dataList.push(...(res.data.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
},
onLoad() {
// this.loadmore();
},
onShow() {
this.sectionChange(this.current);
},
onPullDownRefresh() {
this.sectionChange(this.current);
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
destroyed() {
//页面销毁删除掉数据缓存
stora.remove("fault_fromData");
},
onReachBottom() {
console.log("触底了");
//当前页数小于总页数
if (this.queryPage.pageNo < this.queryPage.pages) {
this.queryPage.pageNo++;
this.loadmore();
} else {
this.noMoreData = true;
console.log("没有更多数据了");
}
},
};
</script>
<style lang="less" scoped>
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
.list {
background: #d7d7d7;
padding: 0 20px 20rpx;
.item {
background: white;
width: calc(100% - 40rpx);
padding: 20rpx;
margin-bottom: 20rpx;
position: relative;
border-radius: 15rpx;
.line {
display: flex;
align-items: center;
margin-bottom: 15rpx;
.left {
margin-right: 50rpx;
width: 300rpx;
}
.text-small {
font-size: x-small;
}
.text-normal {
font-size: small;
}
}
.buttons {
position: absolute;
top: 20rpx;
right: 20rpx;
button {
width: 130rpx;
height: 50rpx;
padding: 12rpx 0;
font-size: 26rpx;
line-height: 26rpx;
margin-bottom: 10rpx;
}
}
}
.no-more {
width: 100%;
text-align: center;
font-size: xx-small;
color: white;
}
}
</style>

3331
pages/truckRent/detail.vue Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,625 @@
<template>
<view class="container">
<view class="item">
<view class="title required">品牌</view>
<u-picker :show="showBrandPicker" :columns="[brands]" keyName="dicName" :immediateChange="true"
@confirm="confirmBand" @cancel="showBrandPicker = false" >
</u-picker>
<u--input border="surround" disabledColor="#ffffff" disabled fontSize="26"
:value="brands[info.brand - 1].dicName" @tap="showBrandPicker = true">
</u--input>
</view>
<view class="item">
<view class="title required">型号</view>
<u--input border="surround" :value="modelName" disabled fontSize="26"></u--input>
</view>
<view class="item">
<view class="title required">车牌号</view>
<u-picker :show="showPlateNumberPicker" :columns="[inStoreList]" keyName="plateNumber" :immediateChange="true"
@confirm="confirmPlateNumber" @cancel="showPlateNumberPicker = false" >
</u-picker>
<u--input border="surround" disabledColor="#ffffff" disabled fontSize="26"
:value="info.plateNumber" @tap="showPlateNumberPicker = true">
</u--input>
</view>
<view class="item">
<view class="title required">车架号</view>
<u--input border="surround" v-model="info.vin" disabled fontSize="26"></u--input>
</view>
<view class="item">
<view class="title required">车身广告</view>
<u-picker :show="showHasAdvPicker" :columns="[yesNoDic]" keyName="dicName" :immediateChange="true"
@confirm="confirmHasAdv" @cancel="showHasAdvPicker = false" >
</u-picker>
<u--input border="surround" disabledColor="#ffffff" disabled fontSize="26"
:value="yesNoDic[info.hasAdvertisement - 1].dicName" @tap="showHasAdvPicker = true">
</u--input>
</view>
<view class="item">
<view class="title required">尾板</view>
<u-picker :show="showHasTailPicker" :columns="[yesNoDic]" keyName="dicName" :immediateChange="true"
@confirm="confirmHasTail" @cancel="showHasTailPicker = false" >
</u-picker>
<u--input border="surround" disabledColor="#ffffff" disabled fontSize="26"
:value="yesNoDic[info.hasTailboard - 1].dicName" @tap="showHasTailPicker = true">
</u--input>
</view>
<view class="item">
<view class="title required">是否有挂</view>
<u-picker :show="showIsHangPicker" :columns="[yesNoDic]" keyName="dicName" :immediateChange="true"
@confirm="confirmIsHang" @cancel="showIsHangPicker = false" >
</u-picker>
<u--input border="surround" disabledColor="#ffffff" disabled fontSize="26"
:value="yesNoDic[info.isHang - 1].dicName" @tap="showIsHangPicker = true">
</u--input>
</view>
<view class="item">
<view class="title">挂车牌号</view>
<u--input border="surround" v-model="info.hangPlateNumber" fontSize="26"></u--input>
</view>
<view class="item">
<view class="title required">合同交车日期</view>
<u--input border="surround" :value="formatDateTime(info.handoverDate)" disabled fontSize="26"></u--input>
</view>
<view class="item">
<view class="title required">约定交车日期</view>
<u--input border="surround" :value="formatDateTime(info.appointedDate)" disabled fontSize="26"></u--input>
</view>
<view class="item">
<view class="title">运维预计交车日期</view>
<u-datetime-picker
:show="showPredictDatePicker"
mode="date"
@confirm="confirmPredictDate"
@cancel="showPredictDatePicker = false"
></u-datetime-picker>
<u--input border="surround" disabledColor="#ffffff" disabled fontSize="26"
:value="formatDateTime(info.operationExpectedDeliveryDate)" @tap="showPredictDatePicker = true">
</u--input>
</view>
<view class="item">
<view class="title required">是否一致</view>
<u-switch v-model="info.isAccord" size="50"
disabled
:inactiveValue="0" :activeValue="1"
inactiveColor="#f5f7fa" activeColor="#7ba746">
</u-switch>
</view>
<view class="item">
<view class="title">备注</view>
<u--textarea border="surround" v-model="info.remark" fontSize="26" autoHeight></u--textarea>
</view>
<view class="item">
<button class="btn checkList required" @tap="openCheckListPopup">备车检查单</button>
</view>
<view class="item">
<view class="title required">备车完成</view>
<u-switch v-model="prepareOk" size="50"
@change="prepareOkChange"
inactiveColor="#f5f7fa" activeColor="#7ba746">
</u-switch>
</view>
<view class="item">
<view class="title">备车完成时间</view>
<u--input border="surround" disabled fontSize="26"
:value="formatDateTime(info.standbyDate, 'hour')">
</u--input>
</view>
<view class="btns">
<button class="save" @tap="saveStandbyVehicleDetail">保存</button>
<button class="cancel" @tap="navigateBack">取消</button>
</view>
<u-popup :show="checkListShow" mode="right" @close="checkListShow = false">
<scroll-view scroll-y="true" style="height: 95vh;">
<no-bad-table :columns="columns" :list="formDataList" :spanArr="spanArr"
:slot-cols="['dataCategory', 'dataName', 'takeTruck', 'quantity']"
:span-method="objectSpanMethod">
<template v-slot="{ row, col, index }">
<view v-if="col.key == 'dataCategory'" style="white-space: pre-wrap">
{{ row.dataCategory }}
</view>
<view v-else-if="col.key == 'dataName'" style="white-space: pre-wrap">
{{ row.dataName }}
</view>
<view v-else-if="col.key == 'takeTruck'" style="display: flex; justify-content: center;">
<u-switch size="50"
v-model="row.takeTruck"
@change="switchTakeTruck(index)"
inactiveColor="#f5f7fa" activeColor="#7ba746">
</u-switch>
</view>
<view v-else-if="col.key == 'quantity' && !row.notUpdate" style="display: flex; justify-content: center;">
<u--input border="surround" fontSize="26"
type="number"
:value="row.quantity"
@change="inputQuality($event, index)"
>
</u--input>
</view>
</template>
</no-bad-table>
<view class="btns">
<button class="save" @tap="saveFormDataList">保存</button>
<button class="cancel" @tap="cancelFormDataChange">取消</button>
</view>
</scroll-view>
</u-popup>
</view>
</template>
<script>
import {
getUser
} from "@/utils/auth.js";
export default {
options: {
styleIsolation: 'shared', // 解除样式隔离
},
data() {
return {
mainId: 0, // 备车主表id
id: 0, // 备车单中某一辆车辆信息id
info: {}, // 该备车车辆记录的数据
brands: [],
truckType: [],
yesNoDic: [],
showBrandPicker: false,
showHasAdvPicker: false, // hasAdvertisement
showHasTailPicker: false, // hasTailboard
showIsHangPicker: false,
showPredictDatePicker: false,
showPlateNumberPicker: false,
prepareOk: false, // 备车完成 switch
checkListShow: false, // 检查单弹窗
formDataList: [], // 备车单数据
spanArr: [],
columns: [
{
title: "检查类别",
key: "dataCategory"
},
{
title: '检查项目',
key: 'dataName'
},
{
title: '选择',
key: 'takeTruck'
},
{
title: '数量',
key: 'quantity'
}
],
inStoreList: [], // 在库状态车辆列表
}
},
methods: {
getData() {
this.$api.standbyVehicle.getById({ id: this.mainId }).then(res => {
if (res.code != 200 || !res.data.detailList) {
return
}
this.info = res.data.detailList.find(x => x.id == this.id)
// 已有备车完成时间,说明已备完车
if (this.info.standbyDate) {
this.prepareOk = true
}
this.getInStoreList()
// formDataList为深度拷贝的一个对象并不会直接影响到该车辆的检查单信息
this.formDataList = this.processFormDataList(this.deepClone(this.info.formDataList))
this.getSpanArr(this.formDataList)
// console.log(`this.info:\n`, this.info)
console.log(`this.formDataList:\n`, this.formDataList)
})
},
getDic() {
this.$api.standbyVehicle.getVehicleBrand().then(res => {
this.brands = res
})
this.$api.standbyVehicle.getTruckType().then(res => {
this.truckType = res
})
this.$api.standbyVehicle.getYesNoDic().then(res => {
this.yesNoDic = res
})
},
formatDateTime(obj, type = "date") {
if (obj == null) {
return ""
}
// 精确到日
if (type == "date") {
let date = new Date(obj);
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return y + "-" + m.substring(m.length - 2, m.length) + "-" + d.substring(d.length - 2, d.length);
}
// 精确到小时
else if (type == "hour") {
const date = new Date(obj); // 将时间戳转换为毫秒
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始
const day = String(date.getDate()).padStart(2, '0');
const hour = String(date.getHours()).padStart(2, '0');
return `${year}-${month}-${day} ${hour}:00`;
}
},
timestampToDateAndBack(timestamp) {
const date = new Date(timestamp);
const year = date.getFullYear();
const month = (date.getMonth() + 1).toString().padStart(2, '0'); // 月份从0开始所以要+1
const day = date.getDate().toString().padStart(2, '0');
const formattedDate = `${year}-${month}-${day}`;
const newTimestamp = new Date(`${formattedDate} 00:00:00`).getTime();
return newTimestamp;
},
getNowTimestamp() {
// 获取当前时间精确到小时的时间戳
const now = new Date();
now.setMinutes(0, 0, 0); // 设置分钟、秒、毫秒为0
return now.getTime(); // 返回时间戳
},
confirmBand(e) {
// 没有更改
if (e.indexs[0] + 1 == this.info.brand) {
this.showBrandPicker = false
return
}
this.info.brand = e.indexs[0] + 1
this.showBrandPicker = false
this.getInStoreList() // 品牌一变,需要重新获取车牌号列表(每种品牌的车牌号列表不同)
this.info.plateNumber = ""
this.info.vin = ""
},
confirmHasAdv(e) {
this.info.hasAdvertisement = e.indexs[0] + 1
this.showHasAdvPicker = false
},
confirmHasTail(e) {
this.info.hasTailboard = e.indexs[0] + 1
this.showHasTailPicker = false
},
confirmIsHang(e) {
this.info.isHang = e.indexs[0] + 1
this.showIsHangPicker= false
},
confirmPredictDate(e) {
// 首次选择日期时,时间戳信息精确到了秒,故这里统一处理,使之仅精确到日
this.info.operationExpectedDeliveryDate = this.timestampToDateAndBack(e.value)
this.showPredictDatePicker = false
},
confirmPlateNumber(e) {
console.log(e)
this.info.plateNumber = e.value[0].plateNumber
this.info.vin = e.value[0].vin
this.info.truckId = e.value[0].id // 换车牌本质是换这个车辆id
this.showPlateNumberPicker = false
},
prepareOkChange(value) {
if (value) {
this.info.standbyDate = this.getNowTimestamp()
// 比较备车完成时间和约定交车日期,若是同一天(或早于约定日期) 则认为 "一致"将isAccord设置为1
if (this.timestampToDateAndBack(this.info.standbyDate) <= this.info.appointedDate) {
this.info.isAccord = 1
} else {
this.info.isAccord = 0
}
} else {
this.info.standbyDate = null
this.info.isAccord = 0
}
},
navigateBack() {
uni.navigateBack()
},
switchTakeTruck(index) {
this.formDataList[index].takeTruck = !this.formDataList[index].takeTruck
},
inputQuality(value, index) {
value = value.replace(/[^0-9.]/g, '')
this.formDataList[index].quantity = value
},
processFormDataList(dataList) {
dataList = dataList.filter(x => x.dataName != "检查项目")
for (let item of dataList) {
if (item.takeTruck == "true") {
item.takeTruck = true
} else if (item.takeTruck == "false") {
item.takeTruck = false
}
if (item.quantity !== "" && item.quantity !== null) {
item.quantity = parseFloat(Number(item.quantity).toFixed(2))
}
}
return dataList
},
// https://www.cnblogs.com/janni/p/12992591.html
getSpanArr(data) {
this.spanArr = []
for (let i = 0; i < data.length; i++) {
if (i === 0) {
this.spanArr.push(1);
this.pos = 0
} else {
// 判断当前元素与上一个元素是否相同 dataCategory (类别字段)
if (data[i].dataCategory === data[i - 1].dataCategory) {
this.spanArr[this.pos] += 1;
this.spanArr.push(0);
} else {
this.spanArr.push(1);
this.pos = i;
}
}
}
},
objectSpanMethod(row, column, rowIndex, columnIndex) {
if (columnIndex === 0) {
const _row = this.spanArr[rowIndex];
const _col = _row > 0 ? 1 : 0;
return {
rowspan: _row,
colspan: _col
}
}
},
// https://www.kancloud.cn/uview/uview-ui_v2/2579089
deepClone(obj) {
if (obj === null) return null;
if (typeof obj !== 'object') return obj;
if (obj instanceof Date) {
let date = new Date();
date.setTime(obj.getTime());
return date;
}
if (obj instanceof RegExp) {
let re = new RegExp(obj.source);
re.lastIndex = obj.lastIndex;
return re;
}
let newObj = new obj.constructor();
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = this.deepClone(obj[key]);
}
}
return newObj;
},
openCheckListPopup() {
if (!this.info.truckId) {
uni.showToast({
title: '请先选择车牌号',
duration: 1500,
icon: "error"
})
return
}
if (this.info.formDataList.length == 0) {
this.$api.standbyVehicle.getFormDataListByTruckId({ id: this.info.truckId }).then(res => {
this.formDataList = this.processFormDataList(res.data)
this.getSpanArr(this.formDataList)
this.checkListShow = true
uni.setNavigationBarTitle({
title: '备车检查单'
});
})
} else {
this.checkListShow = true
uni.setNavigationBarTitle({
title: '备车检查单'
});
}
},
saveFormDataList() {
this.checkListShow = false
this.info.formDataList = this.deepClone(this.formDataList)
uni.setNavigationBarTitle({
title: '备车信息'
});
},
cancelFormDataChange() {
this.formDataList = this.processFormDataList(this.deepClone(this.info.formDataList))
this.getSpanArr(this.formDataList)
this.checkListShow = false
uni.setNavigationBarTitle({
title: '备车信息'
});
},
// 保存备车信息表
saveStandbyVehicleDetail() {
if (!this.info.plateNumber) {
uni.showToast({
title: '请选择车牌号',
duration: 1500,
icon: "error"
})
return
}
this.$api.standbyVehicle.saveStandbyVehicleDetail(this.info).then(res => {
// todo res是接口data数据之后研究一下如何获取整个内容
if (res == this.info.id) {
uni.showToast({
title: '保存成功',
icon: 'success',
duration: 1500,
success() {
setTimeout(() => {
uni.navigateBack()
}, 1500)
}
});
}
})
},
getInStoreList() {
this.$api.truck.queryInStoreList({ brand: this.info.brand, model: this.info.model }).then(res => {
this.inStoreList = res
})
}
},
computed: {
modelName() {
if (this.truckType.length == 0) {
return ""
}
return this.truckType.find(x => x.dicCode == this.info.model)?.dicName ?? ""
}
},
onLoad(options) {
if (options.id) {
this.id = options.id
}
if (options.mainId) {
this.mainId = options.mainId
}
this.getData()
this.getDic()
this.userInfo = getUser() || {}
console.log(`userInfo:\n`, this.userInfo)
},
onPullDownRefresh(){
uni.stopPullDownRefresh() //刷新数据之后停止刷新效果
},
onShow() {
},
destroyed(){
console.log(`备车信息页 destroyed`)
this.$api.standbyVehicle.delCache({ key: this.id }).then(res => {
console.log(`清空操作标识`)
console.log(res)
})
},
}
</script>
<style lang="less" scoped>
.container {
// background-color: #d7d7d7;
padding: 30rpx;
.item {
margin-top: 30rpx;
.title {
font-size: 26rpx;
margin-bottom: 15rpx;
&.required::before {
content: '*';
color: red;
margin-right: 3rpx;
}
}
.btn.checkList {
width: 200rpx;
height: 60rpx;
font-size: 26rpx;
line-height: 26rpx;
padding: 17rpx 0;
text-align: center;
background-color: #7ba746;
color: white;
margin-left: 0;
&.required::before {
content: '*';
color: red;
margin-right: 3rpx;
}
}
}
.btns {
display: flex;
align-items: center;
justify-content: space-around;
margin-top: 40rpx;
button {
width: 200rpx;
height: 60rpx;
font-size: 26rpx;
line-height: 26rpx;
padding: 17rpx 0;
text-align: center;
}
.cancel {
background-color: white;
color: #7ba746;
border: 1rpx #7ba746 solid;
}
.save {
background-color: #7ba746;
color: white;
}
}
}
/deep/ picker-view {
height: 450rpx !important;
}
/deep/ .u-border {
border-width: 1rpx !important;
border-color: #dadbde !important;
border-style: solid;
}
/deep/ .u-switch {
border-color: rgba(0, 0, 0, 0.12) !important;
}
/deep/ .u-slide-right-enter-to.u-slide-right-enter-active {
width: 750rpx;
}
/deep/ .td_wrap {
height: auto !important;
}
/deep/ checkbox-group view.td {
width: 186rpx !important;
}
/deep/ checkbox-group view.td_wrap {
width: 186rpx !important;
}
/deep/ .no-bad-table-wrap .td.rowspan {
display: flex;
align-items: center;
justify-content: center;
}
/deep/ .div-table-head .thead .tr view {
width: 186rpx !important;
}
/deep/ no-bad-table {
overflow-x: hidden;
}
/deep/ .no-bad-table-wrap .thead .tr .td {
background-color: #7ba746;
color: white;
}
/deep/ .no-bad-table-wrap .thead .tr .td .td_wrap {
background-color: #7ba746;
color: white;
}
</style>

478
pages/truckRent/index.vue Normal file
View File

@@ -0,0 +1,478 @@
<template>
<view>
<u-sticky>
<view style="background-color: #fff">
<u-subsection
mode="subsection"
:list="list"
:current="current"
@change="sectionChange"
activeColor="#7ba746"
:fontSize="30"
>
</u-subsection>
</view>
<u-search
placeholder="请输入"
v-model="keyword"
:showAction="false"
@search="searchList()"
></u-search>
</u-sticky>
<view class="list">
<view class="item" v-for="item in dataList" :key="item.id">
<view class="line" v-if="item.safetyAuditStatus == 1 && isSafe">
<u-badge :isDot="true" type="warning"></u-badge>
<view class="text-normal" style="margin-left: 20rpx">待安检</view>
</view>
<view class="line" v-else-if="item.safetyAuditStatus == 2 && isSafe">
<u-badge :isDot="true" type="error"></u-badge>
<view class="text-normal" style="margin-left: 20rpx">驳回</view>
</view>
<view class="line" v-else-if="item.safetyAuditStatus == 3 && isSafe">
<u-badge :isDot="true" type="success"></u-badge>
<view class="text-normal" style="margin-left: 20rpx">已通过</view>
</view>
<view class="line" v-else-if="item.safetyAuditStatus == 4 && isSafe">
<u-badge :isDot="true" type="info"></u-badge>
<view class="text-normal" style="margin-left: 20rpx">待审批</view>
</view>
<view class="line">
<view class="text-normal">合同编号: {{ item.contractNo }}</view>
</view>
<view class="line">
<view class="text-normal">项目名称: {{ item.projectName }}</view>
</view>
<view class="line">
<view class="text-small">客户名称: {{ item.customerName }}</view>
</view>
<view class="line">
<view class="text-small">交车区域: {{ item.deliveryAreaName }}</view>
</view>
<view class="line">
<view class="text-small">交车地点: {{ item.handoverAddress }}</view>
</view>
<view class="line" style="justify-content: space-between">
<view class="text-small left"
>交车时间: {{ formatDateTime(item.handoverDate) }}</view
>
<view class="text-small">车牌号: {{ item.plateNumber }}</view>
</view>
<view class="buttons">
<!--deliveryPermit为1的时候准许交车 -->
<button
@tap="goto"
v-if="item.deliveryPermit == 1 && currSafeRole === 0 && editButton"
:data-url="`/pages/truckRent/detail?id=${item.id}`"
>
编辑
</button>
<button
@tap="returnCar(item.id)"
v-if="isBussinessRole && current === 0"
>
<!-- :disabled="![1, 2].includes(item.safetyAuditStatus)" -->
还车
</button>
<button
@tap="cancelReturnCar(item.id)"
v-if="isBussinessRole && current === 1"
>
撤销还车
</button>
<button
@tap="goto"
v-if="currSafeRole === 1 && [1, 2].includes(item.safetyAuditStatus)"
:data-url="`/pages/truckRent/detail?id=${item.id}${
currSafeRole !== 0 ? '&isRead=1&isSafe=1' : ''
}`"
>
<!-- :disabled="![1, 2].includes(item.safetyAuditStatus)" -->
安全检查
</button>
<button
@tap="goto"
v-if="currSafeRole === 2 && item.safetyAuditStatus === 4"
:data-url="`/pages/truckRent/detail?id=${item.id}${
currSafeRole !== 0 ? '&isRead=1&isSafe=1' : ''
}`"
>
<!-- :disabled="item.safetyAuditStatus !== 4" -->
安全审批
</button>
<button
@tap="goto"
:data-url="`/pages/truckRent/detail?id=${item.id}&isRead=1`"
>
查看
</button>
</view>
</view>
<view class="no-more" v-if="noMoreData">没有更多数据了</view>
</view>
<view
clas="line"
style="margin-top: 150rpx"
v-if="!dataList || dataList.length === 0"
>
<u-empty mode="search" text="暂无数据" width="400" textSize="16">
</u-empty
></view>
<u-loading-page
bg-color="#ffffff"
:loading="loading"
color="#7ba746"
font-size="24"
></u-loading-page>
<custom-modal ref="customModal" @submit="returnCarFunc" />
</view>
</template>
<script>
import CustomModal from "./modal.vue";
import stora from "@/utils/storage";
import { checkButtonPermission } from "@/utils/permission.js";
import { getUser } from "@/utils/auth.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
components: {
CustomModal,
},
data() {
return {
current: 0,
userInfo: {}, // 用户信息
list: ["待交车", "全部"],
queryPage: {
pageNo: 1, // 页码
pageSize: 10, //每页查询条数
total: 0, //总页数
pages: -1, //总页数
// deliveryPermits: ["1"], // 交车许可 1表示 准许交车
},
costDepList: [], //费用部门
dataList: [],
pageNo: 1,
noMoreData: false,
loading: false,
keyword: "", //搜索关键字
pageCode: "applicationForDelivery",
currId: "",
};
},
computed: {
editButton: function () {
return checkButtonPermission("applicationForDeliveryEdit", this.pageCode);
},
currSafeRole() {
const ids = this.userInfo?.roles?.map((item) => item.id) || [];
if (ids.includes("1076403008717209600")) {
return 2; //安全经理
} else if (ids.includes("1012435145369616384")) {
return 1; //安全员
} else {
return 0; //其他
}
},
isBussinessRole() {
console.log(this.userInfo);
if (this.userInfo.depCode === "0501") {
console.log("业务服务组-业务助理");
return true; //业务服务组-业务助理
} else {
return false; //其他
}
},
isSafe() {
return [1, 2].includes(this.currSafeRole);
},
},
methods: {
// 新增的搜索方法
searchList() {
this.queryPage.plateNumber = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
this.current = index;
this.queryPage.plateNumber = undefined; // 清空搜索关键字
this.keyword = ""; // 清空搜索关键字
if ([1, 2].includes(this.currSafeRole)) {
if (index == 1) {
// 已通过
this.queryPage.safetyAuditStatus = ["3"];
} else {
// 未通过
this.queryPage.safetyAuditStatus = ["1", "2", "4"];
}
} else if (this.isBussinessRole) {
if (index == 1) {
console.log("业务助理-待还车");
// 业务助理,待还车
this.queryPage.vehicleArrival = "0";
this.queryPage.taskStatus = "";
} else {
// 全部
this.queryPage.vehicleArrival = "2";
this.queryPage.taskStatus = "1";
}
} else {
if (index == 1) {
// 全部 (准许交车 + 已交车)
this.queryPage.deliveryPermits = ["1", "3"];
} else {
// 仅显示准许交车
this.queryPage.deliveryPermits = ["1"];
}
}
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
submitEvent() {
this.current = 1;
//提交后删除缓存
stora.remove("fault_fromData");
},
formatDateTime(obj) {
if (obj == null) {
return "";
}
let date = new Date(obj);
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return (
y +
"-" +
m.substring(m.length - 2, m.length) +
"-" +
d.substring(d.length - 2, d.length)
);
},
loadmore() {
this.loading = true;
if (this.isBussinessRole && this.current == 1) {
this.$api.returnCar
.queryTakePageList(this.queryPage)
.then((res) => {
console.log(res);
this.queryPage.pageNo = res.current;
this.queryPage.pages = res.pages;
this.queryPage.total = res.total;
this.dataList.push(...(res.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
} else {
this.$api.truckRent
.queryTakePageList(this.queryPage)
.then((res) => {
console.log(res);
this.queryPage.pageNo = res.current;
this.queryPage.pages = res.pages;
this.queryPage.total = res.total;
this.dataList.push(...(res.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
}
},
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
returnCar(id) {
this.currId = id;
this.$refs.customModal.openModal();
},
returnCarFunc(isHasOkPack) {
const _this = this;
this.$api.returnCar
.startReturn({ id: this.currId, hasOkPack: isHasOkPack })
.then((res) => {
if (res) {
uni.showToast({
title: "还车成功",
icon: "success",
duration: 1500,
success() {
_this.sectionChange(_this.current);
},
});
}
});
// const _this = this;
// uni.showModal({
// title: "提示",
// cancelText: "无",
// confirmText: "有",
// content: "请确认退还车辆有无无忧包?",
// success: (res) => {
// if (res.confirm) {
// this.$api.returnCar
// .startReturn({ id, hasOkPack: isHasOkPack })
// .then((res) => {
// if (res) {
// uni.showToast({
// title: "还车成功",
// icon: "success",
// duration: 1500,
// success() {
// _this.sectionChange(_this.current);
// },
// });
// }
// });
// }
// },
// });
},
cancelReturnCar(id) {
const _this = this;
uni.showModal({
title: "提示",
content: "确认撤销本次还车?",
success: (res) => {
if (res.confirm) {
this.$api.returnCar.cancelReturn({ id }).then((res) => {
if (res) {
uni.showToast({
title: "撤销成功",
icon: "success",
duration: 1500,
success() {
_this.sectionChange(_this.current);
},
});
}
});
}
},
});
},
// getCostDeps() {
// this.$api.returnCar.getCostDeps().then((res) => {
// this.costDepList = res;
// });
// },
},
onLoad() {
// this.getCostDeps();
this.userInfo = getUser() || {};
console.log(this.userInfo);
if ([1, 2].includes(this.currSafeRole)) {
this.list = ["未通过", "已通过"]; //安全模块
} else if (this.isBussinessRole) {
this.list = ["全部", "待还车"]; //交还车-费用核算
}
},
onPullDownRefresh() {
this.sectionChange(this.current);
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
destroyed() {
//页面销毁删除掉数据缓存
stora.remove("fault_fromData");
},
onReachBottom() {
console.log("触底了");
//当前页数小于总页数
if (this.queryPage.pageNo < this.queryPage.pages) {
this.queryPage.pageNo++;
this.loadmore();
} else {
this.noMoreData = true;
console.log("没有更多数据了");
}
},
onShow() {
this.sectionChange(this.current);
},
};
</script>
<style lang="less" scoped>
/deep/ .u-badge--success {
background-color: #5ac725 !important;
}
/deep/ .u-badge--info {
background-color: #fcae63 !important;
}
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
// /deep/ .u-search__content__input {
// height: 50rpx !important;
// padding-top: 20rpx !important; /* 上边距 */
// padding-bottom: 20rpx !important; /* 下边距 */
// }
.list {
background: #d7d7d7;
padding: 0 20px 20rpx;
.item {
background: white;
width: calc(100% - 40rpx);
padding: 20rpx;
margin-bottom: 20rpx;
position: relative;
border-radius: 15rpx;
.line {
display: flex;
align-items: center;
margin-bottom: 15rpx;
.left {
margin-right: 50rpx;
width: 300rpx;
}
.text-small {
font-size: x-small;
}
.text-normal {
font-size: small;
}
}
.buttons {
position: absolute;
top: 20rpx;
right: 20rpx;
button {
width: 130rpx;
height: 50rpx;
padding: 12rpx 0;
font-size: 26rpx;
line-height: 26rpx;
margin-bottom: 10rpx;
}
}
}
.no-more {
width: 100%;
text-align: center;
font-size: xx-small;
color: white;
}
}
</style>

112
pages/truckRent/modal.vue Normal file
View File

@@ -0,0 +1,112 @@
<template>
<view class="custom-modal" v-if="show">
<view class="modal-overlay" @click="closeModal"></view>
<view class="modal-container">
<view class="modal-header">提示</view>
<view class="modal-content">请确认退还车辆有无无忧包?</view>
<view class="modal-footer">
<button class="btn cancel" @click="handleCancel"></button>
<button class="btn confirm" @click="handleConfirm"></button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
show: false,
};
},
methods: {
openModal() {
this.show = true;
},
closeModal() {
this.show = false;
},
handleCancel() {
console.log("点击了无");
this.$emit("submit", false);
this.closeModal();
},
handleConfirm() {
console.log("点击了有");
this.$emit("submit", true);
this.closeModal();
},
},
};
</script>
<style>
.custom-modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
}
.modal-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.6);
}
.modal-container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
background-color: #fff;
border-radius: 16rpx;
padding: 30rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.15);
}
.modal-header {
font-size: 32rpx;
font-weight: bold;
text-align: center;
margin-bottom: 20rpx;
}
.modal-content {
font-size: 28rpx;
text-align: center;
margin-bottom: 30rpx;
color: #666;
}
.modal-footer {
display: flex;
justify-content: space-between;
}
.btn {
flex: 1;
margin: 0 40rpx;
height: 80rpx;
line-height: 80rpx;
border-radius: 40rpx;
font-size: 28rpx;
text-align: center;
}
.cancel {
background-color: #f0f0f0;
color: #333;
}
.confirm {
background-color: #007aff;
color: #fff;
}
</style>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,416 @@
<template>
<view>
<u-sticky>
<u-button text="新增" @click="addFailuer"></u-button>
<!-- <u-search placeholder="请输入车牌号" v-model="keyword" :showAction="false" @search="searchList()"></u-search> -->
<view style="background-color: #fff">
<u-subsection
mode="subsection"
:list="list"
:current="current"
@change="sectionChange"
activeColor="#7ba746"
:fontSize="30"
>
</u-subsection>
</view>
<u-search
placeholder="请输入"
v-model="keyword"
:showAction="false"
@search="searchList()"
></u-search>
</u-sticky>
<view class="list">
<view class="item" v-for="item in dataList" :key="item.id">
<view
class="line"
v-if="item.approvalStatus == 10 && item.isSubmit != 0"
>
<u-badge :isDot="true" type="warning"></u-badge>
<view class="text-normal">待审批</view>
</view>
<view class="line" v-else-if="item.approvalStatus === 0">
<u-badge :isDot="true" type="warning"></u-badge>
<view class="text-normal">待提交</view>
</view>
<view class="line" v-else-if="item.approvalStatus == 40">
<u-badge :isDot="true" type="error"></u-badge>
<view class="text-normal">驳回</view>
</view>
<view class="line" v-else-if="item.approvalStatus === 60">
<u-badge :isDot="true" type="warning"></u-badge>
<view class="text-normal">异动超时</view>
</view>
<view class="line" v-else-if="item.approvalStatus == 99">
<u-badge :isDot="true" type="info"></u-badge>
<view class="text-normal">已撤销</view>
</view>
<view class="line" v-else-if="item.approvalStatus == 30">
<u-badge :isDot="true" type="error"></u-badge>
<view class="text-normal">进行中</view>
</view>
<view class="line" v-else-if="item.approvalStatus == 50">
<u-badge :isDot="true" type="success"></u-badge>
<view class="text-normal">异动完成</view>
</view>
<!-- <view class="line" v-else-if="item.approvalStatus == 30">
<u-badge
:isDot="true"
:type="item.transactionStatus === 2 ? 'success' : 'error'"
></u-badge>
<view class="text-normal">{{
item.transactionStatus === 2 ? "异动完成" : "进行中"
}}</view>
</view> -->
<view class="line">
<view class="text-small">车牌号: {{ item.plateNumber || "" }}</view>
</view>
<view class="line">
<view class="text-small">申请人: {{ item.applyUserName || "" }}</view>
</view>
<view
class="line"
v-if="![0, 10].includes(item.approvalStatus) && item.approvalName"
>
<view class="text-small">审批人: {{ item.approvalName || "" }}</view>
</view>
<view class="line">
<view class="text-small"
>开始时间:
{{ formatDateTime(item.transactionStartTime, "minute") }}</view
>
</view>
<view class="line">
<view class="text-small"
>异动目的地: {{ item.transactionAddressName || "" }}</view
>
</view>
<!-- <view class="line">
<view class="text-small"
>结束时间: {{ formatDateTime(item.approvalTime, "minute") }}</view
>
</view> -->
<view class="buttons">
<button
@tap="goto"
:data-url="`/pages/unusualActionApply/detail?id=${item.id}`"
v-if="editButton && [0, 30, 40, 60].includes(item.approvalStatus)"
>
<!-- 25.2.24 注释&&
![2, 3].includes(item.transactionStatus)
2现为approvalStatus50 3为99
去除异动状态沿用审批状态字段当做异动状态显示 仅在前端显示为异动
-->
<!--
item.applyUserId === userId 编辑按钮不跟申请人挂钩跟外勤挂钩
[30, 40].includes(item.approvalStatus) 30通过 40驳回
[2, 3].includes(item.transactionStatus) 2异动完成 3撤销 -->
编辑
</button>
<button
@tap="goto"
:data-url="`/pages/unusualActionApply/detail?id=${item.id}&isAudit=1`"
v-if="item.approvalStatus === 10 && auditButton"
>
审批
</button>
<button
@tap="goto"
:data-url="`/pages/unusualActionApply/detail?id=${item.id}&isRead=1`"
>
查看
</button>
<button
@tap="cancelApply(item.id)"
v-if="
item.applyUserId == userId &&
![50, 99].includes(item.approvalStatus)
"
>
撤销
</button>
<!-- 25.2.24 注释 ![2, 3].includes(item.transactionStatus) &&
item.approvalStatus !== 99
2现为approvalStatus50 3为99
去除异动状态,沿用审批状态字段当做异动状态显示 仅在前端显示为异动
-->
</view>
</view>
<view class="no-more" v-if="noMoreData">没有更多数据了</view>
</view>
<u-loading-page
bg-color="#ffffff"
:loading="loading"
color="#7ba746"
font-size="24"
></u-loading-page>
</view>
</template>
<script>
import { getUser } from "@/utils/auth.js";
import { checkButtonPermission } from "@/utils/permission.js";
export default {
options: {
styleIsolation: "shared", // 解除样式隔离
},
data() {
return {
keyword: "",
userId: null,
current: 0,
list: ["审批通过", "待审批"],
queryPage: {
pageNo: 1, // 页码
pageSize: 10, // 每页查询条数
total: 0, // 总页数
pages: -1, // 总页数
approvalStatusList: [30, 50, 60], // 审批状态集合
wxOrder: 2,
},
dataList: [],
pageNo: 1,
noMoreData: false,
loading: false,
pageCode: "transactionManagement",
};
},
computed: {
auditButton: function () {
console.log(checkButtonPermission("transactionAudit", this.pageCode));
return checkButtonPermission("transactionAudit", this.pageCode);
},
editButton: function () {
return checkButtonPermission("transactionEdit", this.pageCode);
},
},
methods: {
// 新增的搜索方法
searchList() {
this.queryPage.plateNumber = this.keyword.trim(); // 设置车牌号条件
this.queryPage.pageNo = 1; // 重置页码为1
this.dataList = []; // 清空数据列表
this.noMoreData = false; // 重置没有更多数据的标志
this.loadmore(); // 重新加载数据
},
sectionChange(index) {
console.log(index);
this.current = index;
this.queryPage.plateNumber = undefined; // 清空搜索关键字
this.keyword = ""; // 清空搜索关键字
if (index == 1) {
this.queryPage.approvalStatusList = [0, 10, 40, 99]; // 待提交,待审批,审批不通过,已撤销
this.queryPage.wxOrder = 1;
} else {
this.queryPage.approvalStatusList = [30, 50, 60]; //审批通过 60过期
this.queryPage.wxOrder = 2;
}
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
formatDateTime(obj, type = "data") {
if (obj == null) {
return "";
}
const date = new Date(obj);
if (type === "date") {
let y = 1900 + date.getYear();
let m = "0" + (date.getMonth() + 1);
let d = "0" + date.getDate();
return (
y +
"-" +
m.substring(m.length - 2, m.length) +
"-" +
d.substring(d.length - 2, d.length)
);
} else if (type === "minute") {
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从0开始
const day = String(date.getDate()).padStart(2, "0");
const hour = String(date.getHours()).padStart(2, "0");
const minute = String(date.getMinutes()).padStart(2, "0");
return `${year}-${month}-${day} ${hour}:${minute}`;
}
},
loadmore() {
this.loading = true;
this.$api.unusualActionApply
.queryPageList(this.queryPage)
.then((res) => {
console.log(res);
this.queryPage.pageNo = res.data?.current;
this.queryPage.pages = res.data?.pages;
this.queryPage.total = res.data?.total;
this.dataList.push(...(res.data?.records || []));
this.loading = false;
})
.catch((errors) => {
this.loading = false;
});
},
onPullDownRefresh() {
this.sectionChange(this.current);
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
// formatPlateNumber(plateNumbers) {
// if (!plateNumbers) return ""; // 如果为空,返回空字符串
// const plates = plateNumbers.split(","); // 将字符串按逗号分隔成数组
// if (plates.length > 1) {
// return `${plates[0]}...`; // 如果有多个车牌号,返回第一个加上“...”
// }
// return plates[0]; // 如果只有一个车牌号,直接返回
// },
goto(e) {
uni.navigateTo({ url: e.target.dataset.url });
},
cancelApply(id) {
uni.showModal({
title: "提示",
content: "是否撤销本次异动申请?",
success: (res) => {
if (res.confirm) {
this.cancelApplyApi(id);
}
},
});
},
//撤销异动申请
cancelApplyApi(id) {
if (id) {
this.$api.unusualActionApply.revokeTransaction({ id }).then((res) => {
if (res) {
uni.showToast({
title: "撤销成功",
icon: "success",
duration: 1500,
success: () => {
this.sectionChange(this.current);
},
});
}
});
}
},
addFailuer() {
uni.navigateTo({ url: `/pages/unusualActionApply/detail` });
},
},
onLoad() {
this.userInfo = getUser() || {};
this.userId = this.userInfo.id;
console.log("userId type:", typeof this.userId);
},
onPullDownRefresh() {
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
uni.stopPullDownRefresh(); //刷新数据之后停止刷新效果
},
onReachBottom() {
console.log("触底了");
//当前页数小于总页数
if (this.queryPage.pageNo < this.queryPage.pages) {
this.queryPage.pageNo++;
this.loadmore();
} else {
this.noMoreData = true;
console.log("没有更多数据了");
}
},
onShow() {
this.queryPage.pageNo = 1;
this.dataList = [];
this.loadmore();
},
};
</script>
<style lang="less" scoped>
/deep/ .u-search {
background: #d7d7d7 !important;
padding: 20rpx 10rpx !important;
}
// /deep/ .u-search__content__input {
// height: 50rpx !important;
// padding-top: 20rpx !important; /* 上边距 */
// padding-bottom: 20rpx !important; /* 下边距 */
// }
/deep/ .u-icon__icon {
font-size: 26rpx !important;
}
/deep/ .u-badge--error {
background-color: red !important;
}
/deep/ .u-badge--success {
background-color: #4cd964 !important;
}
/deep/ .u-badge--dot {
height: 20rpx !important;
width: 20rpx !important;
}
.list {
background: #d7d7d7;
padding: 0 20px 20rpx;
.item {
background: white;
width: calc(100% - 40rpx);
padding: 20rpx;
margin-bottom: 20rpx;
position: relative;
border-radius: 15rpx;
.line {
display: flex;
align-items: center;
margin-bottom: 15rpx;
.left {
margin-right: 50rpx;
width: 300rpx;
}
.text-small {
font-size: x-small;
}
.text-normal {
margin-left: 20rpx;
font-size: small;
}
}
.buttons {
position: absolute;
top: 20rpx;
right: 20rpx;
button {
width: 130rpx;
height: 50rpx;
padding: 12rpx 0;
font-size: 26rpx;
line-height: 26rpx;
margin-bottom: 10rpx;
}
}
}
.no-more {
width: 100%;
text-align: center;
font-size: xx-small;
color: white;
}
}
</style>

39
pages/webview/index.vue Normal file
View File

@@ -0,0 +1,39 @@
<template>
<view>
<!-- WebView 组件 -->
<web-view ref="webView" :src="url" @message="handleGetMessage"></web-view>
</view>
</template>
<script>
export default {
data() {
return {
url: '' // WebView 的初始地址
}
},
onLoad: function (option) {
this.url = decodeURIComponent(option.url)
this.type = option.type
},
methods: {
handleGetMessage: function(e) {
console.log(e,'\n进入handleGetMessage方法')
console.log('handleGetMessage',e)
if(e.detail.data[0].result=='success'){
// 如果是人脸验证,则需要额外再跳一层
if (this.type == "face") {
console.log("人脸识别方式")
uni.navigateBack()
} else {
// 页面会自动往回跳1层短信认证时不需要手动uni.navigateBack
console.log("短信验证方式")
}
}
},
},
}
</script>

View File

@@ -0,0 +1,32 @@
diff --git a/node_modules/uview-ui/components/u-upload/u-upload.vue b/node_modules/uview-ui/components/u-upload/u-upload.vue
index eb55854..ad84c0e 100644
--- a/node_modules/uview-ui/components/u-upload/u-upload.vue
+++ b/node_modules/uview-ui/components/u-upload/u-upload.vue
@@ -20,14 +20,15 @@
/>
<view
v-else
+ @tap="onClickPreviewCustom(item)"
class="u-upload__wrap__preview__other"
>
<u-icon
color="#80CBF9"
size="26"
- :name="item.isVideo || (item.type && item.type === 'video') ? 'movie' : 'folder'"
+ :name="'folder'"
></u-icon>
- <text class="u-upload__wrap__preview__other__text">{{item.isVideo || (item.type && item.type === 'video') ? '视频' : '文件'}}</text>
+ <text class="u-upload__wrap__preview__other__text">{{ item.name || '文件' }}</text>
</view>
<view
class="u-upload__status"
@@ -351,6 +352,9 @@
'clickPreview',
Object.assign(Object.assign({}, item), this.getDetail(index))
);
+ },
+ onClickPreviewCustom(item) {
+ this.$emit("clickPreview", item);
}
}
}

35
project.config.json Normal file
View File

@@ -0,0 +1,35 @@
{
"setting": {
"es6": true,
"postcss": true,
"minified": true,
"uglifyFileName": false,
"enhance": true,
"packNpmRelationList": [],
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"useCompilerPlugins": false,
"minifyWXML": true,
"compileWorklet": false,
"uploadWithSourceMap": true,
"packNpmManually": false,
"minifyWXSS": true,
"localPlugins": false,
"disableUseStrict": false,
"condition": false,
"swc": false,
"disableSWC": true
},
"compileType": "miniprogram",
"simulatorPluginLibVersion": {},
"packOptions": {
"ignore": [],
"include": []
},
"appid": "wx4438f1a71e030de0",
"editorSetting": {},
"libVersion": "3.13.0"
}

View File

@@ -0,0 +1,22 @@
{
"libVersion": "3.13.0",
"projectname": "gjt_mini",
"setting": {
"urlCheck": false,
"coverView": true,
"lazyloadPlaceholderEnable": false,
"skylineRenderEnable": false,
"preloadBackgroundData": false,
"autoAudits": false,
"showShadowRootInWxmlPanel": true,
"compileHotReLoad": true,
"useApiHook": true,
"useApiHostProcess": true,
"useStaticServer": false,
"useLanDebug": false,
"showES6CompileOption": false,
"checkInvalidKey": true,
"ignoreDevUnusedFiles": true,
"bigPackageSizeSupport": false
}
}

BIN
static/audit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 B

BIN
static/baoyang.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
static/beiche.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
static/bi.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 558 B

BIN
static/chongdianzhan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 710 B

BIN
static/cost.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
static/detail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 938 B

BIN
static/electricity.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

BIN
static/expand-left-line.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
static/fault.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
static/g_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
static/huanche.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
static/hydrogen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 881 B

BIN
static/hydrogenStation.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
static/jiaoche.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
static/jiaqingzhan.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

BIN
static/kachetou.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 B

BIN
static/login_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
static/logo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
static/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
static/logo3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

BIN
static/mapcar.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
static/mapcar2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
static/maph.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 B

BIN
static/maph2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

BIN
static/nianshen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
static/offline.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

1
static/online-exam.svg Normal file
View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M24 24V19L39 4L44 9L29 24H24Z" fill="none" stroke="#4a90e2" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M16 24H9C6.23858 24 4 26.2386 4 29C4 31.7614 6.23858 34 9 34H39C41.7614 34 44 36.2386 44 39C44 41.7614 41.7614 44 39 44H18" stroke="#4a90e2" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg>

After

Width:  |  Height:  |  Size: 528 B

Some files were not shown because too many files have changed in this diff Show More