31 changed files with 13157 additions and 504 deletions
@ -0,0 +1,61 @@ |
|||
import request from '@/utils/request' |
|||
|
|||
// 查询字典数据列表
|
|||
export function listData(query) { |
|||
return request({ |
|||
url: '/system/dict/data/list', |
|||
method: 'post', |
|||
data: query |
|||
}) |
|||
} |
|||
|
|||
// 查询字典数据详细
|
|||
export function getData(dictCode) { |
|||
return request({ |
|||
url: '/system/dict/data/' + dictCode, |
|||
method: 'get' |
|||
}) |
|||
} |
|||
|
|||
// 根据字典类型查询字典数据信息
|
|||
export function getDicts(dictType) { |
|||
return request({ |
|||
url: '/system/dict/data/type/' + dictType, |
|||
method: 'get' |
|||
}) |
|||
} |
|||
|
|||
// 新增字典数据
|
|||
export function addData(data) { |
|||
return request({ |
|||
url: '/system/dict/data', |
|||
method: 'post', |
|||
data: data |
|||
}) |
|||
} |
|||
|
|||
// 修改字典数据
|
|||
export function updateData(data) { |
|||
return request({ |
|||
url: '/system/dict/data', |
|||
method: 'put', |
|||
data: data |
|||
}) |
|||
} |
|||
|
|||
// 删除字典数据
|
|||
export function delData(dictCode) { |
|||
return request({ |
|||
url: '/system/dict/data/' + dictCode, |
|||
method: 'delete' |
|||
}) |
|||
} |
|||
|
|||
// 导出字典数据
|
|||
export function exportData(query) { |
|||
return request({ |
|||
url: '/system/dict/data/export', |
|||
method: 'get', |
|||
params: query |
|||
}) |
|||
} |
@ -0,0 +1,76 @@ |
|||
import request from '@/utils/request' |
|||
|
|||
// 查询字典类型列表
|
|||
export function listType(query) { |
|||
return request({ |
|||
url: '/system/dict/type/list', |
|||
method: 'post', |
|||
data: query |
|||
}) |
|||
} |
|||
|
|||
export function allTypes() { |
|||
return request({ |
|||
url: '/system/dict/type/allList', |
|||
method: 'get' |
|||
}) |
|||
} |
|||
|
|||
// 查询字典类型详细
|
|||
export function getType(id) { |
|||
return request({ |
|||
url: '/system/dict/type/' + id, |
|||
method: 'get' |
|||
}) |
|||
} |
|||
|
|||
// 新增字典类型
|
|||
export function addType(data) { |
|||
return request({ |
|||
url: '/system/dict/type', |
|||
method: 'post', |
|||
data: data |
|||
}) |
|||
} |
|||
|
|||
// 修改字典类型
|
|||
export function updateType(data) { |
|||
return request({ |
|||
url: '/system/dict/type', |
|||
method: 'put', |
|||
data: data |
|||
}) |
|||
} |
|||
|
|||
// 删除字典类型
|
|||
export function delType(id) { |
|||
return request({ |
|||
url: '/system/dict/type/' + id, |
|||
method: 'delete' |
|||
}) |
|||
} |
|||
|
|||
// 清理参数缓存
|
|||
export function clearCache() { |
|||
return request({ |
|||
url: '/system/dict/type/clearCache', |
|||
method: 'delete' |
|||
}) |
|||
} |
|||
|
|||
// 导出字典类型
|
|||
export function exportType(query) { |
|||
return request({ |
|||
url: '/system/dict/type/export', |
|||
method: 'get', |
|||
params: query |
|||
}) |
|||
} |
|||
|
|||
// 获取字典选择框列表
|
|||
export function optionselect() { |
|||
return request({ |
|||
url: '/system/dict/type/optionselect', |
|||
method: 'get' |
|||
}) |
|||
} |
@ -0,0 +1,70 @@ |
|||
import request from '@/utils/request' |
|||
|
|||
// 获取项目列表
|
|||
export function getProjectListApi(data) { |
|||
return request({ |
|||
url: '/build/projectInfo/list', |
|||
method: 'post', |
|||
data, |
|||
timeout: 1000 * 60 |
|||
}) |
|||
} |
|||
|
|||
// 获取项目申请列表
|
|||
export function projectApplyListApi(data) { |
|||
return request({ |
|||
url: '/build/proInfoApply/list', |
|||
method: 'post', |
|||
data, |
|||
timeout: 1000 * 60 |
|||
}) |
|||
} |
|||
|
|||
// 新增项目
|
|||
export function projectAddApi(data) { |
|||
return request({ |
|||
url: '/build/projectInfo', |
|||
method: 'post', |
|||
data, |
|||
timeout: 1000 * 60 |
|||
}) |
|||
} |
|||
|
|||
// 获取项目详情
|
|||
export function projectInfoApi(id) { |
|||
return request({ |
|||
url: '/build/projectInfo/' + id, |
|||
method: 'get', |
|||
timeout: 1000 * 60 |
|||
}) |
|||
} |
|||
|
|||
// 获取资金下达列表
|
|||
export function projectSourceFundsListApi(data) { |
|||
return request({ |
|||
url: '/build/sourceFunds/getSourceFundsList', |
|||
method: 'post', |
|||
data, |
|||
timeout: 1000 * 60 |
|||
}) |
|||
} |
|||
|
|||
// 获取资金支付列表
|
|||
export function projectContractInfoListApi(data) { |
|||
return request({ |
|||
url: '/build/contractInfo/listByNo', |
|||
method: 'post', |
|||
data, |
|||
timeout: 1000 * 60 |
|||
}) |
|||
} |
|||
|
|||
// 获取检查列表
|
|||
export function projectCheckListApi(data) { |
|||
return request({ |
|||
url: '/warn/inspections/list', |
|||
method: 'post', |
|||
data, |
|||
timeout: 1000 * 60 |
|||
}) |
|||
} |
@ -0,0 +1,10 @@ |
|||
import request from '@/utils/request' |
|||
|
|||
// 获取投资统计数据
|
|||
export function getSourceFundsNumApi(params){ |
|||
return request({ |
|||
url:'/statistics/assert/getSourceFundsNum', |
|||
method:'get', |
|||
params |
|||
}) |
|||
} |
@ -0,0 +1,242 @@ |
|||
<template> |
|||
<!-- #ifdef MP-WEIXIN || MP-TOUTIAO --> |
|||
<canvas type="2d" class="echarts" :canvas-id="canvasId" :id="canvasId" @touchstart="touchStart" |
|||
@touchmove="touchMove" @touchend="touchEnd" /> |
|||
<!-- #endif --> |
|||
<!-- #ifndef MP-WEIXIN || MP-TOUTIAO --> |
|||
<canvas class="echarts" :canvas-id="canvasId" :id="canvasId" @touchstart="touchStart" @touchmove="touchMove" |
|||
@touchend="touchEnd" /> |
|||
<!-- #endif --> |
|||
|
|||
</template> |
|||
<script> |
|||
|
|||
/** |
|||
* echartsForUniApp echart兼容uni-app |
|||
* @description echart兼容uni-app |
|||
* @property {Object} option 图表数据 |
|||
* @property {String} canvasId 画布id |
|||
* @example <echarts ref="echarts" :option="option" canvasId="echarts"></echarts> |
|||
*/ |
|||
import WxCanvas from './wx-canvas.js'; |
|||
import * as echarts from './echarts.min.js'; |
|||
|
|||
var chartList = {} |
|||
export default { |
|||
props: { |
|||
canvasId: { |
|||
type: String, |
|||
default: 'echarts' |
|||
}, |
|||
option: { |
|||
type: Object, |
|||
default: () => { |
|||
return {} |
|||
} |
|||
}, |
|||
}, |
|||
watch: { |
|||
option(newValue, oldValue) { |
|||
if(newValue.series){ |
|||
this.initChart(newValue) |
|||
} |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
ctx:null |
|||
} |
|||
}, |
|||
|
|||
mounted() { |
|||
// Disable prograssive because drawImage doesn't support DOM as parameter |
|||
// See https://developers.weixin.qq.com/miniprogram/dev/api/canvas/CanvasContext.drawImage.html |
|||
echarts.registerPreprocessor(option => { |
|||
if (option && option.series) { |
|||
if (option.series.length > 0) { |
|||
option.series.forEach(series => { |
|||
series.progressive = 0; |
|||
}); |
|||
} else if (typeof option.series === 'object') { |
|||
option.series.progressive = 0; |
|||
} |
|||
} |
|||
}); |
|||
|
|||
}, |
|||
|
|||
methods: { |
|||
getCanvasAttr2d() { |
|||
return new Promise((resolve, reject) => { |
|||
const query = uni.createSelectorQuery().in(this) |
|||
query |
|||
.select('#' + this.canvasId) |
|||
.fields({ |
|||
node: true, |
|||
size: true |
|||
}) |
|||
.exec(res => { |
|||
const canvasNode = res[0].node |
|||
this.canvasNode = canvasNode |
|||
const canvasDpr = uni.getSystemInfoSync().pixelRatio |
|||
const canvasWidth = res[0].width |
|||
const canvasHeight = res[0].height |
|||
this.ctx = canvasNode.getContext('2d') |
|||
|
|||
const canvas = new WxCanvas(this.ctx, this.canvasId, true, canvasNode) |
|||
echarts.setCanvasCreator(() => { |
|||
return canvas |
|||
}) |
|||
resolve({ |
|||
canvas, |
|||
canvasWidth, |
|||
canvasHeight, |
|||
canvasDpr |
|||
}) |
|||
}) |
|||
}); |
|||
}, |
|||
getCanvasAttr() { |
|||
return new Promise((resolve, reject) => { |
|||
this.ctx = uni.createCanvasContext(this.canvasId, this); |
|||
var canvas = new WxCanvas(this.ctx, this.canvasId, false); |
|||
echarts.setCanvasCreator(() => { |
|||
return canvas; |
|||
}); |
|||
const canvasDpr = 1 |
|||
var query = uni.createSelectorQuery() |
|||
// #ifndef MP-ALIPAY |
|||
.in(this) |
|||
// #endif |
|||
query.select('#' + this.canvasId).boundingClientRect(res => { |
|||
const canvasWidth = res.width |
|||
const canvasHeight = res.height |
|||
resolve({ |
|||
canvas, |
|||
canvasWidth, |
|||
canvasHeight, |
|||
canvasDpr |
|||
}) |
|||
}).exec(); |
|||
}); |
|||
}, |
|||
// #ifdef H5 |
|||
//H5绘制图表 |
|||
initChart(option) { |
|||
this.ctx = uni.createCanvasContext(this.canvasId, this); |
|||
chartList[this.canvasId] = echarts.init(document.getElementById(this.canvasId)); |
|||
chartList[this.canvasId].setOption(option?option:this.option); |
|||
}, |
|||
//H5生成图片 |
|||
canvasToTempFilePath(opt) { |
|||
const base64 = chartList[this.canvasId].getDataURL() |
|||
opt.success && opt.success({tempFilePath:base64}) |
|||
}, |
|||
// #endif |
|||
// #ifndef H5 |
|||
//绘制图表 |
|||
async initChart(option) { |
|||
// #ifdef MP-WEIXIN || MP-TOUTIAO |
|||
const canvasAttr = await this.getCanvasAttr2d(); |
|||
// #endif |
|||
// #ifndef MP-WEIXIN || MP-TOUTIAO |
|||
const canvasAttr = await this.getCanvasAttr(); |
|||
// #endif |
|||
const { |
|||
canvas, |
|||
canvasWidth, |
|||
canvasHeight, |
|||
canvasDpr |
|||
} = canvasAttr |
|||
chartList[this.canvasId] = echarts.init(canvas, null, { |
|||
width: canvasWidth, |
|||
height: canvasHeight, |
|||
devicePixelRatio: canvasDpr // new |
|||
}); |
|||
canvas.setChart(chartList[this.canvasId]); |
|||
chartList[this.canvasId].setOption(option?option:this.option); |
|||
}, |
|||
//生成图片 |
|||
canvasToTempFilePath(opt) { |
|||
// #ifdef MP-WEIXIN || MP-TOUTIAO |
|||
var query = uni.createSelectorQuery() |
|||
// #ifndef MP-ALIPAY |
|||
.in(this) |
|||
// #endif |
|||
query.select('#' + this.canvasId).fields({ node: true, size: true }).exec(res => { |
|||
const canvasNode = res[0].node |
|||
opt.canvas = canvasNode |
|||
uni.canvasToTempFilePath(opt, this) |
|||
}) |
|||
// #endif |
|||
// #ifndef MP-WEIXIN || MP-TOUTIAO |
|||
if (!opt.canvasId) { |
|||
opt.canvasId = this.canvasId; |
|||
} |
|||
this.ctx.draw(true, () => { |
|||
uni.canvasToTempFilePath(opt, this); |
|||
}); |
|||
// #endif |
|||
}, |
|||
// #endif |
|||
|
|||
touchStart(e) { |
|||
if (chartList[this.canvasId] && e.touches.length > 0) { |
|||
var touch = e.touches[0]; |
|||
var handler = chartList[this.canvasId].getZr().handler; |
|||
handler.dispatch('mousedown', { |
|||
zrX: touch.x, |
|||
zrY: touch.y |
|||
}); |
|||
handler.dispatch('mousemove', { |
|||
zrX: touch.x, |
|||
zrY: touch.y |
|||
}); |
|||
handler.processGesture(wrapTouch(e), 'start'); |
|||
} |
|||
}, |
|||
touchMove(e) { |
|||
if (chartList[this.canvasId] && e.touches.length > 0) { |
|||
var touch = e.touches[0]; |
|||
var handler = chartList[this.canvasId].getZr().handler; |
|||
handler.dispatch('mousemove', { |
|||
zrX: touch.x, |
|||
zrY: touch.y |
|||
}); |
|||
handler.processGesture(wrapTouch(e), 'change'); |
|||
} |
|||
}, |
|||
|
|||
touchEnd(e) { |
|||
if (chartList[this.canvasId]) { |
|||
const touch = e.changedTouches ? e.changedTouches[0] : {}; |
|||
var handler = chartList[this.canvasId].getZr().handler; |
|||
handler.dispatch('mouseup', { |
|||
zrX: touch.x, |
|||
zrY: touch.y |
|||
}); |
|||
handler.dispatch('click', { |
|||
zrX: touch.x, |
|||
zrY: touch.y |
|||
}); |
|||
handler.processGesture(wrapTouch(e), 'end'); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
function wrapTouch(event) { |
|||
for (let i = 0; i < event.touches.length; ++i) { |
|||
const touch = event.touches[i]; |
|||
touch.offsetX = touch.x; |
|||
touch.offsetY = touch.y; |
|||
} |
|||
return event; |
|||
} |
|||
</script> |
|||
<style lang="scss" scoped> |
|||
.echarts { |
|||
width: 100%; |
|||
height: 100%; |
|||
} |
|||
</style> |
File diff suppressed because one or more lines are too long
@ -0,0 +1,105 @@ |
|||
export default class WxCanvas { |
|||
constructor(ctx, canvasId, isNew, canvasNode) { |
|||
this.ctx = ctx; |
|||
this.canvasId = canvasId; |
|||
this.chart = null; |
|||
this.isNew = isNew |
|||
if (isNew) { |
|||
this.canvasNode = canvasNode; |
|||
} |
|||
else { |
|||
this._initStyle(ctx); |
|||
} |
|||
|
|||
// this._initCanvas(zrender, ctx);
|
|||
|
|||
this._initEvent(); |
|||
} |
|||
|
|||
getContext(contextType) { |
|||
if (contextType === '2d') { |
|||
return this.ctx; |
|||
} |
|||
} |
|||
|
|||
// canvasToTempFilePath(opt) {
|
|||
// if (!opt.canvasId) {
|
|||
// opt.canvasId = this.canvasId;
|
|||
// }
|
|||
// return wx.canvasToTempFilePath(opt, this);
|
|||
// }
|
|||
|
|||
setChart(chart) { |
|||
this.chart = chart; |
|||
} |
|||
|
|||
attachEvent() { |
|||
// noop
|
|||
} |
|||
|
|||
detachEvent() { |
|||
// noop
|
|||
} |
|||
|
|||
_initCanvas(zrender, ctx) { |
|||
zrender.util.getContext = function () { |
|||
return ctx; |
|||
}; |
|||
|
|||
zrender.util.$override('measureText', function (text, font) { |
|||
ctx.font = font || '12px sans-serif'; |
|||
return ctx.measureText(text); |
|||
}); |
|||
} |
|||
|
|||
_initStyle(ctx) { |
|||
ctx.createRadialGradient = () => { |
|||
return ctx.createCircularGradient(arguments); |
|||
}; |
|||
} |
|||
|
|||
_initEvent() { |
|||
this.event = {}; |
|||
const eventNames = [{ |
|||
wxName: 'touchStart', |
|||
ecName: 'mousedown' |
|||
}, { |
|||
wxName: 'touchMove', |
|||
ecName: 'mousemove' |
|||
}, { |
|||
wxName: 'touchEnd', |
|||
ecName: 'mouseup' |
|||
}, { |
|||
wxName: 'touchEnd', |
|||
ecName: 'click' |
|||
}]; |
|||
|
|||
eventNames.forEach(name => { |
|||
this.event[name.wxName] = e => { |
|||
const touch = e.touches[0]; |
|||
this.chart.getZr().handler.dispatch(name.ecName, { |
|||
zrX: name.wxName === 'tap' ? touch.clientX : touch.x, |
|||
zrY: name.wxName === 'tap' ? touch.clientY : touch.y |
|||
}); |
|||
}; |
|||
}); |
|||
} |
|||
|
|||
set width(w) { |
|||
if (this.canvasNode) this.canvasNode.width = w |
|||
} |
|||
set height(h) { |
|||
if (this.canvasNode) this.canvasNode.height = h |
|||
} |
|||
|
|||
get width() { |
|||
if (this.canvasNode) |
|||
return this.canvasNode.width |
|||
return 0 |
|||
} |
|||
get height() { |
|||
if (this.canvasNode) |
|||
return this.canvasNode.height |
|||
return 0 |
|||
} |
|||
} |
@ -1,28 +1,3 @@ |
|||
{ |
|||
"requires": true, |
|||
"lockfileVersion": 1, |
|||
"dependencies": { |
|||
"echarts": { |
|||
"version": "5.5.1", |
|||
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.1.tgz", |
|||
"integrity": "sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA==", |
|||
"requires": { |
|||
"tslib": "2.3.0", |
|||
"zrender": "5.6.0" |
|||
} |
|||
}, |
|||
"tslib": { |
|||
"version": "2.3.0", |
|||
"resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz", |
|||
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==" |
|||
}, |
|||
"zrender": { |
|||
"version": "5.6.0", |
|||
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.0.tgz", |
|||
"integrity": "sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg==", |
|||
"requires": { |
|||
"tslib": "2.3.0" |
|||
} |
|||
} |
|||
} |
|||
"lockfileVersion": 1 |
|||
} |
|||
|
@ -0,0 +1,16 @@ |
|||
{ |
|||
"id": "echarts-uniapp", |
|||
"name": "echarts for uniapp", |
|||
"version": "0.0.1", |
|||
"description": "echarts适配uni-app", |
|||
"keywords": [ |
|||
"echarts", |
|||
"图表" |
|||
], |
|||
"dcloudext": { |
|||
"category": [ |
|||
"前端组件", |
|||
"通用组件" |
|||
] |
|||
} |
|||
} |
@ -0,0 +1,80 @@ |
|||
项目名称 |
|||
projectName |
|||
|
|||
行政区号 |
|||
adcd |
|||
|
|||
项目编码 |
|||
proCode |
|||
|
|||
项目种类 |
|||
projectKinds |
|||
|
|||
项目法人单位 |
|||
projectLegalPerson |
|||
|
|||
项目负责人 |
|||
projectSuperintendent |
|||
|
|||
单位负责人电话 |
|||
projectLegalPhone |
|||
|
|||
单位法定代表人 |
|||
projectUnitLegal |
|||
|
|||
单位法定代表人电话 |
|||
projectUnitLegalPhone |
|||
|
|||
项目类型 |
|||
projectType |
|||
|
|||
工程等别 |
|||
engineeringGrade |
|||
|
|||
工程用途 |
|||
engineeringPurposes |
|||
|
|||
项目建设地址 |
|||
constructionAddress |
|||
|
|||
建设模式 |
|||
constructionMode |
|||
|
|||
建设性质 |
|||
constructionNature |
|||
|
|||
建设内容 |
|||
constructionContent |
|||
|
|||
中央资金 |
|||
centralArrangedFunds |
|||
|
|||
中央资金比例 |
|||
centralArrangedFundsRate |
|||
|
|||
省级资金 |
|||
provincialFunding |
|||
|
|||
省级资金比例 |
|||
provincialFundingRate |
|||
|
|||
地市资金 |
|||
cityLevelFunds |
|||
|
|||
地市资金比例 |
|||
cityLevelFundsRate |
|||
|
|||
区县资金 |
|||
countyLevelFunds |
|||
|
|||
区县资金比例 |
|||
cityLevelFundsRate |
|||
|
|||
乡镇及群众自筹和其他投资 |
|||
townshipInvestments |
|||
|
|||
乡镇及群众自筹和其他投资比例 |
|||
townshipInvestmentsRate |
|||
|
|||
是否省重大水利工程项目 |
|||
isMajorProject |
@ -0,0 +1,22 @@ |
|||
## 1.1.7(2024-10-29) |
|||
修复底部露出部分组件bug |
|||
## 1.1.6(2024-08-20) |
|||
更新本地数据源为最新数据源 |
|||
## 1.1.5(2024-06-12) |
|||
使用说明文档优化 |
|||
## 1.1.4(2024-06-12) |
|||
增加问题反馈描述 |
|||
## 1.1.3(2024-02-29) |
|||
更新使用文档 |
|||
## 1.1.2(2024-01-16) |
|||
解决Vue3项目导入导出报错问题 |
|||
## 1.1.1(2023-12-06) |
|||
defaultValue可以传入defaultValue:['河北省','唐山市','丰南区']数组类型以及defaultValue: '420103'地区编码字符串类型 |
|||
## 1.1.0(2023-12-05) |
|||
即默认值传入地区编码,也支持传入中文省市区数组 |
|||
## 1.0.9(2023-12-04) |
|||
优化 |
|||
## 1.0.8(2023-10-24) |
|||
修复东菀市和中山市下各镇的行政编码错误问题 |
|||
## 1.0.4(2023-09-15) |
|||
改为uni_modules规范 |
File diff suppressed because it is too large
@ -0,0 +1,282 @@ |
|||
<template> |
|||
<view class="pupop"> |
|||
<view class="popup-box" :animation="animationData"> |
|||
<view class="pupop-btn"> |
|||
<view @tap="cancel" style="font-size: 17px;color: #888;">取消</view> |
|||
<view @tap="confirm" style="font-size: 17px;color: #007aff;">完成</view> |
|||
</view> |
|||
<picker-view :value="value" :indicator-style="indicatorStyle" @change="bindChange" class="picker-view"> |
|||
<picker-view-column> |
|||
<view class="item" v-for="(item,index) in provinceList" :key="index">{{item.name}}</view> |
|||
</picker-view-column> |
|||
<picker-view-column> |
|||
<view class="item" v-for="(item,index) in cityList" :key="index">{{item.name}}</view> |
|||
</picker-view-column> |
|||
<picker-view-column v-if="column == 3"> |
|||
<view class="item" v-for="(item,index) in areaList" :key="index">{{item.name}}</view> |
|||
</picker-view-column> |
|||
</picker-view> |
|||
</view> |
|||
<view @tap="close" @touchmove.stop.prevent :class="visible ? 'pupop-model' : 'pupop-models'"></view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import { |
|||
addressList |
|||
} from './cityData.js' |
|||
export default { |
|||
data() { |
|||
return { |
|||
value: [], |
|||
addressList, |
|||
provinceList: [], |
|||
cityList: [], |
|||
areaList: [], |
|||
indicatorStyle: `height: 50px;`, |
|||
provinceIndex: 0, |
|||
cityIndex: 0, |
|||
areaIndex: 0, |
|||
animationData: {} |
|||
} |
|||
}, |
|||
props: { |
|||
column: { |
|||
type: Number, |
|||
default: 3 |
|||
}, |
|||
defaultValue: { |
|||
default: () => '' |
|||
}, |
|||
visible: { |
|||
type: Boolean, |
|||
default: () => false |
|||
}, |
|||
maskCloseAble: { |
|||
type: Boolean, |
|||
default: () => true |
|||
}, |
|||
}, |
|||
watch: { |
|||
visible (val) { |
|||
this.changeActive() |
|||
}, |
|||
defaultValue() { |
|||
this.init() |
|||
} |
|||
}, |
|||
created() { |
|||
this.init() |
|||
}, |
|||
methods: { |
|||
init () { |
|||
var provinceList = [] |
|||
addressList.filter(item => { |
|||
provinceList.push({ |
|||
code: item.code, |
|||
name: item.name |
|||
}) |
|||
}) |
|||
this.provinceList = [...provinceList] |
|||
if (!this.defaultValue) { |
|||
this.cityList = addressList[0].children |
|||
this.areaList = addressList[0].children[0].children |
|||
} else { |
|||
var city = {11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江 ",31:"上海",32:"江苏",33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北 ",43:"湖南",44:"广东",45:"广西",46:"海南",50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏 ",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆",71:"台湾",81:"香港",82:"澳门",91:"国外 "} |
|||
if (Array.isArray(this.defaultValue) && this.defaultValue.length >= 2) { |
|||
console.log(this.defaultValue) |
|||
var province = this.defaultValue[0] |
|||
var city = this.defaultValue[1] |
|||
this.provinceIndex = 0 |
|||
this.cityIndex = 0 |
|||
this.areaIndex = 0 |
|||
this.provinceIndex = addressList.findIndex(obj => { |
|||
return obj.name == province |
|||
}) |
|||
this.provinceIndex = this.provinceIndex >= 0 ? this.provinceIndex : 0 |
|||
this.cityList = addressList[this.provinceIndex].children |
|||
this.cityIndex = this.cityList.findIndex(obj => { |
|||
return obj.name == city |
|||
}) |
|||
this.cityIndex = this.cityIndex >= 0 ? this.cityIndex : 0 |
|||
this.areaList = this.cityList[this.cityIndex].children |
|||
if (this.defaultValue.length > 2) { |
|||
this.areaIndex = this.areaList.findIndex(obj => { |
|||
return obj.name == this.defaultValue[2] |
|||
}) |
|||
} |
|||
this.areaIndex = this.areaIndex >= 0 ? this.areaIndex : 0 |
|||
this.$nextTick(() => { |
|||
if (this.column == 3) { |
|||
this.value = JSON.parse(JSON.stringify([this.provinceIndex, this.cityIndex, this.areaIndex])) |
|||
} else if (this.column == 2) { |
|||
this.value = JSON.parse(JSON.stringify([this.provinceIndex, this.cityIndex])) |
|||
} |
|||
}) |
|||
} else if (/^\d{6}$/.test(this.defaultValue)) { |
|||
var province = this.defaultValue.substr(0, 2) |
|||
var city = this.defaultValue.substr(0, 4) |
|||
this.provinceIndex = 0 |
|||
this.cityIndex = 0 |
|||
this.areaIndex = 0 |
|||
this.provinceIndex = addressList.findIndex(obj => { |
|||
return obj.code == province |
|||
}) |
|||
this.provinceIndex = this.provinceIndex >= 0 ? this.provinceIndex : 0 |
|||
this.cityList = addressList[this.provinceIndex].children |
|||
this.cityIndex = this.cityList.findIndex(obj => { |
|||
return obj.code == city |
|||
}) |
|||
this.cityIndex = this.cityIndex >= 0 ? this.cityIndex : 0 |
|||
this.areaList = this.cityList[this.cityIndex].children |
|||
this.areaIndex = this.areaList.findIndex(obj => { |
|||
return obj.code == this.defaultValue |
|||
}) |
|||
this.areaIndex = this.areaIndex >= 0 ? this.areaIndex : 0 |
|||
this.$nextTick(() => { |
|||
if (this.column == 3) { |
|||
this.value = JSON.parse(JSON.stringify([this.provinceIndex, this.cityIndex, this.areaIndex])) |
|||
} else if (this.column == 2) { |
|||
this.value = JSON.parse(JSON.stringify([this.provinceIndex, this.cityIndex])) |
|||
} |
|||
}) |
|||
} else { |
|||
uni.showToast({ |
|||
title: '地区编码格式不正确', |
|||
icon: 'none' |
|||
}) |
|||
console.log('地区编码格式不正确') |
|||
} |
|||
} |
|||
this.changeActive() |
|||
}, |
|||
confirm () { |
|||
if (this.column == 3) { |
|||
this.$emit('confirm', { |
|||
code: addressList[this.provinceIndex].children[this.cityIndex].children[this.areaIndex].code, |
|||
name: addressList[this.provinceIndex].name + addressList[this.provinceIndex].children[this.cityIndex].name + addressList[this.provinceIndex].children[this.cityIndex].children[this.areaIndex].name, |
|||
provinceName: addressList[this.provinceIndex].name, |
|||
cityName: addressList[this.provinceIndex].children[this.cityIndex].name, |
|||
areaName: addressList[this.provinceIndex].children[this.cityIndex].children[this.areaIndex].name |
|||
}) |
|||
} else if (this.column == 2) { |
|||
this.$emit('confirm', { |
|||
code: addressList[this.provinceIndex].children[this.cityIndex].children[this.areaIndex].code.substring(0, 4) + '00', |
|||
name: addressList[this.provinceIndex].name + addressList[this.provinceIndex].children[this.cityIndex].name, |
|||
provinceName: addressList[this.provinceIndex].name, |
|||
cityName: addressList[this.provinceIndex].children[this.cityIndex].name |
|||
}) |
|||
} else { |
|||
uni.showToast({ |
|||
title: '目前column只能传2和3', |
|||
icon: 'none' |
|||
}) |
|||
} |
|||
}, |
|||
cancel () { |
|||
this.$emit('cancel') |
|||
}, |
|||
// 动画 |
|||
changeActive () { |
|||
var active = '-415px' |
|||
if (this.visible) { |
|||
active = 0 |
|||
} |
|||
var animation = uni.createAnimation({ |
|||
duration: 400, |
|||
timingFunction: 'linear' |
|||
}) |
|||
animation.bottom(active).step() |
|||
this.animationData = animation.export() |
|||
}, |
|||
bindChange(e) { |
|||
e.detail.value[0] = e.detail.value[0] || 0 |
|||
e.detail.value[1] = e.detail.value[1] || 0 |
|||
e.detail.value[2] = e.detail.value[2] || 0 |
|||
if (e.detail.value[0] != this.provinceIndex) { |
|||
// console.log('监听第一列') |
|||
this.provinceChange(e.detail.value[0]) |
|||
} else if (e.detail.value[1] != this.cityIndex) { |
|||
// console.log('监听第二列') |
|||
this.cityChange(e.detail.value[1]) |
|||
} else if (e.detail.value[2] != this.areaIndex) { |
|||
// console.log('监听第三列') |
|||
this.areaChange(e.detail.value[2]) |
|||
} |
|||
}, |
|||
// 监听第一列变化 |
|||
provinceChange (e) { |
|||
this.provinceIndex = e |
|||
this.cityIndex = 0 |
|||
this.areaIndex = 0 |
|||
this.value = [...[e, 0, 0]] |
|||
this.cityList = addressList[e].children |
|||
this.areaList = addressList[e].children[0].children |
|||
}, |
|||
// 监听第二列变化 |
|||
cityChange (e) { |
|||
this.cityIndex = e |
|||
this.areaIndex = 0 |
|||
// console.log(this.cityIndex, this.areaIndex) |
|||
this.value = [...[this.provinceIndex, e, 0]] |
|||
this.cityList = addressList[this.provinceIndex].children |
|||
this.areaList = addressList[this.provinceIndex].children[e].children |
|||
}, |
|||
// 监听第三列变化 |
|||
areaChange (e) { |
|||
this.areaIndex = e |
|||
}, |
|||
// 点击模态框 |
|||
close () { |
|||
if (this.maskCloseAble) { |
|||
this.cancel() |
|||
} |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style scoped lang="scss"> |
|||
.pupop { |
|||
.popup-box { |
|||
position: fixed; |
|||
left: 0; |
|||
bottom: -315px; |
|||
z-index: 99999; |
|||
background: #fff; |
|||
padding-bottom: 50px; |
|||
.pupop-btn{ |
|||
height: 45px; |
|||
display: flex; |
|||
align-items: center; |
|||
padding: 0 30upx; |
|||
justify-content: space-between; |
|||
border-bottom: 1px solid #f5f5f5; |
|||
} |
|||
} |
|||
.pupop-model { |
|||
position: fixed; |
|||
left: 0; |
|||
top: 0; |
|||
width: 100%; |
|||
height: 100%; |
|||
z-index: 9999; |
|||
background: rgba(0, 0, 0, .5); |
|||
} |
|||
.pupop-models{ |
|||
display: none; |
|||
} |
|||
.picker-view { |
|||
width: 750rpx; |
|||
height: 225px; |
|||
margin-top: 20rpx; |
|||
} |
|||
.item { |
|||
height: 50px; |
|||
align-items: center; |
|||
justify-content: center; |
|||
text-align: center; |
|||
line-height: 50px; |
|||
} |
|||
} |
|||
</style> |
@ -0,0 +1,17 @@ |
|||
{ |
|||
"id": "piaoyi-cityPicker", |
|||
"name": " data-cityPicker省市区地址选择器", |
|||
"displayName": " data-cityPicker省市区地址选择器(兼容vue3)", |
|||
"version": "1.1.7", |
|||
"description": "常用省市区选择器,可反选,自定义模态框、兼容vue3", |
|||
"keywords": [ |
|||
"省市区", |
|||
"选择器", |
|||
"可反选", |
|||
"自定义模态框和弹框", |
|||
"兼容vue3" |
|||
], |
|||
"dcloudext": { |
|||
"type": "component-vue" |
|||
} |
|||
} |
@ -0,0 +1,106 @@ |
|||
## 1.0.7(2023-09-15) |
|||
改为uni_modules规范 |
|||
### cityPicker 省市区选择器(兼容vue3) |
|||
|
|||
**使用方法:** |
|||
|
|||
``` |
|||
<template> |
|||
<view> |
|||
<button @tap="open">打开</button> |
|||
<cityPicker :column="column" :default-value="defaultValue" :mask-close-able="maskCloseAble" @confirm="confirm" @cancel="cancel" :visible="visible"/> |
|||
<view>{{str}}</view> |
|||
</view> |
|||
</template> |
|||
|
|||
<script> |
|||
import cityPicker from '@/uni_modules/piaoyi-cityPicker/components/piaoyi-cityPicker/piaoyi-cityPicker' |
|||
export default { |
|||
data() { |
|||
return { |
|||
visible: false, |
|||
maskCloseAble: true, |
|||
str: '', |
|||
defaultValue: '420103', |
|||
// defaultValue: ['河北省','唐山市','丰南区'], |
|||
column: 3 |
|||
} |
|||
}, |
|||
components: { |
|||
cityPicker |
|||
}, |
|||
methods: { |
|||
open () { |
|||
this.visible = true |
|||
}, |
|||
confirm (val) { |
|||
console.log(val) |
|||
this.str = JSON.stringify(val) |
|||
this.visible = false |
|||
}, |
|||
cancel () { |
|||
this.visible = false |
|||
} |
|||
}, |
|||
onShareAppMessage(res) { |
|||
if (res.from === 'button') { // 来自页面内分享按钮 |
|||
console.log(res.target) |
|||
} |
|||
return { |
|||
title: 'data-cityPicker省市区地址选择器!', |
|||
path: '/pages/cityPicker/cityPicker' |
|||
} |
|||
}, |
|||
onShareTimeline(res) { |
|||
if (res.from === 'button') { // 来自页面内分享按钮 |
|||
console.log(res.target) |
|||
} |
|||
return { |
|||
title: 'data-cityPicker省市区地址选择器!' |
|||
} |
|||
} |
|||
} |
|||
</script> |
|||
|
|||
<style lang="scss"> |
|||
|
|||
</style> |
|||
|
|||
``` |
|||
|
|||
### 注:近期收到使用用户反馈,存在以下一个问题(如有好的建议,期待私信,谢谢) |
|||
|
|||
1、之前只支持默认值传入地区编码,已更新可以支持传入中文省市区数组 |
|||
|
|||
defaultValue可以传入defaultValue:['河北省','唐山市','丰南区']数组类型以及defaultValue: '420103'地区编码字符串类型 |
|||
|
|||
可以使用const reg =/([\u4e00-\u9fa5]+省|自治区|[\u4e00-\u9fa5]+市|[\u4e00-\u9fa5]+区)/g;将自己的省市区数据进行处理为数组再传入 |
|||
|
|||
2、有些用户反馈vue3下watch监听有问题 |
|||
|
|||
我自己创建一个vue项目,导入插件后,按照示例原封不动进行测试,没有发现问题; 发现有问题的朋友可以提供一下可以复现的demo给我,我这边看看具体什么情况 |
|||
|
|||
3、有些用户返回无法关闭弹框 |
|||
|
|||
不要把插件放到scroll-view里面,请务必放到最外层进行使用 |
|||
|
|||
#### 事件说明 |
|||
|
|||
| 事件名 | 返回值 | 描述 | |
|||
| :---------: | :----: | :------------: | |
|||
| @confirm | 对象(code,完整地区名称) | 点击确定的回调 | |
|||
| @cancel | 无 | 点击取消的回调 | |
|||
|
|||
#### Prop |
|||
|
|||
| 参数名称 | 描述 | |
|||
| -------- | ------------------------------ | |
|||
| visible | 控制选择器显示和隐藏 | |
|||
| column | 可选值2和3,2是省市两列选择;3是省市区三列选择 | |
|||
| maskCloseAble | 点击模态框是否关闭弹框 | |
|||
| defaultValue | 初始地区编码(例:420102或者['河北省','唐山市','丰南区']) | |
|||
|
|||
### 数据来源:[点击查看省市区数据来源](https://github.com/modood/Administrative-divisions-of-China/blob/master/dist/pca-code.json) |
|||
### 可接定制化组件开发 |
|||
### 右侧有本人代表作小程序二维码,可以扫码体验 |
|||
### 如使用过程中有问题或有一些好的建议,欢迎加QQ群互相学习交流:120594820 |
@ -0,0 +1,195 @@ |
|||
import request from '@/utils/request' |
|||
/** |
|||
* 通用js方法封装处理 |
|||
* Copyright (c) 2019 ruoyi |
|||
*/ |
|||
|
|||
const baseURL = process.env.VUE_APP_BASE_API |
|||
|
|||
// 日期格式化
|
|||
export function parseTime(time, pattern) { |
|||
if (arguments.length === 0 || !time) { |
|||
return null |
|||
} |
|||
const format = pattern || '{y}-{m}-{d} {h}:{i}:{s}' |
|||
let date |
|||
if (typeof time === 'object') { |
|||
date = time |
|||
} else { |
|||
if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) { |
|||
time = parseInt(time) |
|||
} else if (typeof time === 'string') { |
|||
time = time.replace(new RegExp(/-/gm), '/'); |
|||
} |
|||
if ((typeof time === 'number') && (time.toString().length === 10)) { |
|||
time = time * 1000 |
|||
} |
|||
date = new Date(time) |
|||
} |
|||
const formatObj = { |
|||
y: date.getFullYear(), |
|||
m: date.getMonth() + 1, |
|||
d: date.getDate(), |
|||
h: date.getHours(), |
|||
i: date.getMinutes(), |
|||
s: date.getSeconds(), |
|||
a: date.getDay() |
|||
} |
|||
const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => { |
|||
let value = formatObj[key] |
|||
// Note: getDay() returns 0 on Sunday
|
|||
if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] } |
|||
if (result.length > 0 && value < 10) { |
|||
value = '0' + value |
|||
} |
|||
return value || 0 |
|||
}) |
|||
return time_str |
|||
} |
|||
|
|||
// 表单重置
|
|||
export function resetForm(refName) { |
|||
if (this.$refs[refName]) { |
|||
this.$refs[refName].resetFields(); |
|||
} |
|||
} |
|||
|
|||
// 添加日期范围
|
|||
export function addDateRange(params, dateRange) { |
|||
var search = params; |
|||
search.beginTime = ""; |
|||
search.endTime = ""; |
|||
if (null != dateRange && '' != dateRange) { |
|||
search.beginTime = this.dateRange[0]; |
|||
search.endTime = this.dateRange[1]; |
|||
} |
|||
return search; |
|||
} |
|||
|
|||
// 回显数据字典
|
|||
export function selectDictLabel(datas, value) { |
|||
var actions = []; |
|||
// console.log(datas);
|
|||
// console.log(value);
|
|||
Object.keys(datas).some((key) => { |
|||
if (datas[key].dictValue == ('' + value)) { |
|||
actions.push(datas[key].dictLabel); |
|||
return true; |
|||
} |
|||
}) |
|||
// console.log(actions);
|
|||
return actions.join(''); |
|||
} |
|||
|
|||
export function selectDictLabelBak(datas, value) { |
|||
var actions = []; |
|||
Object.keys(datas).some((key) => { |
|||
if (datas[key].value == ('' + value)) { |
|||
actions.push(datas[key].label); |
|||
return true; |
|||
} |
|||
}) |
|||
console.log(actions); |
|||
return actions.join(''); |
|||
} |
|||
|
|||
// 回显数据字典(字符串数组)
|
|||
export function selectDictLabels(datas, value, separator) { |
|||
var actions = []; |
|||
var currentSeparator = undefined === separator ? "," : separator; |
|||
var temp = value.split(currentSeparator); |
|||
Object.keys(value.split(currentSeparator)).some((val) => { |
|||
Object.keys(datas).some((key) => { |
|||
if (datas[key].dictValue == ('' + temp[val])) { |
|||
actions.push(datas[key].dictLabel + currentSeparator); |
|||
} |
|||
}) |
|||
}) |
|||
return actions.join('').substring(0, actions.join('').length - 1); |
|||
} |
|||
|
|||
// 通用下载方法
|
|||
export function download(fileName) { |
|||
console.log("下载!"); |
|||
console.log(baseURL); |
|||
return request({ |
|||
url: "common/download?fileName=" + encodeURI(fileName) + "&delete=" + true, |
|||
method: 'get' |
|||
}); |
|||
//window.location.href = baseURL + "common/download?fileName=" + encodeURI(fileName) + "&delete=" + true;
|
|||
} |
|||
|
|||
// 字符串格式化(%s )
|
|||
export function sprintf(str) { |
|||
var args = arguments, flag = true, i = 1; |
|||
str = str.replace(/%s/g, function () { |
|||
var arg = args[i++]; |
|||
if (typeof arg === 'undefined') { |
|||
flag = false; |
|||
return ''; |
|||
} |
|||
return arg; |
|||
}); |
|||
return flag ? str : ''; |
|||
} |
|||
|
|||
// 转换字符串,undefined,null等转化为""
|
|||
export function praseStrEmpty(str) { |
|||
if (!str || str == "undefined" || str == "null") { |
|||
return ""; |
|||
} |
|||
return str; |
|||
} |
|||
|
|||
/** |
|||
* 构造树型结构数据 |
|||
* @param {*} data 数据源 |
|||
* @param {*} id id字段 默认 'id' |
|||
* @param {*} parentId 父节点字段 默认 'parentId' |
|||
* @param {*} children 孩子节点字段 默认 'children' |
|||
* @param {*} rootId 根Id 默认 0 |
|||
*/ |
|||
export function handleTree(data, id, parentId, children, rootId) { |
|||
id = id || 'id' |
|||
parentId = parentId || 'parentId' |
|||
children = children || 'children' |
|||
rootId = rootId || Math.min.apply(Math, data.map(item => { return item[parentId] })) || 0 |
|||
//对源数据深度克隆
|
|||
const cloneData = JSON.parse(JSON.stringify(data)) |
|||
//循环所有项
|
|||
const treeData = cloneData.filter(father => { |
|||
let branchArr = cloneData.filter(child => { |
|||
//返回每一项的子级数组
|
|||
return father[id] === child[parentId] |
|||
}); |
|||
branchArr.length > 0 ? father.children = branchArr : []; |
|||
//返回第一层
|
|||
return father[parentId] === rootId; |
|||
}); |
|||
return treeData !== '' ? treeData : data; |
|||
} |
|||
|
|||
// 数据合并
|
|||
export function mergeRecursive(source, target) { |
|||
for (var p in target) { |
|||
try { |
|||
if (target[p].constructor == Object) { |
|||
source[p] = mergeRecursive(source[p], target[p]); |
|||
} else { |
|||
source[p] = target[p]; |
|||
} |
|||
} catch (e) { |
|||
source[p] = target[p]; |
|||
} |
|||
} |
|||
return source; |
|||
}; |
|||
|
|||
/** |
|||
* 去除所有的标签 |
|||
* @param str |
|||
* @returns {*} |
|||
*/ |
|||
export function delHtmlTag(str){ |
|||
return str.replace(/<[^>]+>/g,""); |
|||
} |
Loading…
Reference in new issue