| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
19cf75a36d | Merge branch 'master' of http://218.59.175.43:3000/zhangzl/rongxin.dashboard | 2 months ago |
|
|
ca28b7150f | 组件化2 | 2 months ago |
|
|
26d6c1a2c9 | 组件化 | 2 months ago |
| @@ -17,3 +17,17 @@ export function addNotice(data) { | |||
| data: data | |||
| }) | |||
| } | |||
| //上传全局方法附件 | |||
| export function commonUpload(data) { | |||
| return request({ | |||
| url: '/common/upload', | |||
| method: 'post', | |||
| data: data, | |||
| timeout: 60000, // 延长超时时间 | |||
| headers: { | |||
| // 不设置 Content-Type,让浏览器自动设置 | |||
| } | |||
| }) | |||
| } | |||
| @@ -1,160 +1,399 @@ | |||
| <!-- 通用上传组件 zhao --> | |||
| <template> | |||
| <van-uploader | |||
| v-model="fileList" | |||
| :multiple="multiple" | |||
| :after-read="afterRead" | |||
| :show-upload="showUpload" | |||
| :deletable="deletable" | |||
| @delete="deleteFile" | |||
| :accept="accept || null" | |||
| /> | |||
| <div class="component-upload-image"> | |||
| <!-- 上传区域 --> | |||
| <el-upload | |||
| multiple | |||
| :disabled="disabled" | |||
| :action="uploadImgUrl" | |||
| list-type="picture-card" | |||
| :on-success="handleUploadSuccess" | |||
| :before-upload="handleBeforeUpload" | |||
| :data="data" | |||
| :limit="limit" | |||
| :on-error="handleUploadError" | |||
| :on-exceed="handleExceed" | |||
| ref="imageUpload" | |||
| :on-remove="handleDelete" | |||
| :show-file-list="true" | |||
| :headers="headers" | |||
| :file-list="fileList" | |||
| :on-preview="handlePictureCardPreview" | |||
| :class="{hide: fileList.length >= limit}" | |||
| style="grid-template-columns: repeat(auto-fill, minmax(70px, 1fr)); gap: 12px; padding: 0;" | |||
| > | |||
| <!-- 上传按钮 --> | |||
| <div class="upload-btn"> | |||
| <i class="el-icon-plus" style="font-size: 20px;"></i> | |||
| </div> | |||
| </el-upload> | |||
| <!-- 上传提示:关键调整 - 减小与上传框的间距 --> | |||
| <div class="el-upload__tip" slot="tip" v-if="showTip && !disabled" style="font-size: 12px; margin-top: 4px; line-height: 1.4;"> | |||
| <template v-if="fileSize"> 大小: ≤ <b style="color: #f56c6c">{{ fileSize }}MB</b> </template> | |||
| <template v-if="fileType && fileSize">,</template> | |||
| <template v-if="fileType"> 格式: <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template> | |||
| </div> | |||
| <!-- 预览弹窗 --> | |||
| <el-dialog :visible.sync="dialogVisible" title="预览" :width="dialogWidth" append-to-body :close-on-click-modal="true"> | |||
| <img :src="dialogImageUrl" style="display: block; max-width: 100%; max-height: 70vh; margin: 0 auto;" @load="handleImageLoad"/> | |||
| </el-dialog> | |||
| </div> | |||
| </template> | |||
| <script> | |||
| import { getToken } from "@/utils/auth"; | |||
| import { isExternal } from "@/utils/validate"; | |||
| import Sortable from 'sortablejs'; | |||
| import {Dialog} from "vant"; | |||
| import {commonUpload} from "@/api/sunVillage_info/fixedAssets"; | |||
| export default { | |||
| name: "commonUpload", | |||
| props: { | |||
| name: String, | |||
| value: { // 绑定值 字符串 ,分隔 可监听 | |||
| type: String, | |||
| default: null, | |||
| }, | |||
| accept: { // 上传类型限制: 默认图片, * = 任意类型 | |||
| type: String, | |||
| }, | |||
| multiple: { // 多文件上传 | |||
| type: Boolean, | |||
| default: false, | |||
| }, | |||
| deletable: { // 允许删除 | |||
| type: Boolean, | |||
| default: true, | |||
| }, | |||
| showUpload: { // 显示上传按钮 | |||
| type: Boolean, | |||
| default: true, | |||
| }, | |||
| formData: { // 额外请求参数 | |||
| type: Object, | |||
| default: function() { | |||
| return {}; | |||
| export default { | |||
| props: { | |||
| value: [String, Object, Array], | |||
| action: { | |||
| type: String, | |||
| default: "/common/upload" | |||
| }, | |||
| data: { | |||
| type: Object | |||
| }, | |||
| limit: { | |||
| type: Number, | |||
| default: 5 | |||
| }, | |||
| fileSize: { | |||
| type: Number, | |||
| default: 3 | |||
| }, | |||
| fileType: { | |||
| type: Array, | |||
| default: () => ["png", "jpg", "jpeg"] | |||
| }, | |||
| isShowTip: { | |||
| type: Boolean, | |||
| default: true | |||
| }, | |||
| disabled: { | |||
| type: Boolean, | |||
| default: false | |||
| }, | |||
| drag: { | |||
| type: Boolean, | |||
| default: false | |||
| } | |||
| }, | |||
| file: { // 上传文件字段名 | |||
| type: String, | |||
| default: 'file', | |||
| }, | |||
| host: { | |||
| type: String, // 文件地址前缀 | |||
| default: '/api', | |||
| data() { | |||
| return { | |||
| number: 0, | |||
| uploadList: [], | |||
| dialogImageUrl: "", | |||
| dialogVisible: false, | |||
| dialogWidth: "90%", | |||
| baseUrl: process.env.VUE_APP_BASE_API, | |||
| uploadImgUrl: process.env.VUE_APP_BASE_API + this.action, | |||
| headers: { | |||
| Authorization: "Bearer " + getToken(), | |||
| }, | |||
| fileList: [] | |||
| }; | |||
| }, | |||
| }, | |||
| watch: { | |||
| value: function (newVal, oldVal) { | |||
| if(newVal != this.internalValue) | |||
| this.setInternalValue(newVal); | |||
| mounted() { | |||
| if (this.drag && !this.disabled) { | |||
| this.$nextTick(() => { | |||
| const element = this.$refs.imageUpload?.$el?.querySelector('.el-upload-list'); | |||
| if (element) { | |||
| Sortable.create(element, { | |||
| onEnd: (evt) => { | |||
| const movedItem = this.fileList.splice(evt.oldIndex, 1)[0]; | |||
| this.fileList.splice(evt.newIndex, 0, movedItem); | |||
| this.$emit("input", this.listToString(this.fileList)); | |||
| }, | |||
| handle: ".el-upload-list__item", | |||
| animation: 150 | |||
| }); | |||
| } | |||
| }); | |||
| } | |||
| window.addEventListener("resize", this.adjustDialogWidth); | |||
| }, | |||
| }, | |||
| created() { | |||
| this.parseValue(this.value); | |||
| }, | |||
| data() { | |||
| return { | |||
| internalValue: this.value, | |||
| fileList: [], | |||
| pathList: [], | |||
| }; | |||
| }, | |||
| methods: { | |||
| setInternalValue(newVal) { | |||
| this.parseValue(newVal); | |||
| this.internalValue = newVal; | |||
| beforeDestroy() { | |||
| window.removeEventListener("resize", this.adjustDialogWidth); | |||
| }, | |||
| parseValue(data) { | |||
| if(data) | |||
| { | |||
| this.pathList = data.split(','); | |||
| } | |||
| else | |||
| { | |||
| this.pathList = []; | |||
| watch: { | |||
| value: { | |||
| handler(val) { | |||
| if (val) { | |||
| const list = Array.isArray(val) ? val : val.split(','); | |||
| this.fileList = list.map(item => { | |||
| if (typeof item === "string") { | |||
| const imgUrl = !isExternal(item) && item.indexOf(this.baseUrl) === -1 | |||
| ? `${this.baseUrl}${item}` | |||
| : item; | |||
| return { | |||
| name: imgUrl, | |||
| url: imgUrl, | |||
| response: { url: imgUrl } | |||
| }; | |||
| } | |||
| return item; | |||
| }); | |||
| } else { | |||
| this.fileList = []; | |||
| } | |||
| }, | |||
| deep: true, | |||
| immediate: true | |||
| } | |||
| this.fileList = this.pathList.map((x) => { | |||
| return { | |||
| url: this.host + x, | |||
| }; | |||
| }); | |||
| }, | |||
| makeFormData() { | |||
| let fd = new FormData(); | |||
| if(this.formData) | |||
| { | |||
| for(let k of Object.keys(this.formData)) | |||
| { | |||
| fd.set(k, this.formData[k]); | |||
| } | |||
| computed: { | |||
| showTip() { | |||
| return this.isShowTip && (this.fileType.length || this.fileSize); | |||
| } | |||
| return fd; | |||
| }, | |||
| upload(file) { | |||
| let params1 = this.makeFormData(); | |||
| params1.append(this.file, file.file); | |||
| return commonUpload(params1).then((resp) => { | |||
| this.pathList.push(resp.fileName); | |||
| this.updateInternalValue(); | |||
| this.$emit('upload', resp.fileName); | |||
| }); | |||
| }, | |||
| afterRead(file) { | |||
| this.$toast.loading({ | |||
| message: "上传中...", | |||
| forbidClick: true, | |||
| duration: 0, | |||
| }); | |||
| // 此时可以自行将文件上传至服务器 | |||
| if (file instanceof Array) {//判断是否为数组,单张图片为array,多张为数组,数组返回true否则为false | |||
| if(file.length > 0) | |||
| { | |||
| let index = 0; | |||
| const f = () => { | |||
| if(index >= file.length) | |||
| return; | |||
| let up = file[index]; | |||
| //console.log(up); | |||
| console.log(`上传文件: ${index} -> ${up.file.name}`); | |||
| this.upload(up).then(() => { | |||
| index++; | |||
| if(index < file.length) | |||
| f(); | |||
| }); | |||
| }; | |||
| f(); | |||
| methods: { | |||
| adjustDialogWidth() { | |||
| const screenWidth = window.innerWidth; | |||
| this.dialogWidth = screenWidth < 375 ? "95%" : "90%"; | |||
| }, | |||
| handleBeforeUpload(file) { | |||
| let isImg = false; | |||
| const fileExtension = file.name.lastIndexOf(".") > -1 | |||
| ? file.name.slice(file.name.lastIndexOf(".") + 1).toLowerCase() | |||
| : ""; | |||
| if (this.fileType.length) { | |||
| isImg = this.fileType.includes(fileExtension) || file.type.includes(fileExtension); | |||
| } else { | |||
| isImg = file.type.indexOf("image") > -1; | |||
| } | |||
| if (!isImg) { | |||
| this.$modal.msgError(`请上传${this.fileType.join("/")}格式图片`); | |||
| return false; | |||
| } | |||
| if (file.name.includes(',')) { | |||
| this.$modal.msgError("文件名不能包含英文逗号"); | |||
| return false; | |||
| } | |||
| if (this.fileSize) { | |||
| const isLt = file.size / 1024 / 1024 < this.fileSize; | |||
| if (!isLt) { | |||
| this.$modal.msgError(`图片大小不能超过${this.fileSize}MB`); | |||
| return false; | |||
| } | |||
| } | |||
| this.$modal.loading({ | |||
| message: "上传中...", | |||
| lock: false | |||
| }); | |||
| this.number++; | |||
| }, | |||
| handleExceed() { | |||
| this.$modal.msgError(`最多可上传${this.limit}张图片`); | |||
| }, | |||
| handleUploadSuccess(res, file) { | |||
| if (res.code === 200) { | |||
| this.uploadList.push({ | |||
| name: res.fileName, | |||
| url: res.fileName, | |||
| response: { url: `${this.baseUrl}${res.fileName}` } | |||
| }); | |||
| this.uploadedSuccessfully(); | |||
| } else { | |||
| this.number--; | |||
| this.$modal.closeLoading(); | |||
| this.$modal.msgError(res.msg || "上传失败"); | |||
| this.$refs.imageUpload?.handleRemove(file); | |||
| } | |||
| }, | |||
| handleDelete(file, list) { | |||
| Dialog.confirm({ | |||
| title: '提示', | |||
| message: '确定要移除这张图片吗?', | |||
| }) | |||
| .then(() => { | |||
| const findex = this.fileList.map(f => f.name).indexOf(file.name); | |||
| if (findex > -1) { | |||
| this.fileList.splice(findex, 1); | |||
| this.$emit("input", this.listToString(this.fileList)); | |||
| } | |||
| }) | |||
| .catch(() => { | |||
| // on cancel | |||
| }); | |||
| }, | |||
| handleUploadError() { | |||
| this.$modal.closeLoading(); | |||
| this.$modal.msgError("上传失败,请重试"); | |||
| }, | |||
| uploadedSuccessfully() { | |||
| if (this.number > 0 && this.uploadList.length === this.number) { | |||
| this.fileList = this.fileList.concat(this.uploadList); | |||
| this.uploadList = []; | |||
| this.number = 0; | |||
| this.$emit("input", this.listToString(this.fileList)); | |||
| this.$modal.closeLoading(); | |||
| this.$modal.msgSuccess("全部上传完成"); | |||
| } | |||
| }, | |||
| handlePictureCardPreview(file) { | |||
| this.dialogImageUrl = file.url || file.response?.url; | |||
| this.adjustDialogWidth(); | |||
| this.dialogVisible = true; | |||
| }, | |||
| handleImageLoad(e) { | |||
| const img = e.target; | |||
| const maxHeight = window.innerHeight * 0.7; | |||
| if (img.height > maxHeight) { | |||
| img.style.height = `${maxHeight}px`; | |||
| img.style.width = "auto"; | |||
| } | |||
| } else { | |||
| this.upload(file); | |||
| }, | |||
| listToString(list, separator) { | |||
| separator = separator || ","; | |||
| return list | |||
| .filter(item => item.url) | |||
| .map(item => item.url.replace(this.baseUrl, "")) | |||
| .join(separator); | |||
| } | |||
| }, | |||
| deleteFile(detail){ | |||
| this.pathList.splice(detail.index,1); | |||
| this.updateInternalValue(); | |||
| this.$emit('remove', detail.index); | |||
| }, | |||
| updateInternalValue() { | |||
| let files = this.pathList.join(','); | |||
| console.log(files); | |||
| this.internalValue = files; | |||
| if(this.internalValue != this.value) | |||
| this.$emit('input', this.internalValue); | |||
| }, | |||
| }, | |||
| } | |||
| } | |||
| }; | |||
| </script> | |||
| <style scoped> | |||
| <style scoped lang="scss"> | |||
| // 上传按钮样式 | |||
| .upload-btn { | |||
| width: 60px; | |||
| height: 60px; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| border: 1px dashed #dcdcdc; | |||
| border-radius: 4px; | |||
| background-color: #fafafa; | |||
| margin: 0; | |||
| transition: all 0.2s; | |||
| &:hover { | |||
| border-color: #409eff; | |||
| background-color: #f5faff; | |||
| } | |||
| &:active { | |||
| background-color: #f0f7ff; | |||
| } | |||
| } | |||
| // 已上传图片项样式 | |||
| ::v-deep .el-upload-list--picture-card .el-upload-list__item { | |||
| width: 60px; | |||
| height: 60px; | |||
| border-radius: 4px; | |||
| overflow: hidden; | |||
| position: relative; | |||
| border: 1px solid #e5e7eb; | |||
| .el-upload-list__item-thumbnail { | |||
| object-fit: cover; | |||
| width: 100%; | |||
| height: 100%; | |||
| } | |||
| .el-upload-list__item-delete { | |||
| position: absolute; | |||
| top: -8px; | |||
| right: -8px; | |||
| width: 20px; | |||
| height: 20px; | |||
| font-size: 12px; | |||
| background-color: #f56c6c; | |||
| color: #fff; | |||
| border-radius: 50%; | |||
| display: flex; | |||
| align-items: center; | |||
| justify-content: center; | |||
| box-shadow: 0 2px 4px rgba(0,0,0,0.1); | |||
| z-index: 10; | |||
| &:hover, &:active { | |||
| width: 22px; | |||
| height: 22px; | |||
| background-color: #e4393c; | |||
| top: -9px; | |||
| right: -9px; | |||
| } | |||
| } | |||
| &:hover { | |||
| border-color: #409eff; | |||
| } | |||
| &:hover .el-upload-list__item-delete { | |||
| opacity: 1; | |||
| } | |||
| } | |||
| // 移除外层默认边框 | |||
| ::v-deep .el-upload--picture-card { | |||
| border: none !important; | |||
| background: transparent !important; | |||
| margin-bottom: 0 !important; /* 移除上传组件底部默认边距 */ | |||
| } | |||
| // 隐藏上传按钮(数量达限时) | |||
| ::v-deep.hide .el-upload--picture-card { | |||
| display: none; | |||
| } | |||
| // 禁用状态样式 | |||
| ::v-deep .el-upload-list--picture-card.is-disabled + .el-upload--picture-card { | |||
| display: none !important; | |||
| } | |||
| // 列表动画优化 | |||
| ::v-deep .el-list-enter-active, | |||
| ::v-deep .el-list-leave-active { | |||
| transition: all 0s; | |||
| } | |||
| ::v-deep .el-list-enter, | |||
| ::v-deep .el-list-leave-active { | |||
| opacity: 0; | |||
| transform: translateY(0); | |||
| } | |||
| // 小屏幕适配 | |||
| @media screen and (max-width: 375px) { | |||
| .upload-btn, | |||
| ::v-deep .el-upload-list--picture-card .el-upload-list__item { | |||
| width: 55px; | |||
| height: 55px; | |||
| } | |||
| .el-upload--picture-card { | |||
| grid-template-columns: repeat(auto-fill, minmax(55px, 1fr)); | |||
| gap: 8px; | |||
| } | |||
| // 提示文字进一步缩小间距 | |||
| .el-upload__tip { | |||
| margin-top: 3px !important; | |||
| font-size: 11px !important; | |||
| } | |||
| ::v-deep .el-upload-list__item-delete { | |||
| width: 18px; | |||
| height: 18px; | |||
| top: -7px; | |||
| right: -7px; | |||
| &:hover, &:active { | |||
| width: 20px; | |||
| height: 20px; | |||
| top: -8px; | |||
| right: -8px; | |||
| } | |||
| } | |||
| } | |||
| </style> | |||
| @@ -416,3 +416,265 @@ export function save(name, src) { | |||
| } | |||
| } | |||
| /** | |||
| * 解析日期时间 | |||
| * @param date 日期时间字符串 字符串 | |||
| * @param format 格式化字符串 字符串 默认 yyyy-MM-dd HH:mm:ss | |||
| * @param initNow 缺省部分是否使用当前日期时间部分代替 bool 默认不使用当前 | |||
| * @returns {Date} 解析日期时间出来的Date对象 | |||
| */ | |||
| export function strtotime(date, format, initNow) | |||
| { | |||
| if (!date) | |||
| return null; | |||
| let expect = function(target, str) { | |||
| if(Array.isArray(target)) | |||
| { | |||
| let res = 0; | |||
| if(typeof(target[0]) === 'number') | |||
| { | |||
| for(let t of target) | |||
| { | |||
| if(str.length >= t) | |||
| { | |||
| if(t > res && new RegExp(`^\\d{${t}}`).test(str)) | |||
| res = t; | |||
| } | |||
| } | |||
| } | |||
| else | |||
| { | |||
| for(let t of target) | |||
| { | |||
| if(str.length < t.length) | |||
| continue; | |||
| if(str.startsWith(t)) | |||
| { | |||
| res = t.length; | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| return res; | |||
| } | |||
| else | |||
| { | |||
| if(typeof(target) === 'number') | |||
| { | |||
| if(str.length < target) | |||
| return 0; | |||
| if(!new RegExp(`^\\d{${target}}`).test(str)) | |||
| return null; | |||
| return target; | |||
| } | |||
| else if(typeof(target) === 'object') | |||
| { | |||
| let res = 0; | |||
| let min = target.min || 0; | |||
| let max = target.max; | |||
| for(let m = min; m <= max; m++) | |||
| { | |||
| let t = '' + m; | |||
| if(str.length >= t.length) | |||
| { | |||
| if(str.startsWith(t)) | |||
| res = t.length; | |||
| } | |||
| } | |||
| return res; | |||
| } | |||
| else | |||
| { | |||
| if(str.length < target.length) | |||
| return 0; | |||
| if(!str.startsWith(target)) | |||
| return 0; | |||
| return target.length; | |||
| } | |||
| } | |||
| }; | |||
| format = format || 'yyyy-MM-dd HH:mm:ss'; | |||
| let arr = parseDateTimeFormatter(format); | |||
| let i = 0; | |||
| let _y = undefined; | |||
| let _m = undefined; | |||
| let _d = undefined; | |||
| let _h = undefined; | |||
| let _i = undefined; | |||
| let _s = undefined; | |||
| let _z = undefined; | |||
| let _h_12 = undefined; | |||
| let _ap = undefined; | |||
| let get_token = function(str, target) { | |||
| let r = expect(target, date.substr(i)); | |||
| if(r <= 0) | |||
| return null; | |||
| let nstr = date.substr(i, r); | |||
| i += r; | |||
| return nstr; | |||
| }; | |||
| //console.log(arr); | |||
| for(let part of arr) | |||
| { | |||
| if(part.type === DATE_TIME_FORMAT_TYPE_RAW || part.type === DATE_TIME_FORMAT_TYPE_IGNORE) | |||
| { | |||
| let r = expect(part.str, date.substr(i)); | |||
| if(!r) | |||
| return null; | |||
| i += r; | |||
| } | |||
| else | |||
| { | |||
| let p = null; | |||
| switch(part.str) | |||
| { | |||
| case 'yyyy': | |||
| case '%Y': | |||
| p = get_token(part.str, 4); | |||
| if(p) | |||
| _y = parseInt(p); | |||
| break; | |||
| case 'yy': | |||
| case '%y': | |||
| p = get_token(part.str, 2); | |||
| if(p) | |||
| _y = Math.floor((date.getFullYear()) / 100) * 100 + parseInt(p); | |||
| break; | |||
| case 'MM': | |||
| case '%m': | |||
| p = get_token(part.str, 2); | |||
| if(p) | |||
| _m = parseInt(p); | |||
| break; | |||
| case 'M': | |||
| case '%c': | |||
| p = get_token(part.str, {min: 1, max: 12}); | |||
| if(p) | |||
| _m = parseInt(p); | |||
| break; | |||
| case 'MMMM': | |||
| case '%M': | |||
| p = get_token(part.str, MONTHS); | |||
| if(p) | |||
| _m = MONTHS.indexOf(p) + 1; | |||
| break; | |||
| case 'MMM': | |||
| case '%b': | |||
| p = get_token(part.str, MONTHS_SIMPLE); | |||
| if(p) | |||
| _m = MONTHS_SIMPLE.indexOf(p) + 1; | |||
| break; | |||
| case 'dd': | |||
| case '%d': | |||
| p = get_token(part.str, 2); | |||
| if(p) | |||
| _d = parseInt(p); | |||
| break; | |||
| case 'HH': | |||
| case '%H': | |||
| p = get_token(part.str, 2); | |||
| if(p) | |||
| _h = parseInt(p); | |||
| break; | |||
| case 'H': | |||
| case '%k': | |||
| p = get_token(part.str, {max: 23}); | |||
| if(p) | |||
| _h = parseInt(p); | |||
| break; | |||
| case 'hh': | |||
| case '%I': | |||
| case '%h': | |||
| p = get_token(part.str, 2); | |||
| if(p) | |||
| _h_12 = parseInt(p); | |||
| break; | |||
| case 'h': | |||
| case '%l': | |||
| p = get_token(part.str, {max: 12}); | |||
| if(p) | |||
| _h_12 = parseInt(p); | |||
| break; | |||
| case 'mm': | |||
| case 'ii': | |||
| case '%i': | |||
| p = get_token(part.str, 2); | |||
| if(p) | |||
| _i = parseInt(p); | |||
| break; | |||
| case 'm': | |||
| case 'i': | |||
| p = get_token(part.str, {max: 59}); | |||
| if(p) | |||
| _i = parseInt(p); | |||
| break; | |||
| case 'ss': | |||
| case '%s': | |||
| case '%S': | |||
| p = get_token(part.str, 2); | |||
| if(p) | |||
| _s = parseInt(p); | |||
| break; | |||
| case 's': | |||
| p = get_token(part.str, {max: 59}); | |||
| if(p) | |||
| _s = parseInt(p); | |||
| break; | |||
| case 'sss': | |||
| p = get_token(part.str, {max: 999}); | |||
| if(p) | |||
| _z = parseInt(p); | |||
| break; | |||
| case 'A': | |||
| case 'p': { | |||
| const AP = ['AM', 'PM']; | |||
| p = get_token(part.str, AP); | |||
| if(p) | |||
| _ap = p.toLowerCase(); | |||
| } | |||
| break; | |||
| case 'a': | |||
| case 'P': | |||
| case '%p':{ | |||
| const AP = ['am', 'pm']; | |||
| p = get_token(part.str, AP); | |||
| if(p) | |||
| _ap = p; | |||
| } | |||
| break; | |||
| case 'u': | |||
| case '%w': | |||
| case '%W': | |||
| case 'dddd': | |||
| case 'ddd': | |||
| throw new Error('不支持星期几解析: ' + part.str); // not ignore and throw | |||
| //break; | |||
| case '%%': | |||
| //TODO: ignore 最好不解析出来 | |||
| break; | |||
| default: | |||
| throw new Error('不支持的格式解析: ' + part.str); | |||
| break; | |||
| } | |||
| if(!p) | |||
| return null; | |||
| } | |||
| } | |||
| if(_h_12 !== undefined && _ap !== undefined) | |||
| { | |||
| _h = (_ap === 'pm' ? _h_12 + 12 : _h_12) % 24; | |||
| } | |||
| let res = new Date; | |||
| //console.log('1111111111',_y, _m, _d, _h, _i, _s, _z); | |||
| if(_y === undefined) _y = initNow ? res.getFullYear() : 0; | |||
| if(_m === undefined) _m = initNow ? res.getMonth() + 1 : 1; | |||
| if(_d === undefined) _d = initNow ? res.getDate() : 1; | |||
| if(_h === undefined) _h = initNow ? res.getHours() : 0; | |||
| if(_i === undefined) _i = initNow ? res.getMinutes() : 0; | |||
| if(_s === undefined) _s = initNow ? res.getSeconds() : 0; | |||
| if(_z === undefined) _z = initNow ? res.getMilliseconds() : 0; | |||
| //console.log('2222222222',_y, _m, _d, _h, _i, _s, _z); | |||
| res.setFullYear(_y, _m - 1, _d); | |||
| res.setHours(_h, _i, _s, _z); | |||
| return res; | |||
| } | |||
| @@ -3,70 +3,48 @@ | |||
| <van-nav-bar title="经营信息维护" left-arrow placeholder safe-area-inset-top @click-left="onClickLeft"/> | |||
| <van-form @submit="onSubmit"> | |||
| <div class="main"> | |||
| <p class="title"><i></i>经营信息</p> | |||
| <van-field readonly v-model="form.deptName" label="区域位置名称" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field readonly required :rules="[{ required: true }]" v-model="form.dkbm" label="地块编码" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field readonly :rules="[{ required: true }]" v-model="form.dkmc" label="地块名称" placeholder="请输入" input-align="right" label-width="auto" required /> | |||
| <van-field readonly v-model="form.dkdz" label="地块东至" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field readonly v-model="form.dkxz" label="地块西至" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field readonly v-model="form.dknz" label="地块南至" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field readonly v-model="form.dkbz" label="地块北至" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <div class="main"> | |||
| <p class="title"><i></i>经营信息</p> | |||
| <van-field readonly v-model="form.deptName" label="区域位置名称" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field readonly v-model="form.dkbm" label="地块编码" placeholder="请输入" input-align="right" label-width="auto" required :rules="[{ required: true }]"/> | |||
| <van-field readonly v-model="form.dkmc" label="地块名称" placeholder="请输入" input-align="right" label-width="auto" required :rules="[{ required: true }]"/> | |||
| <van-field readonly v-model="form.dkdz" label="地块东至" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field readonly v-model="form.dkxz" label="地块西至" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field readonly v-model="form.dknz" label="地块南至" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field readonly v-model="form.dkbz" label="地块北至" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field required :rules="[{ required: true }]" v-model="form.jymj" label="经营面积" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field v-model="form.jymj" label="经营面积" placeholder="请输入" type="number" input-align="right" label-width="auto" required :rules="[{ required: true }]"/> | |||
| <van-field required :rules="[{ required: true }]" readonly @click="showJyfsPicker = true" v-model="form.jyfsText" label="经营方式" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-popup v-model="showJyfsPicker" round position="bottom"> | |||
| <van-picker show-toolbar :columns="dict.type.jyfs" value-key="label" @cancel="showJyfsPicker = false" @confirm="onConfirmJyfs"/> | |||
| </van-popup> | |||
| <field-select v-model="form.jyfs" label="经营方式" placeholder="请选择" value-key="dictLabel" data-key="dictValue" remote-url="/system/dict/data/type/jyfs" :on-remote-response="'data'" required/> | |||
| <van-field readonly @click="showJydxlxPicker = true" v-model="form.jydxlxText" label="经营对象类型" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-popup v-model="showJydxlxPicker" round position="bottom"> | |||
| <van-picker show-toolbar :columns="dict.type.jydxlx" value-key="label" @cancel="showJydxlxPicker = false" @confirm="onConfirmJydxlx"/> | |||
| </van-popup> | |||
| <field-select v-model="form.jydxlx" label="经营对象类型" placeholder="请选择" value-key="dictLabel" data-key="dictValue" remote-url="/system/dict/data/type/jydxlx" :on-remote-response="'data'" required/> | |||
| <van-field required :rules="[{ required: true }]" v-model="form.jydxmc" label="经营对象名称" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field v-model="form.jydxmc" label="经营对象名称" placeholder="请输入" input-align="right" label-width="auto" required :rules="[{ required: true }]"/> | |||
| <van-field readonly @click="showJydxzjlxPicker = true" v-model="form.jydxzjlxText" label="经营对象证件类型" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-popup v-model="showJydxzjlxPicker" round position="bottom"> | |||
| <van-picker show-toolbar :columns="dict.type.zjlx" value-key="label" @cancel="showJydxzjlxPicker = false" @confirm="onConfirmJydxzjlx"/> | |||
| </van-popup> | |||
| <field-select v-model="form.jydxlx" label="经营对象证件类型" placeholder="请选择" value-key="dictLabel" data-key="dictValue" remote-url="/system/dict/data/type/zjlx" :on-remote-response="'data'"/> | |||
| <van-field v-model="form.jydxzjhm" label="经营对象证件号码" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field v-model="form.jydxzjhm" label="经营对象证件号码" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field readonly @click="showSfqdhtPicker = true" v-model="form.sfqdhtText" label="是否签订合同" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-popup v-model="showSfqdhtPicker" round position="bottom"> | |||
| <van-picker show-toolbar :columns="dict.type.is_common" value-key="label" @cancel="showSfqdhtPicker = false" @confirm="onConfirmSfqdht"/> | |||
| </van-popup> | |||
| <field-radio v-model="form.sfqdht" label="是否签订合同" value-key="dictLabel" data-key="dictValue" remote-url="/system/dict/data/type/is_common" :on-remote-response="'data'" required/> | |||
| <van-field required :rules="[{ required: true }]" readonly @click="showJykssjPicker = true" v-model="form.jykssj" label="经营开始时间" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-popup v-model="showJykssjPicker" round position="bottom"> | |||
| <van-datetime-picker v-model="jykssj" type="date" title="选择年月日" :min-date="minDate" :max-date="maxDate" @cancel="showJykssjPicker = false" @confirm="onConfirmJykssj"/> | |||
| </van-popup> | |||
| <field-date-picker v-model="form.jykssj" label="经营开始时间" placeholder="请选择" formatter="yyyy-MM-dd" input-align="right" type="date" :required="true" size="large"/> | |||
| <van-field required :rules="[{ required: true }]" readonly @click="showJyjssjPicker = true" v-model="form.jyjssj" label="经营结束时间" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-popup v-model="showJyjssjPicker" round position="bottom"> | |||
| <van-datetime-picker v-model="jyjssj" type="date" title="选择年月日" :min-date="minDate" :max-date="maxDate" @cancel="showJyjssjPicker = false" @confirm="onConfirmJyjssj"/> | |||
| </van-popup> | |||
| <field-date-picker v-model="form.jyjssj" label="经营结束时间" placeholder="请选择" formatter="yyyy-MM-dd" input-align="right" type="date" :required="true" size="large"/> | |||
| <van-field required :rules="[{ required: true }]" v-model="form.cbje" label="承包金额(元)" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field v-model="form.dxje" label="兑现金额(元)" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field v-model="form.sqje" label="尚欠金额(元)" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field v-model="form.nsy" label="年收益(元)" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field v-model="form.bzxx" label="备注信息" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-field v-model="form.cbje" label="承包金额(元)" placeholder="请输入" type="number" input-align="right" label-width="auto" required :rules="[{ required: true }]"/> | |||
| <van-field v-model="form.dxje" label="兑现金额(元)" placeholder="请输入" type="number" input-align="right" label-width="auto" /> | |||
| <van-field v-model="form.sqje" label="尚欠金额(元)" placeholder="请输入" type="number" input-align="right" label-width="auto" /> | |||
| <van-field v-model="form.nsy" label="年收益(元)" placeholder="请输入" type="number" input-align="right" label-width="auto" /> | |||
| <van-field v-model="form.bzxx" label="备注信息" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <!--<van-field readonly required :rules="[{ required: true }]" @click="showSurveyStatusPicker = true" v-model="form.surveyStatusText" label="调查状态" placeholder="请输入" input-align="right" label-width="auto" /> | |||
| <van-popup v-model="showSurveyStatusPicker" round position="bottom"> | |||
| <van-picker show-toolbar :columns="dict.type.survey_status" value-key="label" @cancel="showSurveyStatusPicker = false" @confirm="onConfirmSurveyStatus"/> | |||
| </van-popup>--> | |||
| <field-select v-model="form.surveyStatusText" label="调查状态" value-key="dictLabel" data-key="dictValue" placeholder="请选择" requiredx remote-url="/system/dict/data/type/survey_status" :on-remote-response="'data'"/> | |||
| <field-radio v-model="form.surveyStatus" label="调查状态" value-key="dictLabel" data-key="dictValue" remote-url="/system/dict/data/type/survey_status" :on-remote-response="'data'" required/> | |||
| <van-field readonly label="实物图" placeholder="" input-align="right" label-width="auto" /> | |||
| <image-upload v-model="form.dkImg"/> | |||
| <van-field label="实物图" placeholder="" input-align="right" label-width="auto" /> | |||
| <CommonUpload v-model="form.dkImg" accept="image/*" multiple :deletable="true" :show-upload="true" fileField="file" /> | |||
| </div> | |||
| </div> | |||
| <van-button round block type="primary" native-type="submit" class="subClass">提交</van-button> | |||
| <van-button round block type="primary" native-type="submit" class="subClass">提交</van-button> | |||
| </van-form> | |||
| </div> | |||
| @@ -76,23 +54,18 @@ | |||
| import { getLandDetail } from "@/api/resource/land" | |||
| import { getOperationDetail, updateOperation, addOperation } from "@/api/resource/operation" | |||
| import { getInfoByImportCode } from "@/api/system/dept"; | |||
| import FieldSelect from "@/components/form/FieldSelect.vue"; | |||
| import FieldRadio from "@/components/form/FieldRadio.vue"; | |||
| import FieldDatePicker from "@/components/form/FieldDatePicker.vue"; | |||
| import CommonUpload from "@/components/form/CommonUpload.vue"; | |||
| export default { | |||
| dicts: ['zjlx', 'survey_status', 'is_common', 'jydxlx', 'jyfs'], | |||
| name: "appEdit", | |||
| components: {FieldSelect}, | |||
| components: {FieldSelect, FieldRadio, FieldDatePicker, CommonUpload}, | |||
| data() { | |||
| return { | |||
| showJyfsPicker: false, | |||
| showSfqdhtPicker: false, | |||
| showJydxlxPicker: false, | |||
| showJydxzjlxPicker: false, | |||
| showJykssjPicker: false, | |||
| showJyjssjPicker: false, | |||
| showSurveyStatusPicker: false, | |||
| minDate: new Date(2020, 0, 1), | |||
| maxDate: new Date(2025, 10, 1), | |||
| importCode: null, | |||
| form: { | |||
| dkbm: null, | |||
| @@ -120,10 +93,6 @@ | |||
| importCode: null, | |||
| deptName: null, | |||
| }, | |||
| jykssj:new Date(), | |||
| jyjssj:new Date(), | |||
| openPic: [], | |||
| openPic2: [], | |||
| }; | |||
| }, | |||
| created() { | |||
| @@ -136,13 +105,6 @@ | |||
| getDetail(){ | |||
| getOperationDetail(this.$route.query.dkbm).then(response => { | |||
| if (response.data){ | |||
| response.data.jyfsText = this.selectDictLabel(this.dict.type.jyfs,response.data.jyfs); | |||
| response.data.jydxlxText = this.selectDictLabel(this.dict.type.jydxlx,response.data.jydxlx); | |||
| response.data.jydxzjlxText = this.selectDictLabel(this.dict.type.zjlx,response.data.jydxzjlx); | |||
| response.data.sfqdhtText = this.selectDictLabel(this.dict.type.is_common,response.data.sfqdht); | |||
| response.data.surveyStatusText = this.selectDictLabel(this.dict.type.survey_status,response.data.surveyStatus); | |||
| this.jykssj = new Date(response.data.jykssj); | |||
| this.jyjssj = new Date(response.data.jyjssj); | |||
| this.form = response.data | |||
| }else{ | |||
| getLandDetail(this.$route.query.dkbm).then(response => { | |||
| @@ -157,15 +119,11 @@ | |||
| this.form.dknz = response.data.dknz; | |||
| this.form.dkbz = response.data.dkbz; | |||
| this.form.jymj = response.data.scmjm; | |||
| this.form.jyfsText = '家庭承包'; | |||
| this.form.jyfs = '110'; | |||
| this.form.jydxlxText = '农户'; | |||
| this.form.jydxlx = '1'; | |||
| this.form.jydxzjlxText = '居民身份证'; | |||
| this.form.jydxzjlx = '1'; | |||
| this.form.sfqdhtText = '是'; | |||
| this.form.sfqdht = '1'; | |||
| this.form.surveyStatusText = '已调查'; | |||
| this.form.surveyStatus = '2'; | |||
| getInfoByImportCode(response.data.importCode).then((res) => { | |||
| @@ -175,39 +133,6 @@ | |||
| } | |||
| }); | |||
| }, | |||
| onConfirmJydxlx(value) { | |||
| this.form.jydxlxText = value.label; | |||
| this.form.jydxlx = value.value; | |||
| this.showJydxlxPicker = false; | |||
| }, | |||
| onConfirmJyfs(value) { | |||
| this.form.jyfsText = value.label; | |||
| this.form.jyfs = value.value; | |||
| this.showJyfsPicker = false; | |||
| }, | |||
| onConfirmJydxzjlx(value) { | |||
| this.form.jydxzjlxText = value.label; | |||
| this.form.jydxzjlx = value.value; | |||
| this.showJydxzjlxPicker = false; | |||
| }, | |||
| onConfirmSfqdht(value) { | |||
| this.form.sfqdhtText = value.label; | |||
| this.form.sfqdht = value.value; | |||
| this.showSfqdhtPicker = false; | |||
| }, | |||
| onConfirmJykssj(data) { | |||
| this.form.jykssj = this.format(data, 'yyyy-MM-dd'); | |||
| this.showJykssjPicker = false; | |||
| }, | |||
| onConfirmJyjssj(data) { | |||
| this.form.jyjssj = this.format(data, 'yyyy-MM-dd'); | |||
| this.showJyjssjPicker = false; | |||
| }, | |||
| onConfirmSurveyStatus(value) { | |||
| this.form.surveyStatusText = value.label; | |||
| this.form.surveyStatus = value.value; | |||
| this.showSurveyStatusPicker = false; | |||
| }, | |||
| /** 提交按钮 */ | |||
| onSubmit() { | |||
| if (!this.form.id){ | |||